@cortexkit/aft 0.58.1 → 0.59.0

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
@@ -109,8 +109,124 @@ var ACTIVE_LOGGER_SYMBOL;
109
109
  var init_active_logger = __esm(() => {
110
110
  ACTIVE_LOGGER_SYMBOL = Symbol.for("aft-bridge-active-logger");
111
111
  });
112
+ // ../aft-bridge/dist/path-display.js
113
+ import { homedir } from "node:os";
114
+ import { posix, win32 } from "node:path";
115
+ function shortenHomePath(path, home = homedir(), platform = process.platform) {
116
+ if (!home)
117
+ return path;
118
+ const normalize = (value) => platform === "win32" ? value.replace(/\\/g, "/").toLowerCase() : value;
119
+ const base = normalize(home).replace(/\/+$/, "");
120
+ const target = normalize(path);
121
+ if (target === normalize(home) || target === base)
122
+ return "~";
123
+ return target.startsWith(`${base}/`) ? `~${path.slice(base.length)}` : path;
124
+ }
125
+ function relativePathEscapesRoot(rel, platform = process.platform) {
126
+ return rel === ".." || rel.startsWith("../") || platform === "win32" && rel.startsWith("..\\") || (platform === "win32" ? win32.isAbsolute(rel) : posix.isAbsolute(rel));
127
+ }
128
+ var init_path_display = () => {};
129
+
112
130
  // ../aft-bridge/dist/bash-hints.js
113
- var init_bash_hints = () => {};
131
+ var init_bash_hints = __esm(() => {
132
+ init_path_display();
133
+ });
134
+
135
+ // ../aft-bridge/dist/test-child-environment.js
136
+ import { mkdirSync, realpathSync } from "node:fs";
137
+ import { homedir as homedir2, tmpdir } from "node:os";
138
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
139
+ function toolchainHomes(inherited) {
140
+ const global = globalThis;
141
+ if (!global[TOOLCHAINS]) {
142
+ const home = process.platform === "win32" ? inherited.USERPROFILE || inherited.HOME || homedir2() : inherited.HOME || homedir2();
143
+ global[TOOLCHAINS] = {
144
+ RUSTUP_HOME: inherited.RUSTUP_HOME || join(home, ".rustup"),
145
+ CARGO_HOME: inherited.CARGO_HOME || join(home, ".cargo")
146
+ };
147
+ }
148
+ return global[TOOLCHAINS];
149
+ }
150
+ function createdRoots() {
151
+ const global = globalThis;
152
+ return global[ROOTS] ??= new Set;
153
+ }
154
+ function isolatedAftEnvironment(root, inherited = process.env) {
155
+ const env = { ...inherited };
156
+ const toolchains = toolchainHomes(inherited);
157
+ env.RUSTUP_HOME ||= toolchains.RUSTUP_HOME;
158
+ env.CARGO_HOME ||= toolchains.CARGO_HOME;
159
+ const names = [
160
+ "home",
161
+ "home",
162
+ "local",
163
+ "config",
164
+ "data",
165
+ "state",
166
+ "cache",
167
+ "runtime",
168
+ "storage",
169
+ "aft-cache"
170
+ ];
171
+ for (const [index, key] of DIRECTORIES.entries()) {
172
+ env[key] = join(root, names[index]);
173
+ mkdirSync(env[key], { recursive: true });
174
+ }
175
+ delete env.AFT_ALLOW_PRODUCTION_MIGRATION;
176
+ createdRoots().add(resolve(root));
177
+ return env;
178
+ }
179
+ function canonical(path) {
180
+ let ancestor = resolve(path);
181
+ const tail = [];
182
+ while (true) {
183
+ try {
184
+ return join(realpathSync(ancestor), ...tail);
185
+ } catch {
186
+ const parent = dirname(ancestor);
187
+ if (parent === ancestor)
188
+ return resolve(path);
189
+ tail.unshift(relative(parent, ancestor));
190
+ ancestor = parent;
191
+ }
192
+ }
193
+ }
194
+ function within(path, root) {
195
+ const tail = relative(canonical(root), canonical(path));
196
+ return tail === "" || !tail.startsWith("..") && !isAbsolute(tail);
197
+ }
198
+ function testChildEnvironment(env) {
199
+ const root = process.env.AFT_TEST_ISOLATION_ROOT;
200
+ if (!root)
201
+ return env;
202
+ const fallback = isolatedAftEnvironment(root, env);
203
+ for (const key of DIRECTORIES) {
204
+ const value = env[key];
205
+ if (value && ([...createdRoots()].some((created) => within(value, created)) || within(value, tmpdir()))) {
206
+ mkdirSync(value, { recursive: true });
207
+ fallback[key] = value;
208
+ }
209
+ }
210
+ fallback.AFT_TEST_ISOLATION_ROOT = root;
211
+ return fallback;
212
+ }
213
+ var DIRECTORIES, ROOTS, TOOLCHAINS;
214
+ var init_test_child_environment = __esm(() => {
215
+ DIRECTORIES = [
216
+ "HOME",
217
+ "USERPROFILE",
218
+ "LOCALAPPDATA",
219
+ "XDG_CONFIG_HOME",
220
+ "XDG_DATA_HOME",
221
+ "XDG_STATE_HOME",
222
+ "XDG_CACHE_HOME",
223
+ "XDG_RUNTIME_DIR",
224
+ "AFT_STORAGE_DIR",
225
+ "AFT_CACHE_DIR"
226
+ ];
227
+ ROOTS = Symbol.for("cortexkit.aft.created-test-child-roots");
228
+ TOOLCHAINS = Symbol.for("cortexkit.aft.test-child-toolchain-homes");
229
+ });
114
230
 
115
231
  // ../aft-bridge/dist/child-process.js
116
232
  import { execFile as nodeExecFile, execFileSync as nodeExecFileSync, execSync as nodeExecSync, spawn as nodeSpawn, spawnSync as nodeSpawnSync } from "node:child_process";
@@ -130,10 +246,19 @@ function withWindowsHidden(args, takesArgv) {
130
246
  return out;
131
247
  }
132
248
  function hidden(resolve, takesArgv) {
133
- return (...args) => resolve()(...withWindowsHidden(args, takesArgv));
249
+ return (...args) => {
250
+ const out = withWindowsHidden(args, takesArgv);
251
+ if (process.env.AFT_TEST_ISOLATION_ROOT) {
252
+ const index = takesArgv && (Array.isArray(out[1]) || out[1] == null && out.length > 2) ? 2 : 1;
253
+ const options = out[index];
254
+ options.env = testChildEnvironment(options.env ?? process.env);
255
+ }
256
+ return resolve()(...out);
257
+ };
134
258
  }
135
259
  var HIDDEN, spawn, spawnSync, execFile, execFileSync, execSync;
136
260
  var init_child_process = __esm(() => {
261
+ init_test_child_environment();
137
262
  HIDDEN = { windowsHide: true };
138
263
  spawn = hidden(() => nodeSpawn, true);
139
264
  spawnSync = hidden(() => nodeSpawnSync, true);
@@ -165,8 +290,8 @@ function withPathPrepended(env, dir, platform = process.platform) {
165
290
  }
166
291
 
167
292
  // ../aft-bridge/dist/storage-paths.js
168
- import { homedir, tmpdir } from "node:os";
169
- import { join, resolve } from "node:path";
293
+ import { homedir as homedir3, tmpdir as tmpdir2 } from "node:os";
294
+ import { join as join2, resolve as resolve2 } from "node:path";
170
295
  function environmentValue(context, name) {
171
296
  const value = (context.lookup ?? ((key) => process.env[key]))(name);
172
297
  return value !== undefined && value.length > 0 ? value : undefined;
@@ -176,7 +301,7 @@ function storagePlatform(context) {
176
301
  }
177
302
  function homeDir(context) {
178
303
  const configured = storagePlatform(context) === "windows" ? environmentValue(context, "USERPROFILE") ?? environmentValue(context, "HOME") : environmentValue(context, "HOME") ?? environmentValue(context, "USERPROFILE");
179
- return configured ?? context.fallbackHome ?? homedir();
304
+ return configured ?? context.fallbackHome ?? homedir3();
180
305
  }
181
306
  function resolveDataHome(context = {}) {
182
307
  const xdg = environmentValue(context, "XDG_DATA_HOME");
@@ -188,21 +313,21 @@ function resolveDataHome(context = {}) {
188
313
  return localAppData;
189
314
  const userProfile = environmentValue(context, "USERPROFILE");
190
315
  if (userProfile)
191
- return join(userProfile, "AppData", "Local");
316
+ return join2(userProfile, "AppData", "Local");
192
317
  }
193
318
  const home = environmentValue(context, "HOME");
194
319
  if (home)
195
- return join(home, ".local", "share");
196
- return join(".local", "share");
320
+ return join2(home, ".local", "share");
321
+ return join2(".local", "share");
197
322
  }
198
323
  function resolveStoragePath(raw, context = {}) {
199
324
  let expanded = raw;
200
325
  if (raw === "~") {
201
326
  expanded = homeDir(context);
202
327
  } else if (raw.startsWith("~/") || raw.startsWith("~\\")) {
203
- expanded = join(homeDir(context), raw.slice(2));
328
+ expanded = join2(homeDir(context), raw.slice(2));
204
329
  }
205
- return resolve(context.currentDirectory ?? process.cwd(), expanded);
330
+ return resolve2(context.currentDirectory ?? process.cwd(), expanded);
206
331
  }
207
332
  function resolveCortexKitStorageRoot(context = {}) {
208
333
  const override = environmentValue(context, "AFT_STORAGE_DIR");
@@ -210,8 +335,8 @@ function resolveCortexKitStorageRoot(context = {}) {
210
335
  return resolveStoragePath(override, context);
211
336
  const legacyCache = environmentValue(context, "AFT_CACHE_DIR");
212
337
  if (legacyCache)
213
- return join(resolveStoragePath(legacyCache, context), "aft");
214
- return resolveStoragePath(join(resolveDataHome(context), "cortexkit", "aft"), context);
338
+ return join2(resolveStoragePath(legacyCache, context), "aft");
339
+ return resolveStoragePath(join2(resolveDataHome(context), "cortexkit", "aft"), context);
215
340
  }
216
341
  function resolveAftStorageRoot(configuredRoot, context = {}) {
217
342
  if (environmentValue(context, "AFT_STORAGE_DIR")) {
@@ -222,14 +347,14 @@ function resolveAftStorageRoot(configuredRoot, context = {}) {
222
347
  return resolveCortexKitStorageRoot(context);
223
348
  }
224
349
  function resolveAftLogPath(filename, configuredRoot, context = {}) {
225
- return join(resolveAftStorageRoot(configuredRoot, context), "logs", filename);
350
+ return join2(resolveAftStorageRoot(configuredRoot, context), "logs", filename);
226
351
  }
227
352
  function isTestEnvironment(context = {}) {
228
353
  return environmentValue(context, "BUN_TEST") === "1" || environmentValue(context, "NODE_ENV") === "test";
229
354
  }
230
355
  function resolvePluginLogPath(context = {}) {
231
356
  if (isTestEnvironment(context)) {
232
- return join(environmentValue(context, "TMPDIR") ?? tmpdir(), "aft-plugin-test.log");
357
+ return join2(environmentValue(context, "TMPDIR") ?? tmpdir2(), `aft-plugin-tests-${process.pid}`, "logs", "aft-plugin-test.log");
233
358
  }
234
359
  return resolveAftLogPath("aft-plugin.log", undefined, context);
235
360
  }
@@ -246,7 +371,7 @@ var init_bash_host_fallback = __esm(() => {
246
371
 
247
372
  // ../aft-bridge/dist/binary-identity.js
248
373
  import { createHash } from "node:crypto";
249
- import { createReadStream, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
374
+ import { closeSync, createReadStream, openSync, readFileSync, readSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
250
375
  function bareVersion(version) {
251
376
  return version.startsWith("v") ? version.slice(1) : version;
252
377
  }
@@ -311,7 +436,7 @@ function writeSidecarAtomically(binaryPath, identity) {
311
436
  const tmp = `${sidecar}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
312
437
  try {
313
438
  writeFileSync(tmp, `${JSON.stringify(identity)}
314
- `, "utf8");
439
+ `, { encoding: "utf8", mode: 384 });
315
440
  if (process.platform === "win32") {
316
441
  try {
317
442
  unlinkSync(sidecar);
@@ -428,12 +553,50 @@ function peekBinaryContentHash(binaryPath) {
428
553
  binaryContentHash(binaryPath);
429
554
  return null;
430
555
  }
431
- var SIDECAR_SCHEMA = 1, pendingIdentityWrites, contentHashCache, contentHashInFlight;
556
+ function digestStamp(path) {
557
+ const s = statSync(path, { bigint: true });
558
+ return `${s.dev}:${s.ino}:${s.size}:${s.mtimeNs}:${s.ctimeNs}`;
559
+ }
560
+ function readStampedFileDigest(path) {
561
+ try {
562
+ const value = JSON.parse(readFileSync(`${path}.digest.json`, "utf8"));
563
+ return value.schema === 1 && value.stamp === digestStamp(path) && typeof value.sha256 === "string" && /^[a-f0-9]{64}$/.test(value.sha256) ? value.sha256 : null;
564
+ } catch {
565
+ return null;
566
+ }
567
+ }
568
+ function writeStampedFileDigest(path, sha256, verifiedStamp) {
569
+ const sidecar = `${path}.digest.json`;
570
+ const tmp = `${sidecar}.${process.pid}.${Math.random().toString(16).slice(2)}.tmp`;
571
+ try {
572
+ writeFileSync(tmp, JSON.stringify({ schema: 1, stamp: verifiedStamp ?? digestStamp(path), sha256 }), { mode: 384 });
573
+ renameSync(tmp, sidecar);
574
+ } catch {} finally {
575
+ try {
576
+ unlinkSync(tmp);
577
+ } catch {}
578
+ }
579
+ }
580
+ async function cachedFileSha256(path) {
581
+ const known = readStampedFileDigest(path);
582
+ if (known)
583
+ return known;
584
+ const before = digestStamp(path);
585
+ digestWork.asyncHashes += 1;
586
+ digestWork.bytesHashed += Number(statSync(path).size);
587
+ const digest = await sha256File(path);
588
+ if (digestStamp(path) !== before)
589
+ throw new Error(`File changed while hashing: ${path}`);
590
+ writeStampedFileDigest(path, digest, before);
591
+ return digest;
592
+ }
593
+ var SIDECAR_SCHEMA = 1, pendingIdentityWrites, contentHashCache, contentHashInFlight, digestWork;
432
594
  var init_binary_identity = __esm(() => {
433
595
  init_active_logger();
434
596
  pendingIdentityWrites = new Set;
435
597
  contentHashCache = new Map;
436
598
  contentHashInFlight = new Map;
599
+ digestWork = { syncHashes: 0, asyncHashes: 0, bytesHashed: 0 };
437
600
  });
438
601
 
439
602
  // ../aft-bridge/dist/command-timeouts.js
@@ -445,9 +608,12 @@ var init_command_timeouts = __esm(() => {
445
608
  PASSIVE_COMMANDS = new Set(["status"]);
446
609
  });
447
610
 
611
+ // ../aft-bridge/dist/transport.js
612
+ var WORKER_SESSION_FIELD = "worker_session";
613
+
448
614
  // ../aft-bridge/dist/bridge.js
449
- import { homedir as homedir2 } from "node:os";
450
- import { join as join2 } from "node:path";
615
+ import { homedir as homedir4 } from "node:os";
616
+ import { join as join3 } from "node:path";
451
617
  import { StringDecoder } from "node:string_decoder";
452
618
  function isTerminalBashStatus(status) {
453
619
  return typeof status === "string" && TERMINAL_BASH_STATUSES.has(status);
@@ -535,14 +701,13 @@ function coerceConfigureDroppedKeys(value) {
535
701
  }
536
702
  return dropped;
537
703
  }
538
- var DEFAULT_BRIDGE_TIMEOUT_MS = 30000, BRIDGE_HANG_TIMEOUT_THRESHOLD = 2, MAX_STDOUT_BUFFER, STDOUT_BUFFER_COMPACT_THRESHOLD, HASHLINE_REGISTRATION_LOG_INTERVAL_MS = 60000, HASHLINE_REGISTRATION_LOG_STATE_LIMIT = 256, TERMINAL_BASH_STATUSES, binaryFingerprintReader, binaryFingerprintAsyncReader, BENIGN_CPUINFO_PROC_CPUINFO_PARSE_FAILURE = "failed to parse processor information from /proc/cpuinfo", BridgeReplacedDuringVersionCheck, BridgeTransportTimeoutError, BridgeTransportUnavailableError, BridgeTransportUnknownOutcomeError, BinaryBridge;
704
+ var DEFAULT_BRIDGE_TIMEOUT_MS = 30000, BRIDGE_HANG_TIMEOUT_THRESHOLD = 2, MAX_STDOUT_BUFFER, MALFORMED_STDOUT_LOG_CHARS = 512, HASHLINE_REGISTRATION_LOG_INTERVAL_MS = 60000, HASHLINE_REGISTRATION_LOG_STATE_LIMIT = 256, TERMINAL_BASH_STATUSES, binaryFingerprintReader, binaryFingerprintAsyncReader, BENIGN_CPUINFO_PROC_CPUINFO_PARSE_FAILURE = "failed to parse processor information from /proc/cpuinfo", BridgeReplacedDuringVersionCheck, BridgeTransportTimeoutError, BridgeTransportUnavailableError, BridgeTransportUnknownOutcomeError, BinaryBridge;
539
705
  var init_bridge = __esm(() => {
540
706
  init_active_logger();
541
707
  init_binary_identity();
542
708
  init_child_process();
543
709
  init_command_timeouts();
544
710
  MAX_STDOUT_BUFFER = 64 * 1024 * 1024;
545
- STDOUT_BUFFER_COMPACT_THRESHOLD = 64 * 1024;
546
711
  TERMINAL_BASH_STATUSES = new Set([
547
712
  "completed",
548
713
  "failed",
@@ -599,8 +764,12 @@ var init_bridge = __esm(() => {
599
764
  outstandingBackgroundTaskIds = new Set;
600
765
  nextId = 1;
601
766
  processGeneration = 0;
602
- stdoutBuffer = "";
603
- stdoutReadOffset = 0;
767
+ stdoutPending = [];
768
+ stdoutPendingLength = 0;
769
+ stdoutScannedChars = 0;
770
+ __stdoutScannedCharsForTests() {
771
+ return this.stdoutScannedChars;
772
+ }
604
773
  stderrBuffer = "";
605
774
  stderrTail = [];
606
775
  _restartCount = 0;
@@ -626,6 +795,7 @@ var init_bridge = __esm(() => {
626
795
  restartResetTimer = null;
627
796
  lastChildActivityAt = 0;
628
797
  consecutiveRequestTimeouts = 0;
798
+ timeoutRestartAwaitingRecovery = false;
629
799
  errorPrefix;
630
800
  logger;
631
801
  childEnv;
@@ -859,15 +1029,17 @@ var init_bridge = __esm(() => {
859
1029
  params.edit_slot_survives = editSlotSurvives;
860
1030
  this.logHashlineRegistrationCarrier("tool_call", sessionId, editSlotSurvives);
861
1031
  }
862
- const { preview, ...sendOptions } = options ?? {};
1032
+ const { preview, workerSession, ...sendOptions } = options ?? {};
863
1033
  if (preview === true)
864
1034
  params.preview = true;
1035
+ if (workerSession === true)
1036
+ params[WORKER_SESSION_FIELD] = true;
865
1037
  return await this.send("tool_call", params, Object.keys(sendOptions).length > 0 ? sendOptions : undefined);
866
1038
  }
867
1039
  async sendWithVersionMismatchRetry(command, params, options, canRetryAfterVersionSwap) {
868
1040
  try {
869
1041
  if (this._retiringDueToBinaryChange) {
870
- throw new Error(`${this.errorPrefix} Bridge is retiring after the on-disk binary changed; retry to respawn on the updated binary`);
1042
+ throw new BridgeTransportUnavailableError(`${this.errorPrefix} Bridge is retiring after the on-disk binary changed; retry to respawn on the updated binary`);
871
1043
  }
872
1044
  if (this._shuttingDown) {
873
1045
  throw new BridgeTransportUnavailableError(`${this.errorPrefix} Bridge is shutting down, cannot send "${command}"`);
@@ -930,7 +1102,7 @@ var init_bridge = __esm(() => {
930
1102
  if (command === "cancel_request" || Object.hasOwn(params, "command") || Object.hasOwn(params, "method")) {
931
1103
  const nested = { ...params };
932
1104
  const reserved = {};
933
- for (const key of ["session_id", "lsp_hints"]) {
1105
+ for (const key of ["session_id", "lsp_hints", WORKER_SESSION_FIELD]) {
934
1106
  if (Object.hasOwn(nested, key)) {
935
1107
  reserved[key] = nested[key];
936
1108
  delete nested[key];
@@ -942,7 +1114,7 @@ var init_bridge = __esm(() => {
942
1114
  }
943
1115
  const line = `${JSON.stringify(request)}
944
1116
  `;
945
- const keepBridgeOnTimeout = passive || options?.keepBridgeOnTimeout === true;
1117
+ const keepBridgeOnTimeout = passive || command === "bash_drain_completions" || options?.keepBridgeOnTimeout === true;
946
1118
  let requestSentAt = Date.now();
947
1119
  const child = this.process;
948
1120
  const response = await new Promise((resolve, reject) => {
@@ -966,7 +1138,8 @@ var init_bridge = __esm(() => {
966
1138
  const childActiveSinceRequest = this.lastChildActivityAt > requestSentAt;
967
1139
  const consecutiveTimeouts = this.consecutiveRequestTimeouts + 1;
968
1140
  this.consecutiveRequestTimeouts = consecutiveTimeouts;
969
- const keepWarm = childActiveSinceRequest || consecutiveTimeouts < this.hangThreshold;
1141
+ const restartSuppressed = this.timeoutRestartAwaitingRecovery;
1142
+ const keepWarm = restartSuppressed || childActiveSinceRequest || consecutiveTimeouts < this.hangThreshold;
970
1143
  const restartSuffix = keepWarm ? " — bridge kept warm" : " — restarting bridge";
971
1144
  const timeoutMsg = `Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms${restartSuffix}`;
972
1145
  if (requestSessionId) {
@@ -975,7 +1148,7 @@ var init_bridge = __esm(() => {
975
1148
  this.warnVia(timeoutMsg);
976
1149
  }
977
1150
  if (keepWarm) {
978
- entry.reject(new Error(`${this.errorPrefix} request "${command}" timed out after ${effectiveTimeoutMs}ms (bridge busy/under load); bridge kept warm — retry`));
1151
+ entry.reject(new Error(restartSuppressed ? `${this.errorPrefix} request "${command}" timed out after ${effectiveTimeoutMs}ms; automatic timeout restart already attempted; bridge kept warm to finish startup. Retry later or restart the host explicitly if it remains unresponsive. A timed-out mutation may still complete; inspect before repeating it.` : `${this.errorPrefix} request "${command}" timed out after ${effectiveTimeoutMs}ms (bridge busy/under load); bridge kept warm — retry`));
979
1152
  return;
980
1153
  }
981
1154
  entry.reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
@@ -1112,7 +1285,7 @@ var init_bridge = __esm(() => {
1112
1285
  this.spawnedBinaryFingerprint = null;
1113
1286
  this.clearRestartResetTimer();
1114
1287
  this.configureWarningClients.clear();
1115
- this.rejectAllPending(new Error(`${this.errorPrefix} Bridge shutting down`));
1288
+ this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Bridge shutting down`));
1116
1289
  if (this.process) {
1117
1290
  const proc = this.process;
1118
1291
  this.process = null;
@@ -1167,7 +1340,7 @@ var init_bridge = __esm(() => {
1167
1340
  this.lastBinaryFingerprintCheckAt = 0;
1168
1341
  this._retiringDueToBinaryChange = false;
1169
1342
  this.clearRestartResetTimer();
1170
- this.rejectAllPending(new Error(`${this.errorPrefix} Bridge restarting with updated binary: ${newBinaryPath}`));
1343
+ this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Bridge restarting with updated binary: ${newBinaryPath}`));
1171
1344
  if (!this.process)
1172
1345
  return;
1173
1346
  const proc = this.process;
@@ -1210,11 +1383,11 @@ var init_bridge = __esm(() => {
1210
1383
  })();
1211
1384
  const useFastembedBackend = semanticBackend === undefined || semanticBackend === "fastembed" || semanticBackend === "";
1212
1385
  const ortDir = typeof this.configOverrides._ort_dylib_dir === "string" && useFastembedBackend ? this.configOverrides._ort_dylib_dir : null;
1213
- const ortLibraryPath = ortDir == null ? null : join2(ortDir, this.platform === "win32" ? "onnxruntime.dll" : this.platform === "darwin" ? "libonnxruntime.dylib" : "libonnxruntime.so");
1386
+ const ortLibraryPath = ortDir == null ? null : join3(ortDir, this.platform === "win32" ? "onnxruntime.dll" : this.platform === "darwin" ? "libonnxruntime.dylib" : "libonnxruntime.so");
1214
1387
  const env = { ...process.env };
1215
1388
  this.logVia(`bridge.spawnProcess: useFastembedBackend=${useFastembedBackend}, ` + `parentORT=${process.env.ORT_DYLIB_PATH ?? "(unset)"}, ` + `ortLibraryPath=${ortLibraryPath ?? "(none)"}`);
1216
1389
  if (useFastembedBackend) {
1217
- env.FASTEMBED_CACHE_DIR = process.env.FASTEMBED_CACHE_DIR || (typeof this.configOverrides.storage_dir === "string" ? join2(this.configOverrides.storage_dir, "semantic", "models") : join2(homedir2() || "", ".cache", "fastembed"));
1390
+ env.FASTEMBED_CACHE_DIR = process.env.FASTEMBED_CACHE_DIR || (typeof this.configOverrides.storage_dir === "string" ? join3(this.configOverrides.storage_dir, "semantic", "models") : join3(homedir4() || "", ".cache", "fastembed"));
1218
1391
  if (process.env.ORT_DYLIB_PATH) {
1219
1392
  this.logVia(`ORT_DYLIB_PATH inherited from parent env: ${process.env.ORT_DYLIB_PATH}`);
1220
1393
  } else if (ortLibraryPath) {
@@ -1298,8 +1471,8 @@ var init_bridge = __esm(() => {
1298
1471
  this.processGeneration += 1;
1299
1472
  this.recordSpawnedBinaryFingerprint();
1300
1473
  this.lastBinaryFingerprintCheckAt = Date.now();
1301
- this.stdoutBuffer = "";
1302
- this.stdoutReadOffset = 0;
1474
+ this.stdoutPending = [];
1475
+ this.stdoutPendingLength = 0;
1303
1476
  this.stderrBuffer = "";
1304
1477
  this.lastChildActivityAt = 0;
1305
1478
  this.consecutiveRequestTimeouts = 0;
@@ -1357,41 +1530,43 @@ var init_bridge = __esm(() => {
1357
1530
  ${tail}`;
1358
1531
  }
1359
1532
  onStdoutData(data) {
1360
- if (this.stdoutReadOffset > STDOUT_BUFFER_COMPACT_THRESHOLD) {
1361
- this.compactStdoutBuffer();
1362
- }
1363
- this.stdoutBuffer += data;
1364
- if (this.stdoutBuffer.length - this.stdoutReadOffset > MAX_STDOUT_BUFFER) {
1533
+ if (this.stdoutPendingLength + data.length > MAX_STDOUT_BUFFER) {
1365
1534
  this.handleCrash(new Error(`aft bridge stdout buffer exceeded ${MAX_STDOUT_BUFFER} bytes — killing bridge`));
1366
1535
  return;
1367
1536
  }
1368
- let newlineIdx;
1369
- while ((newlineIdx = this.stdoutBuffer.indexOf(`
1370
- `, this.stdoutReadOffset)) !== -1) {
1371
- const line = this.stdoutBuffer.slice(this.stdoutReadOffset, newlineIdx).trim();
1372
- this.stdoutReadOffset = newlineIdx + 1;
1537
+ this.stdoutScannedChars += data.length;
1538
+ const generation = this.processGeneration;
1539
+ let start = 0;
1540
+ let newlineIdx = data.indexOf(`
1541
+ `);
1542
+ while (newlineIdx !== -1) {
1543
+ let line = data.slice(start, newlineIdx);
1544
+ if (this.stdoutPending.length > 0) {
1545
+ this.stdoutPending.push(line);
1546
+ line = this.stdoutPending.join("");
1547
+ this.stdoutPending = [];
1548
+ this.stdoutPendingLength = 0;
1549
+ }
1550
+ start = newlineIdx + 1;
1551
+ line = line.trim();
1373
1552
  if (line) {
1374
1553
  this.processStdoutLine(line);
1554
+ if (this.processGeneration !== generation)
1555
+ return;
1375
1556
  }
1376
- if (this.stdoutReadOffset > STDOUT_BUFFER_COMPACT_THRESHOLD && this.stdoutReadOffset > this.stdoutBuffer.length / 2) {
1377
- this.compactStdoutBuffer();
1378
- }
1557
+ newlineIdx = data.indexOf(`
1558
+ `, start);
1379
1559
  }
1380
- if (this.stdoutReadOffset === this.stdoutBuffer.length) {
1381
- this.stdoutBuffer = "";
1382
- this.stdoutReadOffset = 0;
1560
+ if (start < data.length) {
1561
+ const rest = start === 0 ? data : data.slice(start);
1562
+ this.stdoutPending.push(rest);
1563
+ this.stdoutPendingLength += rest.length;
1383
1564
  }
1384
1565
  }
1385
- compactStdoutBuffer() {
1386
- if (this.stdoutReadOffset === 0)
1387
- return;
1388
- this.stdoutBuffer = this.stdoutBuffer.slice(this.stdoutReadOffset);
1389
- this.stdoutReadOffset = 0;
1390
- }
1391
1566
  flushStdoutBuffer() {
1392
- const line = this.stdoutBuffer.slice(this.stdoutReadOffset).trim();
1393
- this.stdoutBuffer = "";
1394
- this.stdoutReadOffset = 0;
1567
+ const line = this.stdoutPending.join("").trim();
1568
+ this.stdoutPending = [];
1569
+ this.stdoutPendingLength = 0;
1395
1570
  if (!line)
1396
1571
  return;
1397
1572
  this.processStdoutLine(line);
@@ -1458,6 +1633,17 @@ var init_bridge = __esm(() => {
1458
1633
  clearTimeout(entry.timer);
1459
1634
  entry.onSettled?.();
1460
1635
  this.consecutiveRequestTimeouts = 0;
1636
+ if (response.success !== false && ![
1637
+ "configure",
1638
+ "version",
1639
+ "status",
1640
+ "ping",
1641
+ "bash_drain_completions",
1642
+ "bash_ack_completions",
1643
+ "cancel_request"
1644
+ ].includes(entry.command)) {
1645
+ this.timeoutRestartAwaitingRecovery = false;
1646
+ }
1461
1647
  this.scheduleRestartCountReset();
1462
1648
  this.accountForBashTaskResponse(entry.command, response);
1463
1649
  entry.resolve(response);
@@ -1465,7 +1651,8 @@ var init_bridge = __esm(() => {
1465
1651
  this.logVia(`Ignoring unknown stdout push frame type: ${response.type}`);
1466
1652
  }
1467
1653
  } catch (_err) {
1468
- this.warnVia(`Failed to parse stdout line: ${line}`);
1654
+ const quoted = line.length > MALFORMED_STDOUT_LOG_CHARS ? `${line.slice(0, MALFORMED_STDOUT_LOG_CHARS)}… (${line.length} chars)` : line;
1655
+ this.warnVia(`Failed to parse stdout line: ${quoted}`);
1469
1656
  }
1470
1657
  }
1471
1658
  accountForBashTaskResponse(command, response) {
@@ -1482,6 +1669,7 @@ var init_bridge = __esm(() => {
1482
1669
  }
1483
1670
  handleTimeout(trigger, triggeringSessionId) {
1484
1671
  this.consecutiveRequestTimeouts = 0;
1672
+ this.timeoutRestartAwaitingRecovery = true;
1485
1673
  this.spawnedBinaryFingerprint = null;
1486
1674
  const abortedSiblings = Array.from(this.pending, ([requestId, entry]) => ({
1487
1675
  request_id: requestId,
@@ -1568,55 +1756,57 @@ var init_bridge = __esm(() => {
1568
1756
  });
1569
1757
 
1570
1758
  // ../aft-bridge/dist/cache-paths.js
1571
- import { homedir as homedir3 } from "node:os";
1572
- import { join as join3 } from "node:path";
1759
+ import { homedir as homedir5 } from "node:os";
1760
+ import { join as join4 } from "node:path";
1573
1761
  function homeDir2(env) {
1574
- return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir3();
1762
+ return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir5();
1575
1763
  }
1576
- function getOpenCodeCacheRoot(env = process.env, home = homedir3()) {
1577
- return join3(env.XDG_CACHE_HOME || join3(home, ".cache"), "opencode");
1764
+ function getOpenCodeCacheRoot(env = process.env, home = homedir5()) {
1765
+ return join4(env.XDG_CACHE_HOME || join4(home, ".cache"), "opencode");
1578
1766
  }
1579
- function getOpenCodeConfigRoot(env = process.env, home = homedir3()) {
1580
- return join3(env.XDG_CONFIG_HOME || join3(home, ".config"), "opencode");
1767
+ function getOpenCodeConfigRoot(env = process.env, home = homedir5()) {
1768
+ return join4(env.XDG_CONFIG_HOME || join4(home, ".config"), "opencode");
1581
1769
  }
1582
1770
  function getAftCacheRoot(env = process.env) {
1583
1771
  if (env.AFT_CACHE_DIR)
1584
1772
  return env.AFT_CACHE_DIR;
1585
1773
  if (process.platform === "win32") {
1586
- const base = env.LOCALAPPDATA || env.APPDATA || join3(homeDir2(env), "AppData", "Local");
1587
- return join3(base, "aft");
1774
+ const base = env.LOCALAPPDATA || env.APPDATA || join4(homeDir2(env), "AppData", "Local");
1775
+ return join4(base, "aft");
1588
1776
  }
1589
- const base = env.XDG_CACHE_HOME || join3(homeDir2(env), ".cache");
1590
- return join3(base, "aft");
1777
+ const base = env.XDG_CACHE_HOME || join4(homeDir2(env), ".cache");
1778
+ return join4(base, "aft");
1591
1779
  }
1592
1780
  function getAftBinaryCacheDir(env = process.env) {
1593
- return join3(getAftCacheRoot(env), "bin");
1781
+ return join4(getAftCacheRoot(env), "bin");
1594
1782
  }
1595
1783
  function getAftLspPackagesDir(env = process.env) {
1596
- return join3(getAftCacheRoot(env), "lsp-packages");
1784
+ return join4(getAftCacheRoot(env), "lsp-packages");
1597
1785
  }
1598
1786
  function getAftLspBinariesDir(env = process.env) {
1599
- return join3(getAftCacheRoot(env), "lsp-binaries");
1787
+ return join4(getAftCacheRoot(env), "lsp-binaries");
1600
1788
  }
1601
1789
  var init_cache_paths = () => {};
1602
1790
 
1603
1791
  // ../aft-bridge/dist/callgraph-format.js
1604
- var init_callgraph_format = () => {};
1792
+ var init_callgraph_format = __esm(() => {
1793
+ init_path_display();
1794
+ });
1605
1795
  // ../aft-bridge/dist/config-error.js
1606
- import { homedir as homedir4 } from "node:os";
1607
- import { isAbsolute, join as join4 } from "node:path";
1796
+ import { homedir as homedir6 } from "node:os";
1797
+ import { isAbsolute as isAbsolute2, join as join5 } from "node:path";
1608
1798
  function formatConfigErrorMessage(detail) {
1609
1799
  const trimmed = detail.trim();
1610
1800
  const sentence = /[.!?]$/.test(trimmed) ? trimmed : `${trimmed}.`;
1611
1801
  return `${sentence} ${CONFIG_ERROR_RESTART_NOTE}`;
1612
1802
  }
1613
- function resolveSubcConnectionFilePath(raw, home = homedir4()) {
1803
+ function resolveSubcConnectionFilePath(raw, home = homedir6()) {
1614
1804
  const trimmed = raw.trim();
1615
1805
  if (trimmed.startsWith("~"))
1616
- return join4(home, trimmed.slice(1).replace(/^[/\\]/, ""));
1617
- if (isAbsolute(trimmed))
1806
+ return join5(home, trimmed.slice(1).replace(/^[/\\]/, ""));
1807
+ if (isAbsolute2(trimmed))
1618
1808
  return trimmed;
1619
- return join4(home, trimmed);
1809
+ return join5(home, trimmed);
1620
1810
  }
1621
1811
  function formatSubcConnectionMissingMessage(raw, resolved) {
1622
1812
  return `subc.connection_file is set to "${raw.trim()}" (resolved: ${resolved}) but no subc ` + `connection file exists there. Start the Subconscious daemon, correct the path, ` + `or remove subc.connection_file from your user config to use the standalone bridge.`;
@@ -1632,7 +1822,7 @@ var init_config_keys = () => {};
1632
1822
 
1633
1823
  // ../aft-bridge/dist/config-tiers.js
1634
1824
  import { existsSync, readFileSync as readFileSync2 } from "node:fs";
1635
- import { resolve as resolve2 } from "node:path";
1825
+ import { resolve as resolve3 } from "node:path";
1636
1826
  function readConfigTiers(opts) {
1637
1827
  const tiers = [];
1638
1828
  try {
@@ -1640,7 +1830,7 @@ function readConfigTiers(opts) {
1640
1830
  const doc = readFileSync2(opts.userConfigPath, "utf-8");
1641
1831
  tiers.push({
1642
1832
  tier: "user",
1643
- source: resolve2(opts.userConfigPath),
1833
+ source: resolve3(opts.userConfigPath),
1644
1834
  doc
1645
1835
  });
1646
1836
  }
@@ -1650,7 +1840,7 @@ function readConfigTiers(opts) {
1650
1840
  const doc = readFileSync2(opts.projectConfigPath, "utf-8");
1651
1841
  tiers.push({
1652
1842
  tier: "project",
1653
- source: resolve2(opts.projectConfigPath),
1843
+ source: resolve3(opts.projectConfigPath),
1654
1844
  doc
1655
1845
  });
1656
1846
  }
@@ -1752,9 +1942,9 @@ var init_version_probe = __esm(() => {
1752
1942
 
1753
1943
  // ../aft-bridge/dist/downloader.js
1754
1944
  import { createHash as createHash2, randomUUID } from "node:crypto";
1755
- import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync as existsSync2, mkdirSync, openSync, readdirSync, readFileSync as readFileSync3, renameSync as renameSync2, rmSync, statSync as statSync2, unlinkSync as unlinkSync2, writeSync } from "node:fs";
1945
+ import { chmodSync, closeSync as closeSync2, copyFileSync, createWriteStream, existsSync as existsSync2, mkdirSync as mkdirSync2, openSync as openSync2, readdirSync, readFileSync as readFileSync3, renameSync as renameSync2, rmSync, statSync as statSync2, unlinkSync as unlinkSync2, writeSync } from "node:fs";
1756
1946
  import { hostname } from "node:os";
1757
- import { join as join5 } from "node:path";
1947
+ import { join as join6 } from "node:path";
1758
1948
  import { Readable } from "node:stream";
1759
1949
  import { pipeline } from "node:stream/promises";
1760
1950
  function expectedVersionFromTag(tag) {
@@ -1778,7 +1968,7 @@ function getBinaryName() {
1778
1968
  function getCachedBinaryPath(version) {
1779
1969
  if (!version)
1780
1970
  return null;
1781
- const binaryPath = join5(getAftBinaryCacheDir(), version, getBinaryName());
1971
+ const binaryPath = join6(getAftBinaryCacheDir(), version, getBinaryName());
1782
1972
  return existsSync2(binaryPath) ? binaryPath : null;
1783
1973
  }
1784
1974
  async function downloadBinary(version) {
@@ -1795,16 +1985,16 @@ async function downloadBinary(version) {
1795
1985
  return null;
1796
1986
  }
1797
1987
  const tag = rawTag.startsWith("v") ? rawTag : `v${rawTag}`;
1798
- const versionedCacheDir = join5(getAftBinaryCacheDir(), tag);
1988
+ const versionedCacheDir = join6(getAftBinaryCacheDir(), tag);
1799
1989
  const binaryName = getBinaryName();
1800
- const binaryPath = join5(versionedCacheDir, binaryName);
1990
+ const binaryPath = join6(versionedCacheDir, binaryName);
1801
1991
  if (existsSync2(binaryPath) && await isExpectedCachedBinary(binaryPath, tag)) {
1802
1992
  return binaryPath;
1803
1993
  }
1804
1994
  const downloadUrl = `https://github.com/${REPO}/releases/download/${tag}/${assetName}`;
1805
1995
  const checksumUrl = `https://github.com/${REPO}/releases/download/${tag}/checksums.sha256`;
1806
1996
  log(`Downloading AFT binary (${tag}) for ${platformKey}...`);
1807
- const lockPath = join5(versionedCacheDir, ".download.lock");
1997
+ const lockPath = join6(versionedCacheDir, ".download.lock");
1808
1998
  let releaseLock = null;
1809
1999
  let binaryController = null;
1810
2000
  let checksumController = null;
@@ -1838,7 +2028,7 @@ async function downloadBinary(version) {
1838
2028
  process.once("exit", handleExit);
1839
2029
  try {
1840
2030
  if (!existsSync2(versionedCacheDir)) {
1841
- mkdirSync(versionedCacheDir, { recursive: true });
2031
+ mkdirSync2(versionedCacheDir, { recursive: true });
1842
2032
  }
1843
2033
  releaseLock = await acquireDownloadLock(lockPath);
1844
2034
  sweepStaleDownloadTemps(versionedCacheDir, binaryName);
@@ -2028,7 +2218,7 @@ function sweepStaleDownloadTemps(versionedCacheDir, binaryName) {
2028
2218
  if (!entry.isFile() || !entry.name.startsWith(tempPrefix) || !entry.name.endsWith(".tmp")) {
2029
2219
  continue;
2030
2220
  }
2031
- const tempPath = join5(versionedCacheDir, entry.name);
2221
+ const tempPath = join6(versionedCacheDir, entry.name);
2032
2222
  const ageMs = Date.now() - statSync2(tempPath).mtimeMs;
2033
2223
  if (Math.abs(ageMs) > DOWNLOAD_LOCK_STALE_MS)
2034
2224
  unlinkSync2(tempPath);
@@ -2043,11 +2233,11 @@ async function acquireDownloadLock(lockPath, timing = {}) {
2043
2233
  while (true) {
2044
2234
  try {
2045
2235
  const owner = createDownloadLockOwner();
2046
- const fd = openSync(lockPath, "wx");
2236
+ const fd = openSync2(lockPath, "wx");
2047
2237
  try {
2048
2238
  writeSync(fd, owner);
2049
2239
  } finally {
2050
- closeSync(fd);
2240
+ closeSync2(fd);
2051
2241
  }
2052
2242
  return () => {
2053
2243
  try {
@@ -2127,13 +2317,86 @@ var init_downloader = __esm(() => {
2127
2317
  ensureBinaryInFlight = new Map;
2128
2318
  });
2129
2319
 
2320
+ // ../aft-bridge/dist/private-storage.js
2321
+ import { closeSync as closeSync3, constants, copyFileSync as copyFileSync2, fchmodSync, fstatSync, lstatSync, mkdirSync as mkdirSync3, openSync as openSync3, readSync as readSync2, writeSync as writeSync2 } from "node:fs";
2322
+ import { isAbsolute as isAbsolute3, join as join7, parse, relative as relative2, resolve as resolve4, sep } from "node:path";
2323
+ function privateMkdirSync(path, recursive = true) {
2324
+ mkdirSync3(path, {
2325
+ recursive,
2326
+ ...process.platform === "win32" ? {} : { mode: PRIVATE_DIRECTORY_MODE }
2327
+ });
2328
+ }
2329
+ function privateCopyFileSync(source, destination) {
2330
+ if (process.platform === "win32") {
2331
+ copyFileSync2(source, destination);
2332
+ return;
2333
+ }
2334
+ const input = openSync3(source, "r");
2335
+ let output;
2336
+ try {
2337
+ output = openSync3(destination, "wx", PRIVATE_FILE_MODE);
2338
+ const buffer = Buffer.allocUnsafe(64 * 1024);
2339
+ for (;; ) {
2340
+ const bytes = readSync2(input, buffer);
2341
+ if (bytes === 0)
2342
+ break;
2343
+ let offset = 0;
2344
+ while (offset < bytes)
2345
+ offset += writeSync2(output, buffer, offset, bytes - offset);
2346
+ }
2347
+ } finally {
2348
+ closeSync3(input);
2349
+ if (output !== undefined)
2350
+ closeSync3(output);
2351
+ }
2352
+ }
2353
+ function openPrivateStorageDir(root, path = root) {
2354
+ const base = resolve4(root);
2355
+ if (!root || base === parse(base).root) {
2356
+ throw new Error(`refusing filesystem root as private storage: ${base}`);
2357
+ }
2358
+ const rel = relative2(base, resolve4(path));
2359
+ if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute3(rel))
2360
+ return;
2361
+ privateMkdirSync(path);
2362
+ if (process.platform === "win32")
2363
+ return;
2364
+ let current = base;
2365
+ for (const component of ["", ...rel.split(sep).filter(Boolean)]) {
2366
+ current = join7(current, component);
2367
+ let fd;
2368
+ try {
2369
+ if (lstatSync(current).isSymbolicLink())
2370
+ return;
2371
+ fd = openSync3(current, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
2372
+ if ((fstatSync(fd).mode & 63) !== 0)
2373
+ fchmodSync(fd, PRIVATE_DIRECTORY_MODE);
2374
+ } catch (error) {
2375
+ if (!warned.has(current)) {
2376
+ warned.add(current);
2377
+ process.stderr.write(`[aft] could not tighten private storage ${current}: ${String(error)}; continuing
2378
+ `);
2379
+ }
2380
+ return;
2381
+ } finally {
2382
+ if (fd !== undefined)
2383
+ closeSync3(fd);
2384
+ }
2385
+ }
2386
+ }
2387
+ var PRIVATE_FILE_MODE = 384, PRIVATE_DIRECTORY_MODE = 448, warned;
2388
+ var init_private_storage = __esm(() => {
2389
+ warned = new Set;
2390
+ });
2391
+
2130
2392
  // ../aft-bridge/dist/durable-log.js
2131
2393
  var DEFAULT_LOG_BYTES;
2132
2394
  var init_durable_log = __esm(() => {
2395
+ init_private_storage();
2133
2396
  init_storage_paths();
2134
2397
  DEFAULT_LOG_BYTES = 32 * 1024 * 1024;
2135
2398
  });
2136
- // ../../node_modules/.bun/@cortexkit+subc-client@0.13.1/node_modules/@cortexkit/subc-client/dist/envelope.js
2399
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.20.0/node_modules/@cortexkit/subc-client/dist/envelope.js
2137
2400
  var MAX_FRAME_BODY_LEN, FrameType, FRAME_TYPE_MAX, Priority, AdmissionClass;
2138
2401
  var init_envelope = __esm(() => {
2139
2402
  MAX_FRAME_BODY_LEN = 64 * 1024 * 1024;
@@ -2164,7 +2427,7 @@ var init_envelope = __esm(() => {
2164
2427
  })(AdmissionClass || (AdmissionClass = {}));
2165
2428
  });
2166
2429
 
2167
- // ../../node_modules/.bun/@cortexkit+subc-client@0.13.1/node_modules/@cortexkit/subc-client/dist/socket.js
2430
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.20.0/node_modules/@cortexkit/subc-client/dist/socket.js
2168
2431
  var WRITE_BORROWED, WRITE_TRACKED_BORROWED;
2169
2432
  var init_socket = __esm(() => {
2170
2433
  init_envelope();
@@ -2172,47 +2435,78 @@ var init_socket = __esm(() => {
2172
2435
  WRITE_TRACKED_BORROWED = Symbol("subc.socket.writeTrackedBorrowed");
2173
2436
  });
2174
2437
 
2175
- // ../../node_modules/.bun/@cortexkit+subc-client@0.13.1/node_modules/@cortexkit/subc-client/dist/auth.js
2438
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.20.0/node_modules/@cortexkit/subc-client/dist/auth.js
2176
2439
  var init_auth = __esm(() => {
2177
2440
  init_socket();
2178
2441
  });
2179
2442
 
2180
- // ../../node_modules/.bun/@cortexkit+subc-client@0.13.1/node_modules/@cortexkit/subc-client/dist/connection-file.js
2443
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.20.0/node_modules/@cortexkit/subc-client/dist/connection-file.js
2181
2444
  var init_connection_file = __esm(() => {
2182
2445
  init_envelope();
2183
2446
  });
2184
2447
 
2185
- // ../../node_modules/.bun/@cortexkit+subc-client@0.13.1/node_modules/@cortexkit/subc-client/dist/route-handle.js
2448
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.20.0/node_modules/@cortexkit/subc-client/dist/launch-nonce.js
2449
+ var PROCESS_CELL_KEY, U64_MAX, I32_MAX, RedactedLaunchNonce;
2450
+ var init_launch_nonce = __esm(() => {
2451
+ PROCESS_CELL_KEY = Symbol.for("@cortexkit/subc-client/launch-nonce/v1");
2452
+ U64_MAX = (1n << 64n) - 1n;
2453
+ I32_MAX = 2 ** 31 - 1;
2454
+ RedactedLaunchNonce = class RedactedLaunchNonce {
2455
+ source;
2456
+ #value;
2457
+ constructor(value, source) {
2458
+ this.#value = value;
2459
+ this.source = source;
2460
+ Object.freeze(this);
2461
+ }
2462
+ get value() {
2463
+ return this.#value;
2464
+ }
2465
+ toJSON() {
2466
+ return { source: this.source };
2467
+ }
2468
+ [Symbol.for("nodejs.util.inspect.custom")]() {
2469
+ return `LaunchNonce { value: <${this.#value.length} bytes redacted>, source: "${this.source}" }`;
2470
+ }
2471
+ };
2472
+ });
2473
+
2474
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.20.0/node_modules/@cortexkit/subc-client/dist/route-handle.js
2186
2475
  var connectionToken, reverseRequests;
2187
2476
  var init_route_handle = __esm(() => {
2188
2477
  connectionToken = new WeakMap;
2189
2478
  reverseRequests = new WeakMap;
2190
2479
  });
2191
2480
 
2192
- // ../../node_modules/.bun/@cortexkit+subc-client@0.13.1/node_modules/@cortexkit/subc-client/dist/client.js
2481
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.20.0/node_modules/@cortexkit/subc-client/dist/client.js
2193
2482
  import { debuglog } from "node:util";
2194
- var debug, EMPTY_BODY;
2483
+ var debug, EMPTY_BODY, errorFrameFlags, ROUTE_OPEN_ADMISSION_PRESSURE_REASONS;
2195
2484
  var init_client = __esm(() => {
2196
2485
  init_auth();
2197
2486
  init_connection_file();
2198
2487
  init_envelope();
2488
+ init_launch_nonce();
2199
2489
  init_route_handle();
2200
2490
  init_socket();
2491
+ init_launch_nonce();
2201
2492
  debug = debuglog("subc-client");
2202
2493
  EMPTY_BODY = new Uint8Array(0);
2494
+ errorFrameFlags = new WeakMap;
2495
+ ROUTE_OPEN_ADMISSION_PRESSURE_REASONS = new Set(["open_admission_full", "target_binds_full"]);
2203
2496
  });
2204
2497
 
2205
- // ../../node_modules/.bun/@cortexkit+subc-client@0.13.1/node_modules/@cortexkit/subc-client/dist/provider.js
2498
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.20.0/node_modules/@cortexkit/subc-client/dist/provider.js
2206
2499
  var init_provider = __esm(() => {
2207
2500
  init_auth();
2208
2501
  init_client();
2209
2502
  init_connection_file();
2210
2503
  init_envelope();
2504
+ init_launch_nonce();
2211
2505
  init_route_handle();
2212
2506
  init_socket();
2213
2507
  });
2214
2508
 
2215
- // ../../node_modules/.bun/@cortexkit+subc-client@0.13.1/node_modules/@cortexkit/subc-client/dist/index.js
2509
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.20.0/node_modules/@cortexkit/subc-client/dist/index.js
2216
2510
  var init_dist = __esm(() => {
2217
2511
  init_client();
2218
2512
  init_route_handle();
@@ -2220,6 +2514,7 @@ var init_dist = __esm(() => {
2220
2514
  init_envelope();
2221
2515
  init_auth();
2222
2516
  init_socket();
2517
+ init_launch_nonce();
2223
2518
  init_provider();
2224
2519
  });
2225
2520
 
@@ -2642,7 +2937,7 @@ var init_lifecycle_registry = __esm(() => {
2642
2937
  var init_project_identity = () => {};
2643
2938
 
2644
2939
  // ../aft-bridge/dist/subc-transport.js
2645
- var CALL_DEADLINE_EXPIRED, LOCALLY_SATISFIED_COMMANDS;
2940
+ var CALL_DEADLINE_EXPIRED, LOCALLY_SATISFIED_COMMANDS, dispatchProbes;
2646
2941
  var init_subc_transport = __esm(() => {
2647
2942
  init_dist();
2648
2943
  init_active_logger();
@@ -2651,6 +2946,7 @@ var init_subc_transport = __esm(() => {
2651
2946
  init_project_identity();
2652
2947
  CALL_DEADLINE_EXPIRED = Symbol("call deadline expired");
2653
2948
  LOCALLY_SATISFIED_COMMANDS = new Set(["configure"]);
2949
+ dispatchProbes = new Map;
2654
2950
  });
2655
2951
 
2656
2952
  // ../aft-bridge/dist/error-contract.js
@@ -2681,26 +2977,9 @@ function surfaceDisables(surface) {
2681
2977
  return;
2682
2978
  }
2683
2979
  }
2684
- function parseMinor(version) {
2685
- const match = /^v?(\d+)\.(\d+)/.exec(version.trim());
2686
- if (!match)
2687
- return;
2688
- return [Number(match[1]), Number(match[2])];
2689
- }
2690
- function policyPhaseForVersion(version) {
2691
- const minor = parseMinor(version);
2692
- if (!minor)
2693
- return "window";
2694
- const [major, min] = minor;
2695
- const [rejectMajor, rejectMinor] = POLICY_REJECT_FROM_MINOR;
2696
- return major > rejectMajor || major === rejectMajor && min >= rejectMinor ? "rejecting" : "window";
2697
- }
2698
2980
  function isRecord(value) {
2699
2981
  return typeof value === "object" && value !== null && !Array.isArray(value);
2700
2982
  }
2701
- function removed(old, replacement) {
2702
- return `removed_config_key:${old}:use:${replacement}`;
2703
- }
2704
2983
  function hasPath(map, path) {
2705
2984
  const dot = path.indexOf(".");
2706
2985
  if (dot < 0)
@@ -2723,12 +3002,89 @@ function falseRuntimeGates(map) {
2723
3002
  function sortedUnique(names) {
2724
3003
  return [...new Set(names)].sort();
2725
3004
  }
2726
- function translateBlock(map, userBase, phase, blockLabel, out) {
2727
- if (Object.hasOwn(map, "gh_read"))
2728
- out.errors.push(removed("gh_read", "github.read"));
2729
- if (isRecord(map.gh_shim) && Object.hasOwn(map.gh_shim, "enabled")) {
2730
- out.errors.push(removed("gh_shim", "github.shim"));
3005
+ function recordRetired(out, prefix, key) {
3006
+ out.legacyInput = true;
3007
+ out.retiredKeys.push(`${prefix}${key}`);
3008
+ }
3009
+ function superseded(out, key, message) {
3010
+ out.warnings.push({ code: "superseded_legacy_config", key, message });
3011
+ }
3012
+ function nestedBool(map, container, leaf) {
3013
+ const inner = map[container];
3014
+ return isRecord(inner) && typeof inner[leaf] === "boolean" ? inner[leaf] : undefined;
3015
+ }
3016
+ function translateGithubAliases(map, prefix, out) {
3017
+ const masterOff = nestedBool(map, "github", "enabled") === false;
3018
+ for (const [alias, leaf, retiredKey] of [
3019
+ ["gh_read", "read", "gh_read"],
3020
+ ["gh_shim", "shim", "gh_shim.enabled"]
3021
+ ]) {
3022
+ const aliasBlock = map[alias];
3023
+ const supplied = alias === "gh_read" ? Object.hasOwn(map, alias) : isRecord(aliasBlock) && Object.hasOwn(aliasBlock, "enabled");
3024
+ if (!supplied)
3025
+ continue;
3026
+ recordRetired(out, prefix, retiredKey);
3027
+ const aliasValue = isRecord(aliasBlock) && typeof aliasBlock.enabled === "boolean" ? aliasBlock.enabled : undefined;
3028
+ if (aliasValue !== undefined) {
3029
+ const canonical = nestedBool(map, "github", leaf);
3030
+ if (canonical !== undefined) {
3031
+ if (canonical !== aliasValue) {
3032
+ superseded(out, `${prefix}${retiredKey}`, `${alias}.enabled=${aliasValue} is ignored because github.${leaf}=${canonical} is set`);
3033
+ }
3034
+ } else if (masterOff) {
3035
+ if (aliasValue) {
3036
+ superseded(out, `${prefix}${retiredKey}`, `${alias}.enabled=true is ignored because github.enabled=false switches github.${leaf} off`);
3037
+ }
3038
+ } else {
3039
+ if (!Object.hasOwn(map, "github"))
3040
+ map.github = {};
3041
+ if (isRecord(map.github))
3042
+ map.github[leaf] = aliasValue;
3043
+ }
3044
+ }
3045
+ if (alias === "gh_read") {
3046
+ delete map.gh_read;
3047
+ } else if (isRecord(aliasBlock)) {
3048
+ delete aliasBlock.enabled;
3049
+ if (Object.keys(aliasBlock).length === 0)
3050
+ delete map.gh_shim;
3051
+ }
3052
+ }
3053
+ }
3054
+ function takeNested(map, container, leaf) {
3055
+ const inner = map[container];
3056
+ if (!isRecord(inner) || !Object.hasOwn(inner, leaf))
3057
+ return { found: false };
3058
+ const value = inner[leaf];
3059
+ delete inner[leaf];
3060
+ if (Object.keys(inner).length === 0)
3061
+ delete map[container];
3062
+ return { found: true, value };
3063
+ }
3064
+ function translateInspectLspPaths(map, prefix, out) {
3065
+ const ttl = takeNested(map, "idle", "lsp_ttl_minutes");
3066
+ if (ttl.found) {
3067
+ recordRetired(out, prefix, "idle.lsp_ttl_minutes");
3068
+ if (isRecord(map.lsp) && map.lsp.idle_minutes !== undefined) {
3069
+ superseded(out, `${prefix}idle.lsp_ttl_minutes`, "idle.lsp_ttl_minutes is ignored because lsp.idle_minutes is set");
3070
+ } else {
3071
+ const raw = typeof ttl.value === "number" && Number.isSafeInteger(ttl.value) ? ttl.value : LSP_IDLE_MINUTES_DEFAULT;
3072
+ const minutes = Math.min(LSP_IDLE_MINUTES_MAX, Math.max(LSP_IDLE_MINUTES_MIN, raw));
3073
+ if (!Object.hasOwn(map, "lsp"))
3074
+ map.lsp = {};
3075
+ if (isRecord(map.lsp))
3076
+ map.lsp.idle_minutes = minutes;
3077
+ }
2731
3078
  }
3079
+ for (const leaf of ["tier2_soft_deadline_ms", "max_drill_down_items"]) {
3080
+ if (takeNested(map, "inspect", leaf).found)
3081
+ recordRetired(out, prefix, `inspect.${leaf}`);
3082
+ }
3083
+ }
3084
+ function translateBlock(map, userBase, blockLabel, out) {
3085
+ const prefix = blockLabel === "base" ? "" : `${blockLabel}.`;
3086
+ translateGithubAliases(map, prefix, out);
3087
+ translateInspectLspPaths(map, prefix, out);
2732
3088
  let explicitList;
2733
3089
  const rawList = map.disabled_tools;
2734
3090
  if (Array.isArray(rawList) && rawList.every((entry) => typeof entry === "string")) {
@@ -2736,30 +3092,15 @@ function translateBlock(map, userBase, phase, blockLabel, out) {
2736
3092
  const host = LEGACY_TOOL_ALIASES[name];
2737
3093
  if (host === undefined)
2738
3094
  return name;
2739
- out.legacyInput = true;
2740
- if (phase === "rejecting")
2741
- out.errors.push(removed(name, host));
3095
+ recordRetired(out, prefix, name);
2742
3096
  return host;
2743
3097
  });
2744
3098
  }
2745
- const suppliedPaths = RETIRED_PATHS.map(([path]) => path).filter((path) => hasPath(map, path));
2746
- if (suppliedPaths.length > 0)
2747
- out.legacyInput = true;
2748
- const gates = falseRuntimeGates(map);
2749
- if (phase === "rejecting") {
2750
- for (const path of suppliedPaths) {
2751
- const replacement = RETIRED_PATHS.find(([old]) => old === path)?.[1] ?? "disabled_tools";
2752
- out.errors.push(removed(path, replacement));
2753
- }
2754
- if (gates.length > 0 && explicitList === undefined) {
2755
- out.warnings.push({
2756
- code: "legacy_runtime_gate_runtime_only",
2757
- key: blockLabel,
2758
- message: `${gates.join(", ")} now restricts runtime behavior only and no longer removes tool registrations; list tools in disabled_tools to unregister them`
2759
- });
2760
- }
2761
- return;
3099
+ for (const [path] of RETIRED_PATHS) {
3100
+ if (hasPath(map, path))
3101
+ recordRetired(out, prefix, path);
2762
3102
  }
3103
+ const gates = falseRuntimeGates(map);
2763
3104
  if (explicitList !== undefined)
2764
3105
  map.disabled_tools = explicitList;
2765
3106
  for (const [leaf, legacy, experimental] of INDEX_INPUTS) {
@@ -2786,19 +3127,11 @@ function translateBlock(map, userBase, phase, blockLabel, out) {
2786
3127
  }
2787
3128
  if (canonical !== undefined) {
2788
3129
  if (canonical !== value) {
2789
- out.warnings.push({
2790
- code: "superseded_legacy_config",
2791
- key,
2792
- message: `${key}=${value} is ignored because indexes.${leaf}=${canonical} is set`
2793
- });
3130
+ superseded(out, key, `${key}=${value} is ignored because indexes.${leaf}=${canonical} is set`);
2794
3131
  }
2795
3132
  } else if (chosen !== undefined) {
2796
3133
  if (chosen !== value) {
2797
- out.warnings.push({
2798
- code: "superseded_legacy_config",
2799
- key,
2800
- message: `${key}=${value} is ignored because ${legacy}=${chosen} takes precedence`
2801
- });
3134
+ superseded(out, key, `${key}=${value} is ignored because ${legacy}=${chosen} takes precedence`);
2802
3135
  }
2803
3136
  } else {
2804
3137
  chosen = value;
@@ -2820,11 +3153,7 @@ function translateBlock(map, userBase, phase, blockLabel, out) {
2820
3153
  if (!Object.hasOwn(github, leaf))
2821
3154
  github[leaf] = false;
2822
3155
  else if (github[leaf] === true) {
2823
- out.warnings.push({
2824
- code: "superseded_legacy_config",
2825
- key: "github.enabled",
2826
- message: `github.enabled=false is ignored for github.${leaf} because github.${leaf}=true is set`
2827
- });
3156
+ superseded(out, "github.enabled", `github.enabled=false is ignored for github.${leaf} because github.${leaf}=true is set`);
2828
3157
  }
2829
3158
  }
2830
3159
  }
@@ -2865,21 +3194,19 @@ function translateBlock(map, userBase, phase, blockLabel, out) {
2865
3194
  message: RETIRED_ENABLED_FALSE_INDEXES_NOTE
2866
3195
  });
2867
3196
  }
2868
- for (const gate of gates) {
2869
- if (gate === "backup.enabled")
2870
- generated.add("aft_safety");
2871
- else if (gate === "inspect.enabled")
2872
- generated.add("aft_inspect");
2873
- else
2874
- for (const name of BASH_GATE_DISABLES)
2875
- generated.add(name);
3197
+ if (gates.length > 0 && explicitList === undefined) {
3198
+ out.warnings.push({
3199
+ code: "legacy_runtime_gate_runtime_only",
3200
+ key: blockLabel,
3201
+ message: `${gates.join(", ")} now restricts runtime behavior only and no longer removes tool registrations; list tools in disabled_tools to unregister them`
3202
+ });
2876
3203
  }
2877
3204
  if (explicitList !== undefined) {
2878
3205
  if (explicitSurface || generated.size > 0) {
2879
3206
  out.warnings.push({
2880
3207
  code: "superseded_legacy_config",
2881
3208
  key: blockLabel,
2882
- message: "disabled_tools is set explicitly, so legacy tool_surface/hoist_builtin_tools/enabled and runtime gates do not change registration",
3209
+ message: "disabled_tools is set explicitly, so legacy tool_surface/hoist_builtin_tools/enabled do not change registration",
2883
3210
  once: true
2884
3211
  });
2885
3212
  }
@@ -2896,29 +3223,22 @@ function translateBlock(map, userBase, phase, blockLabel, out) {
2896
3223
  }
2897
3224
  if (list !== undefined)
2898
3225
  map.disabled_tools = list;
2899
- if (gates.length > 0) {
2900
- out.warnings.push({
2901
- code: "legacy_runtime_gate_requires_fix",
2902
- key: blockLabel,
2903
- message: `${gates.join(", ")} still removes tool registrations during this release only; run \`npx @cortexkit/aft doctor --fix\` to record the choice in disabled_tools`
2904
- });
2905
- }
2906
3226
  }
2907
- function translateConfigDocument(map, phase, tier) {
3227
+ function translateConfigDocument(map, tier) {
2908
3228
  const out = {
2909
- errors: [],
2910
3229
  warnings: [],
2911
3230
  legacyInput: false,
3231
+ retiredKeys: [],
2912
3232
  retiredEnabledFalse: false
2913
3233
  };
2914
- translateBlock(map, tier === "user", phase, "base", out);
3234
+ translateBlock(map, tier === "user", "base", out);
2915
3235
  if (isRecord(map.harnesses)) {
2916
3236
  for (const [name, block] of Object.entries(map.harnesses)) {
2917
3237
  if (isRecord(block))
2918
- translateBlock(block, false, phase, `harnesses.${name}`, out);
3238
+ translateBlock(block, false, `harnesses.${name}`, out);
2919
3239
  }
2920
3240
  }
2921
- out.errors = sortedUnique(out.errors);
3241
+ out.retiredKeys = sortedUnique(out.retiredKeys);
2922
3242
  return out;
2923
3243
  }
2924
3244
  function canonicalJson(value) {
@@ -2945,7 +3265,7 @@ function mergeIndexes(base, override, restricted) {
2945
3265
  }
2946
3266
  return merged;
2947
3267
  }
2948
- var CANONICAL_TOOLS, HOST_TOOL_NAMES, DEFAULT_DISABLED_TOOLS, LEGACY_TOOL_ALIASES, BASH_GATE_DISABLES, POLICY_REJECT_FROM_MINOR, RETIRED_PATHS, INDEX_INPUTS, RETIRED_ENABLED_FALSE_INDEXES_NOTE = "enabled: false no longer turns AFT off: it is translated to disabling every tool, but the trigram, semantic and callgraph indexes still build. To keep AFT from indexing this repository, also set indexes.trigram, indexes.semantic and indexes.callgraph to false.", SEMANTIC_COST_NOTICE_DIGEST, ConfigRejectedError;
3268
+ var CANONICAL_TOOLS, HOST_TOOL_NAMES, DEFAULT_DISABLED_TOOLS, LEGACY_TOOL_ALIASES, RETIRED_PATHS, INDEX_INPUTS, LSP_IDLE_MINUTES_DEFAULT = 60, LSP_IDLE_MINUTES_MIN = 5, LSP_IDLE_MINUTES_MAX = 1440, RETIRED_ENABLED_FALSE_INDEXES_NOTE = "enabled: false no longer turns AFT off: it is translated to disabling every tool, but the trigram, semantic and callgraph indexes still build. To keep AFT from indexing this repository, also set indexes.trigram, indexes.semantic and indexes.callgraph to false.", SEMANTIC_COST_NOTICE_DIGEST;
2949
3269
  var init_feature_config = __esm(() => {
2950
3270
  CANONICAL_TOOLS = [
2951
3271
  "aft_callgraph",
@@ -2991,14 +3311,6 @@ var init_feature_config = __esm(() => {
2991
3311
  aft_glob: "glob",
2992
3312
  aft_bash: "bash"
2993
3313
  };
2994
- BASH_GATE_DISABLES = [
2995
- "bash",
2996
- "bash_kill",
2997
- "bash_status",
2998
- "bash_watch",
2999
- "bash_write"
3000
- ];
3001
- POLICY_REJECT_FROM_MINOR = [0, 59];
3002
3314
  RETIRED_PATHS = [
3003
3315
  ["tool_surface", "disabled_tools"],
3004
3316
  ["hoist_builtin_tools", "disabled_tools"],
@@ -3016,14 +3328,6 @@ var init_feature_config = __esm(() => {
3016
3328
  ["callgraph", "callgraph_store", undefined]
3017
3329
  ];
3018
3330
  SEMANTIC_COST_NOTICE_DIGEST = noticeDigest({ notice: "semantic_default_cost_v1" });
3019
- ConfigRejectedError = class ConfigRejectedError extends Error {
3020
- errors;
3021
- constructor(errors, source) {
3022
- super(`AFT configuration${source ? ` at ${source}` : ""} was rejected: ${errors.join(", ")}. ` + "Run `npx @cortexkit/aft doctor --fix` to migrate removed keys.");
3023
- this.name = "ConfigRejectedError";
3024
- this.errors = errors;
3025
- }
3026
- };
3027
3331
  });
3028
3332
  // ../aft-bridge/dist/pool.js
3029
3333
  var DEFAULT_IDLE_TIMEOUT_MS, CLEANUP_INTERVAL_MS;
@@ -3053,6 +3357,7 @@ var init_transport_factory = __esm(() => {
3053
3357
  // ../aft-bridge/dist/location-lifecycle.js
3054
3358
  var LIFECYCLE_STATE, RELEASE_LOCATION;
3055
3359
  var init_location_lifecycle = __esm(() => {
3360
+ init_bridge();
3056
3361
  init_project_identity();
3057
3362
  init_transport_factory();
3058
3363
  LIFECYCLE_STATE = Symbol.for("@cortexkit/aft-bridge/location-lifecycle/v1");
@@ -3068,35 +3373,37 @@ var init_message_detach = __esm(() => {
3068
3373
  });
3069
3374
 
3070
3375
  // ../aft-bridge/dist/paths.js
3071
- import { homedir as homedir5 } from "node:os";
3072
- import { dirname, isAbsolute as isAbsolute2, join as join6, resolve as resolve3 } from "node:path";
3376
+ import { homedir as homedir7 } from "node:os";
3377
+ import { dirname as dirname2, isAbsolute as isAbsolute4, join as join8, resolve as resolve5 } from "node:path";
3073
3378
  function homeDir3() {
3074
3379
  if (process.platform === "win32")
3075
- return process.env.USERPROFILE || process.env.HOME || homedir5();
3076
- return process.env.HOME || homedir5();
3380
+ return process.env.USERPROFILE || process.env.HOME || homedir7();
3381
+ return process.env.HOME || homedir7();
3077
3382
  }
3078
3383
  function configHome() {
3079
3384
  const xdg = process.env.XDG_CONFIG_HOME;
3080
- if (xdg && isAbsolute2(xdg))
3385
+ if (xdg && isAbsolute4(xdg))
3081
3386
  return xdg;
3082
- return join6(homeDir3(), ".config");
3387
+ return join8(homeDir3(), ".config");
3083
3388
  }
3084
3389
  function resolveCortexKitUserConfigPath() {
3085
- return join6(configHome(), "cortexkit", "aft.jsonc");
3390
+ return join8(configHome(), "cortexkit", "aft.jsonc");
3086
3391
  }
3087
3392
  function resolveCortexKitProjectConfigPath(projectDirectory) {
3088
- return join6(projectDirectory, ".cortexkit", "aft.jsonc");
3393
+ return join8(projectDirectory, ".cortexkit", "aft.jsonc");
3089
3394
  }
3090
- var init_paths = () => {};
3395
+ var init_paths = __esm(() => {
3396
+ init_private_storage();
3397
+ });
3091
3398
 
3092
3399
  // ../aft-bridge/dist/resolver.js
3093
- import { closeSync as closeSync2, existsSync as existsSync3, promises as fsPromises, openSync as openSync2, readFileSync as readFileSync4, readSync } from "node:fs";
3400
+ import { closeSync as closeSync4, existsSync as existsSync3, promises as fsPromises, openSync as openSync4, readFileSync as readFileSync4, readSync as readSync3 } from "node:fs";
3094
3401
  function isNativeExecutable(binaryPath) {
3095
3402
  let fd = null;
3096
3403
  try {
3097
- fd = openSync2(binaryPath, "r");
3404
+ fd = openSync4(binaryPath, "r");
3098
3405
  const buf = Buffer.alloc(4);
3099
- const read = readSync(fd, buf, 0, 4, 0);
3406
+ const read = readSync3(fd, buf, 0, 4, 0);
3100
3407
  if (read < 2)
3101
3408
  return false;
3102
3409
  const b0 = buf[0];
@@ -3117,7 +3424,7 @@ function isNativeExecutable(binaryPath) {
3117
3424
  } finally {
3118
3425
  if (fd !== null) {
3119
3426
  try {
3120
- closeSync2(fd);
3427
+ closeSync4(fd);
3121
3428
  } catch {}
3122
3429
  }
3123
3430
  }
@@ -3145,12 +3452,12 @@ var init_migration = __esm(() => {
3145
3452
  });
3146
3453
 
3147
3454
  // ../aft-bridge/dist/migration-notices.js
3148
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync5, renameSync as renameSync3, rmdirSync, statSync as statSync3, writeFileSync as writeFileSync2 } from "node:fs";
3149
- import { homedir as homedir6 } from "node:os";
3150
- import { dirname as dirname2, join as join7, resolve as resolve4 } from "node:path";
3455
+ import { readFileSync as readFileSync5, renameSync as renameSync3, rmdirSync, statSync as statSync3, writeFileSync as writeFileSync2 } from "node:fs";
3456
+ import { homedir as homedir8 } from "node:os";
3457
+ import { dirname as dirname3, join as join9, resolve as resolve6 } from "node:path";
3151
3458
  function migrationNoticeStorePath(env = process.env) {
3152
- const stateHome = env.XDG_STATE_HOME && env.XDG_STATE_HOME.length > 0 ? env.XDG_STATE_HOME : join7(homedir6(), ".local", "state");
3153
- return join7(stateHome, "cortexkit", "aft", "migration-notices.json");
3459
+ const stateHome = env.XDG_STATE_HOME && env.XDG_STATE_HOME.length > 0 ? env.XDG_STATE_HOME : join9(homedir8(), ".local", "state");
3460
+ return join9(stateHome, "cortexkit", "aft", "migration-notices.json");
3154
3461
  }
3155
3462
  function readRecords(storePath) {
3156
3463
  try {
@@ -3162,11 +3469,11 @@ function readRecords(storePath) {
3162
3469
  }
3163
3470
  function withStoreLock(storePath, action) {
3164
3471
  const lockPath = `${storePath}.lock`;
3165
- mkdirSync2(dirname2(storePath), { recursive: true });
3472
+ openPrivateStorageDir(dirname3(storePath));
3166
3473
  const deadline = Date.now() + 2000;
3167
3474
  for (;; ) {
3168
3475
  try {
3169
- mkdirSync2(lockPath);
3476
+ privateMkdirSync(lockPath, false);
3170
3477
  break;
3171
3478
  } catch (error) {
3172
3479
  if (error.code !== "EEXIST")
@@ -3189,30 +3496,34 @@ function withStoreLock(storePath, action) {
3189
3496
  }
3190
3497
  }
3191
3498
  function clearMigrationNotices(configPath, storePath = migrationNoticeStorePath()) {
3192
- const prefix = `${resolve4(configPath)}|`;
3499
+ const prefix = `${resolve6(configPath)}|`;
3193
3500
  withStoreLock(storePath, () => {
3194
3501
  const records = readRecords(storePath);
3195
3502
  for (const key of Object.keys(records))
3196
3503
  if (key.startsWith(prefix))
3197
3504
  delete records[key];
3198
3505
  writeFileSync2(storePath, `${JSON.stringify(records, null, 2)}
3199
- `, "utf8");
3506
+ `, {
3507
+ encoding: "utf8",
3508
+ mode: PRIVATE_FILE_MODE
3509
+ });
3200
3510
  });
3201
3511
  }
3202
3512
  var LOCK_STALE_MS = 1e4;
3203
3513
  var init_migration_notices = __esm(() => {
3204
3514
  init_feature_config();
3515
+ init_private_storage();
3205
3516
  });
3206
3517
 
3207
3518
  // ../aft-bridge/dist/npm-resolver.js
3208
3519
  import { readdirSync as readdirSync2, statSync as statSync4 } from "node:fs";
3209
- import { homedir as homedir7 } from "node:os";
3210
- import { dirname as dirname3, isAbsolute as isAbsolute3, join as join8 } from "node:path";
3520
+ import { homedir as homedir9 } from "node:os";
3521
+ import { dirname as dirname4, isAbsolute as isAbsolute5, join as join10 } from "node:path";
3211
3522
  function defaultDeps() {
3212
3523
  return {
3213
3524
  platform: process.platform,
3214
3525
  env: process.env,
3215
- home: homedir7(),
3526
+ home: homedir9(),
3216
3527
  execPath: process.execPath
3217
3528
  };
3218
3529
  }
@@ -3234,16 +3545,16 @@ function npmFromPath(deps) {
3234
3545
  const separator = deps.platform === "win32" ? ";" : ":";
3235
3546
  for (const entry of raw.split(separator)) {
3236
3547
  const dir = entry.trim().replace(/^"|"$/g, "");
3237
- if (!dir || !isAbsolute3(dir))
3548
+ if (!dir || !isAbsolute5(dir))
3238
3549
  continue;
3239
- if (isFile(join8(dir, name)))
3550
+ if (isFile(join10(dir, name)))
3240
3551
  return dir;
3241
3552
  }
3242
3553
  return null;
3243
3554
  }
3244
3555
  function npmAdjacentToNode(deps) {
3245
- const dir = dirname3(deps.execPath);
3246
- return isFile(join8(dir, npmBinaryName(deps.platform))) ? dir : null;
3556
+ const dir = dirname4(deps.execPath);
3557
+ return isFile(join10(dir, npmBinaryName(deps.platform))) ? dir : null;
3247
3558
  }
3248
3559
  function highestVersionedNodeBin(installsDir, name) {
3249
3560
  let entries;
@@ -3252,8 +3563,8 @@ function highestVersionedNodeBin(installsDir, name) {
3252
3563
  } catch {
3253
3564
  return null;
3254
3565
  }
3255
- const candidates = entries.filter((v) => isFile(join8(installsDir, v, "bin", name))).sort((a, b) => compareVersionsDesc(a, b));
3256
- return candidates.length > 0 ? join8(installsDir, candidates[0], "bin") : null;
3566
+ const candidates = entries.filter((v) => isFile(join10(installsDir, v, "bin", name))).sort((a, b) => compareVersionsDesc(a, b));
3567
+ return candidates.length > 0 ? join10(installsDir, candidates[0], "bin") : null;
3257
3568
  }
3258
3569
  function compareVersionsDesc(a, b) {
3259
3570
  const pa = a.replace(/^v/, "").split(".").map((n) => Number.parseInt(n, 10));
@@ -3278,22 +3589,22 @@ function wellKnownNpmDirs(deps) {
3278
3589
  const programFiles = env.ProgramFiles || "C:\\Program Files";
3279
3590
  const appData = env.APPDATA;
3280
3591
  const localAppData = env.LOCALAPPDATA;
3281
- push(join8(programFiles, "nodejs"));
3592
+ push(join10(programFiles, "nodejs"));
3282
3593
  if (appData)
3283
- push(join8(appData, "npm"));
3594
+ push(join10(appData, "npm"));
3284
3595
  if (localAppData)
3285
- push(join8(localAppData, "Volta", "bin"));
3596
+ push(join10(localAppData, "Volta", "bin"));
3286
3597
  if (env.NVM_SYMLINK)
3287
3598
  push(env.NVM_SYMLINK);
3288
3599
  } else {
3289
3600
  if (env.NVM_BIN)
3290
3601
  push(env.NVM_BIN);
3291
- push(highestVersionedNodeBin(join8(home, ".nvm", "versions", "node"), name));
3292
- push(highestVersionedNodeBin(join8(home, ".local", "share", "mise", "installs", "node"), name));
3293
- push(highestVersionedNodeBin(join8(home, ".asdf", "installs", "nodejs"), name));
3294
- push(join8(home, ".volta", "bin"));
3295
- push(join8(home, ".asdf", "shims"));
3296
- const systemDirs = deps.systemNpmDirs ?? (platform === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin"] : ["/usr/local/bin", "/usr/bin", join8(home, ".local", "bin")]);
3602
+ push(highestVersionedNodeBin(join10(home, ".nvm", "versions", "node"), name));
3603
+ push(highestVersionedNodeBin(join10(home, ".local", "share", "mise", "installs", "node"), name));
3604
+ push(highestVersionedNodeBin(join10(home, ".asdf", "installs", "nodejs"), name));
3605
+ push(join10(home, ".volta", "bin"));
3606
+ push(join10(home, ".asdf", "shims"));
3607
+ const systemDirs = deps.systemNpmDirs ?? (platform === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin"] : ["/usr/local/bin", "/usr/bin", join10(home, ".local", "bin")]);
3297
3608
  for (const dir of systemDirs)
3298
3609
  push(dir);
3299
3610
  }
@@ -3303,12 +3614,12 @@ function resolveNpm(deps = defaultDeps()) {
3303
3614
  const name = npmBinaryName(deps.platform);
3304
3615
  const onPath = npmFromPath(deps);
3305
3616
  if (onPath)
3306
- return { command: join8(onPath, name), binDir: onPath };
3617
+ return { command: join10(onPath, name), binDir: onPath };
3307
3618
  const adjacent = npmAdjacentToNode(deps);
3308
3619
  if (adjacent)
3309
- return { command: join8(adjacent, name), binDir: adjacent };
3620
+ return { command: join10(adjacent, name), binDir: adjacent };
3310
3621
  for (const dir of wellKnownNpmDirs(deps)) {
3311
- const candidate = join8(dir, name);
3622
+ const candidate = join10(dir, name);
3312
3623
  if (isFile(candidate))
3313
3624
  return { command: candidate, binDir: dir };
3314
3625
  }
@@ -3469,7 +3780,7 @@ function terminateNpmProcessTree(child, invocation, env = process.env, gracePeri
3469
3780
  };
3470
3781
  child.once("exit", onChildExit);
3471
3782
  const systemRoot = env.SystemRoot ?? env.SYSTEMROOT;
3472
- const taskkill = systemRoot ? join8(systemRoot, "System32", "taskkill.exe") : "taskkill.exe";
3783
+ const taskkill = systemRoot ? join10(systemRoot, "System32", "taskkill.exe") : "taskkill.exe";
3473
3784
  try {
3474
3785
  killer = spawn(taskkill, ["/pid", String(child.pid), "/t", "/f"], {
3475
3786
  stdio: "ignore",
@@ -3505,10 +3816,10 @@ var init_npm_resolver = __esm(() => {
3505
3816
  });
3506
3817
 
3507
3818
  // ../aft-bridge/dist/onnx-probe.js
3508
- import { closeSync as closeSync3, existsSync as existsSync4, openSync as openSync3, readSync as readSync2, realpathSync } from "node:fs";
3819
+ import { closeSync as closeSync5, existsSync as existsSync4, openSync as openSync5, readSync as readSync4, realpathSync as realpathSync2 } from "node:fs";
3509
3820
  function readAt(fd, offset, length) {
3510
3821
  const buffer = Buffer.alloc(length);
3511
- const read = readSync2(fd, buffer, 0, length, offset);
3822
+ const read = readSync4(fd, buffer, 0, length, offset);
3512
3823
  return buffer.subarray(0, read);
3513
3824
  }
3514
3825
  function cpuTypeForArch(arch) {
@@ -3582,7 +3893,7 @@ function isUncheckableDependency(path) {
3582
3893
  function probeOnnxRuntimeLoadable(libPath, arch = process.arch) {
3583
3894
  let fd;
3584
3895
  try {
3585
- fd = openSync3(realpathSync(libPath), "r");
3896
+ fd = openSync5(realpathSync2(libPath), "r");
3586
3897
  } catch (err) {
3587
3898
  return {
3588
3899
  loadable: false,
@@ -3616,7 +3927,7 @@ function probeOnnxRuntimeLoadable(libPath, arch = process.arch) {
3616
3927
  } catch {
3617
3928
  return UNCHECKED;
3618
3929
  } finally {
3619
- closeSync3(fd);
3930
+ closeSync5(fd);
3620
3931
  }
3621
3932
  }
3622
3933
  var MH_MAGIC = 4277009102, MH_MAGIC_64 = 4277009103, FAT_MAGIC = 3405691582, LC_LOAD_DYLIB = 12, LC_REEXPORT_DYLIB = 2147483679, LC_LOAD_UPWARD_DYLIB = 2147483683, CPU_TYPE_X86_64 = 16777223, CPU_TYPE_ARM64 = 16777228, MAX_HEADER_BYTES, UNCHECKED;
@@ -3627,19 +3938,30 @@ var init_onnx_probe = __esm(() => {
3627
3938
 
3628
3939
  // ../aft-bridge/dist/tar-executable.js
3629
3940
  import { existsSync as existsSync5 } from "node:fs";
3630
- import { join as join9 } from "node:path";
3941
+ import { join as join11 } from "node:path";
3631
3942
  function windowsTarExecutable(options = {}) {
3632
3943
  const platform = options.platform ?? process.platform;
3633
3944
  if (platform !== "win32")
3634
3945
  return "tar";
3635
3946
  const env = options.env ?? process.env;
3636
- const systemTar = join9(env.SystemRoot ?? "C:\\Windows", "System32", "tar.exe");
3947
+ const systemTar = join11(env.SystemRoot ?? "C:\\Windows", "System32", "tar.exe");
3637
3948
  return (options.exists ?? existsSync5)(systemTar) ? systemTar : "tar";
3638
3949
  }
3639
- function execTarExtractionSync(args, timeout) {
3950
+ function execTarExtractionSync(args, timeout, privateStorage = false) {
3640
3951
  const executable = windowsTarExecutable();
3641
3952
  try {
3642
- execFileSync(executable, args, { stdio: "pipe", timeout });
3953
+ if (privateStorage && process.platform !== "win32") {
3954
+ execFileSync("/bin/sh", [
3955
+ "-c",
3956
+ 'umask 077; exec "$@"',
3957
+ "aft-extract",
3958
+ executable,
3959
+ "--no-same-permissions",
3960
+ ...args.map((arg, index) => index === 0 && !arg.startsWith("-") ? `-${arg}` : arg)
3961
+ ], { stdio: "pipe", timeout });
3962
+ } else {
3963
+ execFileSync(executable, args, { stdio: "pipe", timeout });
3964
+ }
3643
3965
  } catch (cause) {
3644
3966
  const detail = cause instanceof Error ? cause.message : String(cause);
3645
3967
  throw new Error(`tar extraction failed using ${executable}: ${detail}`, { cause });
@@ -3650,9 +3972,9 @@ var init_tar_executable = __esm(() => {
3650
3972
  });
3651
3973
 
3652
3974
  // ../aft-bridge/dist/onnx-runtime.js
3653
- import { createHash as createHash4, randomBytes } from "node:crypto";
3654
- import { chmodSync as chmodSync2, closeSync as closeSync4, copyFileSync as copyFileSync2, createWriteStream as createWriteStream2, existsSync as existsSync6, lstatSync, mkdirSync as mkdirSync3, openSync as openSync4, readdirSync as readdirSync3, readFileSync as readFileSync6, readlinkSync, realpathSync as realpathSync2, renameSync as renameSync4, rmSync as rmSync2, statSync as statSync5, symlinkSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "node:fs";
3655
- import { basename, dirname as dirname4, isAbsolute as isAbsolute4, join as join10, relative, resolve as resolve5, win32 } from "node:path";
3975
+ import { randomBytes } from "node:crypto";
3976
+ import { chmodSync as chmodSync2, closeSync as closeSync6, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync6, lstatSync as lstatSync2, openSync as openSync6, readdirSync as readdirSync3, readFileSync as readFileSync6, readlinkSync, realpathSync as realpathSync3, renameSync as renameSync4, rmSync as rmSync2, statSync as statSync5, symlinkSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "node:fs";
3977
+ import { basename, dirname as dirname5, isAbsolute as isAbsolute6, join as join12, relative as relative3, resolve as resolve7, win32 as win322 } from "node:path";
3656
3978
  import { Readable as Readable2 } from "node:stream";
3657
3979
  import { pipeline as pipeline2 } from "node:stream/promises";
3658
3980
  function getPlatformInfo() {
@@ -3689,14 +4011,14 @@ function resolveOnnxRuntime(storageDir, seams) {
3689
4011
  inflightResolutions.set(storageDir, resolution);
3690
4012
  return resolution;
3691
4013
  }
3692
- function findCachedOnnxRuntime(ortVersionDir, libName) {
4014
+ async function findCachedOnnxRuntime(ortVersionDir, libName) {
3693
4015
  const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
3694
- const libPath = join10(resolvedOrtDir, libName);
4016
+ const libPath = join12(resolvedOrtDir, libName);
3695
4017
  if (existsSync6(libPath)) {
3696
4018
  const meta = readOnnxInstalledMeta(ortVersionDir);
3697
4019
  if (meta?.sha256) {
3698
4020
  try {
3699
- const currentHash = sha256File2(libPath);
4021
+ const currentHash = await cachedFileSha256(libPath);
3700
4022
  if (currentHash !== meta.sha256) {
3701
4023
  error(`ONNX Runtime at ${resolvedOrtDir}: TOFU sha256 mismatch — refusing to use ` + `tampered binary. Recorded ${meta.sha256}, current ${currentHash}. ` + `Run \`npx @cortexkit/aft doctor --clear\` to re-download from scratch.`);
3702
4024
  } else {
@@ -3716,9 +4038,9 @@ function findCachedOnnxRuntime(ortVersionDir, libName) {
3716
4038
  }
3717
4039
  async function resolveOnnxRuntimeUncoalesced(storageDir, seams) {
3718
4040
  const info = seams.platformInfo !== undefined ? seams.platformInfo : getPlatformInfo();
3719
- const ortVersionDir = join10(storageDir, "onnxruntime", ORT_VERSION);
4041
+ const ortVersionDir = join12(storageDir, "onnxruntime", ORT_VERSION);
3720
4042
  const libName = info?.libName ?? "libonnxruntime.dylib";
3721
- const cached = findCachedOnnxRuntime(ortVersionDir, libName);
4043
+ const cached = await findCachedOnnxRuntime(ortVersionDir, libName);
3722
4044
  if (cached)
3723
4045
  return cached;
3724
4046
  const systemPath = findSystemOnnxRuntime(info?.libName, seams.systemSearchPaths);
@@ -3730,9 +4052,9 @@ async function resolveOnnxRuntimeUncoalesced(storageDir, seams) {
3730
4052
  warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
3731
4053
  return null;
3732
4054
  }
3733
- const onnxBaseDir = join10(storageDir, "onnxruntime");
3734
- mkdirSync3(onnxBaseDir, { recursive: true });
3735
- const lockPath = join10(onnxBaseDir, ONNX_LOCK_FILE);
4055
+ const onnxBaseDir = join12(storageDir, "onnxruntime");
4056
+ openPrivateStorageDir(storageDir, onnxBaseDir);
4057
+ const lockPath = join12(onnxBaseDir, ONNX_LOCK_FILE);
3736
4058
  const pollMs = seams.lockPollMs ?? LOCK_POLL_MS;
3737
4059
  const deadline = Date.now() + LOCK_WAIT_MS;
3738
4060
  let announcedWait = false;
@@ -3747,14 +4069,14 @@ async function resolveOnnxRuntimeUncoalesced(storageDir, seams) {
3747
4069
  return null;
3748
4070
  }
3749
4071
  await new Promise((done) => setTimeout(done, pollMs));
3750
- const published = findCachedOnnxRuntime(ortVersionDir, libName);
4072
+ const published = await findCachedOnnxRuntime(ortVersionDir, libName);
3751
4073
  if (published) {
3752
4074
  lastInstallFailure = null;
3753
4075
  return published;
3754
4076
  }
3755
4077
  }
3756
4078
  try {
3757
- const published = findCachedOnnxRuntime(ortVersionDir, libName);
4079
+ const published = await findCachedOnnxRuntime(ortVersionDir, libName);
3758
4080
  if (published) {
3759
4081
  lastInstallFailure = null;
3760
4082
  return published;
@@ -3777,7 +4099,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
3777
4099
  for (const entry of entries) {
3778
4100
  if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
3779
4101
  continue;
3780
- const stagingDir = join10(onnxBaseDir, entry);
4102
+ const stagingDir = join12(onnxBaseDir, entry);
3781
4103
  const parts = entry.split(".");
3782
4104
  const pidStr = parts[parts.length - 2];
3783
4105
  const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
@@ -3814,7 +4136,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
3814
4136
  }
3815
4137
  function cleanupIncompleteTargetIfUnowned(ortDir) {
3816
4138
  try {
3817
- if (existsSync6(ortDir) && !existsSync6(join10(ortDir, ONNX_INSTALLED_META_FILE))) {
4139
+ if (existsSync6(ortDir) && !existsSync6(join12(ortDir, ONNX_INSTALLED_META_FILE))) {
3818
4140
  log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
3819
4141
  rmSync2(ortDir, { recursive: true, force: true });
3820
4142
  }
@@ -3839,14 +4161,14 @@ function parseOnnxVersionFromDirectoryPath(value) {
3839
4161
  return null;
3840
4162
  }
3841
4163
  function isPathInsideRoot(root, candidate) {
3842
- const rel = relative(root, candidate);
3843
- return rel === "" || !rel.startsWith("../") && !rel.startsWith("..\\") && rel !== ".." && !isAbsolute4(rel) && !win32.isAbsolute(rel);
4164
+ const rel = relative3(root, candidate);
4165
+ return rel === "" || !rel.startsWith("../") && !rel.startsWith("..\\") && rel !== ".." && !isAbsolute6(rel) && !win322.isAbsolute(rel);
3844
4166
  }
3845
4167
  function detectOnnxVersion(libDir, libName) {
3846
4168
  try {
3847
4169
  const entries = readdirSync3(libDir);
3848
4170
  try {
3849
- const resolved = parseOnnxVersionFromPath(realpathSync2(join10(libDir, libName)));
4171
+ const resolved = parseOnnxVersionFromPath(realpathSync3(join12(libDir, libName)));
3850
4172
  if (resolved && resolved !== INVALID_ORT_VERSION)
3851
4173
  return resolved;
3852
4174
  } catch {}
@@ -3860,10 +4182,10 @@ function detectOnnxVersion(libDir, libName) {
3860
4182
  if (version)
3861
4183
  return version;
3862
4184
  }
3863
- const base = join10(libDir, libName);
4185
+ const base = join12(libDir, libName);
3864
4186
  if (existsSync6(base)) {
3865
4187
  try {
3866
- const real = realpathSync2(base);
4188
+ const real = realpathSync3(base);
3867
4189
  const version = parseOnnxVersionFromPath(real) ?? parseOnnxVersionFromDirectoryPath(real);
3868
4190
  if (version)
3869
4191
  return version;
@@ -3900,18 +4222,18 @@ function pathEntriesForPlatform() {
3900
4222
  return pathEnvValue().split(delimiter).map((entry) => entry.trim().replace(/^"|"$/g, "")).filter((entry) => {
3901
4223
  if (!entry || entry === "." || entry.includes("\x00"))
3902
4224
  return false;
3903
- return isAbsolute4(entry) || win32.isAbsolute(entry);
4225
+ return isAbsolute6(entry) || win322.isAbsolute(entry);
3904
4226
  });
3905
4227
  }
3906
4228
  function isWindowsSystem32Directory(dir) {
3907
4229
  if (process.platform !== "win32")
3908
4230
  return false;
3909
- const normalizedDir = win32.resolve(dir).replace(/[\\/]+$/, "").toLowerCase();
4231
+ const normalizedDir = win322.resolve(dir).replace(/[\\/]+$/, "").toLowerCase();
3910
4232
  const windowsRoots = [process.env.SystemRoot, process.env.windir, "C:\\Windows"];
3911
4233
  return windowsRoots.some((root) => {
3912
4234
  if (!root)
3913
4235
  return false;
3914
- return normalizedDir === win32.resolve(root, "System32").replace(/[\\/]+$/, "").toLowerCase();
4236
+ return normalizedDir === win322.resolve(root, "System32").replace(/[\\/]+$/, "").toLowerCase();
3915
4237
  });
3916
4238
  }
3917
4239
  function directoryContainsLibrary(dir, libName) {
@@ -3927,10 +4249,10 @@ function directoryContainsLibrary(dir, libName) {
3927
4249
  }
3928
4250
  }
3929
4251
  function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
3930
- if (existsSync6(join10(ortVersionDir, libName)))
4252
+ if (existsSync6(join12(ortVersionDir, libName)))
3931
4253
  return ortVersionDir;
3932
- const libSubdir = join10(ortVersionDir, "lib");
3933
- if (existsSync6(join10(libSubdir, libName)))
4254
+ const libSubdir = join12(ortVersionDir, "lib");
4255
+ if (existsSync6(join12(libSubdir, libName)))
3934
4256
  return libSubdir;
3935
4257
  return ortVersionDir;
3936
4258
  }
@@ -3945,12 +4267,12 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
3945
4267
  } else if (process.platform === "win32") {
3946
4268
  const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
3947
4269
  const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
3948
- searchPaths.push(join10(programFiles, "onnxruntime", "lib"), join10(programFiles, "Microsoft ONNX Runtime", "lib"), join10(programFiles, "Microsoft Machine Learning", "lib"), join10(programFilesX86, "onnxruntime", "lib"), ...(() => {
4270
+ searchPaths.push(join12(programFiles, "onnxruntime", "lib"), join12(programFiles, "Microsoft ONNX Runtime", "lib"), join12(programFiles, "Microsoft Machine Learning", "lib"), join12(programFilesX86, "onnxruntime", "lib"), ...(() => {
3949
4271
  const nugetPaths = [];
3950
4272
  const userProfile = process.env.USERPROFILE ?? "";
3951
4273
  if (!userProfile)
3952
4274
  return nugetPaths;
3953
- const nugetPackageDir = join10(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
4275
+ const nugetPackageDir = join12(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
3954
4276
  if (!existsSync6(nugetPackageDir))
3955
4277
  return nugetPaths;
3956
4278
  try {
@@ -3959,7 +4281,7 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
3959
4281
  continue;
3960
4282
  if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
3961
4283
  continue;
3962
- nugetPaths.push(join10(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join10(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
4284
+ nugetPaths.push(join12(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join12(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
3963
4285
  }
3964
4286
  } catch (err) {
3965
4287
  warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
@@ -3971,7 +4293,7 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
3971
4293
  const normalizeCase = process.platform === "win32" || process.platform === "darwin";
3972
4294
  const seen = new Set;
3973
4295
  const uniquePaths = searchPaths.filter((p) => {
3974
- let key = resolve5(p).replace(/[/\\]+$/, "");
4296
+ let key = resolve7(p).replace(/[/\\]+$/, "");
3975
4297
  if (normalizeCase)
3976
4298
  key = key.toLowerCase();
3977
4299
  if (seen.has(key))
@@ -3981,7 +4303,7 @@ function findSystemOnnxRuntime(libName, searchPathsOverride) {
3981
4303
  });
3982
4304
  const unknownVersionPaths = [];
3983
4305
  for (const dir of uniquePaths) {
3984
- const libPath = join10(dir, libName);
4306
+ const libPath = join12(dir, libName);
3985
4307
  if (process.platform === "win32") {
3986
4308
  if (!directoryContainsLibrary(dir, libName))
3987
4309
  continue;
@@ -4028,7 +4350,7 @@ async function downloadFileWithCap(url, destPath) {
4028
4350
  if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES2) {
4029
4351
  throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES2}`);
4030
4352
  }
4031
- mkdirSync3(dirname4(destPath), { recursive: true });
4353
+ privateMkdirSync(dirname5(destPath));
4032
4354
  let bytesWritten = 0;
4033
4355
  const guard = new TransformStream({
4034
4356
  transform(chunk, transformController) {
@@ -4042,7 +4364,9 @@ async function downloadFileWithCap(url, destPath) {
4042
4364
  });
4043
4365
  const guarded = res.body.pipeThrough(guard);
4044
4366
  const nodeStream = Readable2.fromWeb(guarded);
4045
- await pipeline2(nodeStream, createWriteStream2(destPath), { signal: controller.signal });
4367
+ await pipeline2(nodeStream, createWriteStream2(destPath, { mode: PRIVATE_FILE_MODE }), {
4368
+ signal: controller.signal
4369
+ });
4046
4370
  } catch (err) {
4047
4371
  try {
4048
4372
  unlinkSync3(destPath);
@@ -4053,31 +4377,35 @@ async function downloadFileWithCap(url, destPath) {
4053
4377
  }
4054
4378
  }
4055
4379
  function validateExtractedTree(stagingRoot) {
4056
- const realRoot = realpathSync2(stagingRoot);
4380
+ const realRoot = realpathSync3(stagingRoot);
4057
4381
  let totalBytes = 0;
4058
4382
  const walk = (dir) => {
4059
4383
  const entries = readdirSync3(dir);
4060
4384
  for (const entry of entries) {
4061
- const fullPath = join10(dir, entry);
4062
- const lst = lstatSync(fullPath);
4385
+ const fullPath = join12(dir, entry);
4386
+ const lst = lstatSync2(fullPath);
4063
4387
  if (lst.isSymbolicLink()) {
4064
4388
  const linkTarget = readlinkSync(fullPath);
4065
- const resolvedTarget = resolve5(dirname4(fullPath), linkTarget);
4066
- const rel = relative(realRoot, resolvedTarget);
4067
- if (rel.startsWith("..") || isAbsolute4(rel) || win32.isAbsolute(rel)) {
4389
+ const resolvedTarget = resolve7(dirname5(fullPath), linkTarget);
4390
+ const rel = relative3(realRoot, resolvedTarget);
4391
+ if (relativePathEscapesRoot(rel) || win322.isAbsolute(rel)) {
4068
4392
  throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
4069
4393
  }
4070
4394
  continue;
4071
4395
  }
4072
- const rel = relative(realRoot, fullPath);
4073
- if (rel.startsWith("..") || isAbsolute4(rel) || win32.isAbsolute(rel)) {
4396
+ const rel = relative3(realRoot, fullPath);
4397
+ if (relativePathEscapesRoot(rel) || win322.isAbsolute(rel)) {
4074
4398
  throw new Error(`extracted entry ${fullPath} escapes staging root`);
4075
4399
  }
4076
4400
  if (lst.isDirectory()) {
4401
+ if (process.platform !== "win32")
4402
+ chmodSync2(fullPath, PRIVATE_DIRECTORY_MODE);
4077
4403
  walk(fullPath);
4078
4404
  continue;
4079
4405
  }
4080
4406
  if (lst.isFile()) {
4407
+ if (process.platform !== "win32")
4408
+ chmodSync2(fullPath, PRIVATE_FILE_MODE);
4081
4409
  totalBytes += lst.size;
4082
4410
  if (totalBytes > MAX_EXTRACT_BYTES) {
4083
4411
  throw new Error(`extracted size ${totalBytes} exceeds max ${MAX_EXTRACT_BYTES} (decompression bomb defense)`);
@@ -4091,16 +4419,16 @@ async function downloadOnnxRuntime(info, targetDir) {
4091
4419
  const url = `https://github.com/${ORT_REPO}/releases/download/v${ORT_VERSION}/${info.assetName}.${info.archiveType === "tgz" ? "tgz" : "zip"}`;
4092
4420
  log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
4093
4421
  const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}${randomBytes(4).toString("hex")}`;
4094
- const extractionRoot = join10(tmpDir, "extract");
4095
- const stagedInstallDir = join10(tmpDir, "install");
4422
+ const extractionRoot = join12(tmpDir, "extract");
4423
+ const stagedInstallDir = join12(tmpDir, "install");
4096
4424
  try {
4097
- mkdirSync3(extractionRoot, { recursive: true });
4098
- const archivePath = join10(tmpDir, `onnxruntime.${info.archiveType}`);
4425
+ privateMkdirSync(extractionRoot);
4426
+ const archivePath = join12(tmpDir, `onnxruntime.${info.archiveType}`);
4099
4427
  await downloadFileWithCap(url, archivePath);
4100
- const archiveSha256 = sha256File2(archivePath);
4428
+ const archiveSha256 = await sha256File(archivePath);
4101
4429
  log(`ONNX Runtime archive sha256=${archiveSha256}`);
4102
4430
  if (info.archiveType === "tgz") {
4103
- execTarExtractionSync(["xzf", archivePath, "-C", extractionRoot], 120000);
4431
+ execTarExtractionSync(["xzf", archivePath, "-C", extractionRoot], 120000, true);
4104
4432
  } else {
4105
4433
  await extractZipArchive(archivePath, extractionRoot);
4106
4434
  }
@@ -4108,7 +4436,7 @@ async function downloadOnnxRuntime(info, targetDir) {
4108
4436
  unlinkSync3(archivePath);
4109
4437
  } catch {}
4110
4438
  validateExtractedTree(extractionRoot);
4111
- const extractedDir = join10(extractionRoot, info.assetName, "lib");
4439
+ const extractedDir = join12(extractionRoot, info.assetName, "lib");
4112
4440
  if (!existsSync6(extractedDir)) {
4113
4441
  throw new Error(`Expected directory not found: ${extractedDir}`);
4114
4442
  }
@@ -4116,9 +4444,9 @@ async function downloadOnnxRuntime(info, targetDir) {
4116
4444
  const realFiles = [];
4117
4445
  const symlinks = [];
4118
4446
  for (const libFile of libFiles) {
4119
- const src = join10(extractedDir, libFile);
4447
+ const src = join12(extractedDir, libFile);
4120
4448
  try {
4121
- const stat = lstatSync(src);
4449
+ const stat = lstatSync2(src);
4122
4450
  log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
4123
4451
  if (stat.isSymbolicLink()) {
4124
4452
  symlinks.push({ name: libFile, target: readlinkSync(src) });
@@ -4131,10 +4459,14 @@ async function downloadOnnxRuntime(info, targetDir) {
4131
4459
  }
4132
4460
  }
4133
4461
  copyOnnxLibraries(info, extractedDir, stagedInstallDir, realFiles, symlinks);
4134
- const libPath = join10(stagedInstallDir, info.libName);
4135
- const libHash = sha256File2(libPath);
4462
+ const libPath = join12(stagedInstallDir, info.libName);
4463
+ const libHash = await sha256File(libPath);
4464
+ if (libHash !== info.librarySha256) {
4465
+ throw new Error(`onnx runtime library hash mismatch at ${libPath}: sha256 ${libHash}, ` + `expected the pinned ${info.librarySha256} for ${info.assetName}`);
4466
+ }
4136
4467
  writeOnnxInstalledMeta(stagedInstallDir, ORT_VERSION, libHash, archiveSha256);
4137
4468
  publishOnnxRuntime(stagedInstallDir, targetDir);
4469
+ writeStampedFileDigest(join12(targetDir, info.libName), libHash);
4138
4470
  rmSync2(tmpDir, { recursive: true, force: true });
4139
4471
  log(`ONNX Runtime v${ORT_VERSION} installed to ${targetDir}`);
4140
4472
  return targetDir;
@@ -4172,16 +4504,19 @@ function publishOnnxRuntime(stagedInstallDir, targetDir) {
4172
4504
  }
4173
4505
  }
4174
4506
  }
4175
- function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync2) {
4507
+ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync3) {
4176
4508
  const requiredLibs = new Set([info.libName]);
4177
- mkdirSync3(targetDir, { recursive: true });
4509
+ privateMkdirSync(targetDir);
4178
4510
  for (const libFile of realFiles) {
4179
- const src = join10(extractedDir, libFile);
4180
- const dst = join10(targetDir, libFile);
4511
+ const src = join12(extractedDir, libFile);
4512
+ const dst = join12(targetDir, libFile);
4181
4513
  try {
4182
- copyFile(src, dst);
4514
+ if (copyFile === copyFileSync3)
4515
+ privateCopyFileSync(src, dst);
4516
+ else
4517
+ copyFile(src, dst);
4183
4518
  if (process.platform !== "win32") {
4184
- chmodSync2(dst, 493);
4519
+ chmodSync2(dst, PRIVATE_FILE_MODE);
4185
4520
  }
4186
4521
  } catch (copyErr) {
4187
4522
  if (requiredLibs.has(libFile)) {
@@ -4191,14 +4526,14 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
4191
4526
  log(`ORT extract: failed to copy optional ${libFile}: ${copyErr}`);
4192
4527
  }
4193
4528
  }
4194
- const targetRoot = realpathSync2(targetDir);
4529
+ const targetRoot = realpathSync3(targetDir);
4195
4530
  for (const link of symlinks) {
4196
- const dst = join10(targetDir, link.name);
4531
+ const dst = join12(targetDir, link.name);
4197
4532
  try {
4198
4533
  unlinkSync3(dst);
4199
4534
  } catch {}
4200
- const dstForContainment = join10(targetRoot, link.name);
4201
- const resolvedTarget = resolve5(dirname4(dstForContainment), link.target);
4535
+ const dstForContainment = join12(targetRoot, link.name);
4536
+ const resolvedTarget = resolve7(dirname5(dstForContainment), link.target);
4202
4537
  if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
4203
4538
  const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
4204
4539
  if (requiredLibs.has(link.name)) {
@@ -4218,7 +4553,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
4218
4553
  log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
4219
4554
  }
4220
4555
  }
4221
- const requiredPath = join10(targetDir, info.libName);
4556
+ const requiredPath = join12(targetDir, info.libName);
4222
4557
  if (!existsSync6(requiredPath)) {
4223
4558
  rmSync2(targetDir, { recursive: true, force: true });
4224
4559
  throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
@@ -4242,13 +4577,16 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
4242
4577
  ...sha256 ? { sha256 } : {},
4243
4578
  archiveSha256
4244
4579
  };
4245
- writeFileSync3(join10(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
4580
+ writeFileSync3(join12(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), {
4581
+ encoding: "utf8",
4582
+ mode: PRIVATE_FILE_MODE
4583
+ });
4246
4584
  } catch (err) {
4247
4585
  log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
4248
4586
  }
4249
4587
  }
4250
4588
  function readOnnxInstalledMeta(installDir) {
4251
- const path = join10(installDir, ONNX_INSTALLED_META_FILE);
4589
+ const path = join12(installDir, ONNX_INSTALLED_META_FILE);
4252
4590
  try {
4253
4591
  if (!statSync5(path).isFile())
4254
4592
  return null;
@@ -4266,21 +4604,16 @@ function readOnnxInstalledMeta(installDir) {
4266
4604
  return null;
4267
4605
  }
4268
4606
  }
4269
- function sha256File2(path) {
4270
- const hash = createHash4("sha256");
4271
- hash.update(readFileSync6(path));
4272
- return hash.digest("hex");
4273
- }
4274
4607
  function acquireLock(lockPath) {
4275
4608
  const tryClaim = () => {
4276
4609
  try {
4277
- const fd = openSync4(lockPath, "wx");
4610
+ const fd = openSync6(lockPath, "wx", PRIVATE_FILE_MODE);
4278
4611
  try {
4279
4612
  writeFileSync3(fd, `${process.pid}
4280
4613
  ${new Date().toISOString()}
4281
4614
  `);
4282
4615
  } finally {
4283
- closeSync4(fd);
4616
+ closeSync6(fd);
4284
4617
  }
4285
4618
  return true;
4286
4619
  } catch (err) {
@@ -4387,9 +4720,12 @@ function isProcessAlive2(pid) {
4387
4720
  var ORT_VERSION = "1.24.4", ORT_REPO = "microsoft/onnxruntime", MAX_DOWNLOAD_BYTES2, MAX_EXTRACT_BYTES, ONNX_LOCK_FILE = ".aft-onnx-installing", ONNX_INSTALLED_META_FILE = ".aft-onnx-installed", STALE_LOCK_MS, LOCK_WAIT_MS, LOCK_POLL_MS = 1000, ORT_PLATFORM_MAP, lastInstallFailure = null, inflightResolutions, REQUIRED_ORT_MAJOR = 1, REQUIRED_ORT_MIN_MINOR = 20, INVALID_ORT_VERSION = "<invalid>";
4388
4721
  var init_onnx_runtime = __esm(() => {
4389
4722
  init_active_logger();
4723
+ init_binary_identity();
4390
4724
  init_child_process();
4391
4725
  init_onnx_probe();
4726
+ init_path_display();
4392
4727
  init_platform();
4728
+ init_private_storage();
4393
4729
  init_tar_executable();
4394
4730
  MAX_DOWNLOAD_BYTES2 = 256 * 1024 * 1024;
4395
4731
  MAX_EXTRACT_BYTES = 1 * 1024 * 1024 * 1024;
@@ -4400,31 +4736,36 @@ var init_onnx_runtime = __esm(() => {
4400
4736
  arm64: {
4401
4737
  assetName: `onnxruntime-osx-arm64-${ORT_VERSION}`,
4402
4738
  libName: "libonnxruntime.dylib",
4403
- archiveType: "tgz"
4739
+ archiveType: "tgz",
4740
+ librarySha256: "872533f130f1839a5bc01788ddb4f75c83a189763441ba1178788ed965449289"
4404
4741
  }
4405
4742
  },
4406
4743
  linux: {
4407
4744
  x64: {
4408
4745
  assetName: `onnxruntime-linux-x64-${ORT_VERSION}`,
4409
4746
  libName: "libonnxruntime.so",
4410
- archiveType: "tgz"
4747
+ archiveType: "tgz",
4748
+ librarySha256: "d132535d051344ff5c64c9c200004150559049a81ed330eb4422c1962fb6b7e4"
4411
4749
  },
4412
4750
  arm64: {
4413
4751
  assetName: `onnxruntime-linux-aarch64-${ORT_VERSION}`,
4414
4752
  libName: "libonnxruntime.so",
4415
- archiveType: "tgz"
4753
+ archiveType: "tgz",
4754
+ librarySha256: "52b2a0e75e79468404284fec38ad5ee1a7a996232274f5e1b84f3e793fb07554"
4416
4755
  }
4417
4756
  },
4418
4757
  win32: {
4419
4758
  x64: {
4420
4759
  assetName: `onnxruntime-win-x64-${ORT_VERSION}`,
4421
4760
  libName: "onnxruntime.dll",
4422
- archiveType: "zip"
4761
+ archiveType: "zip",
4762
+ librarySha256: "b95efb2113b603bbbf3f191061c5516a871ed546893c820e4f3b7b6c358dbf2a"
4423
4763
  },
4424
4764
  arm64: {
4425
4765
  assetName: `onnxruntime-win-arm64-${ORT_VERSION}`,
4426
4766
  libName: "onnxruntime.dll",
4427
- archiveType: "zip"
4767
+ archiveType: "zip",
4768
+ librarySha256: "724d81ac50b11bfaa01ab3ce01b99fb6734a4b762259a8be4395ca662ce99fe6"
4428
4769
  }
4429
4770
  }
4430
4771
  };
@@ -4455,8 +4796,8 @@ var init_path_aliases = __esm(() => {
4455
4796
  });
4456
4797
 
4457
4798
  // ../aft-bridge/dist/path-lookup.js
4458
- import { accessSync, constants, statSync as statSync6 } from "node:fs";
4459
- import { delimiter, resolve as resolve6 } from "node:path";
4799
+ import { accessSync, constants as constants2, statSync as statSync6 } from "node:fs";
4800
+ import { delimiter, resolve as resolve8 } from "node:path";
4460
4801
  function executableNames(name, platform) {
4461
4802
  if (platform !== "win32")
4462
4803
  return [name];
@@ -4472,12 +4813,12 @@ function findExecutablesOnPath(name, options = {}) {
4472
4813
  if (!directory)
4473
4814
  continue;
4474
4815
  for (const candidateName of executableNames(name, platform)) {
4475
- const candidate = resolve6(directory, candidateName);
4816
+ const candidate = resolve8(directory, candidateName);
4476
4817
  if (seen.has(candidate))
4477
4818
  continue;
4478
4819
  seen.add(candidate);
4479
4820
  try {
4480
- accessSync(candidate, platform === "win32" ? constants.F_OK : constants.X_OK);
4821
+ accessSync(candidate, platform === "win32" ? constants2.F_OK : constants2.X_OK);
4481
4822
  if (statSync6(candidate).isFile())
4482
4823
  hits.push(candidate);
4483
4824
  } catch {}
@@ -4523,6 +4864,7 @@ var init_dist2 = __esm(() => {
4523
4864
  init_onnx_probe();
4524
4865
  init_onnx_runtime();
4525
4866
  init_path_aliases();
4867
+ init_path_display();
4526
4868
  init_path_lookup();
4527
4869
  init_paths();
4528
4870
  init_platform();
@@ -4553,8 +4895,8 @@ var init_paths2 = __esm(() => {
4553
4895
  // src/lib/binary-probe.ts
4554
4896
  import { existsSync as existsSync7, readdirSync as readdirSync4 } from "node:fs";
4555
4897
  import { createRequire } from "node:module";
4556
- import { homedir as homedir8 } from "node:os";
4557
- import { join as join11 } from "node:path";
4898
+ import { homedir as homedir10 } from "node:os";
4899
+ import { join as join13 } from "node:path";
4558
4900
  async function loadPluginVersion() {
4559
4901
  try {
4560
4902
  const bridge = await Promise.resolve().then(() => (init_dist2(), {}));
@@ -4684,7 +5026,7 @@ function newestCachedBinary(cacheDir, binaryName) {
4684
5026
  const version = entry.match(CACHE_VERSION_DIR)?.[1];
4685
5027
  if (!version)
4686
5028
  continue;
4687
- const path = join11(cacheDir, entry, binaryName);
5029
+ const path = join13(cacheDir, entry, binaryName);
4688
5030
  try {
4689
5031
  if (!existsSync7(path))
4690
5032
  continue;
@@ -4705,7 +5047,7 @@ function cacheLocation(preferredVersion) {
4705
5047
  const tag = preferredVersion.startsWith("v") ? preferredVersion : `v${preferredVersion}`;
4706
5048
  return {
4707
5049
  label,
4708
- paths: [join11(cacheDir, tag, binaryName)],
5050
+ paths: [join13(cacheDir, tag, binaryName)],
4709
5051
  emptyReason: `no ${tag}/${binaryName} under ${cacheDir} (${installedHere})`
4710
5052
  };
4711
5053
  }
@@ -4749,7 +5091,7 @@ function pathLocation() {
4749
5091
  };
4750
5092
  }
4751
5093
  function cargoLocation() {
4752
- const path = join11(homedir8(), ".cargo", "bin", getAftBinaryName());
5094
+ const path = join13(homedir10(), ".cargo", "bin", getAftBinaryName());
4753
5095
  return { label: "cargo install", paths: [path], emptyReason: `no ${path}` };
4754
5096
  }
4755
5097
  function aftBinarySearchLocations(preferredVersion) {
@@ -4802,7 +5144,7 @@ var init_binary_probe = __esm(async () => {
4802
5144
 
4803
5145
  // src/lib/fs-util.ts
4804
5146
  import { existsSync as existsSync8, readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
4805
- import { join as join12 } from "node:path";
5147
+ import { join as join14 } from "node:path";
4806
5148
  function dirSize(path) {
4807
5149
  if (!existsSync8(path)) {
4808
5150
  return 0;
@@ -4816,7 +5158,7 @@ function dirSize(path) {
4816
5158
  }
4817
5159
  let total = 0;
4818
5160
  for (const entry of readdirSync5(path)) {
4819
- total += dirSize(join12(path, entry));
5161
+ total += dirSize(join14(path, entry));
4820
5162
  }
4821
5163
  return total;
4822
5164
  }
@@ -4834,27 +5176,27 @@ var init_fs_util = () => {};
4834
5176
 
4835
5177
  // src/lib/omp-paths.ts
4836
5178
  import { existsSync as existsSync9 } from "node:fs";
4837
- import { homedir as homedir9 } from "node:os";
4838
- import { join as join13, resolve as resolve7 } from "node:path";
5179
+ import { homedir as homedir11 } from "node:os";
5180
+ import { join as join15, resolve as resolve9 } from "node:path";
4839
5181
  function envFirstHomeDir() {
4840
- return process.env.HOME?.trim() || homedir9();
5182
+ return process.env.HOME?.trim() || homedir11();
4841
5183
  }
4842
5184
  function resolveOmpPaths() {
4843
5185
  const normalizedProfile = (process.env.OMP_PROFILE ?? process.env.PI_PROFILE)?.trim();
4844
5186
  const profile = normalizedProfile && normalizedProfile !== "default" && /^[a-z0-9][a-z0-9._-]{0,63}$/.test(normalizedProfile) ? normalizedProfile : undefined;
4845
5187
  const configDirName = process.env.PI_CONFIG_DIR?.trim() || ".omp";
4846
- const baseConfigRoot = join13(envFirstHomeDir(), configDirName);
4847
- const configRoot = profile ? join13(baseConfigRoot, "profiles", profile) : baseConfigRoot;
4848
- const defaultAgentDir = join13(configRoot, "agent");
5188
+ const baseConfigRoot = join15(envFirstHomeDir(), configDirName);
5189
+ const configRoot = profile ? join15(baseConfigRoot, "profiles", profile) : baseConfigRoot;
5190
+ const defaultAgentDir = join15(configRoot, "agent");
4849
5191
  const configuredAgentDir = profile ? undefined : process.env.PI_CODING_AGENT_DIR?.trim();
4850
- const agentDir = configuredAgentDir ? resolve7(configuredAgentDir) : defaultAgentDir;
5192
+ const agentDir = configuredAgentDir ? resolve9(configuredAgentDir) : defaultAgentDir;
4851
5193
  const canUseXdg = (process.platform === "linux" || process.platform === "darwin") && agentDir === defaultAgentDir;
4852
5194
  let dataRoot = configRoot;
4853
5195
  if (canUseXdg) {
4854
5196
  const xdgDataHome = process.env.XDG_DATA_HOME?.trim();
4855
5197
  if (xdgDataHome) {
4856
- const appRoot = join13(xdgDataHome, "omp");
4857
- const candidate = profile ? join13(appRoot, "profiles", profile) : appRoot;
5198
+ const appRoot = join15(xdgDataHome, "omp");
5199
+ const candidate = profile ? join15(appRoot, "profiles", profile) : appRoot;
4858
5200
  if (existsSync9(candidate))
4859
5201
  dataRoot = candidate;
4860
5202
  }
@@ -4865,8 +5207,8 @@ function resolveOmpPaths() {
4865
5207
  agentDir,
4866
5208
  dataRoot,
4867
5209
  dataAgentRoot,
4868
- pluginsDir: join13(dataRoot, "plugins"),
4869
- sessionsRoot: join13(dataAgentRoot, "sessions")
5210
+ pluginsDir: join15(dataRoot, "plugins"),
5211
+ sessionsRoot: join15(dataAgentRoot, "sessions")
4870
5212
  };
4871
5213
  }
4872
5214
  function getOmpAgentDir() {
@@ -4876,7 +5218,7 @@ function getOmpPluginsDir() {
4876
5218
  return resolveOmpPaths().pluginsDir;
4877
5219
  }
4878
5220
  function getOmpPluginsLockPath() {
4879
- return join13(getOmpPluginsDir(), "omp-plugins.lock.json");
5221
+ return join15(getOmpPluginsDir(), "omp-plugins.lock.json");
4880
5222
  }
4881
5223
  function getOmpSessionsRoot() {
4882
5224
  return resolveOmpPaths().sessionsRoot;
@@ -4888,21 +5230,21 @@ function getOmpPackageDir() {
4888
5230
  if (value === "~")
4889
5231
  return envFirstHomeDir();
4890
5232
  if (value.startsWith("~/") || value.startsWith("~\\")) {
4891
- return resolve7(envFirstHomeDir(), value.slice(2));
5233
+ return resolve9(envFirstHomeDir(), value.slice(2));
4892
5234
  }
4893
- return resolve7(value);
5235
+ return resolve9(value);
4894
5236
  }
4895
5237
  var init_omp_paths = () => {};
4896
5238
 
4897
5239
  // src/lib/omp-helpers.ts
4898
- import { accessSync as accessSync2, constants as constants2, existsSync as existsSync10, readFileSync as readFileSync7, statSync as statSync8 } from "node:fs";
4899
- import { homedir as homedir10 } from "node:os";
4900
- import { delimiter as delimiter2, extname, join as join14, resolve as resolve8 } from "node:path";
5240
+ import { accessSync as accessSync2, constants as constants3, existsSync as existsSync10, readFileSync as readFileSync7, statSync as statSync8 } from "node:fs";
5241
+ import { homedir as homedir12 } from "node:os";
5242
+ import { delimiter as delimiter2, extname, join as join16, resolve as resolve10 } from "node:path";
4901
5243
  function isExecutableFile(path, platform = process.platform) {
4902
5244
  try {
4903
5245
  if (!existsSync10(path) || !statSync8(path).isFile())
4904
5246
  return false;
4905
- accessSync2(path, platform === "win32" ? constants2.F_OK : constants2.X_OK);
5247
+ accessSync2(path, platform === "win32" ? constants3.F_OK : constants3.X_OK);
4906
5248
  return true;
4907
5249
  } catch {
4908
5250
  return false;
@@ -4917,7 +5259,7 @@ function findOnPath(name, pathValue = process.env.PATH ?? "", platform = process
4917
5259
  if (!directory)
4918
5260
  continue;
4919
5261
  for (const candidateName of executableNames2(name, platform)) {
4920
- const candidate = resolve8(directory, candidateName);
5262
+ const candidate = resolve10(directory, candidateName);
4921
5263
  if (isExecutableFile(candidate, platform))
4922
5264
  return candidate;
4923
5265
  }
@@ -4929,10 +5271,10 @@ function detectOmpPackageCli() {
4929
5271
  if (!packageDir || !findOnPath("bun"))
4930
5272
  return null;
4931
5273
  try {
4932
- const manifest = JSON.parse(readFileSync7(join14(packageDir, "package.json"), "utf8"));
5274
+ const manifest = JSON.parse(readFileSync7(join16(packageDir, "package.json"), "utf8"));
4933
5275
  if (manifest.name !== OMP_HOST_PACKAGE)
4934
5276
  return null;
4935
- const cli = join14(packageDir, "dist", "cli.js");
5277
+ const cli = join16(packageDir, "dist", "cli.js");
4936
5278
  return existsSync10(cli) ? cli : null;
4937
5279
  } catch {
4938
5280
  return null;
@@ -4953,13 +5295,13 @@ function getOmpCommandInvocation(ompPath, args) {
4953
5295
  }
4954
5296
  function getOmpFallbackCandidates(platform, home, appData) {
4955
5297
  if (platform !== "win32") {
4956
- return [join14(home, ".bun", "bin", "omp"), join14(home, ".local", "bin", "omp")];
5298
+ return [join16(home, ".bun", "bin", "omp"), join16(home, ".local", "bin", "omp")];
4957
5299
  }
4958
5300
  const npmRoot = appData?.trim();
4959
5301
  return [
4960
- ...npmRoot ? [join14(npmRoot, "npm", "omp.cmd"), join14(npmRoot, "npm", "omp.exe")] : [],
4961
- join14(home, ".bun", "bin", "omp.exe"),
4962
- join14(home, ".bun", "bin", "omp.cmd")
5302
+ ...npmRoot ? [join16(npmRoot, "npm", "omp.cmd"), join16(npmRoot, "npm", "omp.exe")] : [],
5303
+ join16(home, ".bun", "bin", "omp.exe"),
5304
+ join16(home, ".bun", "bin", "omp.cmd")
4963
5305
  ];
4964
5306
  }
4965
5307
  function detectOmpBinary() {
@@ -4969,7 +5311,7 @@ function detectOmpBinary() {
4969
5311
  const fromPackage = detectOmpPackageCli();
4970
5312
  if (fromPackage)
4971
5313
  return { path: fromPackage, source: "package" };
4972
- const home = process.env.HOME?.trim() || homedir10();
5314
+ const home = process.env.HOME?.trim() || homedir12();
4973
5315
  const candidate = getOmpFallbackCandidates(process.platform, home, process.env.APPDATA).find((path) => isExecutableFile(path));
4974
5316
  return candidate ? { path: candidate, source: "home" } : null;
4975
5317
  }
@@ -5042,7 +5384,7 @@ var init_omp_helpers = __esm(() => {
5042
5384
 
5043
5385
  // src/adapters/omp.ts
5044
5386
  import { existsSync as existsSync11, readFileSync as readFileSync8 } from "node:fs";
5045
- import { join as join15 } from "node:path";
5387
+ import { join as join17 } from "node:path";
5046
5388
 
5047
5389
  class OmpAdapter {
5048
5390
  kind = "omp";
@@ -5184,12 +5526,12 @@ class OmpAdapter {
5184
5526
  describeStorageSubtrees() {
5185
5527
  const storage = this.getStorageDir();
5186
5528
  return {
5187
- index: dirSize(join15(storage, "index")),
5188
- semantic: dirSize(join15(storage, "semantic")),
5189
- backups: dirSize(join15(storage, "backups")),
5190
- url_cache: dirSize(join15(storage, "url_cache")),
5191
- onnxruntime: dirSize(join15(storage, "onnxruntime")),
5192
- logs: dirSize(join15(storage, "logs"))
5529
+ index: dirSize(join17(storage, "index")),
5530
+ semantic: dirSize(join17(storage, "semantic")),
5531
+ backups: dirSize(join17(storage, "backups")),
5532
+ url_cache: dirSize(join17(storage, "url_cache")),
5533
+ onnxruntime: dirSize(join17(storage, "onnxruntime")),
5534
+ logs: dirSize(join17(storage, "logs"))
5193
5535
  };
5194
5536
  }
5195
5537
  readRuntimeEnabled(configPath) {
@@ -5227,8 +5569,8 @@ var init_omp = __esm(() => {
5227
5569
 
5228
5570
  // src/lib/fs-errors.ts
5229
5571
  import { existsSync as existsSync12, statSync as statSync9 } from "node:fs";
5230
- import { homedir as homedir11 } from "node:os";
5231
- import { dirname as dirname5, resolve as resolve9, sep } from "node:path";
5572
+ import { homedir as homedir13 } from "node:os";
5573
+ import { dirname as dirname6, resolve as resolve11, sep as sep2 } from "node:path";
5232
5574
  function errorCode(error) {
5233
5575
  if (typeof error === "object" && error !== null && "code" in error) {
5234
5576
  const code = error.code;
@@ -5258,10 +5600,8 @@ function errorPath(error) {
5258
5600
  const native = message.match(/\b(?:write|update|create|open|read|mkdir|rename)\s+((?:[A-Za-z]:)?[\\/][^:\n]+?):\s/i);
5259
5601
  return native?.[1] ?? null;
5260
5602
  }
5261
- function tildePath(path, home = homedir11()) {
5262
- if (path === home)
5263
- return "~";
5264
- return path.startsWith(home + sep) ? `~${path.slice(home.length)}` : path;
5603
+ function tildePath(path, home = homedir13()) {
5604
+ return shortenHomePath(path, home);
5265
5605
  }
5266
5606
  function shellPath(path) {
5267
5607
  if (/^[\w@%+=:,./~-]+$/.test(path))
@@ -5271,10 +5611,10 @@ function shellPath(path) {
5271
5611
  return `'${path.replace(/'/g, "'\\''")}'`;
5272
5612
  }
5273
5613
  function describePermissionProblem(target, facts = defaultFacts) {
5274
- const home = resolve9(facts.home());
5275
- let existing = resolve9(target);
5276
- while (!facts.exists(existing) && dirname5(existing) !== existing)
5277
- existing = dirname5(existing);
5614
+ const home = resolve11(facts.home());
5615
+ let existing = resolve11(target);
5616
+ while (!facts.exists(existing) && dirname6(existing) !== existing)
5617
+ existing = dirname6(existing);
5278
5618
  const ownerUid = facts.ownerUid(existing);
5279
5619
  const me = facts.currentUid();
5280
5620
  const shownTarget = tildePath(target, home);
@@ -5288,8 +5628,8 @@ function describePermissionProblem(target, facts = defaultFacts) {
5288
5628
  }
5289
5629
  let widest = existing;
5290
5630
  while (true) {
5291
- const parent = dirname5(widest);
5292
- if (parent === widest || parent === home || !parent.startsWith(home + sep))
5631
+ const parent = dirname6(widest);
5632
+ if (parent === widest || parent === home || !parent.startsWith(home + sep2))
5293
5633
  break;
5294
5634
  if (facts.ownerUid(parent) !== ownerUid)
5295
5635
  break;
@@ -5339,7 +5679,7 @@ var init_fs_errors = __esm(() => {
5339
5679
  return false;
5340
5680
  }
5341
5681
  },
5342
- home: () => homedir11()
5682
+ home: () => homedir13()
5343
5683
  };
5344
5684
  });
5345
5685
 
@@ -13102,7 +13442,7 @@ var require_src2 = __commonJS(function(exports, module) {
13102
13442
 
13103
13443
  // src/lib/jsonc.ts
13104
13444
  import { existsSync as existsSync13, mkdirSync as mkdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "node:fs";
13105
- import { dirname as dirname6 } from "node:path";
13445
+ import { dirname as dirname7 } from "node:path";
13106
13446
  function detectJsoncFile(configDir, baseName) {
13107
13447
  const jsoncPath = `${configDir}/${baseName}.jsonc`;
13108
13448
  const jsonPath = `${configDir}/${baseName}.json`;
@@ -13130,7 +13470,7 @@ function readJsoncFile(path) {
13130
13470
  }
13131
13471
  }
13132
13472
  function writeJsoncFile(path, value, format = "json") {
13133
- mkdirSync4(dirname6(path), { recursive: true });
13473
+ mkdirSync4(dirname7(path), { recursive: true });
13134
13474
  const serialized = format === "jsonc" ? import_comment_json.stringify(value, null, 2) : JSON.stringify(value, null, 2);
13135
13475
  writeFileSync4(path, `${serialized}
13136
13476
  `);
@@ -13346,15 +13686,16 @@ function pluginConfigNeedsUpdate(value, version, hasLocalAftEntry = () => false,
13346
13686
  return !pluginEntryFitsKey(list[local.index], key);
13347
13687
  return true;
13348
13688
  }
13349
- function hostShellPluginDisabled(value) {
13689
+ function hostToolPluginDisabled(value, hostTool) {
13350
13690
  const list = value?.plugins;
13351
- return Array.isArray(list) && list.includes(OPENCODE_HOST_SHELL_DISABLE_ENTRY);
13691
+ return Array.isArray(list) && list.includes(OPENCODE_HOST_TOOLS[hostTool].disableEntry);
13352
13692
  }
13353
- function setHostShellPluginDisabled(value, disabled) {
13693
+ function setHostToolPluginDisabled(value, hostTool, disabled) {
13694
+ const entry = OPENCODE_HOST_TOOLS[hostTool].disableEntry;
13354
13695
  const existing = Array.isArray(value.plugins) ? value.plugins : null;
13355
13696
  const indexes = [];
13356
13697
  existing?.forEach((entry, index) => {
13357
- if (entry === OPENCODE_HOST_SHELL_DISABLE_ENTRY)
13698
+ if (entry === OPENCODE_HOST_TOOLS[hostTool].disableEntry)
13358
13699
  indexes.push(index);
13359
13700
  });
13360
13701
  if (disabled ? indexes.length === 1 : indexes.length === 0)
@@ -13367,17 +13708,19 @@ function setHostShellPluginDisabled(value, disabled) {
13367
13708
  list.splice(remove[index], 1);
13368
13709
  }
13369
13710
  if (disabled && indexes.length === 0)
13370
- list.push(OPENCODE_HOST_SHELL_DISABLE_ENTRY);
13711
+ list.push(entry);
13371
13712
  return { changed: true };
13372
13713
  }
13373
- function aftBashEnabled(userConfig) {
13714
+ function aftHostReplacementEnabled(userConfig, hostTool) {
13374
13715
  if (!userConfig)
13375
13716
  return true;
13376
13717
  if (userConfig.enabled === false)
13377
13718
  return false;
13378
13719
  const disabled = userConfig.disabled_tools;
13379
- if (Array.isArray(disabled) && disabled.includes("bash"))
13720
+ if (Array.isArray(disabled) && disabled.includes(OPENCODE_HOST_TOOLS[hostTool].aftTool))
13380
13721
  return false;
13722
+ if (hostTool !== "shell")
13723
+ return true;
13381
13724
  const bash = userConfig.bash;
13382
13725
  if (bash === false)
13383
13726
  return false;
@@ -13386,30 +13729,35 @@ function aftBashEnabled(userConfig) {
13386
13729
  }
13387
13730
  return true;
13388
13731
  }
13389
- var AFT_OPENCODE_PACKAGE = "@cortexkit/aft-opencode", MODERN_V1_VERSION, EXACT_VERSION, OPENCODE_HOST_SHELL_DISABLE_ENTRY = "-opencode.tool.shell";
13732
+ var AFT_OPENCODE_PACKAGE = "@cortexkit/aft-opencode", MODERN_V1_VERSION, EXACT_VERSION, OPENCODE_HOST_SHELL_DISABLE_ENTRY = "-opencode.tool.shell", OPENCODE_HOST_PATCH_DISABLE_ENTRY = "-opencode.tool.patch", OPENCODE_HOST_TOOLS, OPENCODE_HOST_TOOL_NAMES;
13390
13733
  var init_opencode_config = __esm(() => {
13391
13734
  init_opencode_version();
13392
13735
  MODERN_V1_VERSION = opencode_version_default.trim();
13393
13736
  EXACT_VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
13737
+ OPENCODE_HOST_TOOLS = {
13738
+ shell: { aftTool: "bash", disableEntry: OPENCODE_HOST_SHELL_DISABLE_ENTRY },
13739
+ patch: { aftTool: "apply_patch", disableEntry: OPENCODE_HOST_PATCH_DISABLE_ENTRY }
13740
+ };
13741
+ OPENCODE_HOST_TOOL_NAMES = Object.keys(OPENCODE_HOST_TOOLS);
13394
13742
  });
13395
13743
 
13396
13744
  // src/setup/host-generation.ts
13397
- import { createHash as createHash5 } from "node:crypto";
13745
+ import { createHash as createHash4 } from "node:crypto";
13398
13746
  import {
13399
- closeSync as closeSync5,
13747
+ closeSync as closeSync7,
13400
13748
  existsSync as existsSync14,
13401
13749
  mkdirSync as mkdirSync5,
13402
13750
  mkdtempSync,
13403
- openSync as openSync5,
13751
+ openSync as openSync7,
13404
13752
  readdirSync as readdirSync6,
13405
13753
  readFileSync as readFileSync10,
13406
- readSync as readSync3,
13407
- realpathSync as realpathSync3,
13754
+ readSync as readSync5,
13755
+ realpathSync as realpathSync4,
13408
13756
  rmSync as rmSync3,
13409
13757
  statSync as statSync10
13410
13758
  } from "node:fs";
13411
- import { homedir as homedir12, tmpdir as tmpdir2 } from "node:os";
13412
- import { dirname as dirname7, join as join16, parse } from "node:path";
13759
+ import { homedir as homedir14, tmpdir as tmpdir3 } from "node:os";
13760
+ import { dirname as dirname8, join as join18, parse as parse2 } from "node:path";
13413
13761
  function findExecutableOnPath2(name, pathValue = process.env.PATH ?? "", platform = process.platform) {
13414
13762
  return findExecutableOnPath(name, { pathValue, platform });
13415
13763
  }
@@ -13424,31 +13772,63 @@ function packageMetadataAt(path, expectedName) {
13424
13772
  function packageMetadataNearExecutable(executable, expectedName) {
13425
13773
  let current;
13426
13774
  try {
13427
- current = dirname7(realpathSync3(executable));
13775
+ current = dirname8(realpathSync4(executable));
13428
13776
  } catch {
13429
- current = dirname7(executable);
13777
+ current = dirname8(executable);
13430
13778
  }
13431
13779
  while (true) {
13432
- const direct = packageMetadataAt(join16(current, "package.json"), expectedName);
13780
+ const direct = packageMetadataAt(join18(current, "package.json"), expectedName);
13433
13781
  if (direct)
13434
13782
  return direct;
13435
- const parent = dirname7(current);
13436
- if (parent === current || current === parse(current).root)
13783
+ const parent = dirname8(current);
13784
+ if (parent === current || current === parse2(current).root)
13437
13785
  return null;
13438
13786
  current = parent;
13439
13787
  }
13440
13788
  }
13789
+ function npmLauncherTarget(launcher) {
13790
+ let source;
13791
+ try {
13792
+ if (statSync10(launcher).size > LAUNCHER_MAX_BYTES)
13793
+ return null;
13794
+ source = readFileSync10(launcher, "utf8");
13795
+ } catch {
13796
+ return null;
13797
+ }
13798
+ const operands = [...source.matchAll(CMD_LAUNCHER_PATH)];
13799
+ if (operands.length === 0)
13800
+ operands.push(...source.matchAll(SH_LAUNCHER_PATH));
13801
+ const relativeTarget = operands.at(-1)?.[1];
13802
+ if (!relativeTarget)
13803
+ return null;
13804
+ const target = join18(dirname8(launcher), ...relativeTarget.split(/[\\/]+/).filter(Boolean));
13805
+ try {
13806
+ return statSync10(target).isFile() ? target : null;
13807
+ } catch {
13808
+ return null;
13809
+ }
13810
+ }
13811
+ function hostLaunchPath(executable, platform) {
13812
+ const isBatch = BATCH_FILE.test(executable);
13813
+ const isScript = isBatch || platform === "win32" && !/\.(?:exe|com)$/i.test(executable);
13814
+ if (!isScript)
13815
+ return executable;
13816
+ const target = npmLauncherTarget(executable);
13817
+ if (target)
13818
+ return target;
13819
+ return isBatch ? null : executable;
13820
+ }
13441
13821
  function packageVersion(metadata) {
13442
13822
  return typeof metadata?.version === "string" && metadata.version.length > 0 ? metadata.version : null;
13443
13823
  }
13444
13824
  function hashFileBytes(hash, path, size) {
13445
13825
  const buffer = Buffer.allocUnsafe(Math.min(Math.max(size, 1), PARTIAL_CONTENT_WINDOW_BYTES));
13446
- const descriptor = openSync5(path, "r");
13826
+ const descriptor = openSync7(path, "r");
13447
13827
  try {
13448
13828
  if (size <= FULL_CONTENT_HASH_MAX_BYTES) {
13449
13829
  let position = 0;
13450
13830
  while (position < size) {
13451
- const read = readSync3(descriptor, buffer, 0, buffer.length, position);
13831
+ const read = readSync5(descriptor, buffer, 0, buffer.length, position);
13452
13832
  if (read <= 0)
13453
13833
  break;
13454
13834
  hash.update(buffer.subarray(0, read));
@@ -13457,19 +13837,19 @@ function hashFileBytes(hash, path, size) {
13457
13837
  return;
13458
13838
  }
13459
13839
  hash.update("partial\x00");
13460
- const head = readSync3(descriptor, buffer, 0, buffer.length, 0);
13840
+ const head = readSync5(descriptor, buffer, 0, buffer.length, 0);
13461
13841
  hash.update(buffer.subarray(0, Math.max(head, 0)));
13462
13842
  const tailStart = Math.max(size - PARTIAL_CONTENT_WINDOW_BYTES, 0);
13463
- const tail = readSync3(descriptor, buffer, 0, buffer.length, tailStart);
13843
+ const tail = readSync5(descriptor, buffer, 0, buffer.length, tailStart);
13464
13844
  hash.update(buffer.subarray(0, Math.max(tail, 0)));
13465
13845
  } finally {
13466
- closeSync5(descriptor);
13846
+ closeSync7(descriptor);
13467
13847
  }
13468
13848
  }
13469
13849
  function snapshotTree(path) {
13470
13850
  if (!existsSync14(path))
13471
13851
  return "missing";
13472
- const hash = createHash5("sha256");
13852
+ const hash = createHash4("sha256");
13473
13853
  const visit = (current, relativePath) => {
13474
13854
  let info;
13475
13855
  try {
@@ -13481,7 +13861,7 @@ function snapshotTree(path) {
13481
13861
  hash.update(`${relativePath}\x00${info.mode}\x00${info.size}\x00${info.mtimeMs}\x00`);
13482
13862
  if (info.isDirectory()) {
13483
13863
  for (const entry of readdirSync6(current).sort()) {
13484
- visit(join16(current, entry), join16(relativePath, entry));
13864
+ visit(join18(current, entry), join18(relativePath, entry));
13485
13865
  }
13486
13866
  return;
13487
13867
  }
@@ -13497,31 +13877,34 @@ function snapshotTree(path) {
13497
13877
  return hash.digest("hex");
13498
13878
  }
13499
13879
  function snapshotOperatorState(operatorHome) {
13500
- const database = join16(operatorHome, ".local", "share", "opencode", "opencode.db");
13880
+ const database = join18(operatorHome, ".local", "share", "opencode", "opencode.db");
13501
13881
  return JSON.stringify({
13502
13882
  database: snapshotTree(database),
13503
13883
  databaseWal: snapshotTree(`${database}-wal`),
13504
13884
  databaseShm: snapshotTree(`${database}-shm`),
13505
- logs: snapshotTree(join16(operatorHome, ".local", "share", "opencode", "log"))
13885
+ logs: snapshotTree(join18(operatorHome, ".local", "share", "opencode", "log"))
13506
13886
  });
13507
13887
  }
13508
13888
  function probeCreatedIsolatedState(dataRoot, stateRoot) {
13509
13889
  return [dataRoot, stateRoot].some((root) => {
13510
- const opencodeRoot = join16(root, "opencode");
13511
- const database = join16(opencodeRoot, "opencode.db");
13512
- return [database, `${database}-wal`, `${database}-shm`, join16(opencodeRoot, "log")].some(existsSync14);
13890
+ const opencodeRoot = join18(root, "opencode");
13891
+ const database = join18(opencodeRoot, "opencode.db");
13892
+ return [database, `${database}-wal`, `${database}-shm`, join18(opencodeRoot, "log")].some(existsSync14);
13513
13893
  });
13514
13894
  }
13515
13895
  function probeOpenCodeV1Version(executable, options = {}) {
13516
- const operatorHome = options.operatorHome ?? homedir12();
13896
+ const launchPath = hostLaunchPath(executable, options.platform ?? process.platform);
13897
+ if (launchPath === null)
13898
+ return null;
13899
+ const operatorHome = options.operatorHome ?? homedir14();
13517
13900
  const before = snapshotOperatorState(operatorHome);
13518
- const root = mkdtempSync(join16(options.tempParent ?? tmpdir2(), "aft-opencode-probe-"));
13519
- const home = join16(root, "home");
13520
- const config = join16(root, "config");
13521
- const data = join16(root, "data");
13522
- const state = join16(root, "state");
13523
- const cache = join16(root, "cache");
13524
- const project = join16(root, "project");
13901
+ const root = mkdtempSync(join18(options.tempParent ?? tmpdir3(), "aft-opencode-probe-"));
13902
+ const home = join18(root, "home");
13903
+ const config = join18(root, "config");
13904
+ const data = join18(root, "data");
13905
+ const state = join18(root, "state");
13906
+ const cache = join18(root, "cache");
13907
+ const project = join18(root, "project");
13525
13908
  for (const directory of [home, config, data, state, cache, project]) {
13526
13909
  mkdirSync5(directory, { recursive: true });
13527
13910
  }
@@ -13532,7 +13915,7 @@ function probeOpenCodeV1Version(executable, options = {}) {
13532
13915
  XDG_DATA_HOME: data,
13533
13916
  XDG_STATE_HOME: state,
13534
13917
  XDG_CACHE_HOME: cache,
13535
- TMPDIR: join16(root, "tmp")
13918
+ TMPDIR: join18(root, "tmp")
13536
13919
  };
13537
13920
  mkdirSync5(env.TMPDIR, { recursive: true });
13538
13921
  delete env.OPENCODE_CONFIG;
@@ -13542,7 +13925,7 @@ function probeOpenCodeV1Version(executable, options = {}) {
13542
13925
  let result;
13543
13926
  let probeError;
13544
13927
  try {
13545
- result = (options.spawn ?? spawnSync)(executable, ["--standalone", "--version"], {
13928
+ result = (options.spawn ?? spawnSync)(launchPath, ["--standalone", "--version"], {
13546
13929
  cwd: project,
13547
13930
  encoding: "utf8",
13548
13931
  env,
@@ -13592,7 +13975,7 @@ function isV2Version(version) {
13592
13975
  }
13593
13976
  function resolvedPath(executable) {
13594
13977
  try {
13595
- return realpathSync3(executable);
13978
+ return realpathSync4(executable);
13596
13979
  } catch {
13597
13980
  return executable;
13598
13981
  }
@@ -13601,13 +13984,18 @@ function detectOpenCodeHostGeneration(dependencies = {}) {
13601
13984
  const findExecutable = dependencies.findExecutable ?? ((name) => findExecutableOnPath2(name, dependencies.path, dependencies.platform));
13602
13985
  const openCodeExecutable = findExecutable("opencode");
13603
13986
  const openCode2Executable = findExecutable("opencode2");
13987
+ const platform = dependencies.platform ?? process.platform;
13988
+ const hostOf = (executable) => executable === null ? null : hostLaunchPath(executable, platform) ?? executable;
13989
+ const openCodeHost = hostOf(openCodeExecutable);
13990
+ const openCode2Host = hostOf(openCode2Executable);
13604
13991
  const evidence = [];
13605
- const sharedExecutable = openCodeExecutable !== null && openCode2Executable !== null && resolvedPath(openCodeExecutable) === resolvedPath(openCode2Executable);
13606
- if (openCodeExecutable) {
13607
- const v1Metadata = packageMetadataNearExecutable(openCodeExecutable, "opencode-ai");
13608
- const v2Metadata = v2MetadataNearExecutable(openCodeExecutable);
13992
+ const sharedExecutable = openCodeHost !== null && openCode2Host !== null && resolvedPath(openCodeHost) === resolvedPath(openCode2Host);
13993
+ if (openCodeExecutable !== null && openCodeHost !== null) {
13994
+ const v1Metadata = packageMetadataNearExecutable(openCodeHost, "opencode-ai");
13995
+ const v2Metadata = v2MetadataNearExecutable(openCodeHost);
13609
13996
  const metadataVersion = packageVersion(v2Metadata) ?? packageVersion(v1Metadata);
13610
- const version = metadataVersion ?? (dependencies.probeV1Version ?? probeOpenCodeV1Version)(openCodeExecutable);
13997
+ const probeVersion = dependencies.probeV1Version ?? ((executable) => probeOpenCodeV1Version(executable, { platform }));
13998
+ const version = metadataVersion ?? probeVersion(openCodeExecutable);
13611
13999
  const isV2 = Boolean(v2Metadata) || sharedExecutable || isV2Version(version);
13612
14000
  evidence.push({
13613
14001
  generation: isV2 ? "v2" : "v1",
@@ -13617,8 +14005,8 @@ function detectOpenCodeHostGeneration(dependencies = {}) {
13617
14005
  modernV1: !isV2 && version === MODERN_V1_VERSION
13618
14006
  });
13619
14007
  }
13620
- if (openCode2Executable && !sharedExecutable) {
13621
- const version = packageVersion(v2MetadataNearExecutable(openCode2Executable));
14008
+ if (openCode2Executable !== null && openCode2Host !== null && !sharedExecutable) {
14009
+ const version = packageVersion(v2MetadataNearExecutable(openCode2Host));
13622
14010
  evidence.push({
13623
14011
  generation: "v2",
13624
14012
  executable: openCode2Executable,
@@ -13654,10 +14042,14 @@ function formatHostGenerations(detection) {
13654
14042
  return "V2";
13655
14043
  return "unknown";
13656
14044
  }
13657
- var FULL_CONTENT_HASH_MAX_BYTES, PARTIAL_CONTENT_WINDOW_BYTES, V2_PACKAGE_NAMES;
14045
+ var LAUNCHER_MAX_BYTES, CMD_LAUNCHER_PATH, SH_LAUNCHER_PATH, BATCH_FILE, FULL_CONTENT_HASH_MAX_BYTES, PARTIAL_CONTENT_WINDOW_BYTES, V2_PACKAGE_NAMES;
13658
14046
  var init_host_generation = __esm(() => {
13659
14047
  init_dist2();
13660
14048
  init_opencode_config();
14049
+ LAUNCHER_MAX_BYTES = 64 * 1024;
14050
+ CMD_LAUNCHER_PATH = /"%~?dp0%?\\([^"%\r\n]+)"/g;
14051
+ SH_LAUNCHER_PATH = /"\$basedir\/([^"$\r\n]+)"/g;
14052
+ BATCH_FILE = /\.(?:cmd|bat)$/i;
13661
14053
  FULL_CONTENT_HASH_MAX_BYTES = 64 * 1024 * 1024;
13662
14054
  PARTIAL_CONTENT_WINDOW_BYTES = 1024 * 1024;
13663
14055
  V2_PACKAGE_NAMES = ["@opencode/cli", "@opencode-ai/cli"];
@@ -13665,21 +14057,21 @@ var init_host_generation = __esm(() => {
13665
14057
 
13666
14058
  // src/adapters/opencode.ts
13667
14059
  import { existsSync as existsSync15, readFileSync as readFileSync11, rmSync as rmSync4, statSync as statSync11 } from "node:fs";
13668
- import { homedir as homedir13 } from "node:os";
13669
- import { dirname as dirname8, join as join17, parse as parse2, resolve as resolve10 } from "node:path";
14060
+ import { homedir as homedir15 } from "node:os";
14061
+ import { dirname as dirname9, join as join19, parse as parse3, resolve as resolve12 } from "node:path";
13670
14062
  import { fileURLToPath } from "node:url";
13671
14063
  function getOpenCodeConfigDir() {
13672
14064
  const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
13673
14065
  if (envDir)
13674
- return resolve10(envDir);
14066
+ return resolve12(envDir);
13675
14067
  return getOpenCodeConfigRoot();
13676
14068
  }
13677
14069
  function getLegacyOpenCodePluginCachePath(primaryPath) {
13678
14070
  if (process.platform !== "win32")
13679
14071
  return null;
13680
- const localAppData = process.env.LOCALAPPDATA ?? join17(homedir13(), "AppData", "Local");
13681
- const legacyPath = join17(localAppData, "opencode", "packages", LEGACY_PLUGIN_ENTRY);
13682
- return resolve10(legacyPath) === resolve10(primaryPath) ? null : legacyPath;
14072
+ const localAppData = process.env.LOCALAPPDATA ?? join19(homedir15(), "AppData", "Local");
14073
+ const legacyPath = join19(localAppData, "opencode", "packages", LEGACY_PLUGIN_ENTRY);
14074
+ return resolve12(legacyPath) === resolve12(primaryPath) ? null : legacyPath;
13683
14075
  }
13684
14076
  function clearLegacyOpenCodePluginCache(primaryPath) {
13685
14077
  const legacyPath = getLegacyOpenCodePluginCachePath(primaryPath);
@@ -13701,12 +14093,12 @@ function hasOpenCodeCli() {
13701
14093
  function openCodeDesktopAppExists() {
13702
14094
  const candidates = [];
13703
14095
  if (process.platform === "darwin") {
13704
- candidates.push("/Applications/OpenCode.app", "/Applications/OpenCode Beta.app", join17(homedir13(), "Applications", "OpenCode.app"), join17(homedir13(), "Applications", "OpenCode Beta.app"));
14096
+ candidates.push("/Applications/OpenCode.app", "/Applications/OpenCode Beta.app", join19(homedir15(), "Applications", "OpenCode.app"), join19(homedir15(), "Applications", "OpenCode Beta.app"));
13705
14097
  } else if (process.platform === "win32") {
13706
- const localAppData = process.env.LOCALAPPDATA ?? join17(homedir13(), "AppData", "Local");
13707
- candidates.push(join17(localAppData, "Programs", "opencode"), join17(localAppData, "opencode"));
14098
+ const localAppData = process.env.LOCALAPPDATA ?? join19(homedir15(), "AppData", "Local");
14099
+ candidates.push(join19(localAppData, "Programs", "opencode"), join19(localAppData, "opencode"));
13708
14100
  } else {
13709
- candidates.push("/opt/OpenCode", "/usr/lib/opencode", join17(homedir13(), ".local", "share", "applications", "opencode.desktop"));
14101
+ candidates.push("/opt/OpenCode", "/usr/lib/opencode", join19(homedir15(), ".local", "share", "applications", "opencode.desktop"));
13710
14102
  }
13711
14103
  return candidates.some((p) => {
13712
14104
  try {
@@ -13735,16 +14127,16 @@ function pathPointsToOurPlugin(entry) {
13735
14127
  try {
13736
14128
  if (!existsSync15(fsPath))
13737
14129
  return false;
13738
- let searchDir = statSync11(fsPath).isDirectory() ? fsPath : dirname8(fsPath);
14130
+ let searchDir = statSync11(fsPath).isDirectory() ? fsPath : dirname9(fsPath);
13739
14131
  let pkgJsonPath = null;
13740
14132
  while (true) {
13741
- const candidate = join17(searchDir, "package.json");
14133
+ const candidate = join19(searchDir, "package.json");
13742
14134
  if (existsSync15(candidate)) {
13743
14135
  pkgJsonPath = candidate;
13744
14136
  break;
13745
14137
  }
13746
- const parent = dirname8(searchDir);
13747
- if (parent === searchDir || searchDir === parse2(searchDir).root)
14138
+ const parent = dirname9(searchDir);
14139
+ if (parent === searchDir || searchDir === parse3(searchDir).root)
13748
14140
  break;
13749
14141
  searchDir = parent;
13750
14142
  }
@@ -13912,23 +14304,33 @@ class OpenCodeAdapter {
13912
14304
  };
13913
14305
  }
13914
14306
  hostShellState() {
14307
+ return this.hostToolState("shell");
14308
+ }
14309
+ hostToolState(hostTool) {
13915
14310
  if (this.configGeneration() !== "v2")
13916
14311
  return "not_applicable";
13917
14312
  const { value } = readJsoncFile(this.detectConfigPaths().harnessConfig);
13918
- return hostShellPluginDisabled(value) ? "disabled" : "enabled";
14313
+ return hostToolPluginDisabled(value, hostTool) ? "disabled" : "enabled";
13919
14314
  }
13920
14315
  aftBashEnabled() {
14316
+ return this.aftHostReplacementEnabled("shell");
14317
+ }
14318
+ aftHostReplacementEnabled(hostTool) {
13921
14319
  const { value } = readJsoncFile(this.detectConfigPaths().aftConfig);
13922
- return aftBashEnabled(value);
14320
+ return aftHostReplacementEnabled(value, hostTool);
13923
14321
  }
13924
14322
  setHostShellDisabled(disabled) {
14323
+ return this.setHostToolDisabled("shell", disabled);
14324
+ }
14325
+ setHostToolDisabled(hostTool, disabled) {
14326
+ const { disableEntry, aftTool } = OPENCODE_HOST_TOOLS[hostTool];
13925
14327
  const configPath = this.detectConfigPaths().harnessConfig;
13926
14328
  const format = this.detectConfigPaths().harnessConfigFormat;
13927
14329
  if (this.configGeneration() !== "v2") {
13928
14330
  return {
13929
14331
  ok: false,
13930
14332
  action: "error",
13931
- message: "only OpenCode 2 has a built-in shell tool plugin to disable",
14333
+ message: `only OpenCode 2 has a built-in ${hostTool} tool plugin to disable`,
13932
14334
  configPath
13933
14335
  };
13934
14336
  }
@@ -13936,13 +14338,13 @@ class OpenCodeAdapter {
13936
14338
  if (!disabled) {
13937
14339
  return { ok: true, action: "already_present", message: "no config to change", configPath };
13938
14340
  }
13939
- const failed = this.tryWrite(configPath, () => writeJsoncFile(configPath, { plugins: [OPENCODE_HOST_SHELL_DISABLE_ENTRY] }, "json"));
14341
+ const failed = this.tryWrite(configPath, () => writeJsoncFile(configPath, { plugins: [disableEntry] }, "json"));
13940
14342
  if (failed)
13941
14343
  return failed;
13942
14344
  return {
13943
14345
  ok: true,
13944
14346
  action: "added",
13945
- message: `Created ${configPath} with ${OPENCODE_HOST_SHELL_DISABLE_ENTRY} under \`plugins\``,
14347
+ message: `Created ${configPath} with ${disableEntry} under \`plugins\``,
13946
14348
  configPath
13947
14349
  };
13948
14350
  }
@@ -13955,12 +14357,12 @@ class OpenCodeAdapter {
13955
14357
  configPath
13956
14358
  };
13957
14359
  }
13958
- const { changed } = setHostShellPluginDisabled(value, disabled);
14360
+ const { changed } = setHostToolPluginDisabled(value, hostTool, disabled);
13959
14361
  if (!changed) {
13960
14362
  return {
13961
14363
  ok: true,
13962
14364
  action: "already_present",
13963
- message: disabled ? `${OPENCODE_HOST_SHELL_DISABLE_ENTRY} is already set in ${configPath}` : `${OPENCODE_HOST_SHELL_DISABLE_ENTRY} is not set in ${configPath}`,
14365
+ message: disabled ? `${disableEntry} is already set in ${configPath}` : `${disableEntry} is not set in ${configPath}`,
13964
14366
  configPath
13965
14367
  };
13966
14368
  }
@@ -13970,7 +14372,7 @@ class OpenCodeAdapter {
13970
14372
  return {
13971
14373
  ok: true,
13972
14374
  action: disabled ? "added" : "updated",
13973
- message: disabled ? `Added ${OPENCODE_HOST_SHELL_DISABLE_ENTRY} under \`plugins\` in ${configPath}: OpenCode's own shell tool is disabled, so agents use AFT's bash` : `Removed ${OPENCODE_HOST_SHELL_DISABLE_ENTRY} from ${configPath}: OpenCode's own shell tool is enabled again`,
14375
+ message: disabled ? `Added ${disableEntry} under \`plugins\` in ${configPath}: OpenCode's own ${hostTool} tool is disabled, so agents use AFT's ${aftTool}` : `Removed ${disableEntry} from ${configPath}: OpenCode's own ${hostTool} tool is enabled again`,
13974
14376
  configPath
13975
14377
  };
13976
14378
  }
@@ -13994,10 +14396,10 @@ class OpenCodeAdapter {
13994
14396
  const configPath = this.detectConfigPaths().harnessConfig;
13995
14397
  const { value } = readJsoncFile(configPath);
13996
14398
  const configuredEntry = openCodePluginReadKeys(this.configGeneration()).flatMap((key) => Array.isArray(value?.[key]) ? value[key] : []).map(pluginEntryPackage).find(isAftNpmEntry);
13997
- const path = join17(getOpenCodeCacheDir(), "packages", configuredEntry ?? PLUGIN_ENTRY);
14399
+ const path = join19(getOpenCodeCacheDir(), "packages", configuredEntry ?? PLUGIN_ENTRY);
13998
14400
  let cached;
13999
14401
  try {
14000
- const installedPkgPath = join17(path, "node_modules", "@cortexkit", "aft-opencode", "package.json");
14402
+ const installedPkgPath = join19(path, "node_modules", "@cortexkit", "aft-opencode", "package.json");
14001
14403
  if (existsSync15(installedPkgPath)) {
14002
14404
  const pkg = JSON.parse(readFileSync11(installedPkgPath, "utf-8"));
14003
14405
  cached = typeof pkg.version === "string" ? pkg.version : undefined;
@@ -14073,12 +14475,12 @@ class OpenCodeAdapter {
14073
14475
  describeStorageSubtrees() {
14074
14476
  const storage = this.getStorageDir();
14075
14477
  return {
14076
- index: dirSize(join17(storage, "index")),
14077
- semantic: dirSize(join17(storage, "semantic")),
14078
- backups: dirSize(join17(storage, "backups")),
14079
- url_cache: dirSize(join17(storage, "url_cache")),
14080
- onnxruntime: dirSize(join17(storage, "onnxruntime")),
14081
- logs: dirSize(join17(storage, "logs"))
14478
+ index: dirSize(join19(storage, "index")),
14479
+ semantic: dirSize(join19(storage, "semantic")),
14480
+ backups: dirSize(join19(storage, "backups")),
14481
+ url_cache: dirSize(join19(storage, "url_cache")),
14482
+ onnxruntime: dirSize(join19(storage, "onnxruntime")),
14483
+ logs: dirSize(join19(storage, "logs"))
14082
14484
  };
14083
14485
  }
14084
14486
  }
@@ -14099,18 +14501,18 @@ var init_opencode = __esm(() => {
14099
14501
 
14100
14502
  // src/adapters/pi.ts
14101
14503
  import { existsSync as existsSync16, readFileSync as readFileSync12 } from "node:fs";
14102
- import { homedir as homedir14 } from "node:os";
14103
- import { join as join18, resolve as resolve11 } from "node:path";
14504
+ import { homedir as homedir16 } from "node:os";
14505
+ import { join as join20, resolve as resolve13 } from "node:path";
14104
14506
  function getPiAgentDir() {
14105
14507
  const configuredDir = process.env.PI_CODING_AGENT_DIR?.trim();
14106
14508
  if (configuredDir)
14107
- return resolve11(configuredDir);
14509
+ return resolve13(configuredDir);
14108
14510
  const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
14109
- const home = envHome && envHome.length > 0 ? envHome : homedir14();
14110
- return join18(home, ".pi", "agent");
14511
+ const home = envHome && envHome.length > 0 ? envHome : homedir16();
14512
+ return join20(home, ".pi", "agent");
14111
14513
  }
14112
14514
  function readPiExtensionIndex() {
14113
- const settingsPath = join18(getPiAgentDir(), "settings.json");
14515
+ const settingsPath = join20(getPiAgentDir(), "settings.json");
14114
14516
  if (existsSync16(settingsPath)) {
14115
14517
  try {
14116
14518
  const raw = readFileSync12(settingsPath, "utf-8");
@@ -14131,10 +14533,10 @@ function readPiExtensionIndex() {
14131
14533
  } catch {}
14132
14534
  }
14133
14535
  const candidates = [
14134
- join18(getPiAgentDir(), "extensions.json"),
14135
- join18(getPiAgentDir(), "extensions.jsonc"),
14136
- join18(getPiAgentDir(), "config.json"),
14137
- join18(getPiAgentDir(), "config.jsonc")
14536
+ join20(getPiAgentDir(), "extensions.json"),
14537
+ join20(getPiAgentDir(), "extensions.jsonc"),
14538
+ join20(getPiAgentDir(), "config.json"),
14539
+ join20(getPiAgentDir(), "config.jsonc")
14138
14540
  ];
14139
14541
  for (const path of candidates) {
14140
14542
  if (!existsSync16(path))
@@ -14170,14 +14572,14 @@ function piEntryMatchesAft(entry) {
14170
14572
  } else if (entry.startsWith("/")) {
14171
14573
  resolved = entry;
14172
14574
  } else if (entry.length > 0) {
14173
- resolved = join18(getPiAgentDir(), entry);
14575
+ resolved = join20(getPiAgentDir(), entry);
14174
14576
  }
14175
14577
  if (!resolved)
14176
14578
  return false;
14177
14579
  try {
14178
14580
  if (!existsSync16(resolved))
14179
14581
  return false;
14180
- const pkgPath = join18(resolved, "package.json");
14582
+ const pkgPath = join20(resolved, "package.json");
14181
14583
  if (!existsSync16(pkgPath))
14182
14584
  return false;
14183
14585
  const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
@@ -14229,7 +14631,7 @@ class PiAdapter {
14229
14631
  const aftConfigExists = existsSync16(aftConfigPath);
14230
14632
  return {
14231
14633
  configDir,
14232
- harnessConfig: index.path ?? join18(configDir, "extensions.json"),
14634
+ harnessConfig: index.path ?? join20(configDir, "extensions.json"),
14233
14635
  harnessConfigFormat: index.path ? "json" : "none",
14234
14636
  aftConfig: aftConfigPath,
14235
14637
  aftConfigFormat: aftConfigExists ? "jsonc" : "none"
@@ -14274,9 +14676,9 @@ class PiAdapter {
14274
14676
  }
14275
14677
  getPluginCacheInfo() {
14276
14678
  const candidates = [
14277
- join18(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
14278
- join18(getPiAgentDir(), "node_modules", "@cortexkit", "aft-pi", "package.json"),
14279
- join18(getPiAgentDir(), "extensions", "node_modules", "@cortexkit", "aft-pi", "package.json")
14679
+ join20(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
14680
+ join20(getPiAgentDir(), "node_modules", "@cortexkit", "aft-pi", "package.json"),
14681
+ join20(getPiAgentDir(), "extensions", "node_modules", "@cortexkit", "aft-pi", "package.json")
14280
14682
  ];
14281
14683
  for (const candidate of candidates) {
14282
14684
  if (!existsSync16(candidate))
@@ -14293,7 +14695,7 @@ class PiAdapter {
14293
14695
  } catch {}
14294
14696
  }
14295
14697
  return {
14296
- path: join18(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
14698
+ path: join20(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
14297
14699
  exists: false
14298
14700
  };
14299
14701
  }
@@ -14315,12 +14717,12 @@ class PiAdapter {
14315
14717
  describeStorageSubtrees() {
14316
14718
  const storage = this.getStorageDir();
14317
14719
  return {
14318
- index: dirSize(join18(storage, "index")),
14319
- semantic: dirSize(join18(storage, "semantic")),
14320
- backups: dirSize(join18(storage, "backups")),
14321
- url_cache: dirSize(join18(storage, "url_cache")),
14322
- onnxruntime: dirSize(join18(storage, "onnxruntime")),
14323
- logs: dirSize(join18(storage, "logs"))
14720
+ index: dirSize(join20(storage, "index")),
14721
+ semantic: dirSize(join20(storage, "semantic")),
14722
+ backups: dirSize(join20(storage, "backups")),
14723
+ url_cache: dirSize(join20(storage, "url_cache")),
14724
+ onnxruntime: dirSize(join20(storage, "onnxruntime")),
14725
+ logs: dirSize(join20(storage, "logs"))
14324
14726
  };
14325
14727
  }
14326
14728
  }
@@ -15741,11 +16143,11 @@ var init_version = __esm(async () => {
15741
16143
 
15742
16144
  // src/lib/cli-logger.ts
15743
16145
  import { appendFileSync, mkdirSync as mkdirSync6 } from "node:fs";
15744
- import { tmpdir as tmpdir3 } from "node:os";
15745
- import { dirname as dirname9, join as join19 } from "node:path";
16146
+ import { tmpdir as tmpdir4 } from "node:os";
16147
+ import { dirname as dirname10, join as join21 } from "node:path";
15746
16148
  function cliLogPath() {
15747
16149
  if (isTestEnvironment())
15748
- return join19(tmpdir3(), "aft-cli-test.log");
16150
+ return join21(tmpdir4(), "aft-cli-test.log");
15749
16151
  return resolveAftLogPath("aft-cli.log");
15750
16152
  }
15751
16153
  function write(level, message) {
@@ -15760,7 +16162,7 @@ function write(level, message) {
15760
16162
  }
15761
16163
  try {
15762
16164
  const path = cliLogPath();
15763
- mkdirSync6(dirname9(path), { recursive: true });
16165
+ mkdirSync6(dirname10(path), { recursive: true });
15764
16166
  appendFileSync(path, `${new Date().toISOString()} ${level.toUpperCase()} ${message}
15765
16167
  `);
15766
16168
  } catch {}
@@ -15798,10 +16200,10 @@ var init_cli_logger = __esm(() => {
15798
16200
 
15799
16201
  // src/lib/binary-install.ts
15800
16202
  import { existsSync as existsSync17 } from "node:fs";
15801
- import { join as join20 } from "node:path";
16203
+ import { join as join22 } from "node:path";
15802
16204
  function cachedBinaryFor(version) {
15803
16205
  const tag = version.startsWith("v") ? version : `v${version}`;
15804
- const path = join20(getAftBinaryCacheDir(), tag, getAftBinaryName());
16206
+ const path = join22(getAftBinaryCacheDir(), tag, getAftBinaryName());
15805
16207
  try {
15806
16208
  return existsSync17(path) ? path : null;
15807
16209
  } catch {
@@ -15935,7 +16337,7 @@ function loadFeaturePlan(harness, run = runNative) {
15935
16337
  return {
15936
16338
  ok: false,
15937
16339
  error: withCliCommands(error),
15938
- configRejected: result.status === 1 && error.includes("aft doctor --fix"),
16340
+ configRejected: result.status === 1 && error.includes("AFT cannot load this configuration"),
15939
16341
  missingBinary: result.missingBinary === true
15940
16342
  };
15941
16343
  }
@@ -16417,8 +16819,10 @@ async function runSetup(argv, options = {}) {
16417
16819
  for (const adapter of nextSteps) {
16418
16820
  if (!(adapter instanceof OpenCodeAdapter))
16419
16821
  continue;
16420
- if (await offerHostShellDisable(adapter, argv, options) === "failed")
16421
- anyFailure = true;
16822
+ for (const hostTool of OPENCODE_HOST_TOOL_NAMES) {
16823
+ if (await offerHostToolDisable(adapter, hostTool, argv, options) === "failed")
16824
+ anyFailure = true;
16825
+ }
16422
16826
  }
16423
16827
  for (const adapter of nextSteps)
16424
16828
  printNextSteps(adapter);
@@ -16488,19 +16892,20 @@ async function configureAdapter(adapter, options) {
16488
16892
  }
16489
16893
  return failed ? "failed" : "ok";
16490
16894
  }
16491
- async function offerHostShellDisable(adapter, argv, options = {}) {
16492
- if (adapter.hostShellState() === "not_applicable")
16895
+ async function offerHostToolDisable(adapter, hostTool, argv, options = {}) {
16896
+ if (adapter.hostToolState(hostTool) === "not_applicable")
16493
16897
  return "skipped";
16494
- const bashOn = adapter.aftBashEnabled();
16898
+ const { aftTool } = OPENCODE_HOST_TOOLS[hostTool];
16899
+ const replacementOn = adapter.aftHostReplacementEnabled(hostTool);
16495
16900
  const interactive = !argv.includes("--yes") && !argv.includes("-y") && (options.interactive ?? Boolean(process.stdin.isTTY));
16496
- const disable = interactive ? await (options.confirmHostShell ?? confirm2)(HOST_SHELL_QUESTION, bashOn) : bashOn;
16497
- const result = adapter.setHostShellDisabled(disable);
16901
+ const disable = interactive ? await (options.confirmHostTool ?? (hostTool === "shell" ? options.confirmHostShell : undefined) ?? confirm2)(hostTool === "shell" ? HOST_SHELL_QUESTION : `OpenCode's own ${hostTool} tool: disable it so agents use AFT's ${aftTool}?`, replacementOn) : replacementOn;
16902
+ const result = adapter.setHostToolDisabled(hostTool, disable);
16498
16903
  if (!result.ok) {
16499
16904
  log2.error(`${adapter.displayName}: ${result.message}`);
16500
16905
  return "failed";
16501
16906
  }
16502
16907
  if (result.action === "already_present") {
16503
- log2.info(`${adapter.displayName}: OpenCode's own shell tool is ${disable ? "already disabled" : "enabled"}${disable ? "; agents use AFT's bash" : bashOn ? "" : " (AFT's bash is disabled)"}`);
16908
+ log2.info(`${adapter.displayName}: OpenCode's own ${hostTool} tool is ${disable ? "already disabled" : "enabled"}${disable ? `; agents use AFT's ${aftTool}` : replacementOn ? "" : ` (AFT's ${aftTool} is disabled)`}`);
16504
16909
  } else {
16505
16910
  log2.success(`${adapter.displayName}: ${result.message}`);
16506
16911
  }
@@ -16556,6 +16961,7 @@ var init_setup = __esm(async () => {
16556
16961
  init_prompts();
16557
16962
  init_self_version();
16558
16963
  init_host_generation();
16964
+ init_opencode_config();
16559
16965
  await __promiseAll([
16560
16966
  init_binary_probe(),
16561
16967
  init_feature_plan(),
@@ -16607,6 +17013,28 @@ var init_backups = __esm(async () => {
16607
17013
  await init_binary_probe();
16608
17014
  });
16609
17015
 
17016
+ // src/commands/cache.ts
17017
+ function runCache(argv) {
17018
+ const binary = findAftBinary();
17019
+ if (!binary) {
17020
+ console.error(missingAftBinaryMessage(`${CLI} cache`));
17021
+ return 1;
17022
+ }
17023
+ const result = spawnSync(binary, ["cache", ...argv], {
17024
+ stdio: "inherit",
17025
+ env: process.env
17026
+ });
17027
+ if (result.error) {
17028
+ console.error(`aft cache failed to start ${binary}: ${result.error.message}`);
17029
+ return 1;
17030
+ }
17031
+ return result.status ?? 1;
17032
+ }
17033
+ var init_cache = __esm(async () => {
17034
+ init_dist2();
17035
+ await init_binary_probe();
17036
+ });
17037
+
16610
17038
  // src/doctor/features.ts
16611
17039
  function isOn(feature) {
16612
17040
  return feature.effective !== "off";
@@ -16716,7 +17144,7 @@ var init_features = __esm(() => {
16716
17144
 
16717
17145
  // src/doctor/opencode.ts
16718
17146
  import { existsSync as existsSync18, readFileSync as readFileSync13 } from "node:fs";
16719
- import { dirname as dirname10, join as join21 } from "node:path";
17147
+ import { dirname as dirname11, join as join23 } from "node:path";
16720
17148
  import { fileURLToPath as fileURLToPath2 } from "node:url";
16721
17149
  function isLoadPath(value) {
16722
17150
  return OPENCODE_LOAD_PATHS.includes(value);
@@ -16787,13 +17215,13 @@ function readManifest(path) {
16787
17215
  }
16788
17216
  function manifestFromLocalPath(path) {
16789
17217
  let current = path;
16790
- if (!existsSync18(join21(current, "package.json")))
16791
- current = dirname10(current);
17218
+ if (!existsSync18(join23(current, "package.json")))
17219
+ current = dirname11(current);
16792
17220
  while (true) {
16793
- const manifest = readManifest(join21(current, "package.json"));
17221
+ const manifest = readManifest(join23(current, "package.json"));
16794
17222
  if (manifest)
16795
17223
  return manifest;
16796
- const parent = dirname10(current);
17224
+ const parent = dirname11(current);
16797
17225
  if (parent === current)
16798
17226
  return null;
16799
17227
  current = parent;
@@ -16803,7 +17231,7 @@ function pluginManifest(entry, cachePath) {
16803
17231
  const localRoot = localPluginRoot(entry);
16804
17232
  if (localRoot)
16805
17233
  return manifestFromLocalPath(localRoot);
16806
- return readManifest(join21(cachePath, "node_modules", "@cortexkit", "aft-opencode", "package.json"));
17234
+ return readManifest(join23(cachePath, "node_modules", "@cortexkit", "aft-opencode", "package.json"));
16807
17235
  }
16808
17236
  function pinProblem(entry, pinned) {
16809
17237
  return `the plugin entry ${entry} ${describePluginEntry(entry)}; run \`${CLI} doctor --fix\` to pin it to ${pinned}`;
@@ -16903,6 +17331,36 @@ function isResponseForRequest(parsed, expectedIds) {
16903
17331
  return false;
16904
17332
  return expectedIds.has(id);
16905
17333
  }
17334
+ function createNdjsonLineSplitter(onLine) {
17335
+ let pending = [];
17336
+ let scannedChars = 0;
17337
+ return {
17338
+ push(chunk) {
17339
+ scannedChars += chunk.length;
17340
+ let start = 0;
17341
+ let newline = chunk.indexOf(`
17342
+ `);
17343
+ while (newline !== -1) {
17344
+ let line = chunk.slice(start, newline);
17345
+ if (pending.length > 0) {
17346
+ pending.push(line);
17347
+ line = pending.join("");
17348
+ pending = [];
17349
+ }
17350
+ start = newline + 1;
17351
+ if (onLine(line.trim()) === true)
17352
+ return;
17353
+ newline = chunk.indexOf(`
17354
+ `, start);
17355
+ }
17356
+ if (start < chunk.length)
17357
+ pending.push(start === 0 ? chunk : chunk.slice(start));
17358
+ },
17359
+ get scannedChars() {
17360
+ return scannedChars;
17361
+ }
17362
+ };
17363
+ }
16906
17364
  async function sendAftRequest(binaryPath, request) {
16907
17365
  const responses = await sendAftRequests(binaryPath, [request]);
16908
17366
  const response = responses[0];
@@ -16917,7 +17375,7 @@ async function sendAftRequests(binaryPath, requests) {
16917
17375
  });
16918
17376
  const responses = [];
16919
17377
  const noiseLines = [];
16920
- let stdout = "";
17378
+ let noiseLineCount = 0;
16921
17379
  let stderr = "";
16922
17380
  let settled = false;
16923
17381
  const finish = (fn) => {
@@ -16928,18 +17386,23 @@ async function sendAftRequests(binaryPath, requests) {
16928
17386
  fn();
16929
17387
  };
16930
17388
  const expectedIds = new Set(requests.map((req) => req.id));
17389
+ const recordNoise = (line) => {
17390
+ noiseLineCount += 1;
17391
+ if (noiseLines.length < MAX_NOISE_LINES_IN_ERROR)
17392
+ noiseLines.push(line);
17393
+ };
16931
17394
  const handleLine = (line) => {
16932
17395
  if (!line)
16933
17396
  return;
16934
17397
  if (!line.startsWith("{")) {
16935
- noiseLines.push(line);
17398
+ recordNoise(line);
16936
17399
  return;
16937
17400
  }
16938
17401
  let parsed;
16939
17402
  try {
16940
17403
  parsed = JSON.parse(line);
16941
17404
  } catch {
16942
- noiseLines.push(line);
17405
+ recordNoise(line);
16943
17406
  return;
16944
17407
  }
16945
17408
  if (!isResponseForRequest(parsed, expectedIds)) {
@@ -16951,20 +17414,15 @@ async function sendAftRequests(binaryPath, requests) {
16951
17414
  finish(() => resolve(responses));
16952
17415
  }
16953
17416
  };
17417
+ const stdoutLines = createNdjsonLineSplitter((line) => {
17418
+ handleLine(line);
17419
+ return settled;
17420
+ });
16954
17421
  child.stdout.setEncoding("utf-8");
16955
17422
  child.stdout.on("data", (chunk) => {
16956
- stdout += chunk;
16957
- while (true) {
16958
- const newline = stdout.indexOf(`
16959
- `);
16960
- if (newline === -1)
16961
- break;
16962
- const line = stdout.slice(0, newline).trim();
16963
- stdout = stdout.slice(newline + 1);
16964
- handleLine(line);
16965
- if (settled)
16966
- break;
16967
- }
17423
+ if (settled)
17424
+ return;
17425
+ stdoutLines.push(chunk);
16968
17426
  });
16969
17427
  child.stderr.setEncoding("utf-8");
16970
17428
  child.stderr.on("data", (chunk) => {
@@ -16976,7 +17434,7 @@ async function sendAftRequests(binaryPath, requests) {
16976
17434
  child.on("close", (code) => {
16977
17435
  if (settled)
16978
17436
  return;
16979
- finish(() => reject(buildBridgeError({ binaryPath, code, stderr, noiseLines, responses })));
17437
+ finish(() => reject(buildBridgeError({ binaryPath, code, stderr, noiseLines, noiseLineCount, responses })));
16980
17438
  });
16981
17439
  child.stdin.on("error", () => {});
16982
17440
  try {
@@ -16994,14 +17452,14 @@ function buildBridgeError(ctx) {
16994
17452
  if (ctx.responses.length > 0) {
16995
17453
  parts.push(`Got ${ctx.responses.length} valid response(s) before exit.`);
16996
17454
  }
16997
- if (ctx.noiseLines.length > 0) {
17455
+ if (ctx.noiseLineCount > 0) {
16998
17456
  parts.push(`
16999
- The binary printed ${ctx.noiseLines.length} non-JSON line(s) to stdout — this usually means ` + "the resolved binary isn't an AFT release binary (wrapper script, panic output, or unrelated tool):");
17457
+ The binary printed ${ctx.noiseLineCount} non-JSON line(s) to stdout — this usually means ` + "the resolved binary isn't an AFT release binary (wrapper script, panic output, or unrelated tool):");
17000
17458
  const sample = ctx.noiseLines.slice(0, MAX_NOISE_LINES_IN_ERROR).map((line) => ` | ${line}`);
17001
17459
  parts.push(sample.join(`
17002
17460
  `));
17003
- if (ctx.noiseLines.length > MAX_NOISE_LINES_IN_ERROR) {
17004
- parts.push(` | (… ${ctx.noiseLines.length - MAX_NOISE_LINES_IN_ERROR} more line(s) omitted)`);
17461
+ if (ctx.noiseLineCount > MAX_NOISE_LINES_IN_ERROR) {
17462
+ parts.push(` | (… ${ctx.noiseLineCount - MAX_NOISE_LINES_IN_ERROR} more line(s) omitted)`);
17005
17463
  }
17006
17464
  parts.push(`
17007
17465
  Try: ${CLI} doctor (full diagnostics) or check ~/.cache/aft/bin/ for the right binary.`);
@@ -17022,7 +17480,7 @@ var init_aft_bridge = __esm(() => {
17022
17480
 
17023
17481
  // src/lib/binary-cache.ts
17024
17482
  import { existsSync as existsSync19, readdirSync as readdirSync7, statSync as statSync12 } from "node:fs";
17025
- import { join as join22 } from "node:path";
17483
+ import { join as join24 } from "node:path";
17026
17484
  function getBinaryCacheInfo(activeVersion) {
17027
17485
  const path = getAftBinaryCacheDir();
17028
17486
  if (!existsSync19(path)) {
@@ -17035,7 +17493,7 @@ function getBinaryCacheInfo(activeVersion) {
17035
17493
  }
17036
17494
  const versions = readdirSync7(path).filter((entry) => {
17037
17495
  try {
17038
- return statSync12(join22(path, entry)).isDirectory();
17496
+ return statSync12(join24(path, entry)).isDirectory();
17039
17497
  } catch {
17040
17498
  return false;
17041
17499
  }
@@ -17055,14 +17513,14 @@ var init_binary_cache = __esm(() => {
17055
17513
  });
17056
17514
 
17057
17515
  // src/lib/sanitize.ts
17058
- import { realpathSync as realpathSync4 } from "node:fs";
17059
- import { homedir as homedir15, userInfo } from "node:os";
17516
+ import { realpathSync as realpathSync5 } from "node:fs";
17517
+ import { homedir as homedir17, userInfo } from "node:os";
17060
17518
  function escapeRegex(value) {
17061
17519
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
17062
17520
  }
17063
17521
  function safeRealpath(p) {
17064
17522
  try {
17065
- return realpathSync4(p);
17523
+ return realpathSync5(p);
17066
17524
  } catch {
17067
17525
  return null;
17068
17526
  }
@@ -17092,7 +17550,7 @@ function redactSecrets(content) {
17092
17550
  }
17093
17551
  function sanitizeContent(content) {
17094
17552
  const username = userInfo().username;
17095
- const home = homedir15();
17553
+ const home = homedir17();
17096
17554
  let sanitized = redactSecrets(content);
17097
17555
  const cwd = process.cwd();
17098
17556
  for (const candidate of new Set([cwd, safeRealpath(cwd)])) {
@@ -17109,7 +17567,7 @@ function sanitizeContent(content) {
17109
17567
  sanitized = sanitized.replace(/([A-Za-z]:\\Users\\)[^\\"'\s]+/g, "$1<USER>");
17110
17568
  sanitized = sanitized.replace(/([A-Za-z]:\/Users\/)[^/\s"']+/g, "$1<USER>");
17111
17569
  if (username) {
17112
- sanitized = sanitized.replace(new RegExp(escapeRegex(username), "g"), "<USER>");
17570
+ sanitized = redactUsername(sanitized, username);
17113
17571
  }
17114
17572
  return sanitized;
17115
17573
  }
@@ -17125,6 +17583,11 @@ function sanitizeValue(value) {
17125
17583
  }
17126
17584
  return value;
17127
17585
  }
17586
+ function redactUsername(content, username) {
17587
+ if (!username)
17588
+ return content;
17589
+ return content.replace(new RegExp(`(?<![\\p{L}\\p{N}_])${escapeRegex(username)}(?![\\p{L}\\p{N}_])`, "gu"), "<USER>");
17590
+ }
17128
17591
  var SECRET_PLACEHOLDER = "<REDACTED_SECRET>", URL_CREDENTIAL_PLACEHOLDER = "***", KEY_NAME = "[A-Za-z_][A-Za-z0-9_.-]*", SENSITIVE_KEY_WORD, SEGMENTED_KEY_WORD, CAMEL_CASE_KEY_WORD, JWT_PATTERN, AWS_ACCESS_KEY_ID_PATTERN, CREDENTIAL_QUERY_PATTERN, KEY_QUERY_PATTERN, quotedSensitiveKeyValuePattern, unquotedSensitiveKeyValuePattern, bareSensitiveKeyValuePattern;
17129
17592
  var init_sanitize = __esm(() => {
17130
17593
  SENSITIVE_KEY_WORD = /(?:token|password|secret|api[_-]?key|passwd|pwd|credential)/i;
@@ -17140,7 +17603,7 @@ var init_sanitize = __esm(() => {
17140
17603
  });
17141
17604
 
17142
17605
  // src/lib/bridge-tool-failures.ts
17143
- import { closeSync as closeSync6, existsSync as existsSync20, openSync as openSync6, readSync as readSync4, statSync as statSync13 } from "node:fs";
17606
+ import { closeSync as closeSync8, existsSync as existsSync20, openSync as openSync8, readSync as readSync6, statSync as statSync13 } from "node:fs";
17144
17607
  function resolveBridgePluginLogPath() {
17145
17608
  return resolvePluginLogPath();
17146
17609
  }
@@ -17154,16 +17617,16 @@ function tailLogFileBytes(path, maxBytes) {
17154
17617
  return "";
17155
17618
  const readLength = Math.min(size, maxBytes);
17156
17619
  const position = size - readLength;
17157
- fd = openSync6(path, "r");
17620
+ fd = openSync8(path, "r");
17158
17621
  const buffer = Buffer.allocUnsafe(readLength);
17159
- const bytesRead = readSync4(fd, buffer, 0, readLength, position);
17622
+ const bytesRead = readSync6(fd, buffer, 0, readLength, position);
17160
17623
  return buffer.subarray(0, bytesRead).toString("utf-8").trim();
17161
17624
  } catch {
17162
17625
  return "";
17163
17626
  } finally {
17164
17627
  if (fd !== null) {
17165
17628
  try {
17166
- closeSync6(fd);
17629
+ closeSync8(fd);
17167
17630
  } catch {}
17168
17631
  }
17169
17632
  }
@@ -17283,7 +17746,7 @@ var init_bridge_tool_failures = __esm(() => {
17283
17746
  // src/lib/build-breaker.ts
17284
17747
  import { existsSync as existsSync21, readdirSync as readdirSync8 } from "node:fs";
17285
17748
  import { createRequire as createRequire3 } from "node:module";
17286
- import { join as join23 } from "node:path";
17749
+ import { join as join25 } from "node:path";
17287
17750
  function loadDatabaseSync() {
17288
17751
  const require2 = createRequire3(import.meta.url);
17289
17752
  try {
@@ -17297,11 +17760,11 @@ function loadDatabaseSync() {
17297
17760
  }
17298
17761
  }
17299
17762
  function buildBreakerDatabases(storageRoot) {
17300
- const callgraphRoot = join23(storageRoot, "callgraph");
17763
+ const callgraphRoot = join25(storageRoot, "callgraph");
17301
17764
  if (!existsSync21(callgraphRoot))
17302
17765
  return [];
17303
17766
  try {
17304
- return readdirSync8(callgraphRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join23(callgraphRoot, entry.name, "build-breaker.sqlite")).filter((path) => existsSync21(path));
17767
+ return readdirSync8(callgraphRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join25(callgraphRoot, entry.name, "build-breaker.sqlite")).filter((path) => existsSync21(path));
17305
17768
  } catch {
17306
17769
  return [];
17307
17770
  }
@@ -17437,21 +17900,10 @@ function previewConfigMigration(targets) {
17437
17900
  if (!raw)
17438
17901
  continue;
17439
17902
  const translated = structuredClone(raw);
17440
- const translation = translateConfigDocument(translated, "window", target.tier);
17441
- const retiredGithub = Object.hasOwn(raw, "gh_read") || isRecord2(raw.gh_shim) && "enabled" in raw.gh_shim;
17442
- if (!translation.legacyInput && translation.errors.length === 0 && !retiredGithub)
17903
+ const translation = translateConfigDocument(translated, target.tier);
17904
+ if (!translation.legacyInput)
17443
17905
  continue;
17444
17906
  const changes = diffConfig(raw, translated);
17445
- for (const code of translation.errors) {
17446
- const match = /^removed_config_key:([^:]+):use:(.+)$/.exec(code);
17447
- if (match)
17448
- changes.push({
17449
- kind: "changed",
17450
- key: match[1],
17451
- before: undefined,
17452
- after: `→ ${match[2]}`
17453
- });
17454
- }
17455
17907
  previews.push({ ...target, changes });
17456
17908
  }
17457
17909
  return previews;
@@ -17464,9 +17916,6 @@ function describeConfigChange(change) {
17464
17916
  return `removed ${change.key} (was ${show(change.before)})`;
17465
17917
  if (change.kind === "added")
17466
17918
  return `added ${change.key}: ${show(change.after)}`;
17467
- if (change.before === undefined && typeof change.after === "string" && change.after.startsWith("→ ")) {
17468
- return `replaced ${change.key} with ${change.after.slice(2)}`;
17469
- }
17470
17919
  return `changed ${change.key}: ${show(change.before)} → ${show(change.after)}`;
17471
17920
  }
17472
17921
  var import_comment_json2;
@@ -17477,19 +17926,19 @@ var init_config_migration = __esm(() => {
17477
17926
 
17478
17927
  // src/lib/legacy-storage.ts
17479
17928
  import { existsSync as existsSync23, readdirSync as readdirSync9, statSync as statSync14 } from "node:fs";
17480
- import { join as join24 } from "node:path";
17929
+ import { join as join26 } from "node:path";
17481
17930
  function summarizeLegacyPartitionDuplication(storageRoot) {
17482
17931
  if (!existsSync23(storageRoot)) {
17483
17932
  return { totalPartitions: 0, totalBytes: 0, byHarness: [] };
17484
17933
  }
17485
17934
  const byHarness = [];
17486
17935
  for (const harness of safeReadDir(storageRoot)) {
17487
- const harnessPath = join24(storageRoot, harness);
17936
+ const harnessPath = join26(storageRoot, harness);
17488
17937
  if (!isDirectory(harnessPath))
17489
17938
  continue;
17490
17939
  const partitions = new Map;
17491
- collectCallgraphPartitions(join24(harnessPath, "callgraph"), partitions);
17492
- collectInspectPartitions(join24(harnessPath, "inspect"), partitions);
17940
+ collectCallgraphPartitions(join26(harnessPath, "callgraph"), partitions);
17941
+ collectInspectPartitions(join26(harnessPath, "inspect"), partitions);
17493
17942
  if (partitions.size === 0)
17494
17943
  continue;
17495
17944
  let bytes = 0;
@@ -17508,7 +17957,7 @@ function collectCallgraphPartitions(domainPath, partitions) {
17508
17957
  if (!isDirectory(domainPath))
17509
17958
  return;
17510
17959
  for (const name of safeReadDir(domainPath)) {
17511
- const path = join24(domainPath, name);
17960
+ const path = join26(domainPath, name);
17512
17961
  if (isDirectory(path)) {
17513
17962
  if (!looksLikePartitionKey(name))
17514
17963
  continue;
@@ -17525,7 +17974,7 @@ function collectInspectPartitions(domainPath, partitions) {
17525
17974
  if (!isDirectory(domainPath))
17526
17975
  return;
17527
17976
  for (const name of safeReadDir(domainPath)) {
17528
- const path = join24(domainPath, name);
17977
+ const path = join26(domainPath, name);
17529
17978
  if (isDirectory(path)) {
17530
17979
  if (!looksLikePartitionKey(name))
17531
17980
  continue;
@@ -17601,7 +18050,7 @@ var init_legacy_storage = __esm(() => {
17601
18050
 
17602
18051
  // src/lib/lsp-cache.ts
17603
18052
  import { existsSync as existsSync24, readdirSync as readdirSync10, rmSync as rmSync5, statSync as statSync15 } from "node:fs";
17604
- import { join as join25 } from "node:path";
18053
+ import { join as join27 } from "node:path";
17605
18054
  function inspectDir(path) {
17606
18055
  if (!existsSync24(path)) {
17607
18056
  return { entries: [], totalSize: 0 };
@@ -17615,7 +18064,7 @@ function inspectDir(path) {
17615
18064
  return { entries: [], totalSize: 0 };
17616
18065
  }
17617
18066
  for (const name of names) {
17618
- const full = join25(path, name);
18067
+ const full = join27(path, name);
17619
18068
  try {
17620
18069
  if (!statSync15(full).isDirectory())
17621
18070
  continue;
@@ -17673,8 +18122,8 @@ var init_lsp_cache = __esm(() => {
17673
18122
  });
17674
18123
 
17675
18124
  // src/lib/onnx.ts
17676
- import { existsSync as existsSync25, readdirSync as readdirSync11, readlinkSync as readlinkSync2, realpathSync as realpathSync5 } from "node:fs";
17677
- import { basename as basename2, isAbsolute as isAbsolute5, join as join26, resolve as resolve12, win32 as win322 } from "node:path";
18125
+ import { existsSync as existsSync25, readdirSync as readdirSync11, readlinkSync as readlinkSync2, realpathSync as realpathSync6 } from "node:fs";
18126
+ import { basename as basename2, isAbsolute as isAbsolute7, join as join28, resolve as resolve14, win32 as win323 } from "node:path";
17678
18127
  function getOnnxLibraryName() {
17679
18128
  if (process.platform === "darwin")
17680
18129
  return "libonnxruntime.dylib";
@@ -17710,18 +18159,18 @@ function pathEntriesForPlatform2() {
17710
18159
  return pathEnvValue2().split(delimiter).map((entry) => entry.trim().replace(/^"|"$/g, "")).filter((entry) => {
17711
18160
  if (!entry || entry === "." || entry.includes("\x00"))
17712
18161
  return false;
17713
- return isAbsolute5(entry) || win322.isAbsolute(entry);
18162
+ return isAbsolute7(entry) || win323.isAbsolute(entry);
17714
18163
  });
17715
18164
  }
17716
18165
  function isWindowsSystem32Directory2(dir) {
17717
18166
  if (process.platform !== "win32")
17718
18167
  return false;
17719
- const normalizedDir = win322.resolve(dir).replace(/[\\/]+$/, "").toLowerCase();
18168
+ const normalizedDir = win323.resolve(dir).replace(/[\\/]+$/, "").toLowerCase();
17720
18169
  const windowsRoots = [process.env.SystemRoot, process.env.windir, "C:\\Windows"];
17721
18170
  return windowsRoots.some((root) => {
17722
18171
  if (!root)
17723
18172
  return false;
17724
- return normalizedDir === win322.resolve(root, "System32").replace(/[\\/]+$/, "").toLowerCase();
18173
+ return normalizedDir === win323.resolve(root, "System32").replace(/[\\/]+$/, "").toLowerCase();
17725
18174
  });
17726
18175
  }
17727
18176
  function directoryContainsLibrary2(dir, libName) {
@@ -17744,8 +18193,8 @@ function findIgnoredWindowsSystemOnnxRuntime() {
17744
18193
  for (const root of windowsRoots) {
17745
18194
  if (!root)
17746
18195
  continue;
17747
- const systemDir = join26(root, "System32");
17748
- const key = win322.resolve(systemDir).toLowerCase();
18196
+ const systemDir = join28(root, "System32");
18197
+ const key = win323.resolve(systemDir).toLowerCase();
17749
18198
  if (seen.has(key))
17750
18199
  continue;
17751
18200
  seen.add(key);
@@ -17766,12 +18215,12 @@ function inspectSystemOnnxRuntime(searchPathsOverride) {
17766
18215
  searchPaths.push(...pathEntriesForPlatform2());
17767
18216
  const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
17768
18217
  const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
17769
- searchPaths.push(join26(programFiles, "onnxruntime", "lib"), join26(programFiles, "Microsoft ONNX Runtime", "lib"), join26(programFiles, "Microsoft Machine Learning", "lib"), join26(programFilesX86, "onnxruntime", "lib"), ...(() => {
18218
+ searchPaths.push(join28(programFiles, "onnxruntime", "lib"), join28(programFiles, "Microsoft ONNX Runtime", "lib"), join28(programFiles, "Microsoft Machine Learning", "lib"), join28(programFilesX86, "onnxruntime", "lib"), ...(() => {
17770
18219
  const nugetPaths = [];
17771
18220
  const userProfile = process.env.USERPROFILE ?? "";
17772
18221
  if (!userProfile)
17773
18222
  return nugetPaths;
17774
- const nugetPackageDir = join26(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
18223
+ const nugetPackageDir = join28(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
17775
18224
  if (!existsSync25(nugetPackageDir))
17776
18225
  return nugetPaths;
17777
18226
  try {
@@ -17780,7 +18229,7 @@ function inspectSystemOnnxRuntime(searchPathsOverride) {
17780
18229
  continue;
17781
18230
  if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
17782
18231
  continue;
17783
- nugetPaths.push(join26(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join26(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
18232
+ nugetPaths.push(join28(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join28(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
17784
18233
  }
17785
18234
  } catch {}
17786
18235
  return nugetPaths;
@@ -17790,7 +18239,7 @@ function inspectSystemOnnxRuntime(searchPathsOverride) {
17790
18239
  const seen = new Set;
17791
18240
  const unknownVersionPaths = [];
17792
18241
  for (const dir of searchPaths) {
17793
- let key = resolve12(dir).replace(/[/\\]+$/, "");
18242
+ let key = resolve14(dir).replace(/[/\\]+$/, "");
17794
18243
  if (normalizeCase)
17795
18244
  key = key.toLowerCase();
17796
18245
  if (seen.has(key))
@@ -17799,7 +18248,7 @@ function inspectSystemOnnxRuntime(searchPathsOverride) {
17799
18248
  if (!directoryContainsLibrary2(dir, libName))
17800
18249
  continue;
17801
18250
  if (process.platform !== "win32") {
17802
- const probe = probeOnnxRuntimeLoadable(join26(dir, libName));
18251
+ const probe = probeOnnxRuntimeLoadable(join28(dir, libName));
17803
18252
  if (!probe.loadable) {
17804
18253
  ignored ??= { path: dir, reason: `unloadable: ${probe.reason} — ignored` };
17805
18254
  continue;
@@ -17819,12 +18268,12 @@ function inspectSystemOnnxRuntime(searchPathsOverride) {
17819
18268
  return { path: unknownVersionPaths[0] ?? null, ignored };
17820
18269
  }
17821
18270
  function findCachedOnnxRuntime2(storageDir) {
17822
- const ortDir = join26(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
18271
+ const ortDir = join28(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
17823
18272
  const libName = getOnnxLibraryName();
17824
- if (existsSync25(join26(ortDir, libName)))
18273
+ if (existsSync25(join28(ortDir, libName)))
17825
18274
  return ortDir;
17826
- const libSubdir = join26(ortDir, "lib");
17827
- if (existsSync25(join26(libSubdir, libName)))
18275
+ const libSubdir = join28(ortDir, "lib");
18276
+ if (existsSync25(join28(libSubdir, libName)))
17828
18277
  return libSubdir;
17829
18278
  return null;
17830
18279
  }
@@ -17849,7 +18298,7 @@ function detectOrtVersion(libDir) {
17849
18298
  return null;
17850
18299
  const libName = getOnnxLibraryName();
17851
18300
  try {
17852
- const resolved = parseOrtVersionFromPath(realpathSync5(join26(libDir, libName)));
18301
+ const resolved = parseOrtVersionFromPath(realpathSync6(join28(libDir, libName)));
17853
18302
  if (resolved && resolved !== INVALID_ORT_VERSION2)
17854
18303
  return resolved;
17855
18304
  } catch {}
@@ -17865,10 +18314,10 @@ function detectOrtVersion(libDir) {
17865
18314
  if (version)
17866
18315
  return version;
17867
18316
  }
17868
- const base = join26(libDir, libName);
18317
+ const base = join28(libDir, libName);
17869
18318
  if (existsSync25(base)) {
17870
18319
  try {
17871
- const real = realpathSync5(base);
18320
+ const real = realpathSync6(base);
17872
18321
  const version = parseOrtVersionFromPath(real) ?? parseOrtVersionFromDirectoryPath(real);
17873
18322
  if (version)
17874
18323
  return version;
@@ -17929,7 +18378,6 @@ function indexesOf(block) {
17929
18378
  }
17930
18379
  function evaluatePluginLoad(input) {
17931
18380
  const blockers = [];
17932
- const phase = policyPhaseForVersion(input.pluginVersion);
17933
18381
  const tiers = [
17934
18382
  { path: input.userConfigPath, tier: "user" }
17935
18383
  ];
@@ -17957,20 +18405,7 @@ function evaluatePluginLoad(input) {
17957
18405
  if (!value)
17958
18406
  continue;
17959
18407
  const translated = structuredClone(value);
17960
- const translation = translateConfigDocument(translated, phase, tier);
17961
- if (translation.errors.length > 0) {
17962
- const removed = translation.errors.map((code) => code.replace(/^removed_config_key:([^:]+):use:(.+)$/, "$1 → $2")).join(", ");
17963
- const scope = tier === "project" ? " in this project" : "";
17964
- const toolCallError = formatConfigErrorMessage(new ConfigRejectedError(translation.errors, path).message);
17965
- blockers.push({
17966
- code: "config_rejected",
17967
- path,
17968
- message: `${failsEveryToolCall(toolCallError, scope)} (removed keys: ${removed})`,
17969
- toolCallError,
17970
- remediation: `Run \`${CLI} doctor --fix\` to migrate the file, then restart the host.`,
17971
- fixable: true
17972
- });
17973
- }
18408
+ translateConfigDocument(translated, tier);
17974
18409
  loaded[tier] = withHarness(translated, input.harness);
17975
18410
  }
17976
18411
  const subc = loaded.user && isRecord3(loaded.user.subc) ? loaded.user.subc : null;
@@ -18009,11 +18444,11 @@ var init_plugin_load = __esm(() => {
18009
18444
  // src/lib/diagnostics.ts
18010
18445
  import {
18011
18446
  accessSync as accessSync3,
18012
- closeSync as closeSync7,
18013
- constants as constants3,
18447
+ closeSync as closeSync9,
18448
+ constants as constants4,
18014
18449
  existsSync as existsSync27,
18015
- openSync as openSync7,
18016
- readSync as readSync5,
18450
+ openSync as openSync9,
18451
+ readSync as readSync7,
18017
18452
  statSync as statSync16
18018
18453
  } from "node:fs";
18019
18454
  async function collectDiagnostics(adapters) {
@@ -18053,7 +18488,7 @@ async function diagnoseHarness(adapter) {
18053
18488
  if (!existsSync27(storage))
18054
18489
  return false;
18055
18490
  try {
18056
- accessSync3(storage, constants3.R_OK | constants3.W_OK);
18491
+ accessSync3(storage, constants4.R_OK | constants4.W_OK);
18057
18492
  return true;
18058
18493
  } catch {
18059
18494
  return false;
@@ -18064,8 +18499,7 @@ async function diagnoseHarness(adapter) {
18064
18499
  const pluginLoad = evaluatePluginLoad({
18065
18500
  userConfigPath: configPaths.aftConfig,
18066
18501
  projectDirectory: process.cwd(),
18067
- harness: adapter.kind === "opencode" ? "opencode" : "pi",
18068
- pluginVersion: pluginCache.cached ?? getSelfVersion()
18502
+ harness: adapter.kind === "opencode" ? "opencode" : "pi"
18069
18503
  });
18070
18504
  const semanticEnabled = aftEnabled && pluginLoad.onnxRequired;
18071
18505
  const systemInspection = inspectSystemOnnxRuntime();
@@ -18357,7 +18791,7 @@ function tailLogFile(path, lines) {
18357
18791
  let fd = null;
18358
18792
  try {
18359
18793
  const size = statSync16(path).size;
18360
- fd = openSync7(path, "r");
18794
+ fd = openSync9(path, "r");
18361
18795
  const chunks = [];
18362
18796
  let position = size;
18363
18797
  let newlineCount = 0;
@@ -18365,7 +18799,7 @@ function tailLogFile(path, lines) {
18365
18799
  const readLength = Math.min(chunkSize, position);
18366
18800
  position -= readLength;
18367
18801
  const buffer = Buffer.allocUnsafe(readLength);
18368
- const bytesRead = readSync5(fd, buffer, 0, readLength, position);
18802
+ const bytesRead = readSync7(fd, buffer, 0, readLength, position);
18369
18803
  const chunk = bytesRead === readLength ? buffer : buffer.subarray(0, bytesRead);
18370
18804
  chunks.unshift(chunk);
18371
18805
  for (let i = chunk.length - 1;i >= 0; i -= 1) {
@@ -18380,7 +18814,7 @@ function tailLogFile(path, lines) {
18380
18814
  } finally {
18381
18815
  if (fd !== null) {
18382
18816
  try {
18383
- closeSync7(fd);
18817
+ closeSync9(fd);
18384
18818
  } catch {}
18385
18819
  }
18386
18820
  }
@@ -18477,29 +18911,44 @@ function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
18477
18911
  const head = body.slice(0, logBlockStart);
18478
18912
  const log = body.slice(logBlockStart, logBlockEnd);
18479
18913
  const tail = body.slice(logBlockEnd);
18480
- const overheadBytes = Buffer.byteLength(head, "utf8") + Buffer.byteLength(tail, "utf8");
18481
18914
  const truncationMarker = `[truncated for GitHub 64KB limit — older log lines dropped]
18482
18915
  `;
18483
- const markerBytes = Buffer.byteLength(truncationMarker, "utf8");
18484
- const logBudget = maxBytes - overheadBytes - markerBytes;
18485
- if (logBudget <= 0) {
18486
- return `${head}${truncationMarker}${tail}`;
18487
- }
18488
18916
  const lines = log.split(`
18489
18917
  `);
18490
- let keepLines = lines;
18491
- let kept = keepLines.join(`
18492
- `);
18493
- while (Buffer.byteLength(kept, "utf8") > logBudget && keepLines.length > 1) {
18494
- const dropCount = Math.max(1, Math.floor(keepLines.length * 0.05));
18495
- keepLines = keepLines.slice(dropCount);
18496
- kept = keepLines.join(`
18497
- `);
18498
- }
18499
- if (Buffer.byteLength(kept, "utf8") > logBudget) {
18500
- kept = truncateToByteBudget(kept, logBudget);
18918
+ let inFence = false;
18919
+ let fence = "";
18920
+ const payload = [];
18921
+ for (let i = 0;i < lines.length; i++) {
18922
+ const delimiter = lines[i].match(/^\s*(`{3,}|~{3,})/);
18923
+ if (delimiter) {
18924
+ if (!inFence) {
18925
+ inFence = true;
18926
+ fence = delimiter[1];
18927
+ } else if (delimiter[1][0] === fence[0] && delimiter[1].length >= fence.length)
18928
+ inFence = false;
18929
+ } else if (inFence || lines[i] && !/^#{1,6} /.test(lines[i])) {
18930
+ payload.push(i);
18931
+ }
18932
+ }
18933
+ const removed = new Set;
18934
+ const render = () => `${head}${truncationMarker}${lines.filter((_, i) => !removed.has(i)).join(`
18935
+ `)}${tail}`;
18936
+ let size = Buffer.byteLength(render(), "utf8");
18937
+ for (const index of payload) {
18938
+ if (size <= maxBytes)
18939
+ break;
18940
+ const excess = size - maxBytes;
18941
+ const bytes = Buffer.byteLength(lines[index], "utf8");
18942
+ if (index === payload.at(-1) && bytes > excess) {
18943
+ const kept = truncateToByteBudget(lines[index], bytes - excess);
18944
+ size -= bytes - Buffer.byteLength(kept, "utf8");
18945
+ lines[index] = kept;
18946
+ } else {
18947
+ removed.add(index);
18948
+ size -= bytes + 1;
18949
+ }
18501
18950
  }
18502
- return `${head}${truncationMarker}${kept}${tail}`;
18951
+ return render();
18503
18952
  }
18504
18953
  function findNextTopLevelHeading(body, startIdx) {
18505
18954
  const idx = body.indexOf(`
@@ -18535,13 +18984,13 @@ var init_issue_body = __esm(() => {
18535
18984
  // src/lib/onnx-fix.ts
18536
18985
  import { randomBytes as randomBytes2 } from "node:crypto";
18537
18986
  import { existsSync as existsSync28, mkdirSync as mkdirSync7, renameSync as renameSync5, rmSync as rmSync6 } from "node:fs";
18538
- import { isAbsolute as isAbsolute6, join as join27, relative as relative2 } from "node:path";
18987
+ import { isAbsolute as isAbsolute8, join as join29, relative as relative4 } from "node:path";
18539
18988
  function findOnnxFixCandidates(report) {
18540
18989
  const candidates = [];
18541
18990
  for (const harness of report.harnesses) {
18542
18991
  if (!harness.onnxRuntime.required)
18543
18992
  continue;
18544
- const storageOnnxDir = join27(harness.storageDir.path, "onnxruntime");
18993
+ const storageOnnxDir = join29(harness.storageDir.path, "onnxruntime");
18545
18994
  const systemTooOld = harness.onnxRuntime.systemPath !== null && harness.onnxRuntime.systemCompatible === false;
18546
18995
  const cachedTooOld = harness.onnxRuntime.cachedPath !== null && harness.onnxRuntime.cachedCompatible === false;
18547
18996
  const hasCompatibleCached = harness.onnxRuntime.cachedCompatible === true;
@@ -18580,15 +19029,15 @@ function findOnnxFixCandidates(report) {
18580
19029
  async function installManagedReplacement(candidate, ensureFn, rmFn) {
18581
19030
  const suffix = `${process.pid}.${Date.now().toString(36)}.${randomBytes2(6).toString("hex")}`;
18582
19031
  const stagingStorageDir = `${candidate.harness.storageDir.path}.onnx-fix.tmp.${suffix}`;
18583
- const stagedOnnxDir = join27(stagingStorageDir, "onnxruntime");
19032
+ const stagedOnnxDir = join29(stagingStorageDir, "onnxruntime");
18584
19033
  const backupDir = `${candidate.storageOnnxDir}.backup.${suffix}`;
18585
19034
  try {
18586
19035
  const stagedInstalledPath = await ensureFn(stagingStorageDir);
18587
19036
  if (!stagedInstalledPath || !existsSync28(stagedInstalledPath)) {
18588
19037
  throw new Error("managed ONNX Runtime download was unavailable");
18589
19038
  }
18590
- const installedRelativePath = relative2(stagedOnnxDir, stagedInstalledPath);
18591
- if (isAbsolute6(installedRelativePath) || installedRelativePath === ".." || installedRelativePath.startsWith("../") || installedRelativePath.startsWith("..\\")) {
19039
+ const installedRelativePath = relative4(stagedOnnxDir, stagedInstalledPath);
19040
+ if (isAbsolute8(installedRelativePath) || installedRelativePath === ".." || installedRelativePath.startsWith("../") || installedRelativePath.startsWith("..\\")) {
18592
19041
  throw new Error(`managed ONNX Runtime was installed outside staging: ${stagedInstalledPath}`);
18593
19042
  }
18594
19043
  mkdirSync7(candidate.harness.storageDir.path, { recursive: true });
@@ -18616,7 +19065,7 @@ async function installManagedReplacement(candidate, ensureFn, rmFn) {
18616
19065
  }
18617
19066
  }
18618
19067
  return {
18619
- installedPath: join27(candidate.storageOnnxDir, installedRelativePath),
19068
+ installedPath: join29(candidate.storageOnnxDir, installedRelativePath),
18620
19069
  clearedPrevious: hadPrevious && cleanupError === undefined,
18621
19070
  cleanupError
18622
19071
  };
@@ -18683,7 +19132,7 @@ var init_onnx_fix = __esm(() => {
18683
19132
  });
18684
19133
 
18685
19134
  // src/lib/session-log.ts
18686
- import { closeSync as closeSync8, openSync as openSync8, readSync as readSync6, statSync as statSync17 } from "node:fs";
19135
+ import { closeSync as closeSync10, openSync as openSync10, readSync as readSync8, statSync as statSync17 } from "node:fs";
18687
19136
  function readSessionLog(path, session, maxBytes = MAX_SCAN_BYTES) {
18688
19137
  const lines = [];
18689
19138
  const errors = [];
@@ -18721,7 +19170,7 @@ function readSessionLog(path, session, maxBytes = MAX_SCAN_BYTES) {
18721
19170
  break;
18722
19171
  let fd;
18723
19172
  try {
18724
- fd = openSync8(file, "r");
19173
+ fd = openSync10(file, "r");
18725
19174
  let position = statSync17(file).size;
18726
19175
  let suffix = Buffer.alloc(0);
18727
19176
  while (position > 0 && remaining > 0 && (lines.length < 200 || errors.length < 20)) {
@@ -18729,7 +19178,7 @@ function readSessionLog(path, session, maxBytes = MAX_SCAN_BYTES) {
18729
19178
  position -= length;
18730
19179
  remaining -= length;
18731
19180
  const chunk = Buffer.allocUnsafe(length);
18732
- const count = readSync6(fd, chunk, 0, length, position);
19181
+ const count = readSync8(fd, chunk, 0, length, position);
18733
19182
  const bytes = Buffer.concat([chunk.subarray(0, count), suffix]);
18734
19183
  let end = bytes.length;
18735
19184
  for (let i = bytes.length - 1;i >= 0; i -= 1) {
@@ -18748,7 +19197,7 @@ function readSessionLog(path, session, maxBytes = MAX_SCAN_BYTES) {
18748
19197
  boundHit = true;
18749
19198
  } catch {} finally {
18750
19199
  if (fd !== undefined)
18751
- closeSync8(fd);
19200
+ closeSync10(fd);
18752
19201
  }
18753
19202
  }
18754
19203
  return { lines: lines.reverse(), errors: errors.reverse(), boundHit };
@@ -18764,8 +19213,8 @@ var init_session_log = __esm(() => {
18764
19213
  // src/lib/sessions.ts
18765
19214
  import { existsSync as existsSync29, readdirSync as readdirSync12, readFileSync as readFileSync16, statSync as statSync18 } from "node:fs";
18766
19215
  import { createRequire as createRequire4 } from "node:module";
18767
- import { homedir as homedir16 } from "node:os";
18768
- import { basename as basename3, join as join28 } from "node:path";
19216
+ import { homedir as homedir18 } from "node:os";
19217
+ import { basename as basename3, join as join30 } from "node:path";
18769
19218
  function listRecentSessions(adapter) {
18770
19219
  try {
18771
19220
  if (adapter.kind === "opencode")
@@ -18799,7 +19248,7 @@ function mapOpenCodeSessionRows(rows) {
18799
19248
  }).filter((session) => session !== null).sort((a, b) => b.lastActivity - a.lastActivity).slice(0, MAX_RECENT_SESSIONS);
18800
19249
  }
18801
19250
  function listRecentOpenCodeSessions() {
18802
- const dbPath = join28(getXdgDataHome(), "opencode", "opencode.db");
19251
+ const dbPath = join30(getXdgDataHome(), "opencode", "opencode.db");
18803
19252
  if (!existsSync29(dbPath))
18804
19253
  return [];
18805
19254
  let db = null;
@@ -18819,14 +19268,14 @@ function listRecentOpenCodeSessions() {
18819
19268
  }
18820
19269
  function getXdgDataHome() {
18821
19270
  const xdgDataHome = process.env.XDG_DATA_HOME;
18822
- return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join28(homedir16(), ".local", "share");
19271
+ return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join30(homedir18(), ".local", "share");
18823
19272
  }
18824
19273
  function listRecentPiSessions() {
18825
- return listPiSessionsFromDir(join28(getHomeDir(), ".pi", "agent", "sessions"));
19274
+ return listPiSessionsFromDir(join30(getHomeDir(), ".pi", "agent", "sessions"));
18826
19275
  }
18827
19276
  function getHomeDir() {
18828
19277
  const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
18829
- return envHome && envHome.length > 0 ? envHome : homedir16();
19278
+ return envHome && envHome.length > 0 ? envHome : homedir18();
18830
19279
  }
18831
19280
  function listPiSessionsFromDir(sessionsDir) {
18832
19281
  try {
@@ -18868,7 +19317,7 @@ function collectJsonlFiles(root) {
18868
19317
  continue;
18869
19318
  }
18870
19319
  for (const entry of entries) {
18871
- const path = join28(dir, entry.name);
19320
+ const path = join30(dir, entry.name);
18872
19321
  if (entry.isDirectory()) {
18873
19322
  stack.push(path);
18874
19323
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -18973,13 +19422,13 @@ import {
18973
19422
  mkdirSync as mkdirSync8,
18974
19423
  mkdtempSync as mkdtempSync2,
18975
19424
  readFileSync as readFileSync17,
18976
- realpathSync as realpathSync6,
19425
+ realpathSync as realpathSync7,
18977
19426
  rmSync as rmSync7,
18978
19427
  statSync as statSync19,
18979
19428
  writeFileSync as writeFileSync5
18980
19429
  } from "node:fs";
18981
- import { tmpdir as tmpdir4 } from "node:os";
18982
- import { join as join29 } from "node:path";
19430
+ import { tmpdir as tmpdir5 } from "node:os";
19431
+ import { join as join31 } from "node:path";
18983
19432
  function openCodeAdapter(adapters) {
18984
19433
  return adapters.find((adapter) => adapter.kind === "opencode");
18985
19434
  }
@@ -19119,9 +19568,11 @@ async function runDoctor(options) {
19119
19568
  }
19120
19569
  if (opencodeSkew)
19121
19570
  log2.error(` ${opencodeSkew.message} ${opencodeSkew.remediation}`);
19122
- const hostShell = hostShellDoctorLine(opencodeAdapter);
19123
- if (hostShell)
19124
- log2[hostShell.level](` ${hostShell.text}`);
19571
+ for (const hostTool of OPENCODE_HOST_TOOL_NAMES) {
19572
+ const line = hostToolDoctorLine(opencodeAdapter, hostTool);
19573
+ if (line)
19574
+ log2[line.level](` ${line.text}`);
19575
+ }
19125
19576
  }
19126
19577
  const blockers = h.pluginLoad?.blockers ?? [];
19127
19578
  if (h.pluginRegistered && blockers.length > 0) {
@@ -19398,7 +19849,7 @@ function clearOldBinaries() {
19398
19849
  return result;
19399
19850
  }
19400
19851
  for (const version of stale) {
19401
- const dir = join29(info.path, version);
19852
+ const dir = join31(info.path, version);
19402
19853
  let bytes = 0;
19403
19854
  try {
19404
19855
  bytes = statSync19(dir).isDirectory() ? dirSize(dir) : 0;
@@ -19421,34 +19872,35 @@ function clearOldBinaries() {
19421
19872
  }
19422
19873
  return result;
19423
19874
  }
19424
- function hostShellDoctorLine(adapter) {
19875
+ function hostToolDoctorLine(adapter, hostTool) {
19425
19876
  if (!(adapter instanceof OpenCodeAdapter))
19426
19877
  return null;
19427
- const state = adapter.hostShellState();
19878
+ const { disableEntry, aftTool } = OPENCODE_HOST_TOOLS[hostTool];
19879
+ const state = adapter.hostToolState(hostTool);
19428
19880
  if (state === "not_applicable")
19429
19881
  return null;
19430
19882
  if (state === "disabled") {
19431
19883
  return {
19432
19884
  level: "info",
19433
- text: `OpenCode's own shell tool: disabled (${OPENCODE_HOST_SHELL_DISABLE_ENTRY} is set); agents use AFT's bash`
19885
+ text: `OpenCode's own ${hostTool} tool: disabled (${disableEntry} is set); agents use AFT's ${aftTool}`
19434
19886
  };
19435
19887
  }
19436
- if (!adapter.aftBashEnabled()) {
19888
+ if (!adapter.aftHostReplacementEnabled(hostTool)) {
19437
19889
  return {
19438
19890
  level: "info",
19439
- text: "OpenCode's own shell tool: enabled (AFT's bash is disabled, so it stays)"
19891
+ text: `OpenCode's own ${hostTool} tool: enabled (AFT's ${aftTool} is disabled, so it stays)`
19440
19892
  };
19441
19893
  }
19442
19894
  return {
19443
19895
  level: "warn",
19444
- text: `OpenCode's own shell tool: enabled beside AFT's bash — run \`${CLI} doctor --fix\` or \`${CLI} setup\` to disable it (${OPENCODE_HOST_SHELL_DISABLE_ENTRY})`
19896
+ text: `OpenCode's own ${hostTool} tool: enabled beside AFT's ${aftTool} — run \`${CLI} doctor --fix\` or \`${CLI} setup\` to disable it (${disableEntry})`
19445
19897
  };
19446
19898
  }
19447
- function hostShellFixTarget(adapters) {
19899
+ function hostToolFixTargets(adapters) {
19448
19900
  const adapter = openCodeAdapter(adapters);
19449
19901
  if (!(adapter instanceof OpenCodeAdapter))
19450
- return null;
19451
- return adapter.hostShellState() === "enabled" && adapter.aftBashEnabled() ? adapter : null;
19902
+ return [];
19903
+ return OPENCODE_HOST_TOOL_NAMES.filter((hostTool) => adapter.hostToolState(hostTool) === "enabled" && adapter.aftHostReplacementEnabled(hostTool)).map((hostTool) => ({ adapter, hostTool }));
19452
19904
  }
19453
19905
  function findPluginUpdateTargets(adapters, report) {
19454
19906
  const adaptersByKind = new Map(adapters.map((a) => [a.kind, a]));
@@ -19557,7 +20009,7 @@ async function runDoctorNpmInstall(npm, installDir) {
19557
20009
  });
19558
20010
  }
19559
20011
  function installedPluginVersion(installDir) {
19560
- const manifest = join29(installDir, "node_modules", ...AFT_OPENCODE_PACKAGE.split("/"), "package.json");
20012
+ const manifest = join31(installDir, "node_modules", ...AFT_OPENCODE_PACKAGE.split("/"), "package.json");
19561
20013
  try {
19562
20014
  const pkg = JSON.parse(readFileSync17(manifest, "utf-8"));
19563
20015
  return typeof pkg.version === "string" ? pkg.version : null;
@@ -19679,11 +20131,11 @@ function buildDoctorFixPlan(adapters, report) {
19679
20131
  message: `Will ${hasTuiEntry ? "update" : "add"} ${adapter.pluginEntryWithVersion} ${hasTuiEntry ? "in" : "to"} ${harness.configPaths.tuiConfig} (TUI sidebar)`
19680
20132
  });
19681
20133
  }
19682
- const hostShellTarget = hostShellFixTarget(adapters);
19683
- if (hostShellTarget) {
20134
+ for (const { adapter, hostTool } of hostToolFixTargets(adapters)) {
20135
+ const { disableEntry, aftTool } = OPENCODE_HOST_TOOLS[hostTool];
19684
20136
  items.push({
19685
20137
  kind: "plugin",
19686
- message: `Will add ${OPENCODE_HOST_SHELL_DISABLE_ENTRY} to ${hostShellTarget.detectConfigPaths().harnessConfig} so agents use AFT's bash instead of OpenCode's own shell tool`
20138
+ message: `Will add ${disableEntry} to ${adapter.detectConfigPaths().harnessConfig} so agents use AFT's ${aftTool} instead of OpenCode's own ${hostTool} tool`
19687
20139
  });
19688
20140
  }
19689
20141
  for (const target of findPluginUpdateTargets(adapters, report)) {
@@ -19831,9 +20283,8 @@ async function runFixFlow(argv, detectOpenCodeHost, resolveAdapters = resolveAda
19831
20283
  }
19832
20284
  }
19833
20285
  const pluginEntrySummary = configWritesRefused ? { changed: 0, errors: 0 } : await fixPluginEntries(adapters);
19834
- const hostShellTarget = configWritesRefused ? null : hostShellFixTarget(adapters);
19835
- if (hostShellTarget) {
19836
- const result = hostShellTarget.setHostShellDisabled(true);
20286
+ for (const { adapter, hostTool } of configWritesRefused ? [] : hostToolFixTargets(adapters)) {
20287
+ const result = adapter.setHostToolDisabled(hostTool, true);
19837
20288
  if (result.ok) {
19838
20289
  if (result.action !== "already_present")
19839
20290
  log2.success(`OpenCode: ${result.message}`);
@@ -20192,14 +20643,14 @@ function deriveIssueTitleFromBody(body) {
20192
20643
  function writeIssueReviewFile(body) {
20193
20644
  let reviewDir = null;
20194
20645
  try {
20195
- reviewDir = mkdtempSync2(join29(tmpdir4(), "aft-issue-"));
20646
+ reviewDir = mkdtempSync2(join31(tmpdir5(), "aft-issue-"));
20196
20647
  if (process.platform !== "win32") {
20197
20648
  chmodSync3(reviewDir, 448);
20198
20649
  }
20199
- const outPath = join29(reviewDir, "issue.md");
20650
+ const outPath = join31(reviewDir, "issue.md");
20200
20651
  writeFileSync5(outPath, `${body}
20201
20652
  `, { encoding: "utf8", mode: 384, flag: "wx" });
20202
- return { path: outPath, realPath: realpathSync6(outPath) };
20653
+ return { path: outPath, realPath: realpathSync7(outPath) };
20203
20654
  } catch (err) {
20204
20655
  if (reviewDir) {
20205
20656
  try {
@@ -20212,7 +20663,7 @@ function writeIssueReviewFile(body) {
20212
20663
  }
20213
20664
  function readReviewedIssueFile(reviewFile) {
20214
20665
  try {
20215
- const realPath = realpathSync6(reviewFile.path);
20666
+ const realPath = realpathSync7(reviewFile.path);
20216
20667
  if (realPath !== reviewFile.realPath) {
20217
20668
  log2.error(`Review file path changed before filing; refusing to read ${reviewFile.path}.`);
20218
20669
  return null;
@@ -20425,24 +20876,24 @@ var init_doctor = __esm(async () => {
20425
20876
  // src/commands/lsp.ts
20426
20877
  import { existsSync as existsSync31, readdirSync as readdirSync13, statSync as statSync20 } from "node:fs";
20427
20878
  import { createRequire as createRequire5 } from "node:module";
20428
- import { dirname as dirname11, join as join30, resolve as resolve13 } from "node:path";
20879
+ import { dirname as dirname12, join as join32, resolve as resolve15 } from "node:path";
20429
20880
  function findProjectRootForFile(filePath, fallbackCwd = process.cwd()) {
20430
- const resolvedFile = resolve13(fallbackCwd, filePath);
20431
- let dir = dirname11(resolvedFile);
20881
+ const resolvedFile = resolve15(fallbackCwd, filePath);
20882
+ let dir = dirname12(resolvedFile);
20432
20883
  try {
20433
20884
  if (existsSync31(resolvedFile) && statSync20(resolvedFile).isDirectory()) {
20434
20885
  dir = resolvedFile;
20435
20886
  }
20436
20887
  } catch {
20437
- dir = dirname11(resolvedFile);
20888
+ dir = dirname12(resolvedFile);
20438
20889
  }
20439
20890
  while (true) {
20440
- if (PROJECT_ROOT_MARKERS.some((marker) => existsSync31(join30(dir, marker)))) {
20891
+ if (PROJECT_ROOT_MARKERS.some((marker) => existsSync31(join32(dir, marker)))) {
20441
20892
  return dir;
20442
20893
  }
20443
- const parent = dirname11(dir);
20894
+ const parent = dirname12(dir);
20444
20895
  if (parent === dir)
20445
- return resolve13(fallbackCwd);
20896
+ return resolve15(fallbackCwd);
20446
20897
  dir = parent;
20447
20898
  }
20448
20899
  }
@@ -20473,7 +20924,7 @@ async function runLspDoctor(options) {
20473
20924
  log2.error("Could not find the aft binary in the cache, platform package, PATH, or ~/.cargo/bin.");
20474
20925
  return 1;
20475
20926
  }
20476
- const resolvedFile = resolve13(file);
20927
+ const resolvedFile = resolve15(file);
20477
20928
  const projectRoot = findProjectRootForFile(resolvedFile);
20478
20929
  const config = buildConfigureParams(adapter, projectRoot);
20479
20930
  const inspectRequest = {
@@ -20586,10 +21037,10 @@ function buildConfigureParams(adapter, projectRoot) {
20586
21037
  function inferLspPathsExtra(_lsp) {
20587
21038
  const paths = new Set;
20588
21039
  for (const entry of childDirs(getAftLspPackagesDir())) {
20589
- paths.add(join30(entry, "node_modules", ".bin"));
21040
+ paths.add(join32(entry, "node_modules", ".bin"));
20590
21041
  }
20591
21042
  for (const entry of childDirs(getAftLspBinariesDir())) {
20592
- paths.add(join30(entry, "bin"));
21043
+ paths.add(join32(entry, "bin"));
20593
21044
  }
20594
21045
  return [...paths];
20595
21046
  }
@@ -20597,7 +21048,7 @@ function childDirs(path) {
20597
21048
  if (!existsSync31(path))
20598
21049
  return [];
20599
21050
  try {
20600
- return readdirSync13(path).map((entry) => join30(path, entry)).filter((entry) => {
21051
+ return readdirSync13(path).map((entry) => join32(path, entry)).filter((entry) => {
20601
21052
  try {
20602
21053
  return statSync20(entry).isDirectory();
20603
21054
  } catch {
@@ -20609,11 +21060,13 @@ function childDirs(path) {
20609
21060
  }
20610
21061
  }
20611
21062
  function formatBinary(server) {
21063
+ const names = server.binary_names?.length ? server.binary_names : [server.binary_name];
21064
+ const alternatives = names.length > 1 ? `; candidates: ${names.join(" or ")}` : "";
20612
21065
  if (!server.binary_path) {
20613
21066
  const locations = server.kind === "python" || server.kind === "ty" ? "workspace virtualenv, node_modules/.bin, lsp_paths_extra, or PATH" : "node_modules/.bin, lsp_paths_extra, or PATH";
20614
- return `${server.binary_name} (NOT FOUND in ${locations})`;
21067
+ return `${names.join(" or ")} (NOT FOUND in ${locations})`;
20615
21068
  }
20616
- return `${server.binary_path} (found via ${server.binary_source})`;
21069
+ return `${server.binary_path} (found via ${server.binary_source}${alternatives})`;
20617
21070
  }
20618
21071
  function formatWorkspaceRoot(server) {
20619
21072
  if (!server.workspace_root) {
@@ -20639,7 +21092,7 @@ function typescriptPackageWarning(response) {
20639
21092
  if (!typescriptServerSpawned || !response.project_root || diagnosticsCount > 0)
20640
21093
  return null;
20641
21094
  try {
20642
- createRequire5(join30(response.project_root, "package.json")).resolve("typescript");
21095
+ createRequire5(join32(response.project_root, "package.json")).resolve("typescript");
20643
21096
  return null;
20644
21097
  } catch {
20645
21098
  return "typescript package not resolvable from project — server will produce no diagnostics";
@@ -20680,8 +21133,7 @@ var init_lsp = __esm(async () => {
20680
21133
 
20681
21134
  // src/commands/doctor-filters.ts
20682
21135
  import { existsSync as existsSync32 } from "node:fs";
20683
- import { homedir as homedir17 } from "node:os";
20684
- import { relative as relative3, resolve as resolve14 } from "node:path";
21136
+ import { relative as relative5, resolve as resolve16 } from "node:path";
20685
21137
  function printDoctorFiltersHelp() {
20686
21138
  console.log(`Usage: ${CLI} doctor filters [--show <name>] [trust|untrust]`);
20687
21139
  console.log("");
@@ -20716,7 +21168,7 @@ async function runDoctorFilters(options) {
20716
21168
  log2.error("Could not find the aft binary in the cache, platform package, PATH, or ~/.cargo/bin.");
20717
21169
  return 1;
20718
21170
  }
20719
- const projectRoot = resolve14(process.cwd());
21171
+ const projectRoot = resolve16(process.cwd());
20720
21172
  const list = await listFilters(binary, adapter, projectRoot, options.sendRequests ?? sendAftRequests);
20721
21173
  if (!list.success) {
20722
21174
  log2.error(list.message ?? list.code ?? "list_filters failed");
@@ -20898,14 +21350,13 @@ function truncate(value) {
20898
21350
  return value.length <= 80 ? value : `${value.slice(0, 77)}…`;
20899
21351
  }
20900
21352
  function formatHome(path) {
20901
- const home = homedir17();
20902
- return path.startsWith(home) ? `~${path.slice(home.length)}` : path;
21353
+ return shortenHomePath(path);
20903
21354
  }
20904
21355
  function formatProjectPath(path, projectRoot) {
20905
21356
  if (!path)
20906
21357
  return "";
20907
- const rel = relative3(projectRoot, path);
20908
- return rel.startsWith("..") || rel === "" ? path : `./${rel}`;
21358
+ const rel = relative5(projectRoot, path);
21359
+ return relativePathEscapesRoot(rel) || rel === "" ? path : `./${rel}`;
20909
21360
  }
20910
21361
  function formatSourcePath(path, projectRoot) {
20911
21362
  if (!path)
@@ -20913,6 +21364,7 @@ function formatSourcePath(path, projectRoot) {
20913
21364
  return formatProjectPath(path, projectRoot);
20914
21365
  }
20915
21366
  var init_doctor_filters = __esm(async () => {
21367
+ init_dist2();
20916
21368
  init_aft_bridge();
20917
21369
  init_harness_select();
20918
21370
  init_prompts();
@@ -20936,6 +21388,7 @@ function printHelp() {
20936
21388
  console.log(" setup --answers <file> Save feature choices from an answers file");
20937
21389
  console.log(" index Build one configured index snapshot (no scheduler)");
20938
21390
  console.log(" backups purge Remove undo backups by --path and/or --session (dry run unless --yes)");
21391
+ console.log(" cache prune-legacy Delete legacy index caches past their rollback window (dry run unless --yes)");
20939
21392
  console.log(" doctor Check and fix configuration issues");
20940
21393
  console.log(" doctor --profile [seconds] Profile a running AFT daemon");
20941
21394
  console.log(" doctor lsp <file> Inspect LSP setup for one file");
@@ -20956,6 +21409,7 @@ function printHelp() {
20956
21409
  console.log(` ${CLI} setup`);
20957
21410
  console.log(` ${CLI} index`);
20958
21411
  console.log(` ${CLI} backups purge --path ./build --yes`);
21412
+ console.log(` ${CLI} cache prune-legacy`);
20959
21413
  console.log(` ${CLI} doctor`);
20960
21414
  console.log(` ${CLI} doctor --profile 4`);
20961
21415
  console.log(` ${CLI} doctor lsp ./src/main.py`);
@@ -20981,6 +21435,10 @@ async function main() {
20981
21435
  await init_backups();
20982
21436
  return runBackups(args);
20983
21437
  }
21438
+ if (command === "cache") {
21439
+ await init_cache();
21440
+ return runCache(args);
21441
+ }
20984
21442
  if (command === "doctor") {
20985
21443
  if (args.includes("--profile")) {
20986
21444
  await init_doctor();