@cortexkit/aft 0.51.3 → 0.52.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -19,12 +19,14 @@ var __toESM = (mod, isNodeMode, target) => {
19
19
  }
20
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
21
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
- for (let key of __getOwnPropNames(mod))
23
- if (!__hasOwnProp.call(to, key))
24
- __defProp(to, key, {
25
- get: __accessProp.bind(mod, key),
26
- enumerable: true
27
- });
22
+ if (mod && typeof mod === "object" || typeof mod === "function") {
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ }
28
30
  if (canCache)
29
31
  cache.set(mod, to);
30
32
  return to;
@@ -2389,19 +2391,37 @@ async function downloadBinary(version) {
2389
2391
  releaseLock?.();
2390
2392
  }
2391
2393
  }
2394
+ function ensureBinaryKey(version) {
2395
+ if (!version)
2396
+ return "latest";
2397
+ return version.startsWith("v") ? version : `v${version}`;
2398
+ }
2392
2399
  async function ensureBinary(version) {
2393
- if (version) {
2394
- const tag = version.startsWith("v") ? version : `v${version}`;
2395
- const versionCached = getCachedBinaryPath(tag);
2396
- if (versionCached && isExpectedCachedBinary(versionCached, tag)) {
2397
- log(`Found cached binary for ${tag}: ${versionCached}`);
2398
- return versionCached;
2399
- }
2400
- log(`No cached binary for ${tag}, downloading...`);
2401
- return downloadBinary(tag);
2400
+ const key = ensureBinaryKey(version);
2401
+ const existing = ensureBinaryInFlight.get(key);
2402
+ if (existing)
2403
+ return existing;
2404
+ const task = (async () => {
2405
+ if (version) {
2406
+ const tag = ensureBinaryKey(version);
2407
+ const versionCached = getCachedBinaryPath(tag);
2408
+ if (versionCached && isExpectedCachedBinary(versionCached, tag)) {
2409
+ log(`Found cached binary for ${tag}: ${versionCached}`);
2410
+ return versionCached;
2411
+ }
2412
+ log(`No cached binary for ${tag}, downloading...`);
2413
+ return downloadBinary(tag);
2414
+ }
2415
+ log("No cached binary found, downloading latest...");
2416
+ return downloadBinary();
2417
+ })();
2418
+ ensureBinaryInFlight.set(key, task);
2419
+ try {
2420
+ return await task;
2421
+ } finally {
2422
+ if (ensureBinaryInFlight.get(key) === task)
2423
+ ensureBinaryInFlight.delete(key);
2402
2424
  }
2403
- log("No cached binary found, downloading latest...");
2404
- return downloadBinary();
2405
2425
  }
2406
2426
  function createDownloadLockOwner() {
2407
2427
  return JSON.stringify({
@@ -2544,7 +2564,7 @@ async function fetchLatestTag() {
2544
2564
  clearTimeout(timeout);
2545
2565
  }
2546
2566
  }
2547
- var REPO = "cortexkit/aft", DOWNLOAD_TIMEOUT_MS = 300000, LATEST_TAG_TIMEOUT_MS = 30000, MAX_DOWNLOAD_BYTES, DOWNLOAD_LOCK_STALE_MS, DOWNLOAD_LOCK_TIMEOUT_MS;
2567
+ var REPO = "cortexkit/aft", DOWNLOAD_TIMEOUT_MS = 300000, LATEST_TAG_TIMEOUT_MS = 30000, MAX_DOWNLOAD_BYTES, DOWNLOAD_LOCK_STALE_MS, DOWNLOAD_LOCK_TIMEOUT_MS, ensureBinaryInFlight;
2548
2568
  var init_downloader = __esm(() => {
2549
2569
  init_active_logger();
2550
2570
  init_cache_paths();
@@ -2553,6 +2573,7 @@ var init_downloader = __esm(() => {
2553
2573
  MAX_DOWNLOAD_BYTES = 200 * 1024 * 1024;
2554
2574
  DOWNLOAD_LOCK_STALE_MS = 10 * 60000;
2555
2575
  DOWNLOAD_LOCK_TIMEOUT_MS = DOWNLOAD_LOCK_STALE_MS + 30000;
2576
+ ensureBinaryInFlight = new Map;
2556
2577
  });
2557
2578
 
2558
2579
  // ../aft-bridge/dist/durable-log.js
@@ -2716,68 +2737,7 @@ ${reflowText}`;
2716
2737
  return " Auto-formatted.";
2717
2738
  }
2718
2739
 
2719
- // ../../node_modules/.bun/@cortexkit+subc-client@0.5.0/node_modules/@cortexkit/subc-client/dist/auth.js
2720
- import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
2721
- function computeProof(key, domain, clientNonce, serverNonce, daemonId) {
2722
- const mac = createHmac("sha256", Buffer.from(key));
2723
- mac.update(Buffer.from(domain, "utf8"));
2724
- mac.update(Buffer.from(clientNonce));
2725
- mac.update(Buffer.from(serverNonce));
2726
- mac.update(Buffer.from(daemonId));
2727
- return new Uint8Array(mac.digest());
2728
- }
2729
- function constantTimeEq(a, b) {
2730
- if (a.length !== b.length)
2731
- return false;
2732
- return timingSafeEqual(Buffer.from(a), Buffer.from(b));
2733
- }
2734
- async function writeMessage(sock, value, deadlineMs) {
2735
- const json = Buffer.from(JSON.stringify(value), "utf8");
2736
- if (json.length > MAX_AUTH_MESSAGE_LEN) {
2737
- throw new AuthError(`auth message too large: ${json.length} > ${MAX_AUTH_MESSAGE_LEN}`);
2738
- }
2739
- const lenPrefix = new Uint8Array(4);
2740
- new DataView(lenPrefix.buffer).setUint32(0, json.length, true);
2741
- await sock.write(lenPrefix, deadlineMs);
2742
- await sock.write(json, deadlineMs);
2743
- }
2744
- async function readMessage(sock, deadlineMs) {
2745
- const lenBytes = await sock.readExact(4, deadlineMs);
2746
- const len = new DataView(lenBytes.buffer, lenBytes.byteOffset, 4).getUint32(0, true);
2747
- if (len > MAX_AUTH_MESSAGE_LEN) {
2748
- throw new AuthError(`auth message too large: ${len} > ${MAX_AUTH_MESSAGE_LEN}`);
2749
- }
2750
- const body = len === 0 ? new Uint8Array(0) : await sock.readExact(len, deadlineMs);
2751
- try {
2752
- return JSON.parse(Buffer.from(body).toString("utf8"));
2753
- } catch (err) {
2754
- throw new AuthError(`auth message JSON decode failed: ${String(err)}`);
2755
- }
2756
- }
2757
- async function authenticateClient(sock, conn, deadlineMs) {
2758
- const clientNonce = new Uint8Array(randomBytes(NONCE_LEN));
2759
- await writeMessage(sock, { client_nonce: Array.from(clientNonce), role: DEFAULT_CLIENT_ROLE }, deadlineMs);
2760
- const proof = await readMessage(sock, deadlineMs);
2761
- const serverNonce = Uint8Array.from(proof.server_nonce);
2762
- const daemonId = Uint8Array.from(proof.daemon_id);
2763
- const serverProof = Uint8Array.from(proof.server_proof);
2764
- const expected = computeProof(conn.key, SERVER_PROOF_DOMAIN, clientNonce, serverNonce, daemonId);
2765
- if (!constantTimeEq(expected, serverProof)) {
2766
- throw new AuthError("server proof mismatch — wrong key or impostor daemon");
2767
- }
2768
- if (!constantTimeEq(daemonId, conn.daemonId)) {
2769
- throw new AuthError("daemon id mismatch — connection file points at a different daemon");
2770
- }
2771
- const clientAuth = computeProof(conn.key, CLIENT_AUTH_DOMAIN, clientNonce, serverNonce, daemonId);
2772
- await writeMessage(sock, { client_auth: Array.from(clientAuth) }, deadlineMs);
2773
- }
2774
- var NONCE_LEN = 32, MAX_AUTH_MESSAGE_LEN = 4096, SERVER_PROOF_DOMAIN = "subc-server-v1", CLIENT_AUTH_DOMAIN = "subc-client-v1", DEFAULT_CLIENT_ROLE = "client", AuthError;
2775
- var init_auth = __esm(() => {
2776
- AuthError = class AuthError extends Error {
2777
- };
2778
- });
2779
-
2780
- // ../../node_modules/.bun/@cortexkit+subc-client@0.5.0/node_modules/@cortexkit/subc-client/dist/envelope.js
2740
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.8.1/node_modules/@cortexkit/subc-client/dist/envelope.js
2781
2741
  function isPureHeader(ty) {
2782
2742
  return ty === FrameType.Cancel || ty === FrameType.Ping || ty === FrameType.Pong || ty === FrameType.Goodbye;
2783
2743
  }
@@ -2803,6 +2763,39 @@ function encodeHeader(header) {
2803
2763
  view.setBigUint64(13, header.corr, true);
2804
2764
  return buffer;
2805
2765
  }
2766
+ function validateHeaderFields(header) {
2767
+ const len = header.len >>> 0;
2768
+ const ver = header.ver >>> 0 & 255;
2769
+ const typeByte = header.ty >>> 0 & 255;
2770
+ const flags = header.flags >>> 0 & 255;
2771
+ const channel = header.channel >>> 0 & 65535;
2772
+ const epoch = header.epoch >>> 0;
2773
+ BigInt.asUintN(64, header.corr);
2774
+ if (ver !== PROTOCOL_VERSION)
2775
+ throw new DecodeError(`unsupported envelope version ${ver}`, "unsupported_version");
2776
+ if (typeByte > FRAME_TYPE_MAX)
2777
+ throw new DecodeError(`unknown frame type byte ${typeByte}`, "unknown_frame_type");
2778
+ const ty = typeByte;
2779
+ if ((flags & FLAG_RESERVED_MASK) !== 0) {
2780
+ throw new DecodeError(`reserved flag bits set in flags 0b${flags.toString(2).padStart(8, "0")}`, "reserved_flag_bits");
2781
+ }
2782
+ if ((flags & FLAG_PRIORITY_MASK) >> FLAG_PRIORITY_SHIFT === 3) {
2783
+ throw new DecodeError(`reserved priority bits set in flags 0b${flags.toString(2).padStart(8, "0")}`, "reserved_priority_bits");
2784
+ }
2785
+ const admission = (flags & FLAG_ADMISSION_MASK) >> FLAG_ADMISSION_SHIFT;
2786
+ if (admission === 3) {
2787
+ throw new DecodeError(`reserved admission class set in flags 0b${flags.toString(2).padStart(8, "0")}`, "reserved_admission_class");
2788
+ }
2789
+ if (admission === AdmissionClass.Sheddable && ty !== FrameType.Push && ty !== FrameType.StreamData) {
2790
+ throw new DecodeError(`SHEDDABLE admission class is illegal on ${FrameType[ty]} in flags 0b${flags.toString(2).padStart(8, "0")}`, "sheddable_illegal_frame_type");
2791
+ }
2792
+ if (channel === 0 && epoch !== 0) {
2793
+ throw new DecodeError(`control channel carried nonzero epoch ${epoch}`, "nonzero_epoch_on_control_channel");
2794
+ }
2795
+ if (isPureHeader(ty) && len !== 0) {
2796
+ throw new DecodeError(`pure-header frame ${FrameType[ty]} declared non-zero body length ${len}`, "pure_header_frame_with_body");
2797
+ }
2798
+ }
2806
2799
  function decodeHeader(bytes) {
2807
2800
  if (bytes.length < FROZEN_PREFIX_LEN) {
2808
2801
  throw new DecodeError(`header shorter than frozen prefix: have ${bytes.length} bytes`, "too_short_for_prefix");
@@ -2851,7 +2844,7 @@ function buildFrameWithVersion(ver, ty, flags, channel, epoch, corr, body) {
2851
2844
  throw new DecodeError(`frame body ${body.length} exceeds max ${MAX_FRAME_BODY_LEN}`, "frame_body_too_large");
2852
2845
  }
2853
2846
  const header = { len: body.length, ver, ty, flags, channel, epoch, corr };
2854
- decodeHeader(encodeHeader(header));
2847
+ validateHeaderFields(header);
2855
2848
  return { header, body };
2856
2849
  }
2857
2850
  function encodeFrame(frame) {
@@ -2902,12 +2895,324 @@ var init_envelope = __esm(() => {
2902
2895
  };
2903
2896
  });
2904
2897
 
2905
- // ../../node_modules/.bun/@cortexkit+subc-client@0.5.0/node_modules/@cortexkit/subc-client/dist/connection-file.js
2898
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.8.1/node_modules/@cortexkit/subc-client/dist/socket.js
2899
+ import net from "node:net";
2900
+ function toWriteBuffer(bytes) {
2901
+ return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
2902
+ }
2903
+ function writeBorrowed(socket, bytes, deadlineMs) {
2904
+ const borrowed = socket[WRITE_BORROWED];
2905
+ return borrowed ? borrowed.call(socket, bytes, deadlineMs) : socket.write(bytes, deadlineMs);
2906
+ }
2907
+ function writeTrackedBorrowed(socket, bytes, deadlineMs) {
2908
+ const borrowed = socket[WRITE_TRACKED_BORROWED];
2909
+ return borrowed ? borrowed.call(socket, bytes, deadlineMs) : socket.writeTracked(bytes, deadlineMs);
2910
+ }
2911
+ var SocketClosedError, SocketTimeoutError, SocketWriteNotQueuedError, SocketWriteQueuedError, WRITE_BORROWED, WRITE_TRACKED_BORROWED, SubcSocket;
2912
+ var init_socket = __esm(() => {
2913
+ init_envelope();
2914
+ SocketClosedError = class SocketClosedError extends Error {
2915
+ };
2916
+ SocketTimeoutError = class SocketTimeoutError extends Error {
2917
+ };
2918
+ SocketWriteNotQueuedError = class SocketWriteNotQueuedError extends Error {
2919
+ cause;
2920
+ constructor(message, cause) {
2921
+ super(message);
2922
+ this.cause = cause;
2923
+ }
2924
+ };
2925
+ SocketWriteQueuedError = class SocketWriteQueuedError extends Error {
2926
+ cause;
2927
+ constructor(message, cause) {
2928
+ super(message);
2929
+ this.cause = cause;
2930
+ }
2931
+ };
2932
+ WRITE_BORROWED = Symbol("subc.socket.writeBorrowed");
2933
+ WRITE_TRACKED_BORROWED = Symbol("subc.socket.writeTrackedBorrowed");
2934
+ SubcSocket = class SubcSocket {
2935
+ sock;
2936
+ chunks = [];
2937
+ buffered = 0;
2938
+ waiter = null;
2939
+ closedErr = null;
2940
+ bufferedBytes() {
2941
+ return this.buffered;
2942
+ }
2943
+ constructor(sock) {
2944
+ this.sock = sock;
2945
+ sock.on("data", (chunk) => {
2946
+ this.chunks.push(chunk);
2947
+ this.buffered += chunk.length;
2948
+ this.tryServe();
2949
+ });
2950
+ const fail = (err) => {
2951
+ if (!this.closedErr)
2952
+ this.closedErr = err;
2953
+ this.tryServe();
2954
+ };
2955
+ sock.on("error", (err) => fail(err instanceof Error ? err : new Error(String(err))));
2956
+ sock.on("end", () => fail(new SocketClosedError("subc closed the connection")));
2957
+ sock.on("close", () => fail(new SocketClosedError("subc connection closed")));
2958
+ }
2959
+ localPort() {
2960
+ return this.sock.localPort ?? null;
2961
+ }
2962
+ static connect(host, port, deadlineMs) {
2963
+ return new Promise((resolve3, reject) => {
2964
+ const sock = net.connect({ host, port });
2965
+ sock.setNoDelay(true);
2966
+ const timer = setTimeout(() => {
2967
+ sock.destroy();
2968
+ reject(new SocketTimeoutError(`timed out connecting to ${host}:${port}`));
2969
+ }, Math.max(0, deadlineMs - Date.now()));
2970
+ sock.once("connect", () => {
2971
+ clearTimeout(timer);
2972
+ resolve3(new SubcSocket(sock));
2973
+ });
2974
+ sock.once("error", (err) => {
2975
+ clearTimeout(timer);
2976
+ reject(err);
2977
+ });
2978
+ });
2979
+ }
2980
+ async readFrame(headerDeadlineMs, bodyDeadline, onHeader) {
2981
+ const prefix = await this.readExact(FROZEN_PREFIX_LEN, headerDeadlineMs);
2982
+ const version = prefix[4];
2983
+ if (version !== PROTOCOL_VERSION)
2984
+ throw new DecodeError(`unsupported envelope version ${version}`, "unsupported_version");
2985
+ const remainder = await this.readExact(HEADER_LEN - FROZEN_PREFIX_LEN, headerDeadlineMs);
2986
+ const headerBytes = new Uint8Array(HEADER_LEN);
2987
+ headerBytes.set(prefix);
2988
+ headerBytes.set(remainder, FROZEN_PREFIX_LEN);
2989
+ const header = decodeHeader(headerBytes);
2990
+ if (header.len > MAX_FRAME_BODY_LEN) {
2991
+ throw new DecodeError(`frame body ${header.len} exceeds max ${MAX_FRAME_BODY_LEN}`, "frame_body_too_large");
2992
+ }
2993
+ onHeader?.();
2994
+ const bodyDeadlineMs = typeof bodyDeadline === "number" ? bodyDeadline : Date.now() + bodyDeadline.afterHeaderMs;
2995
+ const body = header.len === 0 ? new Uint8Array(0) : await this.readExact(header.len, bodyDeadlineMs);
2996
+ return { header, body };
2997
+ }
2998
+ readExact(n, deadlineMs) {
2999
+ if (this.waiter) {
3000
+ return Promise.reject(new Error("concurrent readExact is not supported"));
3001
+ }
3002
+ if (n === 0)
3003
+ return Promise.resolve(new Uint8Array(0));
3004
+ return new Promise((resolve3, reject) => {
3005
+ let timer = null;
3006
+ if (Number.isFinite(deadlineMs)) {
3007
+ const remaining = deadlineMs - Date.now();
3008
+ if (remaining <= 0) {
3009
+ reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
3010
+ return;
3011
+ }
3012
+ timer = setTimeout(() => {
3013
+ this.waiter = null;
3014
+ reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
3015
+ }, remaining);
3016
+ }
3017
+ this.waiter = { need: n, resolve: resolve3, reject, timer };
3018
+ this.tryServe();
3019
+ });
3020
+ }
3021
+ async write(bytes, deadlineMs) {
3022
+ await this.writeBuffer(Buffer.from(bytes), deadlineMs);
3023
+ }
3024
+ writeTracked(bytes, deadlineMs) {
3025
+ return this.writeTrackedBuffer(Buffer.from(bytes), deadlineMs);
3026
+ }
3027
+ async[WRITE_BORROWED](bytes, deadlineMs) {
3028
+ await this.writeBuffer(toWriteBuffer(bytes), deadlineMs);
3029
+ }
3030
+ [WRITE_TRACKED_BORROWED](bytes, deadlineMs) {
3031
+ return this.writeTrackedBuffer(toWriteBuffer(bytes), deadlineMs);
3032
+ }
3033
+ async writeBuffer(buffer, deadlineMs) {
3034
+ try {
3035
+ await this.writeTrackedBuffer(buffer, deadlineMs).completed;
3036
+ } catch (err) {
3037
+ if (err instanceof SocketWriteNotQueuedError || err instanceof SocketWriteQueuedError) {
3038
+ throw err.cause ?? err;
3039
+ }
3040
+ throw err;
3041
+ }
3042
+ }
3043
+ writeTrackedBuffer(buffer, deadlineMs) {
3044
+ if (this.closedErr) {
3045
+ return {
3046
+ queued: false,
3047
+ completed: Promise.reject(new SocketWriteNotQueuedError("subc socket was closed before bytes could be queued", this.closedErr))
3048
+ };
3049
+ }
3050
+ let queued = false;
3051
+ let settled = false;
3052
+ let timer = null;
3053
+ const completed = new Promise((resolve3, reject) => {
3054
+ const settle = (run) => {
3055
+ if (settled)
3056
+ return;
3057
+ settled = true;
3058
+ if (timer)
3059
+ clearTimeout(timer);
3060
+ run();
3061
+ };
3062
+ const remaining = deadlineMs - Date.now();
3063
+ if (remaining <= 0) {
3064
+ settle(() => reject(new SocketWriteNotQueuedError("timed out before bytes could be queued to subc", new SocketTimeoutError("timed out writing to subc"))));
3065
+ return;
3066
+ }
3067
+ timer = setTimeout(() => {
3068
+ const timeout = new SocketTimeoutError("timed out writing to subc");
3069
+ settle(() => reject(queued ? new SocketWriteQueuedError("timed out after bytes were handed to the subc socket", timeout) : new SocketWriteNotQueuedError("timed out before bytes could be queued to subc", timeout)));
3070
+ }, remaining);
3071
+ try {
3072
+ this.sock.write(buffer, (err) => {
3073
+ settle(() => {
3074
+ if (err) {
3075
+ reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
3076
+ } else {
3077
+ resolve3();
3078
+ }
3079
+ });
3080
+ });
3081
+ queued = true;
3082
+ } catch (err) {
3083
+ settle(() => reject(new SocketWriteNotQueuedError("subc socket write threw before bytes could be queued", err instanceof Error ? err : new Error(String(err)))));
3084
+ }
3085
+ });
3086
+ return { queued, completed };
3087
+ }
3088
+ close() {
3089
+ this.sock.destroy();
3090
+ }
3091
+ tryServe() {
3092
+ const w = this.waiter;
3093
+ if (!w)
3094
+ return;
3095
+ if (this.buffered >= w.need) {
3096
+ const out = this.take(w.need);
3097
+ this.waiter = null;
3098
+ if (w.timer)
3099
+ clearTimeout(w.timer);
3100
+ w.resolve(out);
3101
+ return;
3102
+ }
3103
+ if (this.closedErr) {
3104
+ this.waiter = null;
3105
+ if (w.timer)
3106
+ clearTimeout(w.timer);
3107
+ w.reject(this.closedErr);
3108
+ }
3109
+ }
3110
+ take(n) {
3111
+ const out = Buffer.allocUnsafe(n);
3112
+ let off = 0;
3113
+ while (off < n) {
3114
+ const head = this.chunks[0];
3115
+ const want = n - off;
3116
+ if (head.length <= want) {
3117
+ head.copy(out, off);
3118
+ off += head.length;
3119
+ this.chunks.shift();
3120
+ } else {
3121
+ head.copy(out, off, 0, want);
3122
+ this.chunks[0] = head.subarray(want);
3123
+ off += want;
3124
+ }
3125
+ }
3126
+ this.buffered -= n;
3127
+ return out;
3128
+ }
3129
+ };
3130
+ });
3131
+
3132
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.8.1/node_modules/@cortexkit/subc-client/dist/auth.js
3133
+ import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
3134
+ function computeProof(key, domain, clientNonce, serverNonce, daemonId) {
3135
+ const mac = createHmac("sha256", Buffer.from(key));
3136
+ mac.update(Buffer.from(domain, "utf8"));
3137
+ mac.update(Buffer.from(clientNonce));
3138
+ mac.update(Buffer.from(serverNonce));
3139
+ mac.update(Buffer.from(daemonId));
3140
+ return new Uint8Array(mac.digest());
3141
+ }
3142
+ function constantTimeEq(a, b) {
3143
+ if (a.length !== b.length)
3144
+ return false;
3145
+ return timingSafeEqual(Buffer.from(a), Buffer.from(b));
3146
+ }
3147
+ async function writeMessage(sock, value, deadlineMs) {
3148
+ const json = Buffer.from(JSON.stringify(value), "utf8");
3149
+ if (json.length > MAX_AUTH_MESSAGE_LEN) {
3150
+ throw new AuthError(`auth message too large: ${json.length} > ${MAX_AUTH_MESSAGE_LEN}`);
3151
+ }
3152
+ const lenPrefix = new Uint8Array(4);
3153
+ new DataView(lenPrefix.buffer).setUint32(0, json.length, true);
3154
+ await writeBorrowed(sock, lenPrefix, deadlineMs);
3155
+ await writeBorrowed(sock, json, deadlineMs);
3156
+ }
3157
+ async function readMessage(sock, deadlineMs) {
3158
+ const lenBytes = await sock.readExact(4, deadlineMs);
3159
+ const len = new DataView(lenBytes.buffer, lenBytes.byteOffset, 4).getUint32(0, true);
3160
+ if (len > MAX_AUTH_MESSAGE_LEN) {
3161
+ throw new AuthError(`auth message too large: ${len} > ${MAX_AUTH_MESSAGE_LEN}`);
3162
+ }
3163
+ const body = len === 0 ? new Uint8Array(0) : await sock.readExact(len, deadlineMs);
3164
+ try {
3165
+ return JSON.parse(Buffer.from(body).toString("utf8"));
3166
+ } catch (err) {
3167
+ throw new AuthError(`auth message JSON decode failed: ${String(err)}`);
3168
+ }
3169
+ }
3170
+ function authBytes(value, field) {
3171
+ if (!Array.isArray(value)) {
3172
+ throw new AuthError(`auth field '${field}' must be a byte array`);
3173
+ }
3174
+ for (const byte of value) {
3175
+ if (typeof byte !== "number" || !Number.isInteger(byte) || byte < 0 || byte > 255) {
3176
+ throw new AuthError(`auth field '${field}' has invalid byte ${String(byte)}`);
3177
+ }
3178
+ }
3179
+ return Uint8Array.from(value);
3180
+ }
3181
+ async function authenticateClient(sock, conn, deadlineMs) {
3182
+ const clientNonce = new Uint8Array(randomBytes(NONCE_LEN));
3183
+ await writeMessage(sock, { client_nonce: Array.from(clientNonce), role: DEFAULT_CLIENT_ROLE }, deadlineMs);
3184
+ const proof = await readMessage(sock, deadlineMs);
3185
+ const serverNonce = authBytes(proof.server_nonce, "server_nonce");
3186
+ const daemonId = authBytes(proof.daemon_id, "daemon_id");
3187
+ const serverProof = authBytes(proof.server_proof, "server_proof");
3188
+ const expected = computeProof(conn.key, SERVER_PROOF_DOMAIN, clientNonce, serverNonce, daemonId);
3189
+ if (!constantTimeEq(expected, serverProof)) {
3190
+ throw new AuthError("server proof mismatch — wrong key or impostor daemon");
3191
+ }
3192
+ if (!constantTimeEq(daemonId, conn.daemonId)) {
3193
+ throw new AuthError("daemon id mismatch — connection file points at a different daemon");
3194
+ }
3195
+ const clientAuth = computeProof(conn.key, CLIENT_AUTH_DOMAIN, clientNonce, serverNonce, daemonId);
3196
+ await writeMessage(sock, { client_auth: Array.from(clientAuth) }, deadlineMs);
3197
+ }
3198
+ var NONCE_LEN = 32, MAX_AUTH_MESSAGE_LEN = 4096, SERVER_PROOF_DOMAIN = "subc-server-v1", CLIENT_AUTH_DOMAIN = "subc-client-v1", DEFAULT_CLIENT_ROLE = "client", AuthError;
3199
+ var init_auth = __esm(() => {
3200
+ init_socket();
3201
+ AuthError = class AuthError extends Error {
3202
+ };
3203
+ });
3204
+
3205
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.8.1/node_modules/@cortexkit/subc-client/dist/connection-file.js
2906
3206
  import { promises as fs2 } from "node:fs";
2907
3207
  function toBytes(value, field) {
2908
- if (!Array.isArray(value) || value.some((n) => typeof n !== "number")) {
3208
+ if (!Array.isArray(value)) {
2909
3209
  throw new ConnectionFileError(`connection file field '${field}' must be a JSON array of bytes`);
2910
3210
  }
3211
+ for (const byte of value) {
3212
+ if (typeof byte !== "number" || !Number.isInteger(byte) || byte < 0 || byte > 255) {
3213
+ throw new ConnectionFileError(`connection file field '${field}' has invalid byte ${String(byte)}`);
3214
+ }
3215
+ }
2911
3216
  return Uint8Array.from(value);
2912
3217
  }
2913
3218
  function validate(info) {
@@ -2975,7 +3280,7 @@ var init_connection_file = __esm(() => {
2975
3280
  };
2976
3281
  });
2977
3282
 
2978
- // ../../node_modules/.bun/@cortexkit+subc-client@0.5.0/node_modules/@cortexkit/subc-client/dist/route-handle.js
3283
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.8.1/node_modules/@cortexkit/subc-client/dist/route-handle.js
2979
3284
  class RouteHandle {
2980
3285
  channel;
2981
3286
  epoch;
@@ -3022,237 +3327,27 @@ var init_route_handle = __esm(() => {
3022
3327
  };
3023
3328
  });
3024
3329
 
3025
- // ../../node_modules/.bun/@cortexkit+subc-client@0.5.0/node_modules/@cortexkit/subc-client/dist/socket.js
3026
- import net from "node:net";
3330
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.8.1/node_modules/@cortexkit/subc-client/dist/client.js
3331
+ import { promises as fs3 } from "node:fs";
3332
+ import { debuglog } from "node:util";
3027
3333
 
3028
- class SubcSocket {
3334
+ class SubcClient {
3029
3335
  sock;
3030
- chunks = [];
3031
- buffered = 0;
3032
- waiter = null;
3336
+ currentConn;
3337
+ opts;
3338
+ nextCorr = 1n;
3339
+ pending = new Map;
3340
+ lateResponses = new Map;
3341
+ routes = new Map;
3342
+ liveRoutes = new Map;
3343
+ connectionToken = newConnectionToken();
3344
+ ingressEpochDropCount = 0;
3033
3345
  closedErr = null;
3034
- bufferedBytes() {
3035
- return this.buffered;
3036
- }
3037
- constructor(sock) {
3038
- this.sock = sock;
3039
- sock.on("data", (chunk) => {
3040
- this.chunks.push(chunk);
3041
- this.buffered += chunk.length;
3042
- this.tryServe();
3043
- });
3044
- const fail = (err) => {
3045
- if (!this.closedErr)
3046
- this.closedErr = err;
3047
- this.tryServe();
3048
- };
3049
- sock.on("error", (err) => fail(err instanceof Error ? err : new Error(String(err))));
3050
- sock.on("end", () => fail(new SocketClosedError("subc closed the connection")));
3051
- sock.on("close", () => fail(new SocketClosedError("subc connection closed")));
3052
- }
3053
- localPort() {
3054
- return this.sock.localPort ?? null;
3055
- }
3056
- static connect(host, port, deadlineMs) {
3057
- return new Promise((resolve3, reject) => {
3058
- const sock = net.connect({ host, port });
3059
- sock.setNoDelay(true);
3060
- const timer = setTimeout(() => {
3061
- sock.destroy();
3062
- reject(new SocketTimeoutError(`timed out connecting to ${host}:${port}`));
3063
- }, Math.max(0, deadlineMs - Date.now()));
3064
- sock.once("connect", () => {
3065
- clearTimeout(timer);
3066
- resolve3(new SubcSocket(sock));
3067
- });
3068
- sock.once("error", (err) => {
3069
- clearTimeout(timer);
3070
- reject(err);
3071
- });
3072
- });
3073
- }
3074
- async readFrame(headerDeadlineMs, bodyDeadline, onHeader) {
3075
- const prefix = await this.readExact(FROZEN_PREFIX_LEN, headerDeadlineMs);
3076
- const version = prefix[4];
3077
- if (version !== PROTOCOL_VERSION)
3078
- throw new DecodeError(`unsupported envelope version ${version}`, "unsupported_version");
3079
- const remainder = await this.readExact(HEADER_LEN - FROZEN_PREFIX_LEN, headerDeadlineMs);
3080
- const headerBytes = new Uint8Array(HEADER_LEN);
3081
- headerBytes.set(prefix);
3082
- headerBytes.set(remainder, FROZEN_PREFIX_LEN);
3083
- const header = decodeHeader(headerBytes);
3084
- if (header.len > MAX_FRAME_BODY_LEN) {
3085
- throw new DecodeError(`frame body ${header.len} exceeds max ${MAX_FRAME_BODY_LEN}`, "frame_body_too_large");
3086
- }
3087
- onHeader?.();
3088
- const bodyDeadlineMs = typeof bodyDeadline === "number" ? bodyDeadline : Date.now() + bodyDeadline.afterHeaderMs;
3089
- const body = header.len === 0 ? new Uint8Array(0) : await this.readExact(header.len, bodyDeadlineMs);
3090
- return { header, body };
3091
- }
3092
- readExact(n, deadlineMs) {
3093
- if (this.waiter) {
3094
- return Promise.reject(new Error("concurrent readExact is not supported"));
3095
- }
3096
- if (n === 0)
3097
- return Promise.resolve(new Uint8Array(0));
3098
- return new Promise((resolve3, reject) => {
3099
- let timer = null;
3100
- if (Number.isFinite(deadlineMs)) {
3101
- const remaining = deadlineMs - Date.now();
3102
- if (remaining <= 0) {
3103
- reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
3104
- return;
3105
- }
3106
- timer = setTimeout(() => {
3107
- this.waiter = null;
3108
- reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
3109
- }, remaining);
3110
- }
3111
- this.waiter = { need: n, resolve: resolve3, reject, timer };
3112
- this.tryServe();
3113
- });
3114
- }
3115
- async write(bytes, deadlineMs) {
3116
- try {
3117
- await this.writeTracked(bytes, deadlineMs).completed;
3118
- } catch (err) {
3119
- if (err instanceof SocketWriteNotQueuedError || err instanceof SocketWriteQueuedError) {
3120
- throw err.cause ?? err;
3121
- }
3122
- throw err;
3123
- }
3124
- }
3125
- writeTracked(bytes, deadlineMs) {
3126
- if (this.closedErr) {
3127
- return {
3128
- queued: false,
3129
- completed: Promise.reject(new SocketWriteNotQueuedError("subc socket was closed before bytes could be queued", this.closedErr))
3130
- };
3131
- }
3132
- let queued = false;
3133
- let settled = false;
3134
- let timer = null;
3135
- const completed = new Promise((resolve3, reject) => {
3136
- const settle = (run) => {
3137
- if (settled)
3138
- return;
3139
- settled = true;
3140
- if (timer)
3141
- clearTimeout(timer);
3142
- run();
3143
- };
3144
- const remaining = deadlineMs - Date.now();
3145
- if (remaining <= 0) {
3146
- settle(() => reject(new SocketWriteNotQueuedError("timed out before bytes could be queued to subc", new SocketTimeoutError("timed out writing to subc"))));
3147
- return;
3148
- }
3149
- timer = setTimeout(() => {
3150
- const timeout = new SocketTimeoutError("timed out writing to subc");
3151
- settle(() => reject(queued ? new SocketWriteQueuedError("timed out after bytes were handed to the subc socket", timeout) : new SocketWriteNotQueuedError("timed out before bytes could be queued to subc", timeout)));
3152
- }, remaining);
3153
- try {
3154
- this.sock.write(Buffer.from(bytes), (err) => {
3155
- settle(() => {
3156
- if (err) {
3157
- reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
3158
- } else {
3159
- resolve3();
3160
- }
3161
- });
3162
- });
3163
- queued = true;
3164
- } catch (err) {
3165
- settle(() => reject(new SocketWriteNotQueuedError("subc socket write threw before bytes could be queued", err instanceof Error ? err : new Error(String(err)))));
3166
- }
3167
- });
3168
- return { queued, completed };
3169
- }
3170
- close() {
3171
- this.sock.destroy();
3172
- }
3173
- tryServe() {
3174
- const w = this.waiter;
3175
- if (!w)
3176
- return;
3177
- if (this.buffered >= w.need) {
3178
- const out = this.take(w.need);
3179
- this.waiter = null;
3180
- if (w.timer)
3181
- clearTimeout(w.timer);
3182
- w.resolve(out);
3183
- return;
3184
- }
3185
- if (this.closedErr) {
3186
- this.waiter = null;
3187
- if (w.timer)
3188
- clearTimeout(w.timer);
3189
- w.reject(this.closedErr);
3190
- }
3191
- }
3192
- take(n) {
3193
- const out = Buffer.allocUnsafe(n);
3194
- let off = 0;
3195
- while (off < n) {
3196
- const head = this.chunks[0];
3197
- const want = n - off;
3198
- if (head.length <= want) {
3199
- head.copy(out, off);
3200
- off += head.length;
3201
- this.chunks.shift();
3202
- } else {
3203
- head.copy(out, off, 0, want);
3204
- this.chunks[0] = head.subarray(want);
3205
- off += want;
3206
- }
3207
- }
3208
- this.buffered -= n;
3209
- return out;
3210
- }
3211
- }
3212
- var SocketClosedError, SocketTimeoutError, SocketWriteNotQueuedError, SocketWriteQueuedError;
3213
- var init_socket = __esm(() => {
3214
- init_envelope();
3215
- SocketClosedError = class SocketClosedError extends Error {
3216
- };
3217
- SocketTimeoutError = class SocketTimeoutError extends Error {
3218
- };
3219
- SocketWriteNotQueuedError = class SocketWriteNotQueuedError extends Error {
3220
- cause;
3221
- constructor(message, cause) {
3222
- super(message);
3223
- this.cause = cause;
3224
- }
3225
- };
3226
- SocketWriteQueuedError = class SocketWriteQueuedError extends Error {
3227
- cause;
3228
- constructor(message, cause) {
3229
- super(message);
3230
- this.cause = cause;
3231
- }
3232
- };
3233
- });
3234
-
3235
- // ../../node_modules/.bun/@cortexkit+subc-client@0.5.0/node_modules/@cortexkit/subc-client/dist/client.js
3236
- import { promises as fs3 } from "node:fs";
3237
- import { debuglog } from "node:util";
3238
-
3239
- class SubcClient {
3240
- sock;
3241
- currentConn;
3242
- opts;
3243
- nextCorr = 1n;
3244
- pending = new Map;
3245
- lateResponses = new Map;
3246
- routes = new Map;
3247
- liveRoutes = new Map;
3248
- connectionToken = newConnectionToken();
3249
- ingressEpochDropCount = 0;
3250
- closedErr = null;
3251
- closeStarted = false;
3252
- reconnecting = null;
3253
- generation = 1;
3254
- readerActive = false;
3255
- constructor(sock, currentConn, opts) {
3346
+ closeStarted = false;
3347
+ reconnecting = null;
3348
+ generation = 1;
3349
+ readerActive = false;
3350
+ constructor(sock, currentConn, opts) {
3256
3351
  this.sock = sock;
3257
3352
  this.currentConn = currentConn;
3258
3353
  this.opts = opts;
@@ -3331,12 +3426,13 @@ class SubcClient {
3331
3426
  } catch (err) {
3332
3427
  if (!(err instanceof SubcCallError))
3333
3428
  throw this.terminalCallError("managed call failed", err);
3334
- if (err.code === "unknown_channel" && !retriedUnknownChannel && !this.closeStarted) {
3429
+ const deadBindCode = err.code === "unknown_channel" || err.code === "stale_route_epoch";
3430
+ if (deadBindCode && !retriedUnknownChannel && !this.closeStarted) {
3335
3431
  retriedUnknownChannel = true;
3336
3432
  this.evictRouteHandle(routeHandle);
3337
3433
  continue;
3338
3434
  }
3339
- if (err.code === "unknown_channel" && retriedUnknownChannel) {
3435
+ if (deadBindCode && retriedUnknownChannel) {
3340
3436
  this.evictRouteHandle(routeHandle);
3341
3437
  }
3342
3438
  if (err.kind === "not_sent") {
@@ -3349,6 +3445,8 @@ class SubcClient {
3349
3445
  }
3350
3446
  if (err.kind === "outcome_unknown" && err.code !== DEADLINE_NO_DROP_CODE) {
3351
3447
  this.scheduleReconnectAfterDrop(err);
3448
+ } else if (err.kind === "outcome_unknown" && err.code === DEADLINE_NO_DROP_CODE) {
3449
+ this.probeLivenessAfterDeadline();
3352
3450
  }
3353
3451
  throw err;
3354
3452
  }
@@ -3361,21 +3459,25 @@ class SubcClient {
3361
3459
  const admission = opts.admissionClass ?? AdmissionClass.Normal;
3362
3460
  const corr = this.allocateCorr();
3363
3461
  const key = pendingKey(handle, corr);
3462
+ let subscriptionPending = null;
3463
+ let resolveClosed = null;
3364
3464
  const closed = new Promise((resolve3, reject) => {
3365
3465
  if (this.closedErr) {
3366
3466
  reject(this.closedErr);
3367
3467
  return;
3368
3468
  }
3369
- this.pending.set(key, {
3469
+ resolveClosed = resolve3;
3470
+ subscriptionPending = {
3370
3471
  handle,
3371
3472
  resolve: () => resolve3(),
3372
3473
  reject,
3373
3474
  onProgress: onEvent,
3374
3475
  timer: null,
3375
3476
  subscription: true
3376
- });
3477
+ };
3478
+ this.pending.set(key, subscriptionPending);
3377
3479
  const frame = buildFrame(FrameType.Request, buildFlags(false, priority, false, admission), handle.channel, handle.epoch, corr, bytes);
3378
- this.sock.write(encodeFrame(frame), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch((err) => {
3480
+ writeBorrowed(this.sock, encodeFrame(frame), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch((err) => {
3379
3481
  const pending = this.pending.get(key);
3380
3482
  if (pending)
3381
3483
  this.rejectPending(key, pending, err instanceof Error ? err : new SubcError(String(err)));
@@ -3386,14 +3488,17 @@ class SubcClient {
3386
3488
  if (cancelled)
3387
3489
  return;
3388
3490
  cancelled = true;
3389
- this.cancel(handle, corr, priority);
3491
+ if (subscriptionPending && resolveClosed)
3492
+ this.settle(key, subscriptionPending, resolveClosed);
3493
+ if (this.isLiveHandle(handle))
3494
+ this.cancel(handle, corr, priority);
3390
3495
  };
3391
3496
  return { unsubscribe, closed };
3392
3497
  }
3393
3498
  cancel(handle, corr, priority = Priority.Interactive) {
3394
3499
  this.assertLiveHandle(handle);
3395
3500
  const cancel = buildFrame(FrameType.Cancel, buildFlags(false, priority, false), handle.channel, handle.epoch, corr, EMPTY_BODY);
3396
- this.sock.write(encodeFrame(cancel), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch(() => {
3501
+ writeBorrowed(this.sock, encodeFrame(cancel), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch(() => {
3397
3502
  return;
3398
3503
  });
3399
3504
  }
@@ -3474,7 +3579,7 @@ class SubcClient {
3474
3579
  return;
3475
3580
  }
3476
3581
  const goodbye = buildFrame(FrameType.Goodbye, buildFlags(false, Priority.Interactive, false), handle.channel, handle.epoch, 0n, EMPTY_BODY);
3477
- const write = this.sock.writeTracked(encodeFrame(goodbye), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS);
3582
+ const write = writeTrackedBorrowed(this.sock, encodeFrame(goodbye), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS);
3478
3583
  if (!write.queued && closeOnQueueFailure)
3479
3584
  this.closeConnectionAfterCleanupFailure();
3480
3585
  write.completed.catch(() => {
@@ -3526,7 +3631,7 @@ class SubcClient {
3526
3631
  };
3527
3632
  pending.timer = setTimeout(() => this.arbitrateTimeout(key, pending, channel, corr, ms), ms);
3528
3633
  this.pending.set(key, pending);
3529
- this.sock.write(encodeFrame(frame), Date.now() + ms).catch((error2) => {
3634
+ writeBorrowed(this.sock, encodeFrame(frame), Date.now() + ms).catch((error2) => {
3530
3635
  const current = this.pending.get(key);
3531
3636
  if (current)
3532
3637
  this.rejectPending(key, current, error2 instanceof Error ? error2 : new SubcError(String(error2)));
@@ -3603,7 +3708,7 @@ class SubcClient {
3603
3708
  };
3604
3709
  pending.timer = setTimeout(() => this.arbitrateTimeout(key, pending, handle.channel, corr, ms), ms);
3605
3710
  this.pending.set(key, pending);
3606
- const write = this.sock.writeTracked(encodeFrame(frame), Date.now() + ms);
3711
+ const write = writeTrackedBorrowed(this.sock, encodeFrame(frame), Date.now() + ms);
3607
3712
  handedToSocket = write.queued;
3608
3713
  write.completed.catch((error2) => {
3609
3714
  const current = this.pending.get(key);
@@ -3691,6 +3796,46 @@ class SubcClient {
3691
3796
  }
3692
3797
  }
3693
3798
  }
3799
+ lastInboundAtMs = 0;
3800
+ livenessProbe = null;
3801
+ hasControlPending() {
3802
+ for (const pending of this.pending.values()) {
3803
+ if (pending.handle === null)
3804
+ return true;
3805
+ }
3806
+ return false;
3807
+ }
3808
+ probeLivenessAfterDeadline() {
3809
+ if (this.livenessProbe || this.closeStarted || this.closedErr)
3810
+ return;
3811
+ if (this.hasControlPending())
3812
+ return;
3813
+ const sock = this.sock;
3814
+ const generation = this.generation;
3815
+ let corr;
3816
+ try {
3817
+ corr = this.allocateCorr();
3818
+ } catch {
3819
+ return;
3820
+ }
3821
+ const t0 = Date.now();
3822
+ const ping = buildFrame(FrameType.Ping, buildFlags(false, Priority.Interactive, false, AdmissionClass.Normal), 0, 0, corr, new Uint8Array);
3823
+ const probe = (async () => {
3824
+ await writeBorrowed(sock, encodeFrame(ping), t0 + this.opts.livenessProbeWindowMs).catch(() => {});
3825
+ await this.opts.sleep(this.opts.livenessProbeWindowMs);
3826
+ if (this.sock !== sock || this.generation !== generation || this.closeStarted)
3827
+ return;
3828
+ if (this.lastInboundAtMs >= t0)
3829
+ return;
3830
+ if (this.hasControlPending())
3831
+ return;
3832
+ this.fail(new SocketClosedError(`liveness probe convicted a half-open socket: no inbound frame for ${this.opts.livenessProbeWindowMs}ms after a channel-0 Ping (deadline-no-drop settles preceded this); closing so the next call reconnects`));
3833
+ sock.close();
3834
+ })().finally(() => {
3835
+ this.livenessProbe = null;
3836
+ });
3837
+ this.livenessProbe = probe;
3838
+ }
3694
3839
  async ensureConnectedForManaged() {
3695
3840
  if (this.closeStarted)
3696
3841
  throw new SubcError("client closed");
@@ -3802,6 +3947,24 @@ class SubcClient {
3802
3947
  }
3803
3948
  }
3804
3949
  dispatch(frame) {
3950
+ this.lastInboundAtMs = Date.now();
3951
+ if (frame.header.channel === 0 && frame.header.ty === FrameType.Push) {
3952
+ const observer = this.opts.onControlPush;
3953
+ if (observer) {
3954
+ let parsed = null;
3955
+ try {
3956
+ const body = this.parseJson(frame);
3957
+ if (body && typeof body.op === "string")
3958
+ parsed = { op: body.op, body };
3959
+ } catch {}
3960
+ if (parsed) {
3961
+ try {
3962
+ observer(parsed);
3963
+ } catch {}
3964
+ }
3965
+ }
3966
+ return;
3967
+ }
3805
3968
  let handle = null;
3806
3969
  if (frame.header.channel !== 0) {
3807
3970
  handle = this.liveRoutes.get(frame.header.channel) ?? null;
@@ -3818,7 +3981,9 @@ class SubcClient {
3818
3981
  switch (frame.header.ty) {
3819
3982
  case FrameType.Push:
3820
3983
  case FrameType.StreamData:
3821
- pending.onProgress?.(frame.body);
3984
+ try {
3985
+ pending.onProgress?.(frame.body);
3986
+ } catch {}
3822
3987
  return;
3823
3988
  case FrameType.Response:
3824
3989
  case FrameType.StreamEnd:
@@ -3838,7 +4003,7 @@ class SubcClient {
3838
4003
  return;
3839
4004
  }
3840
4005
  if (frame.header.ty === FrameType.Goodbye && handle) {
3841
- this.failHandle(handle, new SubcError("route closed by subc (GOODBYE)"));
4006
+ this.failHandle(handle, new SubcError("route closed by subc (GOODBYE)", "route_closed"));
3842
4007
  if (this.liveRoutes.get(handle.channel) === handle)
3843
4008
  this.liveRoutes.delete(handle.channel);
3844
4009
  this.evictRouteHandle(handle);
@@ -3945,10 +4110,11 @@ class SubcClient {
3945
4110
  this.scheduleReconnectAfterDrop(error2);
3946
4111
  }
3947
4112
  encode(value) {
3948
- return new Uint8Array(Buffer.from(JSON.stringify(value), "utf8"));
4113
+ return Buffer.from(JSON.stringify(value), "utf8");
3949
4114
  }
3950
4115
  parseJson(frame) {
3951
- return JSON.parse(Buffer.from(frame.body).toString("utf8"));
4116
+ const b = frame.body;
4117
+ return JSON.parse(Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString("utf8"));
3952
4118
  }
3953
4119
  }
3954
4120
  function isConsumerReconnectTransient(err) {
@@ -3966,7 +4132,7 @@ function isConsumerReconnectTransient(err) {
3966
4132
  return code === "ECONNREFUSED" || code === "ECONNRESET" || code === "EPIPE" || code === "ETIMEDOUT" || code === "ENOENT";
3967
4133
  }
3968
4134
  function isRetryableRouteOpenCode(code) {
3969
- return code === "unknown_module" || code === "module_reloading" || code === "target_unavailable" || code === "module_timeout";
4135
+ return code === "unknown_module" || code === "module_reloading" || code === "module_warming" || code === "target_unavailable" || code === "module_timeout";
3970
4136
  }
3971
4137
  async function connectionFileExists(path2) {
3972
4138
  try {
@@ -3984,917 +4150,67 @@ function normalizeConnectOptions(opts) {
3984
4150
  targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
3985
4151
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
3986
4152
  sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
3987
- timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
3988
- };
3989
- }
3990
- function routeCacheKey(target, identity, consumerIdentity) {
3991
- const consumerPart = consumerIdentity ? `${consumerIdentity.module_id}\x00${consumerIdentity.launch_nonce}` : "";
3992
- return `${target.kind}\x00${target.module_id}\x00${identity.project_root}\x00${identity.harness}\x00${identity.session}\x00${consumerPart}`;
3993
- }
3994
- function routeOpenConsumerIdentity(opts = {}) {
3995
- if (opts.consumerIdentity !== undefined)
3996
- return opts.consumerIdentity ?? undefined;
3997
- const moduleId = process.env[SUBC_MODULE_ID_ENV];
3998
- const launchNonce = process.env[SUBC_LAUNCH_NONCE_ENV];
3999
- if (!moduleId || !launchNonce)
4000
- return;
4001
- return { module_id: moduleId, launch_nonce: launchNonce };
4002
- }
4003
- function errorCode(err) {
4004
- if (typeof err === "object" && err !== null && "code" in err) {
4005
- const code = err.code;
4006
- if (typeof code === "string")
4007
- return code;
4008
- }
4009
- return;
4010
- }
4011
- function causeMessage(cause) {
4012
- if (cause === undefined)
4013
- return "";
4014
- return `: ${cause instanceof Error ? cause.message : String(cause)}`;
4015
- }
4016
- function pendingKey(handle, corr) {
4017
- return handle ? `${handle.channel}:${handle.epoch}:${corr}` : `0:0:${corr}`;
4018
- }
4019
- var debug, DEFAULT_HANDSHAKE_TIMEOUT_MS = 1e4, DEFAULT_REQUEST_TIMEOUT_MS = 30000, TIMEOUT_ARBITRATION_GRACE_MS = 50, REQUEST_DEADLINE_MARKER = "request_deadline", DEADLINE_NO_DROP_CODE = "deadline_exceeded_no_drop_observed", ROUTE_OPEN_RETRY_DEADLINE_MS = 30000, BODY_READ_TIMEOUT_MS = 30000, EMPTY_BODY, DEFAULT_MANAGED_TARGET_KIND = "management_surface", SUBC_MODULE_ID_ENV = "SUBC_MODULE_ID", SUBC_LAUNCH_NONCE_ENV = "SUBC_LAUNCH_NONCE", DEFAULT_RECONNECT_BACKOFF, SubcCallError, SubcError;
4020
- var init_client = __esm(() => {
4021
- init_auth();
4022
- init_connection_file();
4023
- init_envelope();
4024
- init_route_handle();
4025
- init_socket();
4026
- debug = debuglog("subc-client");
4027
- EMPTY_BODY = new Uint8Array(0);
4028
- DEFAULT_RECONNECT_BACKOFF = {
4029
- baseMs: 100,
4030
- capMs: 2000,
4031
- maxAttempts: 6
4032
- };
4033
- SubcCallError = class SubcCallError extends Error {
4034
- kind;
4035
- code;
4036
- cause;
4037
- constructor(kind, message, code, cause) {
4038
- super(message);
4039
- this.kind = kind;
4040
- this.code = code;
4041
- this.cause = cause;
4042
- this.name = "SubcCallError";
4043
- }
4044
- };
4045
- SubcError = class SubcError extends Error {
4046
- code;
4047
- constructor(message, code) {
4048
- super(message);
4049
- this.code = code;
4050
- }
4051
- };
4052
- });
4053
-
4054
- // ../../node_modules/.bun/@cortexkit+subc-client@0.5.0/node_modules/@cortexkit/subc-client/dist/provider.js
4055
- import { Buffer as Buffer2 } from "node:buffer";
4056
-
4057
- class AsyncPermitPool {
4058
- available;
4059
- waiters = [];
4060
- constructor(capacity) {
4061
- if (!Number.isInteger(capacity) || capacity <= 0) {
4062
- throw new SubcProviderError("provider handler capacity must be a positive integer", "invalid_handler_capacity");
4063
- }
4064
- this.available = capacity;
4065
- }
4066
- async acquire() {
4067
- if (this.available > 0) {
4068
- this.available -= 1;
4069
- return this.releaseOnce();
4070
- }
4071
- await new Promise((resolve3) => {
4072
- this.waiters.push(resolve3);
4073
- });
4074
- return this.releaseOnce();
4075
- }
4076
- releaseOnce() {
4077
- let released = false;
4078
- return () => {
4079
- if (released)
4080
- return;
4081
- released = true;
4082
- const next = this.waiters.shift();
4083
- if (next) {
4084
- next();
4085
- } else {
4086
- this.available += 1;
4087
- }
4088
- };
4089
- }
4090
- }
4091
-
4092
- class SubcProvider {
4093
- sock;
4094
- currentConn;
4095
- opts;
4096
- closed;
4097
- resolveClosed = () => {
4098
- return;
4099
- };
4100
- closeStarted = false;
4101
- closedErr = null;
4102
- inflight = new Map;
4103
- pending = new Map;
4104
- liveRoutes = new Map;
4105
- connectionToken = newConnectionToken();
4106
- nextCorr = 1n;
4107
- ingressEpochDropCount = 0;
4108
- requestGate = new AsyncPermitPool(DEFAULT_PROVIDER_HANDLER_CAPACITY);
4109
- reconnecting = null;
4110
- generation = 1;
4111
- connectionEpoch = 1;
4112
- stateQueue = [];
4113
- drainingStateQueue = false;
4114
- restoredDebounceToken = 0;
4115
- storage;
4116
- constructor(sock, currentConn, opts, storage) {
4117
- this.sock = sock;
4118
- this.currentConn = currentConn;
4119
- this.opts = opts;
4120
- this.storage = storage;
4121
- this.closed = new Promise((resolve3) => {
4122
- this.resolveClosed = resolve3;
4123
- });
4124
- this.readLoop(sock, this.generation);
4125
- this.enqueueConnectionState({ state: "connected", epoch: this.connectionEpoch });
4126
- }
4127
- get droppedIngressFrames() {
4128
- return this.ingressEpochDropCount;
4129
- }
4130
- get conn() {
4131
- return this.currentConn;
4132
- }
4133
- currentEpoch() {
4134
- return this.connectionEpoch;
4135
- }
4136
- async request(handle, body, opts = {}) {
4137
- this.assertLiveHandle(handle);
4138
- const corr = this.allocateCorr();
4139
- const key = routeKey(handle, corr);
4140
- const timeoutMs = opts.timeoutMs ?? WRITE_TIMEOUT_MS;
4141
- const frame = buildFrame(FrameType.Request, buildFlags(false, opts.priority ?? Priority.Interactive, false, opts.admissionClass ?? AdmissionClass.Normal), handle.channel, handle.epoch, corr, body);
4142
- return await new Promise((resolve3, reject) => {
4143
- const timer = setTimeout(() => {
4144
- if (this.pending.delete(key))
4145
- reject(new SubcProviderError("reverse request timed out", "request_timeout"));
4146
- }, timeoutMs);
4147
- this.pending.set(key, {
4148
- resolve: (response) => resolve3(response.body),
4149
- reject,
4150
- timer
4151
- });
4152
- this.sendOn(this.sock, this.generation, frame).catch((error2) => {
4153
- const pending = this.pending.get(key);
4154
- if (!pending)
4155
- return;
4156
- this.pending.delete(key);
4157
- clearTimeout(pending.timer);
4158
- reject(error2 instanceof Error ? error2 : new SubcProviderError(String(error2)));
4159
- });
4160
- });
4161
- }
4162
- async push(handle, body, opts = {}) {
4163
- this.assertLiveHandle(handle);
4164
- await this.sendOn(this.sock, this.generation, buildFrame(FrameType.Push, buildFlags(false, opts.priority ?? Priority.Interactive, false, opts.admissionClass ?? AdmissionClass.Normal), handle.channel, handle.epoch, 0n, body));
4165
- }
4166
- cancel(handle, corr) {
4167
- this.assertLiveHandle(handle);
4168
- this.sendOn(this.sock, this.generation, buildFrame(FrameType.Cancel, controlFlags(), handle.channel, handle.epoch, corr, new Uint8Array(0)));
4169
- }
4170
- closeRoute(handle) {
4171
- this.assertLiveHandle(handle);
4172
- this.liveRoutes.delete(handle.channel);
4173
- this.abortHandle(handle);
4174
- this.sendOn(this.sock, this.generation, buildFrame(FrameType.Goodbye, controlFlags(), handle.channel, handle.epoch, 0n, new Uint8Array(0)));
4175
- }
4176
- static async connect(opts) {
4177
- if (opts.manifest.protocol_ver !== PROTOCOL_VERSION) {
4178
- throw new SubcProviderError(`manifest protocol_ver ${opts.manifest.protocol_ver} does not match client protocol ${PROTOCOL_VERSION}`, "invalid_manifest");
4179
- }
4180
- const normalized = normalizeProviderConnectOptions(opts);
4181
- const opened = await SubcProvider.openConnection(normalized);
4182
- return new SubcProvider(opened.sock, opened.conn, normalized, opened.ack.storage);
4183
- }
4184
- async close() {
4185
- if (!this.closeStarted) {
4186
- this.closeStarted = true;
4187
- this.cancelRestoredDebounce();
4188
- const sock = this.sock;
4189
- try {
4190
- await sendFrame(sock, buildFrame(FrameType.Goodbye, controlFlags(), 0, 0, 0n, new Uint8Array(0)));
4191
- } catch {} finally {
4192
- sock.close();
4193
- this.finishClosed();
4194
- }
4195
- }
4196
- await this.closed;
4197
- }
4198
- static async openConnection(opts, onSocket) {
4199
- const conn = await readConnectionFile(opts.connectionFile);
4200
- const deadline = Date.now() + (opts.handshakeTimeoutMs ?? DEFAULT_HANDSHAKE_TIMEOUT_MS2);
4201
- const endpoint = conn.endpoints[0];
4202
- const sock = await SubcSocket.connect(endpoint.host, endpoint.port, deadline);
4203
- try {
4204
- onSocket?.(sock);
4205
- await authenticateClient(sock, conn, deadline);
4206
- await sendFrame(sock, buildHelloFrame(opts));
4207
- const ack = await expectHelloAck(sock, deadline);
4208
- return { sock, conn, ack };
4209
- } catch (err) {
4210
- sock.close();
4211
- throw err;
4212
- }
4213
- }
4214
- async readLoop(sock, generation) {
4215
- try {
4216
- for (;; ) {
4217
- const frame = await sock.readFrame(Number.POSITIVE_INFINITY, { afterHeaderMs: BODY_READ_TIMEOUT_MS2 });
4218
- const keepGoing = await this.dispatch(frame, sock, generation);
4219
- if (!keepGoing) {
4220
- if (this.sock === sock && this.generation === generation)
4221
- this.closeStarted = true;
4222
- break;
4223
- }
4224
- }
4225
- } catch (error2) {
4226
- if (this.sock === sock && this.generation === generation && !this.closeStarted) {
4227
- this.handleUnexpectedDrop(sock, generation, error2 instanceof Error ? error2 : new SubcProviderError(String(error2)));
4228
- return;
4229
- }
4230
- } finally {
4231
- if (this.sock === sock && this.generation === generation) {
4232
- sock.close();
4233
- if (this.closeStarted)
4234
- this.finishClosed();
4235
- }
4236
- }
4237
- }
4238
- async dispatch(frame, sock, generation) {
4239
- let handle = null;
4240
- if (frame.header.channel !== 0) {
4241
- handle = this.liveRoutes.get(frame.header.channel) ?? null;
4242
- if (!handle || handle.epoch !== frame.header.epoch) {
4243
- this.ingressEpochDropCount += 1;
4244
- return true;
4245
- }
4246
- }
4247
- if (handle) {
4248
- const pendingKey2 = routeKey(handle, frame.header.corr);
4249
- const pending = this.pending.get(pendingKey2);
4250
- if (pending) {
4251
- if (frame.header.ty === FrameType.Push || frame.header.ty === FrameType.StreamData)
4252
- return true;
4253
- if (frame.header.ty === FrameType.Response || frame.header.ty === FrameType.StreamEnd) {
4254
- this.pending.delete(pendingKey2);
4255
- clearTimeout(pending.timer);
4256
- pending.resolve(frame);
4257
- return true;
4258
- }
4259
- if (frame.header.ty === FrameType.Error) {
4260
- this.pending.delete(pendingKey2);
4261
- clearTimeout(pending.timer);
4262
- pending.reject(providerErrorFromFrame(frame));
4263
- return true;
4264
- }
4265
- }
4266
- }
4267
- switch (frame.header.ty) {
4268
- case FrameType.Ping:
4269
- if (frame.header.channel === 0) {
4270
- await this.sendOn(sock, generation, buildFrameWithVersion(frame.header.ver, FrameType.Pong, frame.header.flags, 0, 0, frame.header.corr, new Uint8Array(0)));
4271
- }
4272
- return true;
4273
- case FrameType.Goodbye:
4274
- if (!handle)
4275
- return false;
4276
- this.liveRoutes.delete(handle.channel);
4277
- this.abortHandle(handle);
4278
- await this.opts.onRouteGone?.(handle);
4279
- return true;
4280
- case FrameType.Cancel:
4281
- if (handle)
4282
- this.inflight.get(routeKey(handle, frame.header.corr))?.abort();
4283
- return true;
4284
- case FrameType.Request:
4285
- if (frame.header.channel === 0) {
4286
- await this.handleControlRequest(frame, sock, generation);
4287
- } else if (handle) {
4288
- this.handleDataRequest(frame, handle, sock, generation).catch((error2) => {
4289
- if (!this.closeStarted && this.sock === sock && this.generation === generation) {
4290
- console.warn("SubcProvider handler failed after its request was dispatched", error2);
4291
- }
4292
- });
4293
- }
4294
- return true;
4295
- default:
4296
- return true;
4297
- }
4298
- }
4299
- abortHandle(handle) {
4300
- const prefix = `${handle.channel}:${handle.epoch}:`;
4301
- for (const [key, controller] of this.inflight) {
4302
- if (key.startsWith(prefix))
4303
- controller.abort();
4304
- }
4305
- for (const [key, pending] of this.pending) {
4306
- if (!key.startsWith(prefix))
4307
- continue;
4308
- this.pending.delete(key);
4309
- clearTimeout(pending.timer);
4310
- pending.reject(new StaleRouteHandleError(handle));
4311
- }
4312
- }
4313
- abortGeneration(_generation) {
4314
- this.abortAllInflight();
4315
- for (const [key, pending] of this.pending) {
4316
- this.pending.delete(key);
4317
- clearTimeout(pending.timer);
4318
- pending.reject(new SubcProviderError("provider connection dropped", "connection_dropped"));
4319
- }
4320
- this.liveRoutes.clear();
4321
- }
4322
- abortAllInflight() {
4323
- for (const controller of this.inflight.values())
4324
- controller.abort();
4325
- }
4326
- async handleControlRequest(frame, sock, generation) {
4327
- const request = parseJson(frame.body);
4328
- if (request.op === HEALTH_CHECK_OP) {
4329
- this.handleHealthRequest(frame, sock, generation).catch((error2) => {
4330
- if (!this.closeStarted && this.sock === sock && this.generation === generation) {
4331
- console.warn("SubcProvider health handler failed after its request was dispatched", error2);
4332
- }
4333
- });
4334
- return;
4335
- }
4336
- if (request.op !== "route.bind") {
4337
- throw new SubcProviderError(`unsupported module control request ${request.op ?? "<missing op>"}`);
4338
- }
4339
- const boundChannel = numberField(request.route_channel, "route_channel");
4340
- const boundEpoch = numberField(request.epoch, "epoch");
4341
- const stale = this.liveRoutes.get(boundChannel);
4342
- if (stale) {
4343
- if (boundEpoch <= stale.epoch) {
4344
- await this.sendError(frame, "route_rejected", `route.bind epoch ${boundEpoch} does not supersede installed epoch ${stale.epoch} on channel ${boundChannel}`, controlFlags(), sock, generation);
4345
- return;
4346
- }
4347
- this.liveRoutes.delete(stale.channel);
4348
- this.abortHandle(stale);
4349
- await this.opts.onRouteGone?.(stale);
4350
- }
4351
- const tentative = createRouteHandle(boundChannel, boundEpoch, this.connectionToken);
4352
- const bindRequest = {
4353
- handle: tentative,
4354
- target: request.target,
4355
- identity: request.identity,
4356
- principal: request.principal,
4357
- consumer_capabilities: request.consumer_capabilities
4358
- };
4359
- let decision;
4360
- try {
4361
- decision = await this.opts.onBind?.(bindRequest);
4362
- } catch (error2) {
4363
- try {
4364
- await this.sendError(frame, "route_rejected", error2 instanceof Error ? error2.message : String(error2), controlFlags(), sock, generation);
4365
- } finally {
4366
- await this.opts.onRouteGone?.(tentative);
4367
- }
4368
- return;
4369
- }
4370
- const rejection = bindRejection(decision);
4371
- if (rejection) {
4372
- try {
4373
- await this.sendError(frame, rejection.code, rejection.message, controlFlags(), sock, generation);
4374
- } finally {
4375
- await this.opts.onRouteGone?.(tentative);
4376
- }
4377
- return;
4378
- }
4379
- try {
4380
- await this.sendOn(sock, generation, buildFrameWithVersion(frame.header.ver, FrameType.Response, controlFlags(), 0, 0, frame.header.corr, encodeJson({ op: "route.bind" })));
4381
- } catch (error2) {
4382
- await this.opts.onRouteGone?.(tentative);
4383
- throw error2;
4384
- }
4385
- if (this.sock !== sock || this.generation !== generation || this.closeStarted || this.closedErr) {
4386
- await this.opts.onRouteGone?.(tentative);
4387
- return;
4388
- }
4389
- this.liveRoutes.set(tentative.channel, tentative);
4390
- await this.opts.onBound?.(tentative);
4391
- }
4392
- async handleDataRequest(frame, handle, sock, generation) {
4393
- const { corr, ver } = frame.header;
4394
- const key = routeKey(handle, corr);
4395
- const controller = new AbortController;
4396
- this.inflight.set(key, controller);
4397
- const context = {
4398
- handle,
4399
- signal: controller.signal,
4400
- currentEpoch: () => this.connectionEpoch,
4401
- emit: async (eventBody, options = {}) => {
4402
- this.assertLiveHandle(handle);
4403
- if (controller.signal.aborted)
4404
- return;
4405
- await this.sendOn(sock, generation, buildFrameWithVersion(ver, FrameType.StreamData, buildFlags(false, options.priority ?? Priority.Interactive, false, options.admissionClass ?? AdmissionClass.Normal), handle.channel, handle.epoch, corr, eventBody));
4406
- }
4407
- };
4408
- const releasePermit = await (this.requestGate ?? new AsyncPermitPool(DEFAULT_PROVIDER_HANDLER_CAPACITY)).acquire();
4409
- const dataFlags = buildFlags(false, Priority.Interactive, false);
4410
- try {
4411
- const body = await this.opts.handler(handle, frame.body, context);
4412
- if (controller.signal.aborted)
4413
- return;
4414
- this.assertLiveHandle(handle);
4415
- if (body === undefined) {
4416
- await this.sendOn(sock, generation, buildFrameWithVersion(ver, FrameType.StreamEnd, dataFlags, handle.channel, handle.epoch, corr, new Uint8Array(0)));
4417
- } else if (body instanceof Uint8Array) {
4418
- await this.sendOn(sock, generation, buildFrameWithVersion(ver, FrameType.Response, dataFlags, handle.channel, handle.epoch, corr, body));
4419
- } else {
4420
- throw new SubcProviderError("provider handler must return a Uint8Array or void", "invalid_handler_response");
4421
- }
4422
- } catch (error2) {
4423
- if (error2 instanceof StaleRouteHandleError || controller.signal.aborted)
4424
- return;
4425
- await this.sendError(frame, error2 instanceof SubcProviderError && error2.code ? error2.code : "handler_error", error2 instanceof Error ? error2.message : String(error2), dataFlags, sock, generation);
4426
- } finally {
4427
- releasePermit();
4428
- if (this.inflight.get(key) === controller)
4429
- this.inflight.delete(key);
4430
- }
4431
- }
4432
- async handleHealthRequest(frame, sock, generation) {
4433
- const { corr, ver } = frame.header;
4434
- const key = `control:${generation}:${corr}`;
4435
- const controller = new AbortController;
4436
- this.inflight.set(key, controller);
4437
- const releasePermit = await (this.requestGate ?? new AsyncPermitPool(DEFAULT_PROVIDER_HANDLER_CAPACITY)).acquire();
4438
- try {
4439
- if (controller.signal.aborted)
4440
- return;
4441
- const report = await this.opts.health();
4442
- await this.sendOn(sock, generation, buildFrameWithVersion(ver, FrameType.Response, controlFlags(), 0, 0, corr, encodeJson({
4443
- op: HEALTH_CHECK_OP,
4444
- status: report.status,
4445
- ...report.detail === undefined ? {} : { detail: report.detail },
4446
- ...report.metrics === undefined ? {} : { metrics: report.metrics }
4447
- })));
4448
- } catch (error2) {
4449
- await this.sendError(frame, error2 instanceof SubcProviderError && error2.code ? error2.code : "health_error", error2 instanceof Error ? error2.message : String(error2), controlFlags(), sock, generation);
4450
- } finally {
4451
- releasePermit();
4452
- if (this.inflight.get(key) === controller)
4453
- this.inflight.delete(key);
4454
- }
4455
- }
4456
- async sendError(frame, code, message, flags, sock, generation) {
4457
- await this.sendOn(sock, generation, buildFrameWithVersion(frame.header.ver, FrameType.Error, flags, frame.header.channel, frame.header.epoch, frame.header.corr, encodeJson({ code, message })));
4458
- }
4459
- async sendOn(sock, generation, frame) {
4460
- if (this.sock !== sock || this.generation !== generation || this.closeStarted || this.closedErr)
4461
- return;
4462
- await sendFrame(sock, frame);
4463
- }
4464
- handleUnexpectedDrop(sock, generation, cause) {
4465
- if (this.closeStarted || this.sock !== sock || this.generation !== generation)
4466
- return;
4467
- this.cancelRestoredDebounce();
4468
- this.abortGeneration(generation);
4469
- this.generation += 1;
4470
- sock.close();
4471
- this.scheduleReconnectAfterDrop(cause, this.generation, sock);
4472
- }
4473
- scheduleReconnectAfterDrop(cause, generation, droppedSocket) {
4474
- if (this.closeStarted)
4475
- return;
4476
- const previous = this.reconnecting;
4477
- if (previous) {
4478
- if (!this.shouldSupersedeReconnect(previous, generation, droppedSocket))
4479
- return;
4480
- previous.superseded = true;
4481
- previous.socket?.close();
4482
- }
4483
- const cycle = {
4484
- generation,
4485
- socket: null,
4486
- socketDied: false,
4487
- superseded: false
4488
- };
4489
- this.reconnecting = cycle;
4490
- this.enqueueConnectionState({ state: "down", cause });
4491
- this.reconnectWithRetry(cycle).catch((err) => {
4492
- if (this.isCurrentReconnect(cycle) && !this.closeStarted) {
4493
- this.failFatal(err instanceof Error ? err : new SubcProviderError(String(err)));
4494
- }
4495
- }).finally(() => {
4496
- if (this.isCurrentReconnect(cycle))
4497
- this.reconnecting = null;
4498
- });
4499
- }
4500
- async reconnectWithRetry(cycle) {
4501
- let attempt = 0;
4502
- let delay = this.opts.reconnectBackoff.baseMs;
4503
- for (;; ) {
4504
- if (!this.isCurrentReconnect(cycle))
4505
- return;
4506
- if (this.closeStarted)
4507
- throw new SubcProviderError("provider closed");
4508
- cycle.socket = null;
4509
- cycle.socketDied = false;
4510
- attempt += 1;
4511
- this.enqueueReconnectState(cycle, attempt);
4512
- try {
4513
- const opened = await SubcProvider.openConnection(this.opts, (sock) => {
4514
- if (!this.isCurrentReconnect(cycle)) {
4515
- sock.close();
4516
- return;
4517
- }
4518
- cycle.socket = sock;
4519
- });
4520
- if (!this.isCurrentReconnect(cycle) || this.closeStarted) {
4521
- opened.sock.close();
4522
- if (this.closeStarted)
4523
- throw new SubcProviderError("provider closed");
4524
- return;
4525
- }
4526
- const epoch = this.replaceConnection(opened, cycle.generation);
4527
- this.reconnecting = null;
4528
- if (this.reconnecting !== null) {
4529
- throw new SubcProviderError("reconnect state must clear before restored", "reconnect_state");
4530
- }
4531
- this.scheduleRestored(cycle.generation, epoch);
4532
- return;
4533
- } catch (err) {
4534
- if (!this.isCurrentReconnect(cycle))
4535
- return;
4536
- if (cycle.socket)
4537
- cycle.socketDied = true;
4538
- if (this.closeStarted)
4539
- throw err;
4540
- if (!isProviderReconnectTransient(err))
4541
- throw err;
4542
- await this.opts.sleep(delay);
4543
- delay = Math.min(delay * 2, this.opts.reconnectBackoff.capMs);
4544
- }
4545
- }
4546
- }
4547
- isCurrentReconnect(cycle) {
4548
- return !cycle.superseded && this.reconnecting === cycle && this.generation === cycle.generation;
4549
- }
4550
- shouldSupersedeReconnect(cycle, generation, droppedSocket) {
4551
- return cycle.generation < generation || cycle.socketDied || cycle.socket === droppedSocket;
4552
- }
4553
- enqueueReconnectState(cycle, attempt) {
4554
- if (!this.isCurrentReconnect(cycle))
4555
- return;
4556
- this.enqueueConnectionState({ state: "reconnecting", attempt }, cycle.generation, cycle);
4557
- }
4558
- replaceConnection(opened, generation) {
4559
- this.sock.close();
4560
- this.sock = opened.sock;
4561
- this.currentConn = opened.conn;
4562
- this.storage = opened.ack.storage;
4563
- this.closedErr = null;
4564
- this.connectionEpoch += 1;
4565
- this.connectionToken = newConnectionToken();
4566
- this.liveRoutes.clear();
4567
- this.nextCorr = 1n;
4568
- this.readLoop(opened.sock, generation);
4569
- return this.connectionEpoch;
4570
- }
4571
- scheduleRestored(generation, epoch) {
4572
- if (!this.opts.onConnectionState)
4573
- return;
4574
- const token = ++this.restoredDebounceToken;
4575
- this.opts.sleep(this.opts.restoredDebounceMs).then(() => {
4576
- if (token === this.restoredDebounceToken && !this.closeStarted && this.sock && this.generation === generation && this.connectionEpoch === epoch) {
4577
- this.enqueueConnectionState({ state: "restored", epoch }, generation);
4578
- }
4579
- }).catch((err) => {
4580
- if (token === this.restoredDebounceToken && !this.closeStarted) {
4581
- console.warn("SubcProvider restored debounce timer failed", err);
4582
- }
4583
- });
4584
- }
4585
- cancelRestoredDebounce() {
4586
- this.restoredDebounceToken += 1;
4587
- }
4588
- enqueueConnectionState(event, generation, reconnect) {
4589
- if (!this.opts.onConnectionState)
4590
- return;
4591
- this.stateQueue.push({ event, generation, reconnect });
4592
- if (!this.drainingStateQueue)
4593
- this.drainConnectionStateQueue();
4594
- }
4595
- async drainConnectionStateQueue() {
4596
- if (this.drainingStateQueue)
4597
- return;
4598
- this.drainingStateQueue = true;
4599
- try {
4600
- while (this.stateQueue.length > 0) {
4601
- const queued = this.stateQueue[0];
4602
- if (this.closeStarted || queued.generation !== undefined && queued.generation !== this.generation || queued.reconnect?.superseded) {
4603
- this.stateQueue.shift();
4604
- continue;
4605
- }
4606
- const { event } = queued;
4607
- try {
4608
- await this.opts.onConnectionState?.(event);
4609
- this.stateQueue.shift();
4610
- } catch (err) {
4611
- if (event.state === "restored") {
4612
- console.warn("SubcProvider restored callback failed; retrying delivery", err);
4613
- await pauseBeforeStateRetry();
4614
- continue;
4615
- }
4616
- console.warn("SubcProvider connection-state callback failed", err);
4617
- this.stateQueue.shift();
4618
- }
4619
- }
4620
- } finally {
4621
- this.drainingStateQueue = false;
4622
- if (this.stateQueue.length > 0)
4623
- this.drainConnectionStateQueue();
4624
- }
4625
- }
4626
- isLiveHandle(handle) {
4627
- return belongsToConnection(handle, this.connectionToken) && this.liveRoutes.get(handle.channel) === handle;
4628
- }
4629
- assertLiveHandle(handle) {
4630
- if (!this.isLiveHandle(handle))
4631
- throw new StaleRouteHandleError(handle);
4632
- }
4633
- allocateCorr() {
4634
- const maximum = 0xffffffffffffffffn;
4635
- if (this.nextCorr > maximum) {
4636
- const error2 = new SubcProviderError("channel-0 correlation id allocator exhausted", "corr_exhausted");
4637
- this.handleUnexpectedDrop(this.sock, this.generation, error2);
4638
- throw error2;
4639
- }
4640
- const corr = this.nextCorr;
4641
- this.nextCorr += 1n;
4642
- return corr;
4643
- }
4644
- failFatal(err) {
4645
- if (!this.closedErr)
4646
- this.closedErr = err;
4647
- this.closeStarted = true;
4648
- this.cancelRestoredDebounce();
4649
- this.abortAllInflight();
4650
- this.sock.close();
4651
- this.finishClosed();
4652
- }
4653
- finishClosed() {
4654
- this.resolveClosed();
4655
- }
4656
- }
4657
- function routeKey(handle, corr) {
4658
- return `${handle.channel}:${handle.epoch}:${corr}`;
4659
- }
4660
- function providerErrorFromFrame(frame) {
4661
- try {
4662
- const body = parseJson(frame.body);
4663
- return new SubcProviderError(body.message ?? "subc error", body.code);
4664
- } catch {
4665
- return new SubcProviderError(Buffer2.from(frame.body).toString("utf8") || "subc error");
4666
- }
4667
- }
4668
- function launchNonce(opts) {
4669
- const nonce = opts.launchNonce ?? process.env[SUBC_LAUNCH_NONCE_ENV2];
4670
- return nonce && nonce.length > 0 ? nonce : undefined;
4671
- }
4672
- function normalizeProviderConnectOptions(opts) {
4673
- return {
4674
- connectionFile: opts.connectionFile,
4675
- manifest: opts.manifest,
4676
- handler: opts.handler,
4677
- health: opts.health ?? (() => ({ status: "ok" })),
4678
- handshakeTimeoutMs: opts.handshakeTimeoutMs,
4679
- controlOps: opts.controlOps,
4680
- onBind: opts.onBind,
4681
- onBound: opts.onBound,
4682
- onRouteGone: opts.onRouteGone,
4683
- reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
4684
- sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
4685
- restoredDebounceMs: opts.restoredDebounceMs ?? DEFAULT_RESTORED_DEBOUNCE_MS,
4686
- onConnectionState: opts.onConnectionState,
4687
- launchNonce: opts.launchNonce
4688
- };
4689
- }
4690
- function normalizedControlOps(controlOps) {
4691
- if (controlOps === null)
4692
- return null;
4693
- const merged = new Set(controlOps ?? []);
4694
- merged.add(HEALTH_CHECK_OP);
4695
- return [...merged];
4696
- }
4697
- function buildHelloFrame(opts) {
4698
- const nonce = launchNonce(opts);
4699
- return buildFrame(FrameType.Hello, controlFlags(), 0, 0, HELLO_CORR, encodeJson({
4700
- manifest: normalizeManifest(opts.manifest),
4701
- protocol_ver: PROTOCOL_VERSION,
4702
- control_ops: normalizedControlOps(opts.controlOps),
4703
- ...nonce ? { launch_nonce: nonce } : {}
4704
- }));
4705
- }
4706
- function isProviderReconnectTransient(err) {
4707
- if (err instanceof SubcProviderError)
4708
- return err.code === "duplicate_module_id";
4709
- if (err instanceof SocketClosedError || err instanceof SocketTimeoutError)
4710
- return true;
4711
- if (err instanceof SocketWriteNotQueuedError || err instanceof SocketWriteQueuedError)
4712
- return true;
4713
- if (err instanceof AuthError)
4714
- return true;
4715
- if (err instanceof ConnectionFileError)
4716
- return false;
4717
- const code = errorCode2(err);
4718
- return code === "ECONNREFUSED" || code === "ECONNRESET" || code === "EPIPE" || code === "ETIMEDOUT" || code === "ENOENT";
4719
- }
4720
- function errorCode2(err) {
4721
- if (typeof err === "object" && err !== null && "code" in err) {
4722
- const code = err.code;
4723
- if (typeof code === "string")
4724
- return code;
4725
- }
4726
- return;
4727
- }
4728
- async function pauseBeforeStateRetry() {
4729
- await new Promise((resolve3) => setTimeout(resolve3, 0));
4730
- }
4731
- function controlFlags() {
4732
- return buildFlags(false, Priority.Passive, false);
4733
- }
4734
- async function sendFrame(sock, frame) {
4735
- await sock.write(encodeFrame(frame), Date.now() + WRITE_TIMEOUT_MS);
4736
- }
4737
- async function expectHelloAck(sock, deadline) {
4738
- const frame = await sock.readFrame(deadline, deadline);
4739
- switch (frame.header.ty) {
4740
- case FrameType.HelloAck: {
4741
- const ack = parseJson(frame.body);
4742
- if (ack.negotiated_ver !== PROTOCOL_VERSION) {
4743
- throw new SubcProviderError(`subc negotiated protocol ${ack.negotiated_ver}; expected exactly ${PROTOCOL_VERSION}`, "unsupported_version");
4744
- }
4745
- return ack;
4746
- }
4747
- case FrameType.Error: {
4748
- const error2 = parseJson(frame.body);
4749
- throw new SubcProviderError(`subc rejected HELLO: ${error2.code ?? "unknown"} — ${error2.message ?? "subc error"}`, error2.code);
4750
- }
4751
- default:
4752
- throw new SubcProviderError(`unexpected frame ${FrameType[frame.header.ty]} awaiting HELLO_ACK`);
4753
- }
4754
- }
4755
- function encodeJson(value) {
4756
- return new Uint8Array(Buffer2.from(JSON.stringify(value), "utf8"));
4757
- }
4758
- function parseJson(bytes) {
4759
- return JSON.parse(Buffer2.from(bytes).toString("utf8"));
4760
- }
4761
- function numberField(value, field) {
4762
- if (typeof value !== "number" || !Number.isInteger(value)) {
4763
- throw new SubcProviderError(`route.bind ${field} must be an integer`);
4764
- }
4765
- return value;
4766
- }
4767
- function bindRejection(decision) {
4768
- if (decision === undefined || decision === true)
4769
- return null;
4770
- if (decision === false) {
4771
- return { code: "route_rejected", message: "route.bind rejected by provider" };
4772
- }
4773
- if (decision.accept)
4774
- return null;
4775
- return {
4776
- code: decision.code ?? "route_rejected",
4777
- message: decision.message ?? "route.bind rejected by provider"
4778
- };
4779
- }
4780
- function normalizeManifest(manifest) {
4781
- return {
4782
- module_id: manifest.module_id,
4783
- module_version: manifest.module_version,
4784
- protocol_ver: manifest.protocol_ver,
4785
- trust_tier: manifest.trust_tier,
4786
- provides: manifest.provides.map(normalizeProviderRole),
4787
- consumes: manifest.consumes.map(normalizeConsumerRole),
4788
- scheduled_tasks: manifest.scheduled_tasks.map(normalizeScheduledTask),
4789
- bindings: {
4790
- storage: {
4791
- kind: manifest.bindings.storage.kind,
4792
- scope: manifest.bindings.storage.scope,
4793
- owns_schema: manifest.bindings.storage.owns_schema
4794
- },
4795
- vault_grants: manifest.bindings.vault_grants.map((grant) => ({
4796
- secret: grant.secret,
4797
- reason: grant.reason
4798
- })),
4799
- identity: {
4800
- requires: [...manifest.bindings.identity.requires],
4801
- optional: [...manifest.bindings.identity.optional]
4802
- }
4803
- }
4153
+ timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS,
4154
+ livenessProbeWindowMs: opts.livenessProbeWindowMs ?? LIVENESS_PROBE_WINDOW_MS,
4155
+ onControlPush: opts.onControlPush
4804
4156
  };
4805
4157
  }
4806
- function normalizeProviderRole(role) {
4807
- switch (role.role) {
4808
- case "tool_provider":
4809
- return {
4810
- role: "tool_provider",
4811
- tools: role.tools.map((tool) => ({
4812
- name: tool.name,
4813
- ...tool.description === undefined ? {} : { description: tool.description },
4814
- execution_mode: tool.execution_mode,
4815
- schema: tool.schema
4816
- })),
4817
- identity_scope: [...role.identity_scope],
4818
- concurrency: role.concurrency,
4819
- emits_push: role.emits_push,
4820
- sub_supervises: role.sub_supervises
4821
- };
4822
- case "pipeline_stage":
4823
- return {
4824
- role: "pipeline_stage",
4825
- stage: role.stage,
4826
- applies_to: {
4827
- provider: role.applies_to.provider,
4828
- model: role.applies_to.model
4829
- },
4830
- interface: role.interface,
4831
- declares_frozen_floor: role.declares_frozen_floor,
4832
- needs_signals: [...role.needs_signals],
4833
- conformance_class: role.conformance_class
4834
- };
4835
- case "management_surface":
4836
- return {
4837
- role: "management_surface",
4838
- operations: role.operations.map((operation) => ({
4839
- name: operation.name,
4840
- kind: operation.kind
4841
- })),
4842
- config_schema: role.config_schema,
4843
- observability: role.observability.map((surface) => ({
4844
- name: surface.name,
4845
- kind: surface.kind
4846
- })),
4847
- identity_scope: [...role.identity_scope]
4848
- };
4849
- case "internal_service":
4850
- return {
4851
- role: "internal_service",
4852
- service_id: role.service_id,
4853
- transport: role.transport,
4854
- agent_facing: role.agent_facing,
4855
- operations: [...role.operations]
4856
- };
4857
- }
4158
+ function routeCacheKey(target, identity, consumerIdentity) {
4159
+ const consumerPart = consumerIdentity ? `${consumerIdentity.module_id}\x00${consumerIdentity.launch_nonce}` : "";
4160
+ return `${target.kind}\x00${target.module_id}\x00${identity.project_root}\x00${identity.harness}\x00${identity.session}\x00${consumerPart}`;
4161
+ }
4162
+ function routeOpenConsumerIdentity(opts = {}) {
4163
+ if (opts.consumerIdentity !== undefined)
4164
+ return opts.consumerIdentity ?? undefined;
4165
+ const moduleId = process.env[SUBC_MODULE_ID_ENV];
4166
+ const launchNonce = process.env[SUBC_LAUNCH_NONCE_ENV];
4167
+ if (!moduleId || !launchNonce)
4168
+ return;
4169
+ return { module_id: moduleId, launch_nonce: launchNonce };
4858
4170
  }
4859
- function normalizeConsumerRole(role) {
4860
- switch (role.role) {
4861
- case "tool_client":
4862
- return { role: "tool_client", of: [...role.of] };
4863
- case "llm_client":
4864
- return { role: "llm_client", via: role.via, auth: role.auth };
4865
- case "service_client":
4866
- return { role: "service_client", of: [...role.of] };
4171
+ function errorCode(err) {
4172
+ if (typeof err === "object" && err !== null && "code" in err) {
4173
+ const code = err.code;
4174
+ if (typeof code === "string")
4175
+ return code;
4867
4176
  }
4177
+ return;
4868
4178
  }
4869
- function normalizeScheduledTask(task) {
4870
- return {
4871
- task_id: task.task_id,
4872
- eligibility: {
4873
- cooldown: task.eligibility.cooldown,
4874
- window: task.eligibility.window
4875
- },
4876
- lease_scope: task.lease_scope,
4877
- renews_during_calls: task.renews_during_calls,
4878
- toolset: [...task.toolset],
4879
- model_policy: {
4880
- tier: task.model_policy.tier,
4881
- fallback_chain: [...task.model_policy.fallback_chain]
4882
- },
4883
- step_cap: task.step_cap,
4884
- circuit_breaker: {
4885
- identical_failures: task.circuit_breaker.identical_failures
4886
- }
4887
- };
4179
+ function causeMessage(cause) {
4180
+ if (cause === undefined)
4181
+ return "";
4182
+ return `: ${cause instanceof Error ? cause.message : String(cause)}`;
4888
4183
  }
4889
- var DEFAULT_HANDSHAKE_TIMEOUT_MS2 = 1e4, BODY_READ_TIMEOUT_MS2 = 30000, WRITE_TIMEOUT_MS = 30000, DEFAULT_RESTORED_DEBOUNCE_MS = 250, DEFAULT_PROVIDER_HANDLER_CAPACITY = 64, HEALTH_CHECK_OP = "health.check", HELLO_CORR = 1n, SubcProviderError, SUBC_LAUNCH_NONCE_ENV2 = "SUBC_LAUNCH_NONCE";
4890
- var init_provider = __esm(() => {
4184
+ function pendingKey(handle, corr) {
4185
+ return handle ? `${handle.channel}:${handle.epoch}:${corr}` : `0:0:${corr}`;
4186
+ }
4187
+ var debug, DEFAULT_HANDSHAKE_TIMEOUT_MS = 1e4, DEFAULT_REQUEST_TIMEOUT_MS = 30000, TIMEOUT_ARBITRATION_GRACE_MS = 50, LIVENESS_PROBE_WINDOW_MS = 2000, REQUEST_DEADLINE_MARKER = "request_deadline", DEADLINE_NO_DROP_CODE = "deadline_exceeded_no_drop_observed", ROUTE_OPEN_RETRY_DEADLINE_MS = 30000, BODY_READ_TIMEOUT_MS = 30000, EMPTY_BODY, DEFAULT_MANAGED_TARGET_KIND = "management_surface", SUBC_MODULE_ID_ENV = "SUBC_MODULE_ID", SUBC_LAUNCH_NONCE_ENV = "SUBC_LAUNCH_NONCE", DEFAULT_RECONNECT_BACKOFF, SubcCallError, SubcError;
4188
+ var init_client = __esm(() => {
4891
4189
  init_auth();
4892
- init_client();
4893
4190
  init_connection_file();
4894
4191
  init_envelope();
4895
4192
  init_route_handle();
4896
4193
  init_socket();
4897
- SubcProviderError = class SubcProviderError extends Error {
4194
+ debug = debuglog("subc-client");
4195
+ EMPTY_BODY = new Uint8Array(0);
4196
+ DEFAULT_RECONNECT_BACKOFF = {
4197
+ baseMs: 100,
4198
+ capMs: 2000,
4199
+ maxAttempts: 6
4200
+ };
4201
+ SubcCallError = class SubcCallError extends Error {
4202
+ kind;
4203
+ code;
4204
+ cause;
4205
+ constructor(kind, message, code, cause) {
4206
+ super(message);
4207
+ this.kind = kind;
4208
+ this.code = code;
4209
+ this.cause = cause;
4210
+ this.name = "SubcCallError";
4211
+ }
4212
+ };
4213
+ SubcError = class SubcError extends Error {
4898
4214
  code;
4899
4215
  constructor(message, code) {
4900
4216
  super(message);
@@ -4903,7 +4219,17 @@ var init_provider = __esm(() => {
4903
4219
  };
4904
4220
  });
4905
4221
 
4906
- // ../../node_modules/.bun/@cortexkit+subc-client@0.5.0/node_modules/@cortexkit/subc-client/dist/index.js
4222
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.8.1/node_modules/@cortexkit/subc-client/dist/provider.js
4223
+ var init_provider = __esm(() => {
4224
+ init_auth();
4225
+ init_client();
4226
+ init_connection_file();
4227
+ init_envelope();
4228
+ init_route_handle();
4229
+ init_socket();
4230
+ });
4231
+
4232
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.8.1/node_modules/@cortexkit/subc-client/dist/index.js
4907
4233
  var init_dist = __esm(() => {
4908
4234
  init_client();
4909
4235
  init_route_handle();
@@ -5373,6 +4699,9 @@ var init_project_identity = () => {};
5373
4699
 
5374
4700
  // ../aft-bridge/dist/subc-transport.js
5375
4701
  import { existsSync as existsSync3, statSync as statSync3 } from "node:fs";
4702
+ function reconnectBackoffMs(attempt) {
4703
+ return Math.min(RECONNECT_RETRY_FLOOR_MS * 2 ** Math.min(attempt, 6), RECONNECT_RETRY_CAP_MS);
4704
+ }
5376
4705
  function identityKey(identity) {
5377
4706
  return `${identity.project_root}\x00${identity.harness}\x00${identity.session}`;
5378
4707
  }
@@ -5586,6 +4915,8 @@ class BgSubscription {
5586
4915
  giveUp("stopped");
5587
4916
  return;
5588
4917
  }
4918
+ if (Date.now() - subscribedAt >= BG_STABLE_MS)
4919
+ backoffAttempt = 0;
5589
4920
  beginReconnect();
5590
4921
  } catch (err) {
5591
4922
  const routeId2 = this.routeId(route);
@@ -5610,8 +4941,7 @@ class BgSubscription {
5610
4941
  giveUp("stopped");
5611
4942
  }
5612
4943
  async backoff(attempt) {
5613
- const ms = Math.min(100 * 2 ** Math.min(attempt, 6), 2000);
5614
- await this.sleep(ms);
4944
+ await this.sleep(reconnectBackoffMs(attempt));
5615
4945
  }
5616
4946
  }
5617
4947
  function isRecord(value) {
@@ -5626,6 +4956,15 @@ function isAbsentRootRouteError(err) {
5626
4956
  function absentRootError(root) {
5627
4957
  return new SubcError(`invalid route project root: project root does not exist: ${root}`, "config_divergence");
5628
4958
  }
4959
+ function reloadWindowExhaustedError(error2) {
4960
+ if (error2 instanceof Error) {
4961
+ try {
4962
+ error2.message += ROUTE_OPEN_RELOAD_WAIT_EXHAUSTED_SUFFIX;
4963
+ return error2;
4964
+ } catch {}
4965
+ }
4966
+ return new Error(`${String(error2)}${ROUTE_OPEN_RELOAD_WAIT_EXHAUSTED_SUFFIX}`);
4967
+ }
5629
4968
  function safeCloseRoute(client, route) {
5630
4969
  try {
5631
4970
  client.closeRouteChannel(route).catch(() => {
@@ -5734,6 +5073,7 @@ class SubcTransportPool {
5734
5073
  onBgEventsNudge;
5735
5074
  onBgEventsNudgeRef;
5736
5075
  bgBackoffSleep;
5076
+ routeRetrySleep;
5737
5077
  bgDispatchProbeIntervalMs;
5738
5078
  lifecycleDemandCheck;
5739
5079
  onLifecycleEvent;
@@ -5744,6 +5084,9 @@ class SubcTransportPool {
5744
5084
  outerFacadeEvictor;
5745
5085
  client = null;
5746
5086
  connecting = null;
5087
+ routeReopenRetryDelayMs = RECONNECT_RETRY_FLOOR_MS;
5088
+ routeReopenRetry = null;
5089
+ routeReopenRetryMs = null;
5747
5090
  sessions = new Map;
5748
5091
  rootIndex = new Map;
5749
5092
  dormantRoots = new Map;
@@ -5764,6 +5107,7 @@ class SubcTransportPool {
5764
5107
  this.onBgEventsNudge = options.onBgEventsNudge;
5765
5108
  this.onBgEventsNudgeRef = options.onBgEventsNudgeRef;
5766
5109
  this.bgBackoffSleep = options.bgBackoffSleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
5110
+ this.routeRetrySleep = options.routeRetrySleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
5767
5111
  this.bgDispatchProbeIntervalMs = options.bgDispatchProbeIntervalMs ?? BG_DISPATCH_PROBE_INTERVAL_MS;
5768
5112
  const lifecycle = options.lifecycle;
5769
5113
  const demandCheck = options.lifecycleDemandCheck ?? options.demandCheck ?? lifecycle?.demandCheck;
@@ -6216,6 +5560,23 @@ class SubcTransportPool {
6216
5560
  throw error2;
6217
5561
  }
6218
5562
  };
5563
+ const openRouteAfterReloadWindow = async () => {
5564
+ let reloadWaitedMs = 0;
5565
+ while (true) {
5566
+ try {
5567
+ return await openRoute();
5568
+ } catch (error2) {
5569
+ if (!isRouteOpenReloadWindowError(error2))
5570
+ throw error2;
5571
+ const { delayMs, wait } = this.waitForRouteReopenBackoff();
5572
+ if (reloadWaitedMs + delayMs > ROUTE_OPEN_RELOAD_WAIT_CAP_MS) {
5573
+ throw reloadWindowExhaustedError(error2);
5574
+ }
5575
+ reloadWaitedMs += delayMs;
5576
+ await wait;
5577
+ }
5578
+ }
5579
+ };
6219
5580
  const clearRouteEntry = (entry) => {
6220
5581
  if (record.routeEntry !== entry)
6221
5582
  return;
@@ -6252,7 +5613,7 @@ class SubcTransportPool {
6252
5613
  this.ensureBgSubscription(identity, record);
6253
5614
  return reply;
6254
5615
  };
6255
- let routeAndEntry = await openRoute();
5616
+ let routeAndEntry = await openRouteAfterReloadWindow();
6256
5617
  try {
6257
5618
  return await requestOnRoute(routeAndEntry.route);
6258
5619
  } catch (error2) {
@@ -6260,9 +5621,12 @@ class SubcTransportPool {
6260
5621
  throw this.annotateReapError(error2, record);
6261
5622
  if (isRouteProvenAbsentError(error2) && this.isCurrentSession(key, record) && this.client === client) {
6262
5623
  clearRouteEntry(routeAndEntry.entry);
6263
- routeAndEntry = await openRoute();
5624
+ await this.waitForRouteReopenBackoff().wait;
5625
+ routeAndEntry = await openRouteAfterReloadWindow();
6264
5626
  try {
6265
- return await requestOnRoute(routeAndEntry.route);
5627
+ const reply = await requestOnRoute(routeAndEntry.route);
5628
+ this.resetRouteReopenBackoff();
5629
+ return reply;
6266
5630
  } catch (retryError) {
6267
5631
  if (this.isReapInduced(record))
6268
5632
  throw this.annotateReapError(retryError, record);
@@ -6282,6 +5646,27 @@ class SubcTransportPool {
6282
5646
  this.deleteSessionIfEmpty(key, record);
6283
5647
  }
6284
5648
  }
5649
+ waitForRouteReopenBackoff() {
5650
+ const pending = this.routeReopenRetry;
5651
+ const pendingDelay = this.routeReopenRetryMs;
5652
+ if (pending && pendingDelay !== null)
5653
+ return { delayMs: pendingDelay, wait: pending };
5654
+ const delayMs = this.routeReopenRetryDelayMs;
5655
+ this.routeReopenRetryDelayMs = Math.min(delayMs * 2, RECONNECT_RETRY_CAP_MS);
5656
+ let retry;
5657
+ retry = Promise.resolve().then(() => this.routeRetrySleep(delayMs)).finally(() => {
5658
+ if (this.routeReopenRetry === retry) {
5659
+ this.routeReopenRetry = null;
5660
+ this.routeReopenRetryMs = null;
5661
+ }
5662
+ });
5663
+ this.routeReopenRetry = retry;
5664
+ this.routeReopenRetryMs = delayMs;
5665
+ return { delayMs, wait: retry };
5666
+ }
5667
+ resetRouteReopenBackoff() {
5668
+ this.routeReopenRetryDelayMs = RECONNECT_RETRY_FLOOR_MS;
5669
+ }
6285
5670
  async ensureClient() {
6286
5671
  if (this.shuttingDown)
6287
5672
  throw new SubcTransportShuttingDownError;
@@ -6535,10 +5920,11 @@ function resolveBridgeForNudge(pool, ref) {
6535
5920
  currentConcretePoolId: candidate.getConcretePoolId?.()
6536
5921
  });
6537
5922
  }
6538
- var SubcTransportShuttingDownError, AFT_MODULE_ID = "aft", MAX_CONSECUTIVE_TRANSPORT_FAILURES = 3, BG_STABLE_MS = 5000, BG_LIFECYCLE_LOG_INTERVAL_MS = 60000, BG_DISPATCH_PROBE_INTERVAL_MS = 60000, DEFAULT_SESSION_ID = "__default__", LOCALLY_SATISFIED_COMMANDS, SubcRootReapedError, SubcRootGenerationExpiredError, SubcRootDemandRequiredError, RouteTornDownError;
5923
+ var SubcTransportShuttingDownError, AFT_MODULE_ID = "aft", MAX_CONSECUTIVE_TRANSPORT_FAILURES = 3, RECONNECT_RETRY_FLOOR_MS = 100, RECONNECT_RETRY_CAP_MS = 2000, ROUTE_OPEN_RELOAD_WAIT_CAP_MS = 15000, ROUTE_OPEN_RELOAD_WAIT_EXHAUSTED_SUFFIX = " The AFT daemon module did not return within the 15s reload window.", BG_STABLE_MS = 5000, BG_LIFECYCLE_LOG_INTERVAL_MS = 60000, BG_DISPATCH_PROBE_INTERVAL_MS = 60000, DEFAULT_SESSION_ID = "__default__", LOCALLY_SATISFIED_COMMANDS, SubcRootReapedError, SubcRootGenerationExpiredError, SubcRootDemandRequiredError, RouteTornDownError;
6539
5924
  var init_subc_transport = __esm(() => {
6540
5925
  init_dist();
6541
5926
  init_active_logger();
5927
+ init_error_contract();
6542
5928
  init_lifecycle_registry();
6543
5929
  init_project_identity();
6544
5930
  SubcTransportShuttingDownError = class SubcTransportShuttingDownError extends SubcCallError {
@@ -6609,6 +5995,12 @@ function isRouteGoodbyeError(error2) {
6609
5995
  }
6610
5996
  return error2.code === "route_closed" && error2.message.includes("route closed by subc");
6611
5997
  }
5998
+ function isRouteOpenReloadWindowError(error2) {
5999
+ if (error2 === null || typeof error2 !== "object")
6000
+ return false;
6001
+ const code = error2.code;
6002
+ return code === "module_reloading" || code === "module_warming" || code === "target_unavailable";
6003
+ }
6612
6004
  function hasEngineResponse(error2) {
6613
6005
  const response = error2.response;
6614
6006
  if (response !== null && typeof response === "object")
@@ -6967,7 +6359,16 @@ function platformKey(platform = process.platform, arch = process.arch) {
6967
6359
  }
6968
6360
  return key;
6969
6361
  }
6362
+ function logBinaryResolution(resolution) {
6363
+ log(`Resolved binary from ${resolution.source}: ${resolution.path}`);
6364
+ }
6970
6365
  function findBinarySync(expectedVersion) {
6366
+ const resolution = findBinarySyncInner(expectedVersion);
6367
+ if (resolution)
6368
+ logBinaryResolution(resolution);
6369
+ return resolution?.path ?? null;
6370
+ }
6371
+ function findBinarySyncInner(expectedVersion) {
6971
6372
  const ext = process.platform === "win32" ? ".exe" : "";
6972
6373
  const env = { ...process.env };
6973
6374
  const pluginVersion = expectedVersion ?? (() => {
@@ -6981,8 +6382,9 @@ function findBinarySync(expectedVersion) {
6981
6382
  if (pluginVersion) {
6982
6383
  const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
6983
6384
  const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
6984
- if (versionCached && isExpectedCachedBinary2(versionCached, pluginVersion))
6985
- return versionCached;
6385
+ if (versionCached && isExpectedCachedBinary2(versionCached, pluginVersion)) {
6386
+ return { path: versionCached, source: "versioned cache" };
6387
+ }
6986
6388
  }
6987
6389
  try {
6988
6390
  const key = platformKey();
@@ -6997,7 +6399,7 @@ function findBinarySync(expectedVersion) {
6997
6399
  warn(`npm platform package binary v${npmVersion} does not match plugin v${pluginVersion}; skipping (continuing to PATH lookup)`);
6998
6400
  } else {
6999
6401
  const copied = copyToVersionedCache(resolved, npmVersion);
7000
- return copied ?? resolved;
6402
+ return { path: copied ?? resolved, source: "npm platform package" };
7001
6403
  }
7002
6404
  }
7003
6405
  } catch {}
@@ -7015,27 +6417,28 @@ function findBinarySync(expectedVersion) {
7015
6417
  }
7016
6418
  const usable = probeBinaryCandidate(candidate, "PATH", expectedVersion);
7017
6419
  if (usable)
7018
- return usable;
6420
+ return { path: usable, source: "PATH" };
7019
6421
  }
7020
6422
  } catch {}
7021
6423
  const cargoPath = join7(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
7022
6424
  if (existsSync5(cargoPath)) {
7023
6425
  const usable = probeBinaryCandidate(cargoPath, "cargo", expectedVersion);
7024
6426
  if (usable)
7025
- return usable;
6427
+ return { path: usable, source: "cargo" };
7026
6428
  }
7027
6429
  return null;
7028
6430
  }
7029
6431
  async function findBinary(expectedVersion) {
7030
6432
  const syncResult = findBinarySync(expectedVersion);
7031
6433
  if (syncResult) {
7032
- log(`Resolved binary: ${syncResult}`);
7033
6434
  return syncResult;
7034
6435
  }
7035
6436
  log("Binary not found locally, attempting auto-download...");
7036
6437
  const downloaded = await ensureBinaryForResolver(expectedVersion);
7037
- if (downloaded)
6438
+ if (downloaded) {
6439
+ logBinaryResolution({ path: downloaded, source: "auto-download" });
7038
6440
  return downloaded;
6441
+ }
7039
6442
  throw new Error([
7040
6443
  "Could not find the `aft` binary.",
7041
6444
  "",
@@ -9184,6 +8587,8 @@ class RevivableTransportPool {
9184
8587
  onBinaryReplaced;
9185
8588
  activePool;
9186
8589
  revival = null;
8590
+ revivalRetryDelayMs = REVIVAL_RETRY_FLOOR_MS;
8591
+ revivalRetryNotBefore = 0;
9187
8592
  transports = new Map;
9188
8593
  configureOverrides = new Map;
9189
8594
  editSlotSurvivesCaptured = false;
@@ -9277,12 +8682,30 @@ class RevivableTransportPool {
9277
8682
  return this.activePool;
9278
8683
  if (this.revival)
9279
8684
  return this.revival;
8685
+ const delay = Math.max(0, this.revivalRetryNotBefore - Date.now());
8686
+ if (delay > 0) {
8687
+ let scheduled;
8688
+ scheduled = new Promise((resolve7) => setTimeout(resolve7, delay)).then(() => {
8689
+ if (this.revival === scheduled)
8690
+ this.revival = null;
8691
+ return this.ensureActivePool();
8692
+ });
8693
+ this.revival = scheduled;
8694
+ scheduled.then(() => {
8695
+ return;
8696
+ }, () => {
8697
+ return;
8698
+ });
8699
+ return scheduled;
8700
+ }
9280
8701
  warn("transport was shut down but new demand arrived — reviving (host quit hook fired without process exit?)");
9281
- const revival = this.createPool().then((pool) => {
8702
+ const revival = Promise.resolve().then(() => this.createPool()).then((pool) => {
9282
8703
  for (const [key, value] of this.configureOverrides) {
9283
8704
  pool.setConfigureOverride(key, value);
9284
8705
  }
9285
8706
  this.activePool = pool;
8707
+ this.revivalRetryDelayMs = REVIVAL_RETRY_FLOOR_MS;
8708
+ this.revivalRetryNotBefore = 0;
9286
8709
  for (const [root, transport] of this.transports) {
9287
8710
  transport.refreshStatusSubscription(pool.getActiveBridgeForRoot(root));
9288
8711
  }
@@ -9293,6 +8716,8 @@ class RevivableTransportPool {
9293
8716
  if (this.revival === revival)
9294
8717
  this.revival = null;
9295
8718
  }, () => {
8719
+ this.revivalRetryNotBefore = Date.now() + this.revivalRetryDelayMs;
8720
+ this.revivalRetryDelayMs = Math.min(this.revivalRetryDelayMs * 2, REVIVAL_RETRY_CAP_MS);
9296
8721
  if (this.revival === revival)
9297
8722
  this.revival = null;
9298
8723
  });
@@ -9386,6 +8811,7 @@ class RevivableProjectTransport {
9386
8811
  unsubscribe?.();
9387
8812
  }
9388
8813
  }
8814
+ var REVIVAL_RETRY_FLOOR_MS = 100, REVIVAL_RETRY_CAP_MS = 2000;
9389
8815
  var init_revivable_transport = __esm(() => {
9390
8816
  init_active_logger();
9391
8817
  init_project_identity();
@@ -9684,117 +9110,117 @@ function unwrapRustZoomBatchEnvelope(response) {
9684
9110
  // ../aft-bridge/dist/index.js
9685
9111
  var exports_dist = {};
9686
9112
  __export(exports_dist, {
9687
- unwrapRustZoomBatchEnvelope: () => unwrapRustZoomBatchEnvelope,
9688
- toolErrorFromResponse: () => toolErrorFromResponse,
9689
- timeoutForCommand: () => timeoutForCommand,
9690
- tagStderrLine: () => tagStderrLine,
9691
- stripJsoncSymbols: () => stripJsoncSymbols,
9692
- stripHarnessSpecificConfigKeys: () => stripHarnessSpecificConfigKeys,
9693
- sleep: () => sleep,
9694
- shouldShowAnnouncement: () => shouldShowAnnouncement,
9695
- setActiveLogger: () => setActiveLogger,
9696
- runBashHostFallback: () => runBashHostFallback,
9697
- resolveNpm: () => resolveNpm,
9698
- resolveLegacyStorageRoot: () => resolveLegacyStorageRoot,
9699
- resolveLegacyAftConfigSources: () => resolveLegacyAftConfigSources,
9700
- resolveHarnessStoragePath: () => resolveHarnessStoragePath,
9701
- resolveCortexKitUserConfigPath: () => resolveCortexKitUserConfigPath,
9702
- resolveCortexKitStorageRoot: () => resolveCortexKitStorageRoot,
9703
- resolveCortexKitProjectConfigPath: () => resolveCortexKitProjectConfigPath,
9704
- resolveCortexKitConfigPaths: () => resolveCortexKitConfigPaths,
9705
- resolveBridgeForNudge: () => resolveBridgeForNudge,
9706
- resolveBashKillTimeout: () => resolveBashKillTimeout,
9707
- resolveAftStorageRoot: () => resolveAftStorageRoot,
9708
- resolveAftLogPath: () => resolveAftLogPath,
9709
- repairRootScopedStorageFile: () => repairRootScopedStorageFile,
9710
- readConfigTiers: () => readConfigTiers,
9711
- projectRootKeyHash: () => projectRootKeyHash,
9712
- probeNpmVersion: () => probeNpmVersion,
9713
- prepareCanonicalPathArguments: () => prepareCanonicalPathArguments,
9714
- prepareCanonicalEditArguments: () => prepareCanonicalEditArguments,
9715
- platformKey: () => platformKey,
9716
- npmSpawnEnv: () => npmSpawnEnv,
9717
- migrateAftConfigFile: () => migrateAftConfigFile,
9718
- maybeAppendGrepSearchHint: () => maybeAppendGrepSearchHint,
9719
- maybeAppendConflictsHint: () => maybeAppendConflictsHint,
9720
- markAnnouncementSeen: () => markAnnouncementSeen,
9721
- isWellFormedUnicodeString: () => isWellFormedUnicodeString,
9722
- isTerminalStatus: () => isTerminalStatus,
9723
- isRustZoomBatchEnvelope: () => isRustZoomBatchEnvelope,
9724
- isOrtAutoDownloadSupported: () => isOrtAutoDownloadSupported,
9725
- isNpmAvailable: () => isNpmAvailable,
9726
- isNativeExecutable: () => isNativeExecutable,
9727
- isHomeDirectoryRoot: () => isHomeDirectoryRoot,
9728
- isEmptyParam: () => isEmptyParam,
9729
- isBridgeTransportTimeout: () => isBridgeTransportTimeout,
9730
- isBashTransportDeadError: () => isBashTransportDeadError,
9731
- inlineUserConfigTier: () => inlineUserConfigTier,
9732
- getMigrationStatus: () => getMigrationStatus,
9733
- getManualInstallHint: () => getManualInstallHint,
9734
- getCachedBinaryPath: () => getCachedBinaryPath,
9735
- getCacheDir: () => getAftBinaryCacheDir,
9736
- getBinaryName: () => getBinaryName,
9737
- getAftLspPackagesDir: () => getAftLspPackagesDir,
9738
- getAftLspBinariesDir: () => getAftLspBinariesDir,
9739
- getAftCacheRoot: () => getAftCacheRoot,
9740
- getAftBinaryCacheDir: () => getAftBinaryCacheDir,
9741
- formatZoomText: () => formatZoomText,
9742
- formatZoomMultiTargetResult: () => formatZoomMultiTargetResult,
9743
- formatTokenCount: () => formatTokenCount,
9744
- formatSeconds: () => formatSeconds,
9745
- formatReadFooter: () => formatReadFooter,
9746
- formatForegroundResult: () => formatForegroundResult,
9747
- formatEditSummary: () => formatEditSummary,
9748
- formatDroppedKeyWarnings: () => formatDroppedKeyWarnings,
9749
- formatCallgraphSections: () => formatCallgraphSections,
9750
- formatBridgeErrorMessage: () => formatBridgeErrorMessage,
9751
- findBinarySync: () => findBinarySync,
9752
- findBinary: () => findBinary,
9753
- ensureStorageMigrated: () => ensureStorageMigrated,
9754
- ensureOnnxRuntime: () => ensureOnnxRuntime,
9755
- ensureBinary: () => ensureBinary,
9756
- downloadBinary: () => downloadBinary,
9757
- decodeFileUrl: () => decodeFileUrl,
9758
- createAftTransportPool: () => createAftTransportPool,
9759
- compressionSavingsPercent: () => compressionSavingsPercent,
9760
- compareSemver: () => compareSemver,
9761
- commandInvokesCodeSearch: () => commandInvokesCodeSearch,
9762
- coerceTargetParam: () => coerceTargetParam,
9763
- coerceStringArray: () => coerceStringArray,
9764
- coerceOptionalInt: () => coerceOptionalInt,
9765
- coerceBoolean: () => coerceBoolean,
9766
- coerceAliasedStringParam: () => coerceAliasedStringParam,
9767
- cleanupOnnxRuntime: () => cleanupOnnxRuntime,
9768
- canonicalizeProjectRoot: () => canonicalizeProjectRoot,
9769
- bashHostFallbackAskPattern: () => bashHostFallbackAskPattern,
9770
- adaptToolError: () => adaptToolError,
9771
- __onnxTest__: () => __test__,
9772
- SubcTransportShuttingDownError: () => SubcTransportShuttingDownError,
9773
- SubcTransportPool: () => SubcTransportPool,
9774
- RotatingLogSink: () => RotatingLogSink,
9775
- RevivableTransportPool: () => RevivableTransportPool,
9776
- PLATFORM_ASSET_MAP: () => PLATFORM_ASSET_MAP,
9777
- PLATFORM_ARCH_MAP: () => PLATFORM_ARCH_MAP,
9778
- PLAIN_CALLGRAPH_THEME: () => PLAIN_CALLGRAPH_THEME,
9779
- PI_ONLY_KEYS: () => PI_ONLY_KEYS,
9780
- OPENCODE_ONLY_KEYS: () => OPENCODE_ONLY_KEYS,
9781
- LONG_RUNNING_COMMAND_TIMEOUT_MS: () => LONG_RUNNING_COMMAND_TIMEOUT_MS,
9782
- InvalidRequestError: () => InvalidRequestError,
9783
- HomeProjectRootError: () => HomeProjectRootError,
9784
- DEFAULT_LOG_GENERATIONS: () => DEFAULT_LOG_GENERATIONS,
9785
- DEFAULT_LOG_BYTES: () => DEFAULT_LOG_BYTES,
9786
- BridgeTransportUnknownOutcomeError: () => BridgeTransportUnknownOutcomeError,
9787
- BridgeTransportUnavailableError: () => BridgeTransportUnavailableError,
9788
- BridgeTransportTimeoutError: () => BridgeTransportTimeoutError,
9789
- BridgePool: () => BridgePool,
9790
- BinaryBridge: () => BinaryBridge,
9791
- BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION: () => BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION,
9792
- BASH_TRANSPORT_DISPOSITION: () => BASH_TRANSPORT_DISPOSITION,
9793
- BASH_HOST_FALLBACK_REFUSAL: () => BASH_HOST_FALLBACK_REFUSAL,
9794
- BASH_HOST_FALLBACK_MAX_TIMEOUT_MS: () => BASH_HOST_FALLBACK_MAX_TIMEOUT_MS,
9795
- BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES: () => BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES,
9113
+ AftToolError: () => AftToolError,
9796
9114
  BASH_HOST_FALLBACK_BANNER: () => BASH_HOST_FALLBACK_BANNER,
9797
- AftToolError: () => AftToolError
9115
+ BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES: () => BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES,
9116
+ BASH_HOST_FALLBACK_MAX_TIMEOUT_MS: () => BASH_HOST_FALLBACK_MAX_TIMEOUT_MS,
9117
+ BASH_HOST_FALLBACK_REFUSAL: () => BASH_HOST_FALLBACK_REFUSAL,
9118
+ BASH_TRANSPORT_DISPOSITION: () => BASH_TRANSPORT_DISPOSITION,
9119
+ BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION: () => BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION,
9120
+ BinaryBridge: () => BinaryBridge,
9121
+ BridgePool: () => BridgePool,
9122
+ BridgeTransportTimeoutError: () => BridgeTransportTimeoutError,
9123
+ BridgeTransportUnavailableError: () => BridgeTransportUnavailableError,
9124
+ BridgeTransportUnknownOutcomeError: () => BridgeTransportUnknownOutcomeError,
9125
+ DEFAULT_LOG_BYTES: () => DEFAULT_LOG_BYTES,
9126
+ DEFAULT_LOG_GENERATIONS: () => DEFAULT_LOG_GENERATIONS,
9127
+ HomeProjectRootError: () => HomeProjectRootError,
9128
+ InvalidRequestError: () => InvalidRequestError,
9129
+ LONG_RUNNING_COMMAND_TIMEOUT_MS: () => LONG_RUNNING_COMMAND_TIMEOUT_MS,
9130
+ OPENCODE_ONLY_KEYS: () => OPENCODE_ONLY_KEYS,
9131
+ PI_ONLY_KEYS: () => PI_ONLY_KEYS,
9132
+ PLAIN_CALLGRAPH_THEME: () => PLAIN_CALLGRAPH_THEME,
9133
+ PLATFORM_ARCH_MAP: () => PLATFORM_ARCH_MAP,
9134
+ PLATFORM_ASSET_MAP: () => PLATFORM_ASSET_MAP,
9135
+ RevivableTransportPool: () => RevivableTransportPool,
9136
+ RotatingLogSink: () => RotatingLogSink,
9137
+ SubcTransportPool: () => SubcTransportPool,
9138
+ SubcTransportShuttingDownError: () => SubcTransportShuttingDownError,
9139
+ __onnxTest__: () => __test__,
9140
+ adaptToolError: () => adaptToolError,
9141
+ bashHostFallbackAskPattern: () => bashHostFallbackAskPattern,
9142
+ canonicalizeProjectRoot: () => canonicalizeProjectRoot,
9143
+ cleanupOnnxRuntime: () => cleanupOnnxRuntime,
9144
+ coerceAliasedStringParam: () => coerceAliasedStringParam,
9145
+ coerceBoolean: () => coerceBoolean,
9146
+ coerceOptionalInt: () => coerceOptionalInt,
9147
+ coerceStringArray: () => coerceStringArray,
9148
+ coerceTargetParam: () => coerceTargetParam,
9149
+ commandInvokesCodeSearch: () => commandInvokesCodeSearch,
9150
+ compareSemver: () => compareSemver,
9151
+ compressionSavingsPercent: () => compressionSavingsPercent,
9152
+ createAftTransportPool: () => createAftTransportPool,
9153
+ decodeFileUrl: () => decodeFileUrl,
9154
+ downloadBinary: () => downloadBinary,
9155
+ ensureBinary: () => ensureBinary,
9156
+ ensureOnnxRuntime: () => ensureOnnxRuntime,
9157
+ ensureStorageMigrated: () => ensureStorageMigrated,
9158
+ findBinary: () => findBinary,
9159
+ findBinarySync: () => findBinarySync,
9160
+ formatBridgeErrorMessage: () => formatBridgeErrorMessage,
9161
+ formatCallgraphSections: () => formatCallgraphSections,
9162
+ formatDroppedKeyWarnings: () => formatDroppedKeyWarnings,
9163
+ formatEditSummary: () => formatEditSummary,
9164
+ formatForegroundResult: () => formatForegroundResult,
9165
+ formatReadFooter: () => formatReadFooter,
9166
+ formatSeconds: () => formatSeconds,
9167
+ formatTokenCount: () => formatTokenCount,
9168
+ formatZoomMultiTargetResult: () => formatZoomMultiTargetResult,
9169
+ formatZoomText: () => formatZoomText,
9170
+ getAftBinaryCacheDir: () => getAftBinaryCacheDir,
9171
+ getAftCacheRoot: () => getAftCacheRoot,
9172
+ getAftLspBinariesDir: () => getAftLspBinariesDir,
9173
+ getAftLspPackagesDir: () => getAftLspPackagesDir,
9174
+ getBinaryName: () => getBinaryName,
9175
+ getCacheDir: () => getAftBinaryCacheDir,
9176
+ getCachedBinaryPath: () => getCachedBinaryPath,
9177
+ getManualInstallHint: () => getManualInstallHint,
9178
+ getMigrationStatus: () => getMigrationStatus,
9179
+ inlineUserConfigTier: () => inlineUserConfigTier,
9180
+ isBashTransportDeadError: () => isBashTransportDeadError,
9181
+ isBridgeTransportTimeout: () => isBridgeTransportTimeout,
9182
+ isEmptyParam: () => isEmptyParam,
9183
+ isHomeDirectoryRoot: () => isHomeDirectoryRoot,
9184
+ isNativeExecutable: () => isNativeExecutable,
9185
+ isNpmAvailable: () => isNpmAvailable,
9186
+ isOrtAutoDownloadSupported: () => isOrtAutoDownloadSupported,
9187
+ isRustZoomBatchEnvelope: () => isRustZoomBatchEnvelope,
9188
+ isTerminalStatus: () => isTerminalStatus,
9189
+ isWellFormedUnicodeString: () => isWellFormedUnicodeString,
9190
+ markAnnouncementSeen: () => markAnnouncementSeen,
9191
+ maybeAppendConflictsHint: () => maybeAppendConflictsHint,
9192
+ maybeAppendGrepSearchHint: () => maybeAppendGrepSearchHint,
9193
+ migrateAftConfigFile: () => migrateAftConfigFile,
9194
+ npmSpawnEnv: () => npmSpawnEnv,
9195
+ platformKey: () => platformKey,
9196
+ prepareCanonicalEditArguments: () => prepareCanonicalEditArguments,
9197
+ prepareCanonicalPathArguments: () => prepareCanonicalPathArguments,
9198
+ probeNpmVersion: () => probeNpmVersion,
9199
+ projectRootKeyHash: () => projectRootKeyHash,
9200
+ readConfigTiers: () => readConfigTiers,
9201
+ repairRootScopedStorageFile: () => repairRootScopedStorageFile,
9202
+ resolveAftLogPath: () => resolveAftLogPath,
9203
+ resolveAftStorageRoot: () => resolveAftStorageRoot,
9204
+ resolveBashKillTimeout: () => resolveBashKillTimeout,
9205
+ resolveBridgeForNudge: () => resolveBridgeForNudge,
9206
+ resolveCortexKitConfigPaths: () => resolveCortexKitConfigPaths,
9207
+ resolveCortexKitProjectConfigPath: () => resolveCortexKitProjectConfigPath,
9208
+ resolveCortexKitStorageRoot: () => resolveCortexKitStorageRoot,
9209
+ resolveCortexKitUserConfigPath: () => resolveCortexKitUserConfigPath,
9210
+ resolveHarnessStoragePath: () => resolveHarnessStoragePath,
9211
+ resolveLegacyAftConfigSources: () => resolveLegacyAftConfigSources,
9212
+ resolveLegacyStorageRoot: () => resolveLegacyStorageRoot,
9213
+ resolveNpm: () => resolveNpm,
9214
+ runBashHostFallback: () => runBashHostFallback,
9215
+ setActiveLogger: () => setActiveLogger,
9216
+ shouldShowAnnouncement: () => shouldShowAnnouncement,
9217
+ sleep: () => sleep,
9218
+ stripHarnessSpecificConfigKeys: () => stripHarnessSpecificConfigKeys,
9219
+ stripJsoncSymbols: () => stripJsoncSymbols,
9220
+ tagStderrLine: () => tagStderrLine,
9221
+ timeoutForCommand: () => timeoutForCommand,
9222
+ toolErrorFromResponse: () => toolErrorFromResponse,
9223
+ unwrapRustZoomBatchEnvelope: () => unwrapRustZoomBatchEnvelope
9798
9224
  });
9799
9225
  var init_dist2 = __esm(() => {
9800
9226
  init_active_logger();
@@ -10048,7 +9474,7 @@ function compareVersionLabels(a, b) {
10048
9474
  var init_fs_util = () => {};
10049
9475
 
10050
9476
  // ../../node_modules/.bun/esprima@4.0.1/node_modules/esprima/dist/esprima.js
10051
- var require_esprima = __commonJS((exports, module) => {
9477
+ var require_esprima = __commonJS(function(exports, module) {
10052
9478
  (function webpackUniversalModuleDefinition(root, factory) {
10053
9479
  if (typeof exports === "object" && typeof module === "object")
10054
9480
  module.exports = factory();
@@ -16188,7 +15614,7 @@ var require_esprima = __commonJS((exports, module) => {
16188
15614
  });
16189
15615
 
16190
15616
  // ../../node_modules/.bun/array-timsort@1.0.3/node_modules/array-timsort/src/index.js
16191
- var require_src = __commonJS((exports, module) => {
15617
+ var require_src = __commonJS(function(exports, module) {
16192
15618
  var DEFAULT_MIN_MERGE = 32;
16193
15619
  var DEFAULT_MIN_GALLOPING = 7;
16194
15620
  var DEFAULT_TMP_STORAGE_LENGTH = 256;
@@ -16831,7 +16257,7 @@ var require_src = __commonJS((exports, module) => {
16831
16257
  });
16832
16258
 
16833
16259
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/common.js
16834
- var require_common = __commonJS((exports, module) => {
16260
+ var require_common = __commonJS(function(exports, module) {
16835
16261
  var PREFIX_BEFORE = "before";
16836
16262
  var PREFIX_AFTER_PROP = "after-prop";
16837
16263
  var PREFIX_AFTER_COLON = "after-colon";
@@ -17075,7 +16501,7 @@ var require_common = __commonJS((exports, module) => {
17075
16501
  });
17076
16502
 
17077
16503
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/array.js
17078
- var require_array = __commonJS((exports, module) => {
16504
+ var require_array = __commonJS(function(exports, module) {
17079
16505
  var { sort } = require_src();
17080
16506
  var {
17081
16507
  PROP_SYMBOL_PREFIXES,
@@ -17233,7 +16659,7 @@ var require_array = __commonJS((exports, module) => {
17233
16659
  });
17234
16660
 
17235
16661
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/parse.js
17236
- var require_parse = __commonJS((exports, module) => {
16662
+ var require_parse = __commonJS(function(exports, module) {
17237
16663
  var esprima = require_esprima();
17238
16664
  var {
17239
16665
  CommentArray
@@ -17558,7 +16984,7 @@ var require_parse = __commonJS((exports, module) => {
17558
16984
  });
17559
16985
 
17560
16986
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/stringify.js
17561
- var require_stringify = __commonJS((exports, module) => {
16987
+ var require_stringify = __commonJS(function(exports, module) {
17562
16988
  var {
17563
16989
  PREFIX_BEFORE_ALL,
17564
16990
  PREFIX_BEFORE,
@@ -17770,7 +17196,7 @@ var require_stringify = __commonJS((exports, module) => {
17770
17196
  });
17771
17197
 
17772
17198
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/index.js
17773
- var require_src2 = __commonJS((exports, module) => {
17199
+ var require_src2 = __commonJS(function(exports, module) {
17774
17200
  var { parse, tokenize } = require_parse();
17775
17201
  var stringify = require_stringify();
17776
17202
  var { CommentArray } = require_array();
@@ -18201,7 +17627,8 @@ class OpenCodeAdapter {
18201
17627
  semantic: dirSize(join15(storage, "semantic")),
18202
17628
  backups: dirSize(join15(storage, "backups")),
18203
17629
  url_cache: dirSize(join15(storage, "url_cache")),
18204
- onnxruntime: dirSize(join15(storage, "onnxruntime"))
17630
+ onnxruntime: dirSize(join15(storage, "onnxruntime")),
17631
+ logs: dirSize(join15(storage, "logs"))
18205
17632
  };
18206
17633
  }
18207
17634
  }
@@ -18219,8 +17646,11 @@ var init_opencode = __esm(() => {
18219
17646
  import { execSync as execSync4, spawnSync as spawnSync4 } from "node:child_process";
18220
17647
  import { existsSync as existsSync13, readFileSync as readFileSync9 } from "node:fs";
18221
17648
  import { homedir as homedir15 } from "node:os";
18222
- import { join as join16 } from "node:path";
17649
+ import { join as join16, resolve as resolve8 } from "node:path";
18223
17650
  function getPiAgentDir() {
17651
+ const configuredDir = process.env.PI_CODING_AGENT_DIR?.trim();
17652
+ if (configuredDir)
17653
+ return resolve8(configuredDir);
18224
17654
  const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
18225
17655
  const home = envHome && envHome.length > 0 ? envHome : homedir15();
18226
17656
  return join16(home, ".pi", "agent");
@@ -18234,7 +17664,14 @@ function readPiExtensionIndex() {
18234
17664
  const value = JSON.parse(trimmed);
18235
17665
  const packages = value.packages;
18236
17666
  if (Array.isArray(packages)) {
18237
- const installed = packages.filter((p) => typeof p === "string");
17667
+ const installed = packages.flatMap((p) => {
17668
+ if (typeof p === "string")
17669
+ return [p];
17670
+ if (typeof p === "object" && p !== null && typeof p.source === "string") {
17671
+ return [p.source];
17672
+ }
17673
+ return [];
17674
+ });
18238
17675
  return { installed, path: settingsPath };
18239
17676
  }
18240
17677
  } catch {}
@@ -18383,6 +17820,7 @@ class PiAdapter {
18383
17820
  }
18384
17821
  getPluginCacheInfo() {
18385
17822
  const candidates = [
17823
+ join16(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
18386
17824
  join16(getPiAgentDir(), "node_modules", "@cortexkit", "aft-pi", "package.json"),
18387
17825
  join16(getPiAgentDir(), "extensions", "node_modules", "@cortexkit", "aft-pi", "package.json")
18388
17826
  ];
@@ -18401,7 +17839,7 @@ class PiAdapter {
18401
17839
  } catch {}
18402
17840
  }
18403
17841
  return {
18404
- path: join16(getPiAgentDir(), "extensions"),
17842
+ path: join16(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
18405
17843
  exists: false
18406
17844
  };
18407
17845
  }
@@ -18427,7 +17865,8 @@ class PiAdapter {
18427
17865
  semantic: dirSize(join16(storage, "semantic")),
18428
17866
  backups: dirSize(join16(storage, "backups")),
18429
17867
  url_cache: dirSize(join16(storage, "url_cache")),
18430
- onnxruntime: dirSize(join16(storage, "onnxruntime"))
17868
+ onnxruntime: dirSize(join16(storage, "onnxruntime")),
17869
+ logs: dirSize(join16(storage, "logs"))
18431
17870
  };
18432
17871
  }
18433
17872
  }
@@ -18800,7 +18239,7 @@ var init_main = __esm(() => {
18800
18239
  });
18801
18240
 
18802
18241
  // ../../node_modules/.bun/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
18803
- var require_src3 = __commonJS((exports, module) => {
18242
+ var require_src3 = __commonJS(function(exports, module) {
18804
18243
  var ESC2 = "\x1B";
18805
18244
  var CSI2 = `${ESC2}[`;
18806
18245
  var beep = "\x07";
@@ -18867,25 +18306,6 @@ function findCursor(s, o, l) {
18867
18306
  const t = s + o, n = Math.max(l.length - 1, 0), e = t < 0 ? n : t > n ? 0 : t;
18868
18307
  return l[e].disabled ? findCursor(e, o < 0 ? -1 : 1, l) : e;
18869
18308
  }
18870
- function findTextCursor(s, o, l, i) {
18871
- const t = i.split(`
18872
- `);
18873
- let n = 0, e = s;
18874
- for (const r of t) {
18875
- if (e <= r.length)
18876
- break;
18877
- e -= r.length + 1, n++;
18878
- }
18879
- for (n = Math.max(0, Math.min(t.length - 1, n + l)), e = Math.min(e, t[n].length) + o;e < 0 && n > 0; )
18880
- n--, e += t[n].length + 1;
18881
- for (;e > t[n].length && n < t.length - 1; )
18882
- e -= t[n].length + 1, n++;
18883
- e = Math.max(0, Math.min(t[n].length, e));
18884
- let h = 0;
18885
- for (let r = 0;r < n; r++)
18886
- h += t[r].length + 1;
18887
- return h + e;
18888
- }
18889
18309
  function isActionKey(n, e) {
18890
18310
  if (typeof n == "string")
18891
18311
  return settings.aliases.get(n) === e;
@@ -19077,77 +18497,7 @@ class V {
19077
18497
  }
19078
18498
  }
19079
18499
  }
19080
- function p$1(l, e) {
19081
- if (l === undefined || e.length === 0)
19082
- return 0;
19083
- const i = e.findIndex((s) => s.value === l);
19084
- return i !== -1 ? i : 0;
19085
- }
19086
- function g(l, e) {
19087
- return (e.label ?? String(e.value)).toLowerCase().includes(l.toLowerCase());
19088
- }
19089
- function m(l, e) {
19090
- if (e)
19091
- return l ? e : e[0];
19092
- }
19093
- function M(r2) {
19094
- return [...r2].map((t2) => _[t2]);
19095
- }
19096
- function P(r2) {
19097
- const i = new Intl.DateTimeFormat(r2, {
19098
- year: "numeric",
19099
- month: "2-digit",
19100
- day: "2-digit"
19101
- }).formatToParts(new Date(2000, 0, 15)), s = [];
19102
- let n = "/";
19103
- for (const e of i)
19104
- e.type === "literal" ? n = e.value.trim() || e.value : (e.type === "year" || e.type === "month" || e.type === "day") && s.push({ type: e.type, len: e.type === "year" ? 4 : 2 });
19105
- return { segments: s, separator: n };
19106
- }
19107
- function p(r2) {
19108
- return Number.parseInt((r2 || "0").replace(/_/g, "0"), 10) || 0;
19109
- }
19110
- function f(r2) {
19111
- return {
19112
- year: p(r2.year),
19113
- month: p(r2.month),
19114
- day: p(r2.day)
19115
- };
19116
- }
19117
- function c(r2, t2) {
19118
- return new Date(r2 || 2001, t2 || 1, 0).getDate();
19119
- }
19120
- function b(r2) {
19121
- const { year: t2, month: i, day: s } = f(r2);
19122
- if (!t2 || t2 < 0 || t2 > 9999 || !i || i < 1 || i > 12 || !s || s < 1)
19123
- return;
19124
- const n = new Date(Date.UTC(t2, i - 1, s));
19125
- if (!(n.getUTCFullYear() !== t2 || n.getUTCMonth() !== i - 1 || n.getUTCDate() !== s))
19126
- return { year: t2, month: i, day: s };
19127
- }
19128
- function C(r2) {
19129
- const t2 = b(r2);
19130
- return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : undefined;
19131
- }
19132
- function T2(r2, t2, i, s) {
19133
- const n = i ? {
19134
- year: i.getUTCFullYear(),
19135
- month: i.getUTCMonth() + 1,
19136
- day: i.getUTCDate()
19137
- } : null, e = s ? {
19138
- year: s.getUTCFullYear(),
19139
- month: s.getUTCMonth() + 1,
19140
- day: s.getUTCDate()
19141
- } : null;
19142
- return r2 === "year" ? { min: n?.year ?? 1, max: e?.year ?? 9999 } : r2 === "month" ? {
19143
- min: n && t2.year === n.year ? n.month : 1,
19144
- max: e && t2.year === e.year ? e.month : 12
19145
- } : {
19146
- min: n && t2.year === n.year && t2.month === n.month ? n.day : 1,
19147
- max: e && t2.year === e.year && t2.month === e.month ? e.day : c(t2.year, t2.month)
19148
- };
19149
- }
19150
- var import_sisteransi, a$2, t, settings, R, CANCEL_SYMBOL, getColumns = (e) => ("columns" in e) && typeof e.columns == "number" ? e.columns : 80, getRows = (e) => ("rows" in e) && typeof e.rows == "number" ? e.rows : 20, T$1, r, _, U, u$1, o$1, h, a$1, a2, n;
18500
+ var import_sisteransi, a$2, t, settings, R, CANCEL_SYMBOL, getColumns = (e) => ("columns" in e) && typeof e.columns == "number" ? e.columns : 80, getRows = (e) => ("rows" in e) && typeof e.rows == "number" ? e.rows : 20, r, a$1, a2, n;
19151
18501
  var init_dist5 = __esm(() => {
19152
18502
  init_main();
19153
18503
  import_sisteransi = __toESM(require_src3(), 1);
@@ -19194,72 +18544,6 @@ var init_dist5 = __esm(() => {
19194
18544
  };
19195
18545
  R = globalThis.process.platform.startsWith("win");
19196
18546
  CANCEL_SYMBOL = Symbol("clack:cancel");
19197
- T$1 = class T extends V {
19198
- filteredOptions;
19199
- multiple;
19200
- isNavigating = false;
19201
- selectedValues = [];
19202
- focusedValue;
19203
- #e = 0;
19204
- #s = "";
19205
- #t;
19206
- #i;
19207
- #n;
19208
- get cursor() {
19209
- return this.#e;
19210
- }
19211
- get userInputWithCursor() {
19212
- if (!this.userInput)
19213
- return styleText(["inverse", "hidden"], "_");
19214
- if (this._cursor >= this.userInput.length)
19215
- return `${this.userInput}█`;
19216
- const e = this.userInput.slice(0, this._cursor), [t2, ...i] = this.userInput.slice(this._cursor);
19217
- return `${e}${styleText("inverse", t2)}${i.join("")}`;
19218
- }
19219
- get options() {
19220
- return typeof this.#i == "function" ? this.#i() : this.#i;
19221
- }
19222
- constructor(e) {
19223
- super(e), this.#i = e.options, this.#n = e.placeholder;
19224
- const t2 = this.options;
19225
- this.filteredOptions = [...t2], this.multiple = e.multiple === true, this.#t = typeof e.options == "function" ? e.filter : e.filter ?? g;
19226
- let i;
19227
- if (e.initialValue && Array.isArray(e.initialValue) ? this.multiple ? i = e.initialValue : i = e.initialValue.slice(0, 1) : !this.multiple && this.options.length > 0 && (i = [this.options[0].value]), i)
19228
- for (const s of i) {
19229
- const n = t2.findIndex((o) => o.value === s);
19230
- n !== -1 && (this.toggleSelected(s), this.#e = n);
19231
- }
19232
- this.focusedValue = this.options[this.#e]?.value, this.on("key", (s, n) => this.#l(s, n)), this.on("userInput", (s) => this.#u(s));
19233
- }
19234
- _isActionKey(e, t2) {
19235
- return e === "\t" || this.multiple && this.isNavigating && t2.name === "space" && e !== undefined && e !== "";
19236
- }
19237
- #l(e, t2) {
19238
- const i = t2.name === "up", s = t2.name === "down", n = t2.name === "return", o = this.userInput === "" || this.userInput === "\t", u = this.#n, h = this.options, f = u !== undefined && u !== "" && h.some((r) => !r.disabled && (this.#t ? this.#t(u, r) : true));
19239
- if (t2.name === "tab" && o && f) {
19240
- this.userInput === "\t" && this._clearUserInput(), this._setUserInput(u, true), this.isNavigating = false;
19241
- return;
19242
- }
19243
- i || s ? (this.#e = findCursor(this.#e, i ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = m(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== undefined && (t2.name === "tab" || this.isNavigating && t2.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
19244
- }
19245
- deselectAll() {
19246
- this.selectedValues = [];
19247
- }
19248
- toggleSelected(e) {
19249
- this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(e) ? this.selectedValues = this.selectedValues.filter((t2) => t2 !== e) : this.selectedValues = [...this.selectedValues, e] : this.selectedValues = [e]);
19250
- }
19251
- #u(e) {
19252
- if (e !== this.#s) {
19253
- this.#s = e;
19254
- const t2 = this.options;
19255
- e && this.#t ? this.filteredOptions = t2.filter((n) => this.#t?.(e, n)) : this.filteredOptions = [...t2];
19256
- const i = p$1(this.focusedValue, this.filteredOptions);
19257
- this.#e = findCursor(i, 0, this.filteredOptions);
19258
- const s = this.filteredOptions[this.#e];
19259
- s && !s.disabled ? this.focusedValue = s.value : this.focusedValue = undefined, this.multiple || (this.focusedValue !== undefined ? this.toggleSelected(this.focusedValue) : this.deselectAll());
19260
- }
19261
- }
19262
- };
19263
18547
  r = class r extends V {
19264
18548
  get cursor() {
19265
18549
  return this.value ? 0 : 1;
@@ -19277,304 +18561,6 @@ var init_dist5 = __esm(() => {
19277
18561
  });
19278
18562
  }
19279
18563
  };
19280
- _ = {
19281
- Y: { type: "year", len: 4 },
19282
- M: { type: "month", len: 2 },
19283
- D: { type: "day", len: 2 }
19284
- };
19285
- U = class U extends V {
19286
- #i;
19287
- #o;
19288
- #t;
19289
- #h;
19290
- #u;
19291
- #e = { segmentIndex: 0, positionInSegment: 0 };
19292
- #n = true;
19293
- #s = null;
19294
- inlineError = "";
19295
- get segmentCursor() {
19296
- return { ...this.#e };
19297
- }
19298
- get segmentValues() {
19299
- return { ...this.#t };
19300
- }
19301
- get segments() {
19302
- return this.#i;
19303
- }
19304
- get separator() {
19305
- return this.#o;
19306
- }
19307
- get formattedValue() {
19308
- return this.#l(this.#t);
19309
- }
19310
- #l(t2) {
19311
- return this.#i.map((i) => t2[i.type]).join(this.#o);
19312
- }
19313
- #r() {
19314
- this._setUserInput(this.#l(this.#t)), this._setValue(C(this.#t) ?? undefined);
19315
- }
19316
- constructor(t2) {
19317
- const i = t2.format ? { segments: M(t2.format), separator: t2.separator ?? "/" } : P(t2.locale), s = t2.separator ?? i.separator, n = t2.format ? M(t2.format) : i.segments, e = t2.initialValue ?? t2.defaultValue, m2 = e ? {
19318
- year: String(e.getUTCFullYear()).padStart(4, "0"),
19319
- month: String(e.getUTCMonth() + 1).padStart(2, "0"),
19320
- day: String(e.getUTCDate()).padStart(2, "0")
19321
- } : { year: "____", month: "__", day: "__" }, o = n.map((a) => m2[a.type]).join(s);
19322
- super({ ...t2, initialUserInput: o }, false), this.#i = n, this.#o = s, this.#t = m2, this.#h = t2.minDate, this.#u = t2.maxDate, this.#r(), this.on("cursor", (a) => this.#f(a)), this.on("key", (a, u) => this.#y(a, u)), this.on("finalize", () => this.#p(t2));
19323
- }
19324
- #a() {
19325
- const t2 = Math.max(0, Math.min(this.#e.segmentIndex, this.#i.length - 1)), i = this.#i[t2];
19326
- if (i)
19327
- return this.#e.positionInSegment = Math.max(0, Math.min(this.#e.positionInSegment, i.len - 1)), { segment: i, index: t2 };
19328
- }
19329
- #m(t2) {
19330
- this.inlineError = "", this.#s = null;
19331
- const i = this.#a();
19332
- i && (this.#e.segmentIndex = Math.max(0, Math.min(this.#i.length - 1, i.index + t2)), this.#e.positionInSegment = 0, this.#n = true);
19333
- }
19334
- #d(t2) {
19335
- const i = this.#a();
19336
- if (!i)
19337
- return;
19338
- const { segment: s } = i, n = this.#t[s.type], e = !n || n.replace(/_/g, "") === "", m2 = Number.parseInt((n || "0").replace(/_/g, "0"), 10) || 0, o = T2(s.type, f(this.#t), this.#h, this.#u);
19339
- let a;
19340
- e ? a = t2 === 1 ? o.min : o.max : a = Math.max(Math.min(o.max, m2 + t2), o.min), this.#t = {
19341
- ...this.#t,
19342
- [s.type]: a.toString().padStart(s.len, "0")
19343
- }, this.#n = true, this.#s = null, this.#r();
19344
- }
19345
- #f(t2) {
19346
- if (t2)
19347
- switch (t2) {
19348
- case "right":
19349
- return this.#m(1);
19350
- case "left":
19351
- return this.#m(-1);
19352
- case "up":
19353
- return this.#d(1);
19354
- case "down":
19355
- return this.#d(-1);
19356
- }
19357
- }
19358
- #y(t2, i) {
19359
- if (i?.name === "backspace" || i?.sequence === "" || i?.sequence === "\b" || t2 === "" || t2 === "\b") {
19360
- this.inlineError = "";
19361
- const n = this.#a();
19362
- if (!n)
19363
- return;
19364
- if (!this.#t[n.segment.type].replace(/_/g, "")) {
19365
- this.#m(-1);
19366
- return;
19367
- }
19368
- this.#t[n.segment.type] = "_".repeat(n.segment.len), this.#n = true, this.#e.positionInSegment = 0, this.#r();
19369
- return;
19370
- }
19371
- if (i?.name === "tab") {
19372
- this.inlineError = "";
19373
- const n = this.#a();
19374
- if (!n)
19375
- return;
19376
- const e = i.shift ? -1 : 1, m2 = n.index + e;
19377
- m2 >= 0 && m2 < this.#i.length && (this.#e.segmentIndex = m2, this.#e.positionInSegment = 0, this.#n = true);
19378
- return;
19379
- }
19380
- if (t2 && /^[0-9]$/.test(t2)) {
19381
- const n = this.#a();
19382
- if (!n)
19383
- return;
19384
- const { segment: e } = n, m2 = !this.#t[e.type].replace(/_/g, "");
19385
- if (this.#n && this.#s !== null && !m2) {
19386
- const h = this.#s + t2, d = { ...this.#t, [e.type]: h }, g2 = this.#g(d, e);
19387
- if (g2) {
19388
- this.inlineError = g2, this.#s = null, this.#n = false;
19389
- return;
19390
- }
19391
- this.inlineError = "", this.#t[e.type] = h, this.#s = null, this.#n = false, this.#r(), n.index < this.#i.length - 1 && (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true);
19392
- return;
19393
- }
19394
- this.#n && !m2 && (this.#t[e.type] = "_".repeat(e.len), this.#e.positionInSegment = 0), this.#n = false, this.#s = null;
19395
- const o = this.#t[e.type], a = o.indexOf("_"), u = a >= 0 ? a : Math.min(this.#e.positionInSegment, e.len - 1);
19396
- if (u < 0 || u >= e.len)
19397
- return;
19398
- let l = o.slice(0, u) + t2 + o.slice(u + 1), D = false;
19399
- if (u === 0 && o === "__" && (e.type === "month" || e.type === "day")) {
19400
- const h = Number.parseInt(t2, 10);
19401
- l = `0${t2}`, D = h <= (e.type === "month" ? 1 : 2);
19402
- }
19403
- if (e.type === "year" && (l = (o.replace(/_/g, "") + t2).padStart(e.len, "_")), !l.includes("_")) {
19404
- const h = { ...this.#t, [e.type]: l }, d = this.#g(h, e);
19405
- if (d) {
19406
- this.inlineError = d;
19407
- return;
19408
- }
19409
- }
19410
- this.inlineError = "", this.#t[e.type] = l;
19411
- const y = l.includes("_") ? undefined : b(this.#t);
19412
- if (y) {
19413
- const { year: h, month: d } = y, g2 = c(h, d);
19414
- this.#t = {
19415
- year: String(Math.max(0, Math.min(9999, h))).padStart(4, "0"),
19416
- month: String(Math.max(1, Math.min(12, d))).padStart(2, "0"),
19417
- day: String(Math.max(1, Math.min(g2, y.day))).padStart(2, "0")
19418
- };
19419
- }
19420
- this.#r();
19421
- const S = l.indexOf("_");
19422
- D ? (this.#n = true, this.#s = t2) : S >= 0 ? this.#e.positionInSegment = S : a >= 0 && n.index < this.#i.length - 1 ? (this.#e.segmentIndex = n.index + 1, this.#e.positionInSegment = 0, this.#n = true) : this.#e.positionInSegment = Math.min(u + 1, e.len - 1);
19423
- }
19424
- }
19425
- #g(t2, i) {
19426
- const { month: s, day: n } = f(t2);
19427
- if (i.type === "month" && (s < 0 || s > 12))
19428
- return settings.date.messages.invalidMonth;
19429
- if (i.type === "day" && (n < 0 || n > 31))
19430
- return settings.date.messages.invalidDay(31, "any month");
19431
- }
19432
- #p(t2) {
19433
- const { year: i, month: s, day: n } = f(this.#t);
19434
- if (i && s && n) {
19435
- const e = c(i, s);
19436
- this.#t = {
19437
- ...this.#t,
19438
- day: String(Math.min(n, e)).padStart(2, "0")
19439
- };
19440
- }
19441
- this.value = C(this.#t) ?? t2.defaultValue ?? undefined;
19442
- }
19443
- };
19444
- u$1 = class u extends V {
19445
- options;
19446
- cursor = 0;
19447
- #t;
19448
- getGroupItems(t2) {
19449
- return this.options.filter((r2) => r2.group === t2);
19450
- }
19451
- isGroupSelected(t2) {
19452
- const r2 = this.getGroupItems(t2), e = this.value;
19453
- return e === undefined ? false : r2.every((s) => e.includes(s.value));
19454
- }
19455
- toggleValue() {
19456
- const t2 = this.options[this.cursor];
19457
- if (this.value === undefined && (this.value = []), t2.group === true) {
19458
- const r2 = t2.value, e = this.getGroupItems(r2);
19459
- this.isGroupSelected(r2) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
19460
- } else {
19461
- const r2 = this.value.includes(t2.value);
19462
- this.value = r2 ? this.value.filter((e) => e !== t2.value) : [...this.value, t2.value];
19463
- }
19464
- }
19465
- constructor(t2) {
19466
- super(t2, false);
19467
- const { options: r2 } = t2;
19468
- this.#t = t2.selectableGroups !== false, this.options = Object.entries(r2).flatMap(([e, s]) => [
19469
- { value: e, group: true, label: e },
19470
- ...s.map((i) => ({ ...i, group: e }))
19471
- ]), this.value = [...t2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === t2.cursorAt), this.#t ? 0 : 1), this.on("cursor", (e) => {
19472
- switch (e) {
19473
- case "left":
19474
- case "up": {
19475
- this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
19476
- const s = this.options[this.cursor]?.group === true;
19477
- !this.#t && s && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
19478
- break;
19479
- }
19480
- case "down":
19481
- case "right": {
19482
- this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
19483
- const s = this.options[this.cursor]?.group === true;
19484
- !this.#t && s && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
19485
- break;
19486
- }
19487
- case "space":
19488
- this.toggleValue();
19489
- break;
19490
- }
19491
- });
19492
- }
19493
- };
19494
- o$1 = /* @__PURE__ */ new Set(["up", "down", "left", "right"]);
19495
- h = class h extends V {
19496
- #t = false;
19497
- #s;
19498
- focused = "editor";
19499
- get userInputWithCursor() {
19500
- if (this.state === "submit")
19501
- return this.userInput;
19502
- const t2 = this.userInput;
19503
- if (this.cursor >= t2.length)
19504
- return `${t2}█`;
19505
- const s = t2.slice(0, this.cursor), r2 = t2[this.cursor], i = t2.slice(this.cursor + 1);
19506
- return r2 === `
19507
- ` ? `${s}█
19508
- ${i}` : `${s}${styleText("inverse", r2)}${i}`;
19509
- }
19510
- get cursor() {
19511
- return this._cursor;
19512
- }
19513
- #r(t2) {
19514
- if (this.userInput.length === 0) {
19515
- this._setUserInput(t2);
19516
- return;
19517
- }
19518
- this._setUserInput(this.userInput.slice(0, this.cursor) + t2 + this.userInput.slice(this.cursor));
19519
- }
19520
- #i(t2) {
19521
- const s = this.value ?? "";
19522
- switch (t2) {
19523
- case "up":
19524
- this._cursor = findTextCursor(this._cursor, 0, -1, s);
19525
- return;
19526
- case "down":
19527
- this._cursor = findTextCursor(this._cursor, 0, 1, s);
19528
- return;
19529
- case "left":
19530
- this._cursor = findTextCursor(this._cursor, -1, 0, s);
19531
- return;
19532
- case "right":
19533
- this._cursor = findTextCursor(this._cursor, 1, 0, s);
19534
- return;
19535
- }
19536
- }
19537
- _shouldSubmit(t2, s) {
19538
- if (this.#s)
19539
- return this.focused === "submit" ? true : (this.#r(`
19540
- `), this._cursor++, false);
19541
- const r2 = this.#t;
19542
- return this.#t = true, r2 && this.cursor === this.userInput.length ? (this.userInput[this.cursor - 1] === `
19543
- ` && (this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--), true) : (this.#r(`
19544
- `), this._cursor++, false);
19545
- }
19546
- constructor(t2) {
19547
- const s = t2.initialUserInput ?? t2.initialValue;
19548
- super({
19549
- ...t2,
19550
- initialUserInput: s
19551
- }, false), s !== undefined && (this._cursor = s.length), this.#s = t2.showSubmit ?? false, this.on("key", (r2, i) => {
19552
- if (i?.name && o$1.has(i.name)) {
19553
- this.#t = false, this.#i(i.name);
19554
- return;
19555
- }
19556
- if (r2 === "\t" && this.#s) {
19557
- this.focused = this.focused === "editor" ? "submit" : "editor";
19558
- return;
19559
- }
19560
- if (i?.name !== "return") {
19561
- if (this.#t = false, i?.name === "backspace" && this.cursor > 0) {
19562
- this._setUserInput(this.userInput.slice(0, this.cursor - 1) + this.userInput.slice(this.cursor)), this._cursor--;
19563
- return;
19564
- }
19565
- if (i?.name === "delete" && this.cursor < this.userInput.length) {
19566
- this._setUserInput(this.userInput.slice(0, this.cursor) + this.userInput.slice(this.cursor + 1));
19567
- return;
19568
- }
19569
- r2 && (this.#s && this.focused === "submit" && (this.focused = "editor"), this.#r(r2 ?? ""), this._cursor++);
19570
- }
19571
- }), this.on("userInput", (r2) => {
19572
- this._setValue(r2);
19573
- }), this.on("finalize", () => {
19574
- this.value || (this.value = t2.defaultValue), this.value === undefined && (this.value = "");
19575
- });
19576
- }
19577
- };
19578
18564
  a$1 = class a extends V {
19579
18565
  options;
19580
18566
  cursor = 0;
@@ -19712,34 +18698,34 @@ var import_sisteransi2, unicode, unicodeOr = (o2, e) => unicode ? o2 : e, S_STEP
19712
18698
  case "submit":
19713
18699
  return styleText2("green", S_BAR);
19714
18700
  }
19715
- }, E$1 = (l, o2, g2, c2, h2, O = false) => {
18701
+ }, E$1 = (l, o2, g, c, h2, O = false) => {
19716
18702
  let r2 = o2, w = 0;
19717
18703
  if (O)
19718
- for (let i = c2 - 1;i >= g2 && (r2 -= l[i].length, w++, !(r2 <= h2)); i--)
18704
+ for (let i = c - 1;i >= g && (r2 -= l[i].length, w++, !(r2 <= h2)); i--)
19719
18705
  ;
19720
18706
  else
19721
- for (let i = g2;i < c2 && (r2 -= l[i].length, w++, !(r2 <= h2)); i++)
18707
+ for (let i = g;i < c && (r2 -= l[i].length, w++, !(r2 <= h2)); i++)
19722
18708
  ;
19723
18709
  return { lineCount: r2, removals: w };
19724
18710
  }, limitOptions = ({
19725
18711
  cursor: l,
19726
18712
  options: o2,
19727
- style: g2,
19728
- output: c2 = process.stdout,
18713
+ style: g,
18714
+ output: c = process.stdout,
19729
18715
  maxItems: h2 = Number.POSITIVE_INFINITY,
19730
18716
  columnPadding: O = 0,
19731
18717
  rowPadding: r2 = 4
19732
18718
  }) => {
19733
- const i = getColumns(c2) - O, I = getRows(c2), C2 = styleText2("dim", "..."), x = Math.max(I - r2, 0), m2 = Math.max(Math.min(h2, x), 5);
19734
- let p2 = 0;
19735
- l >= m2 - 3 && (p2 = Math.max(Math.min(l - m2 + 3, o2.length - m2), 0));
19736
- let f2 = m2 < o2.length && p2 > 0, u3 = m2 < o2.length && p2 + m2 < o2.length;
19737
- const W = Math.min(p2 + m2, o2.length), e = [];
18719
+ const i = getColumns(c) - O, I = getRows(c), C = styleText2("dim", "..."), x = Math.max(I - r2, 0), m = Math.max(Math.min(h2, x), 5);
18720
+ let p = 0;
18721
+ l >= m - 3 && (p = Math.max(Math.min(l - m + 3, o2.length - m), 0));
18722
+ let f = m < o2.length && p > 0, u2 = m < o2.length && p + m < o2.length;
18723
+ const W = Math.min(p + m, o2.length), e = [];
19738
18724
  let d = 0;
19739
- f2 && d++, u3 && d++;
19740
- const v = p2 + (f2 ? 1 : 0), P2 = W - (u3 ? 1 : 0);
19741
- for (let t2 = v;t2 < P2; t2++) {
19742
- const n2 = wrapAnsi(g2(o2[t2], t2 === l), i, {
18725
+ f && d++, u2 && d++;
18726
+ const v = p + (f ? 1 : 0), P = W - (u2 ? 1 : 0);
18727
+ for (let t2 = v;t2 < P; t2++) {
18728
+ const n2 = wrapAnsi(g(o2[t2], t2 === l), i, {
19743
18729
  hard: true,
19744
18730
  trim: false
19745
18731
  }).split(`
@@ -19748,17 +18734,17 @@ var import_sisteransi2, unicode, unicodeOr = (o2, e) => unicode ? o2 : e, S_STEP
19748
18734
  }
19749
18735
  if (d > x) {
19750
18736
  let t2 = 0, n2 = 0, s = d;
19751
- const M2 = l - v;
18737
+ const M = l - v;
19752
18738
  let a3 = x;
19753
- const T3 = () => E$1(e, s, 0, M2, a3), L = () => E$1(e, s, M2 + 1, e.length, a3, true);
19754
- f2 ? ({ lineCount: s, removals: t2 } = T3(), s > a3 && (u3 || (a3 -= 1), { lineCount: s, removals: n2 } = L())) : (u3 || (a3 -= 1), { lineCount: s, removals: n2 } = L(), s > a3 && (a3 -= 1, { lineCount: s, removals: t2 } = T3())), t2 > 0 && (f2 = true, e.splice(0, t2)), n2 > 0 && (u3 = true, e.splice(e.length - n2, n2));
18739
+ const T = () => E$1(e, s, 0, M, a3), L = () => E$1(e, s, M + 1, e.length, a3, true);
18740
+ f ? ({ lineCount: s, removals: t2 } = T(), s > a3 && (u2 || (a3 -= 1), { lineCount: s, removals: n2 } = L())) : (u2 || (a3 -= 1), { lineCount: s, removals: n2 } = L(), s > a3 && (a3 -= 1, { lineCount: s, removals: t2 } = T())), t2 > 0 && (f = true, e.splice(0, t2)), n2 > 0 && (u2 = true, e.splice(e.length - n2, n2));
19755
18741
  }
19756
- const b2 = [];
19757
- f2 && b2.push(C2);
18742
+ const b = [];
18743
+ f && b.push(C);
19758
18744
  for (const t2 of e)
19759
18745
  for (const n2 of t2)
19760
- b2.push(n2);
19761
- return u3 && b2.push(C2), b2;
18746
+ b.push(n2);
18747
+ return u2 && b.push(C), b;
19762
18748
  }, confirm = (i) => {
19763
18749
  const a3 = i.active ?? "Yes", s = i.inactive ?? "No";
19764
18750
  return new r({
@@ -19769,36 +18755,36 @@ var import_sisteransi2, unicode, unicodeOr = (o2, e) => unicode ? o2 : e, S_STEP
19769
18755
  output: i.output,
19770
18756
  initialValue: i.initialValue ?? true,
19771
18757
  render() {
19772
- const e = i.withGuide ?? settings.withGuide, u3 = `${symbol(this.state)} `, l = e ? `${styleText2("gray", S_BAR)} ` : "", f2 = wrapTextWithPrefix(i.output, i.message, l, u3), o2 = `${e ? `${styleText2("gray", S_BAR)}
19773
- ` : ""}${f2}
19774
- `, c2 = this.value ? a3 : s;
18758
+ const e = i.withGuide ?? settings.withGuide, u2 = `${symbol(this.state)} `, l = e ? `${styleText2("gray", S_BAR)} ` : "", f = wrapTextWithPrefix(i.output, i.message, l, u2), o2 = `${e ? `${styleText2("gray", S_BAR)}
18759
+ ` : ""}${f}
18760
+ `, c = this.value ? a3 : s;
19775
18761
  switch (this.state) {
19776
18762
  case "submit": {
19777
18763
  const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
19778
- return `${o2}${r2}${styleText2("dim", c2)}`;
18764
+ return `${o2}${r2}${styleText2("dim", c)}`;
19779
18765
  }
19780
18766
  case "cancel": {
19781
18767
  const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
19782
- return `${o2}${r2}${styleText2(["strikethrough", "dim"], c2)}${e ? `
18768
+ return `${o2}${r2}${styleText2(["strikethrough", "dim"], c)}${e ? `
19783
18769
  ${styleText2("gray", S_BAR)}` : ""}`;
19784
18770
  }
19785
18771
  default: {
19786
- const r2 = e ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e ? styleText2("cyan", S_BAR_END) : "";
18772
+ const r2 = e ? `${styleText2("cyan", S_BAR)} ` : "", g = e ? styleText2("cyan", S_BAR_END) : "";
19787
18773
  return `${o2}${r2}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a3}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a3)}`}${i.vertical ? e ? `
19788
18774
  ${styleText2("cyan", S_BAR)} ` : `
19789
18775
  ` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s}`}
19790
- ${g2}
18776
+ ${g}
19791
18777
  `;
19792
18778
  }
19793
18779
  }
19794
18780
  }
19795
18781
  }).prompt();
19796
- }, MULTISELECT_INSTRUCTIONS, m2 = (n2, o2) => n2.split(`
18782
+ }, MULTISELECT_INSTRUCTIONS, m = (n2, o2) => n2.split(`
19797
18783
  `).map((d) => o2(d)).join(`
19798
18784
  `), multiselect = (n2) => {
19799
18785
  const o2 = (t2, a3) => {
19800
18786
  const r2 = t2.label ?? String(t2.value);
19801
- return a3 === "disabled" ? `${styleText2("gray", S_CHECKBOX_INACTIVE)} ${m2(r2, (l) => styleText2(["strikethrough", "gray"], l))}${t2.hint ? ` ${styleText2("dim", `(${t2.hint ?? "disabled"})`)}` : ""}` : a3 === "active" ? `${styleText2("cyan", S_CHECKBOX_ACTIVE)} ${r2}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a3 === "selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${m2(r2, (l) => styleText2("dim", l))}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a3 === "cancelled" ? `${m2(r2, (l) => styleText2(["strikethrough", "dim"], l))}` : a3 === "active-selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${r2}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a3 === "submitted" ? `${m2(r2, (l) => styleText2("dim", l))}` : `${styleText2("dim", S_CHECKBOX_INACTIVE)} ${m2(r2, (l) => styleText2("dim", l))}`;
18787
+ return a3 === "disabled" ? `${styleText2("gray", S_CHECKBOX_INACTIVE)} ${m(r2, (l) => styleText2(["strikethrough", "gray"], l))}${t2.hint ? ` ${styleText2("dim", `(${t2.hint ?? "disabled"})`)}` : ""}` : a3 === "active" ? `${styleText2("cyan", S_CHECKBOX_ACTIVE)} ${r2}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a3 === "selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${m(r2, (l) => styleText2("dim", l))}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a3 === "cancelled" ? `${m(r2, (l) => styleText2(["strikethrough", "dim"], l))}` : a3 === "active-selected" ? `${styleText2("green", S_CHECKBOX_SELECTED)} ${r2}${t2.hint ? ` ${styleText2("dim", `(${t2.hint})`)}` : ""}` : a3 === "submitted" ? `${m(r2, (l) => styleText2("dim", l))}` : `${styleText2("dim", S_CHECKBOX_INACTIVE)} ${m(r2, (l) => styleText2("dim", l))}`;
19802
18788
  }, d = n2.required ?? true;
19803
18789
  return new a$1({
19804
18790
  options: n2.options,
@@ -19816,30 +18802,30 @@ ${styleText2("reset", styleText2("dim", `Press ${styleText2(["gray", "bgWhite",
19816
18802
  render() {
19817
18803
  const t2 = n2.withGuide ?? settings.withGuide, a3 = wrapTextWithPrefix(n2.output, n2.message, t2 ? `${symbolBar(this.state)} ` : "", `${symbol(this.state)} `), r2 = `${t2 ? `${styleText2("gray", S_BAR)}
19818
18804
  ` : ""}${a3}
19819
- `, l = this.value ?? [], p2 = (i, u3) => {
18805
+ `, l = this.value ?? [], p = (i, u2) => {
19820
18806
  if (i.disabled)
19821
18807
  return o2(i, "disabled");
19822
18808
  const s = l.includes(i.value);
19823
- return u3 && s ? o2(i, "active-selected") : s ? o2(i, "selected") : o2(i, u3 ? "active" : "inactive");
18809
+ return u2 && s ? o2(i, "active-selected") : s ? o2(i, "selected") : o2(i, u2 ? "active" : "inactive");
19824
18810
  };
19825
18811
  switch (this.state) {
19826
18812
  case "submit": {
19827
- const i = this.options.filter(({ value: s }) => l.includes(s)).map((s) => o2(s, "submitted")).join(styleText2("dim", ", ")) || styleText2("dim", "none"), u3 = wrapTextWithPrefix(n2.output, i, t2 ? `${styleText2("gray", S_BAR)} ` : "");
19828
- return `${r2}${u3}`;
18813
+ const i = this.options.filter(({ value: s }) => l.includes(s)).map((s) => o2(s, "submitted")).join(styleText2("dim", ", ")) || styleText2("dim", "none"), u2 = wrapTextWithPrefix(n2.output, i, t2 ? `${styleText2("gray", S_BAR)} ` : "");
18814
+ return `${r2}${u2}`;
19829
18815
  }
19830
18816
  case "cancel": {
19831
18817
  const i = this.options.filter(({ value: s }) => l.includes(s)).map((s) => o2(s, "cancelled")).join(styleText2("dim", ", "));
19832
18818
  if (i.trim() === "")
19833
18819
  return `${r2}${styleText2("gray", S_BAR)}`;
19834
- const u3 = wrapTextWithPrefix(n2.output, i, t2 ? `${styleText2("gray", S_BAR)} ` : "");
19835
- return `${r2}${u3}${t2 ? `
18820
+ const u2 = wrapTextWithPrefix(n2.output, i, t2 ? `${styleText2("gray", S_BAR)} ` : "");
18821
+ return `${r2}${u2}${t2 ? `
19836
18822
  ${styleText2("gray", S_BAR)}` : ""}`;
19837
18823
  }
19838
18824
  case "error": {
19839
- const i = t2 ? `${styleText2("yellow", S_BAR)} ` : "", u3 = this.error.split(`
18825
+ const i = t2 ? `${styleText2("yellow", S_BAR)} ` : "", u2 = this.error.split(`
19840
18826
  `).map(($, x) => x === 0 ? `${t2 ? `${styleText2("yellow", S_BAR_END)} ` : ""}${styleText2("yellow", $)}` : ` ${$}`).join(`
19841
18827
  `), s = r2.split(`
19842
- `).length, g2 = u3.split(`
18828
+ `).length, g = u2.split(`
19843
18829
  `).length + 1;
19844
18830
  return `${r2}${i}${limitOptions({
19845
18831
  output: n2.output,
@@ -19847,16 +18833,16 @@ ${styleText2("gray", S_BAR)}` : ""}`;
19847
18833
  cursor: this.cursor,
19848
18834
  maxItems: n2.maxItems,
19849
18835
  columnPadding: i.length,
19850
- rowPadding: s + g2,
19851
- style: p2
18836
+ rowPadding: s + g,
18837
+ style: p
19852
18838
  }).join(`
19853
18839
  ${i}`)}
19854
- ${u3}
18840
+ ${u2}
19855
18841
  `;
19856
18842
  }
19857
18843
  default: {
19858
- const i = t2 ? `${styleText2("cyan", S_BAR)} ` : "", u3 = r2.split(`
19859
- `).length, s = formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t2), g2 = s.join(`
18844
+ const i = t2 ? `${styleText2("cyan", S_BAR)} ` : "", u2 = r2.split(`
18845
+ `).length, s = formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t2), g = s.join(`
19860
18846
  `), $ = s.length + 1;
19861
18847
  return `${r2}${i}${limitOptions({
19862
18848
  output: n2.output,
@@ -19864,11 +18850,11 @@ ${u3}
19864
18850
  cursor: this.cursor,
19865
18851
  maxItems: n2.maxItems,
19866
18852
  columnPadding: i.length,
19867
- rowPadding: u3 + $,
19868
- style: p2
18853
+ rowPadding: u2 + $,
18854
+ style: p
19869
18855
  }).join(`
19870
18856
  ${i}`)}
19871
- ${g2}
18857
+ ${g}
19872
18858
  `;
19873
18859
  }
19874
18860
  }
@@ -19884,42 +18870,42 @@ ${styleText2("gray", S_BAR_END)} ` : "";
19884
18870
  i.write(`${e}${o2}
19885
18871
 
19886
18872
  `);
19887
- }, W$1 = (o2) => o2, C2 = (o2, e, s) => {
18873
+ }, W$1 = (o2) => o2, C = (o2, e, s) => {
19888
18874
  const a3 = {
19889
18875
  hard: true,
19890
18876
  trim: false
19891
18877
  }, i = wrapAnsi(o2, e, a3).split(`
19892
- `), c2 = i.reduce((n2, t2) => Math.max(dist_default2(t2), n2), 0), u3 = i.map(s).reduce((n2, t2) => Math.max(dist_default2(t2), n2), 0), g2 = e - (u3 - c2);
19893
- return wrapAnsi(o2, g2, a3);
18878
+ `), c = i.reduce((n2, t2) => Math.max(dist_default2(t2), n2), 0), u2 = i.map(s).reduce((n2, t2) => Math.max(dist_default2(t2), n2), 0), g = e - (u2 - c);
18879
+ return wrapAnsi(o2, g, a3);
19894
18880
  }, note = (o2 = "", e = "", s) => {
19895
- const a3 = s?.output ?? process$1.stdout, i = s?.withGuide ?? settings.withGuide, c2 = s?.format ?? W$1, g2 = ["", ...C2(o2, getColumns(a3) - 6, c2).split(`
19896
- `).map(c2), ""], n2 = dist_default2(e), t2 = Math.max(g2.reduce((m3, F) => {
18881
+ const a3 = s?.output ?? process$1.stdout, i = s?.withGuide ?? settings.withGuide, c = s?.format ?? W$1, g = ["", ...C(o2, getColumns(a3) - 6, c).split(`
18882
+ `).map(c), ""], n2 = dist_default2(e), t2 = Math.max(g.reduce((m2, F) => {
19897
18883
  const O = dist_default2(F);
19898
- return O > m3 ? O : m3;
19899
- }, 0), n2) + 2, h2 = g2.map((m3) => `${styleText2("gray", S_BAR)} ${m3}${" ".repeat(t2 - dist_default2(m3))}${styleText2("gray", S_BAR)}`).join(`
19900
- `), T3 = i ? `${styleText2("gray", S_BAR)}
18884
+ return O > m2 ? O : m2;
18885
+ }, 0), n2) + 2, h2 = g.map((m2) => `${styleText2("gray", S_BAR)} ${m2}${" ".repeat(t2 - dist_default2(m2))}${styleText2("gray", S_BAR)}`).join(`
18886
+ `), T = i ? `${styleText2("gray", S_BAR)}
19901
18887
  ` : "", l$1 = i ? S_CONNECT_LEFT : S_CORNER_BOTTOM_LEFT;
19902
- a3.write(`${T3}${styleText2("green", S_STEP_SUBMIT)} ${styleText2("reset", e)} ${styleText2("gray", S_BAR_H.repeat(Math.max(t2 - n2 - 1, 1)) + S_CORNER_TOP_RIGHT)}
18888
+ a3.write(`${T}${styleText2("green", S_STEP_SUBMIT)} ${styleText2("reset", e)} ${styleText2("gray", S_BAR_H.repeat(Math.max(t2 - n2 - 1, 1)) + S_CORNER_TOP_RIGHT)}
19903
18889
  ${h2}
19904
18890
  ${styleText2("gray", l$1 + S_BAR_H.repeat(t2 + 2) + S_CORNER_BOTTOM_RIGHT)}
19905
18891
  `);
19906
- }, u3, SELECT_INSTRUCTIONS, c2 = (t2, a3) => t2.includes(`
18892
+ }, u2, SELECT_INSTRUCTIONS, c = (t2, a3) => t2.includes(`
19907
18893
  `) ? t2.split(`
19908
18894
  `).map((i) => a3(i)).join(`
19909
18895
  `) : a3(t2), select = (t2) => {
19910
- const a3 = (i, m3) => {
18896
+ const a3 = (i, m2) => {
19911
18897
  const s = i.label ?? String(i.value);
19912
- switch (m3) {
18898
+ switch (m2) {
19913
18899
  case "disabled":
19914
- return `${styleText2("gray", S_RADIO_INACTIVE)} ${c2(s, (n2) => styleText2("gray", n2))}${i.hint ? ` ${styleText2("dim", `(${i.hint ?? "disabled"})`)}` : ""}`;
18900
+ return `${styleText2("gray", S_RADIO_INACTIVE)} ${c(s, (n2) => styleText2("gray", n2))}${i.hint ? ` ${styleText2("dim", `(${i.hint ?? "disabled"})`)}` : ""}`;
19915
18901
  case "selected":
19916
- return `${c2(s, (n2) => styleText2("dim", n2))}`;
18902
+ return `${c(s, (n2) => styleText2("dim", n2))}`;
19917
18903
  case "active":
19918
18904
  return `${styleText2("green", S_RADIO_ACTIVE)} ${s}${i.hint ? ` ${styleText2("dim", `(${i.hint})`)}` : ""}`;
19919
18905
  case "cancelled":
19920
- return `${c2(s, (n2) => styleText2(["strikethrough", "dim"], n2))}`;
18906
+ return `${c(s, (n2) => styleText2(["strikethrough", "dim"], n2))}`;
19921
18907
  default:
19922
- return `${styleText2("dim", S_RADIO_INACTIVE)} ${c2(s, (n2) => styleText2("dim", n2))}`;
18908
+ return `${styleText2("dim", S_RADIO_INACTIVE)} ${c(s, (n2) => styleText2("dim", n2))}`;
19923
18909
  }
19924
18910
  };
19925
18911
  return new a2({
@@ -19929,31 +18915,31 @@ ${styleText2("gray", l$1 + S_BAR_H.repeat(t2 + 2) + S_CORNER_BOTTOM_RIGHT)}
19929
18915
  output: t2.output,
19930
18916
  initialValue: t2.initialValue,
19931
18917
  render() {
19932
- const i = t2.withGuide ?? settings.withGuide, m3 = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, n2 = wrapTextWithPrefix(t2.output, t2.message, s, m3), u4 = `${i ? `${styleText2("gray", S_BAR)}
18918
+ const i = t2.withGuide ?? settings.withGuide, m2 = `${symbol(this.state)} `, s = `${symbolBar(this.state)} `, n2 = wrapTextWithPrefix(t2.output, t2.message, s, m2), u3 = `${i ? `${styleText2("gray", S_BAR)}
19933
18919
  ` : ""}${n2}
19934
18920
  `;
19935
18921
  switch (this.state) {
19936
18922
  case "submit": {
19937
18923
  const r2 = i ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(t2.output, a3(this.options[this.cursor], "selected"), r2);
19938
- return `${u4}${o2}`;
18924
+ return `${u3}${o2}`;
19939
18925
  }
19940
18926
  case "cancel": {
19941
18927
  const r2 = i ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(t2.output, a3(this.options[this.cursor], "cancelled"), r2);
19942
- return `${u4}${o2}${i ? `
18928
+ return `${u3}${o2}${i ? `
19943
18929
  ${styleText2("gray", S_BAR)}` : ""}`;
19944
18930
  }
19945
18931
  default: {
19946
- const r2 = i ? `${styleText2("cyan", S_BAR)} ` : "", o2 = u4.split(`
18932
+ const r2 = i ? `${styleText2("cyan", S_BAR)} ` : "", o2 = u3.split(`
19947
18933
  `).length, $ = formatInstructionFooter(SELECT_INSTRUCTIONS, i), h2 = $.join(`
19948
- `), b2 = $.length + 1;
19949
- return `${u4}${r2}${limitOptions({
18934
+ `), b = $.length + 1;
18935
+ return `${u3}${r2}${limitOptions({
19950
18936
  output: t2.output,
19951
18937
  cursor: this.cursor,
19952
18938
  options: this.options,
19953
18939
  maxItems: t2.maxItems,
19954
18940
  columnPadding: r2.length,
19955
- rowPadding: o2 + b2,
19956
- style: (p2, x) => a3(p2, p2.disabled ? "disabled" : x ? "active" : "inactive")
18941
+ rowPadding: o2 + b,
18942
+ style: (p, x) => a3(p, p.disabled ? "disabled" : x ? "active" : "inactive")
19957
18943
  }).join(`
19958
18944
  ${r2}`)}
19959
18945
  ${h2}
@@ -19973,7 +18959,7 @@ ${h2}
19973
18959
  render() {
19974
18960
  const i2 = t2?.withGuide ?? settings.withGuide, s = `${`${i2 ? `${styleText2("gray", S_BAR)}
19975
18961
  ` : ""}${symbol(this.state)} `}${t2.message}
19976
- `, c3 = t2.placeholder ? styleText2("inverse", t2.placeholder[0]) + styleText2("dim", t2.placeholder.slice(1)) : styleText2(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c3, a3 = this.value ?? "";
18962
+ `, c2 = t2.placeholder ? styleText2("inverse", t2.placeholder[0]) + styleText2("dim", t2.placeholder.slice(1)) : styleText2(["inverse", "hidden"], "_"), o2 = this.userInput ? this.userInputWithCursor : c2, a3 = this.value ?? "";
19977
18963
  switch (this.state) {
19978
18964
  case "error": {
19979
18965
  const n2 = this.error ? ` ${styleText2("yellow", this.error)}` : "", r2 = i2 ? `${styleText2("yellow", S_BAR)} ` : "", d = i2 ? styleText2("yellow", S_BAR_END) : "";
@@ -20041,22 +19027,22 @@ var init_dist6 = __esm(() => {
20041
19027
  message: (s = [], {
20042
19028
  symbol: e = styleText2("gray", S_BAR),
20043
19029
  secondarySymbol: r2 = styleText2("gray", S_BAR),
20044
- output: m3 = process.stdout,
19030
+ output: m2 = process.stdout,
20045
19031
  spacing: l = 1,
20046
- withGuide: c2
19032
+ withGuide: c
20047
19033
  } = {}) => {
20048
- const t2 = [], o2 = c2 ?? settings.withGuide, f2 = o2 ? r2 : "", O = o2 ? `${e} ` : "", u3 = o2 ? `${r2} ` : "";
19034
+ const t2 = [], o2 = c ?? settings.withGuide, f = o2 ? r2 : "", O = o2 ? `${e} ` : "", u2 = o2 ? `${r2} ` : "";
20049
19035
  for (let i = 0;i < l; i++)
20050
- t2.push(f2);
20051
- const g2 = Array.isArray(s) ? s : s.split(`
19036
+ t2.push(f);
19037
+ const g = Array.isArray(s) ? s : s.split(`
20052
19038
  `);
20053
- if (g2.length > 0) {
20054
- const [i, ...y] = g2;
19039
+ if (g.length > 0) {
19040
+ const [i, ...y] = g;
20055
19041
  i.length > 0 ? t2.push(`${O}${i}`) : t2.push(o2 ? e : "");
20056
- for (const p2 of y)
20057
- p2.length > 0 ? t2.push(`${u3}${p2}`) : t2.push(o2 ? r2 : "");
19042
+ for (const p of y)
19043
+ p.length > 0 ? t2.push(`${u2}${p}`) : t2.push(o2 ? r2 : "");
20058
19044
  }
20059
- m3.write(`${t2.join(`
19045
+ m2.write(`${t2.join(`
20060
19046
  `)}
20061
19047
  `);
20062
19048
  },
@@ -20079,7 +19065,7 @@ var init_dist6 = __esm(() => {
20079
19065
  log2.message(s, { ...e, symbol: styleText2("red", S_ERROR) });
20080
19066
  }
20081
19067
  };
20082
- u3 = {
19068
+ u2 = {
20083
19069
  light: unicodeOr("─", "-"),
20084
19070
  heavy: unicodeOr("━", "="),
20085
19071
  block: unicodeOr("█", "#")
@@ -20344,7 +19330,7 @@ function isResponseForRequest(parsed, expectedIds) {
20344
19330
  return expectedIds.has(id);
20345
19331
  }
20346
19332
  async function sendAftRequests(binaryPath, requests) {
20347
- return new Promise((resolve8, reject) => {
19333
+ return new Promise((resolve9, reject) => {
20348
19334
  const child = spawn3(binaryPath, [], {
20349
19335
  stdio: ["pipe", "pipe", "pipe"]
20350
19336
  });
@@ -20381,7 +19367,7 @@ async function sendAftRequests(binaryPath, requests) {
20381
19367
  const response = parsed;
20382
19368
  responses.push(response);
20383
19369
  if (responses.length === requests.length) {
20384
- finish(() => resolve8(responses));
19370
+ finish(() => resolve9(responses));
20385
19371
  }
20386
19372
  };
20387
19373
  child.stdout.setEncoding("utf-8");
@@ -20411,11 +19397,14 @@ async function sendAftRequests(binaryPath, requests) {
20411
19397
  return;
20412
19398
  finish(() => reject(buildBridgeError({ binaryPath, code, stderr, noiseLines, responses })));
20413
19399
  });
20414
- for (const request of requests) {
20415
- child.stdin.write(`${JSON.stringify(request)}
19400
+ child.stdin.on("error", () => {});
19401
+ try {
19402
+ for (const request of requests) {
19403
+ child.stdin.write(`${JSON.stringify(request)}
20416
19404
  `);
20417
- }
20418
- child.stdin.end();
19405
+ }
19406
+ child.stdin.end();
19407
+ } catch {}
20419
19408
  });
20420
19409
  }
20421
19410
  function buildBridgeError(ctx) {
@@ -20451,17 +19440,17 @@ var init_aft_bridge = () => {};
20451
19440
  // src/commands/lsp.ts
20452
19441
  var exports_lsp = {};
20453
19442
  __export(exports_lsp, {
20454
- typescriptPackageWarning: () => typescriptPackageWarning,
20455
- runLspDoctor: () => runLspDoctor,
20456
- renderLspInspection: () => renderLspInspection,
19443
+ findProjectRootForFile: () => findProjectRootForFile,
20457
19444
  printLspDoctorHelp: () => printLspDoctorHelp,
20458
- findProjectRootForFile: () => findProjectRootForFile
19445
+ renderLspInspection: () => renderLspInspection,
19446
+ runLspDoctor: () => runLspDoctor,
19447
+ typescriptPackageWarning: () => typescriptPackageWarning
20459
19448
  });
20460
19449
  import { existsSync as existsSync14, readdirSync as readdirSync5, statSync as statSync9 } from "node:fs";
20461
19450
  import { createRequire as createRequire4 } from "node:module";
20462
- import { dirname as dirname8, join as join17, resolve as resolve8 } from "node:path";
19451
+ import { dirname as dirname8, join as join17, resolve as resolve9 } from "node:path";
20463
19452
  function findProjectRootForFile(filePath, fallbackCwd = process.cwd()) {
20464
- const resolvedFile = resolve8(fallbackCwd, filePath);
19453
+ const resolvedFile = resolve9(fallbackCwd, filePath);
20465
19454
  let dir = dirname8(resolvedFile);
20466
19455
  try {
20467
19456
  if (existsSync14(resolvedFile) && statSync9(resolvedFile).isDirectory()) {
@@ -20476,7 +19465,7 @@ function findProjectRootForFile(filePath, fallbackCwd = process.cwd()) {
20476
19465
  }
20477
19466
  const parent = dirname8(dir);
20478
19467
  if (parent === dir)
20479
- return resolve8(fallbackCwd);
19468
+ return resolve9(fallbackCwd);
20480
19469
  dir = parent;
20481
19470
  }
20482
19471
  }
@@ -20507,7 +19496,7 @@ async function runLspDoctor(options) {
20507
19496
  log2.error("Could not find the aft binary in the cache, platform package, PATH, or ~/.cargo/bin.");
20508
19497
  return 1;
20509
19498
  }
20510
- const resolvedFile = resolve8(file);
19499
+ const resolvedFile = resolve9(file);
20511
19500
  const projectRoot = findProjectRootForFile(resolvedFile);
20512
19501
  const config = buildConfigureParams(adapter, projectRoot);
20513
19502
  const inspectRequest = {
@@ -20712,15 +19701,15 @@ var init_lsp = __esm(async () => {
20712
19701
  // src/commands/doctor-filters.ts
20713
19702
  var exports_doctor_filters = {};
20714
19703
  __export(exports_doctor_filters, {
20715
- runDoctorFilters: () => runDoctorFilters,
20716
- renderTrustedProjects: () => renderTrustedProjects,
20717
- renderFilterShow: () => renderFilterShow,
19704
+ printDoctorFiltersHelp: () => printDoctorFiltersHelp,
20718
19705
  renderFilterList: () => renderFilterList,
20719
- printDoctorFiltersHelp: () => printDoctorFiltersHelp
19706
+ renderFilterShow: () => renderFilterShow,
19707
+ renderTrustedProjects: () => renderTrustedProjects,
19708
+ runDoctorFilters: () => runDoctorFilters
20720
19709
  });
20721
19710
  import { existsSync as existsSync15 } from "node:fs";
20722
19711
  import { homedir as homedir16 } from "node:os";
20723
- import { relative as relative3, resolve as resolve9 } from "node:path";
19712
+ import { relative as relative3, resolve as resolve10 } from "node:path";
20724
19713
  function printDoctorFiltersHelp() {
20725
19714
  console.log(`Usage: ${CLI} doctor filters [--show <name>] [trust|untrust]`);
20726
19715
  console.log("");
@@ -20755,7 +19744,7 @@ async function runDoctorFilters(options) {
20755
19744
  log2.error("Could not find the aft binary in the cache, platform package, PATH, or ~/.cargo/bin.");
20756
19745
  return 1;
20757
19746
  }
20758
- const projectRoot = resolve9(process.cwd());
19747
+ const projectRoot = resolve10(process.cwd());
20759
19748
  const list = await listFilters(binary, adapter, projectRoot, options.sendRequests ?? sendAftRequests);
20760
19749
  if (!list.success) {
20761
19750
  log2.error(list.message ?? list.code ?? "list_filters failed");
@@ -20999,9 +19988,9 @@ import { homedir as homedir17, userInfo } from "node:os";
20999
19988
  function escapeRegex(value) {
21000
19989
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
21001
19990
  }
21002
- function safeRealpath(p2) {
19991
+ function safeRealpath(p) {
21003
19992
  try {
21004
- return realpathSync3(p2);
19993
+ return realpathSync3(p);
21005
19994
  } catch {
21006
19995
  return null;
21007
19996
  }
@@ -21172,11 +20161,11 @@ function aggregateBridgeToolFailures(logText) {
21172
20161
  }
21173
20162
  return counts;
21174
20163
  }
21175
- function sortFailureKeys(a3, b2, counts) {
21176
- const countDiff = (counts.get(b2) ?? 0) - (counts.get(a3) ?? 0);
20164
+ function sortFailureKeys(a3, b, counts) {
20165
+ const countDiff = (counts.get(b) ?? 0) - (counts.get(a3) ?? 0);
21177
20166
  if (countDiff !== 0)
21178
20167
  return countDiff;
21179
- return a3.localeCompare(b2);
20168
+ return a3.localeCompare(b);
21180
20169
  }
21181
20170
  function formatRecentAftToolFailuresSection(counts, options) {
21182
20171
  const maxClasses = options?.maxClasses ?? MAX_TOOL_FAILURE_CLASSES;
@@ -21185,7 +20174,7 @@ function formatRecentAftToolFailuresSection(counts, options) {
21185
20174
  return `${heading}
21186
20175
  No recent AFT tool failures recorded.`;
21187
20176
  }
21188
- const sorted = [...counts.keys()].sort((a3, b2) => sortFailureKeys(a3, b2, counts));
20177
+ const sorted = [...counts.keys()].sort((a3, b) => sortFailureKeys(a3, b, counts));
21189
20178
  const shown = sorted.slice(0, maxClasses);
21190
20179
  const hidden = sorted.length - shown.length;
21191
20180
  const bullets = shown.map((key) => {
@@ -21213,21 +20202,105 @@ var init_bridge_tool_failures = __esm(() => {
21213
20202
  STRUCTURED_CODE_PATTERN = /"code"\s*:\s*"([^"]+)"/;
21214
20203
  });
21215
20204
 
21216
- // src/lib/legacy-storage.ts
21217
- import { existsSync as existsSync18, readdirSync as readdirSync7, statSync as statSync12 } from "node:fs";
20205
+ // src/lib/build-breaker.ts
20206
+ import { existsSync as existsSync18, readdirSync as readdirSync7 } from "node:fs";
21218
20207
  import { join as join19 } from "node:path";
20208
+ import { DatabaseSync } from "node:sqlite";
20209
+ function buildBreakerDatabases(storageRoot) {
20210
+ const callgraphRoot = join19(storageRoot, "callgraph");
20211
+ if (!existsSync18(callgraphRoot))
20212
+ return [];
20213
+ try {
20214
+ return readdirSync7(callgraphRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join19(callgraphRoot, entry.name, "build-breaker.sqlite")).filter((path2) => existsSync18(path2));
20215
+ } catch {
20216
+ return [];
20217
+ }
20218
+ }
20219
+ function readBuildBreakerSuspensions(storageRoot, nowMs = Date.now()) {
20220
+ const suspensions = [];
20221
+ for (const databasePath of buildBreakerDatabases(storageRoot)) {
20222
+ let database;
20223
+ try {
20224
+ database = new DatabaseSync(databasePath, { readOnly: true });
20225
+ const rows = database.prepare(`SELECT root_id, domain, corpus_fingerprint, zero_credit_deaths, credited_deaths,
20226
+ suspended_reason, suspended_since_ms
20227
+ FROM breaker_records
20228
+ WHERE configuration_version = 'v1'
20229
+ AND suspended_reason IS NOT NULL
20230
+ AND suspended_since_ms IS NOT NULL
20231
+ AND suspended_until_ms > ?
20232
+ ORDER BY root_id, domain`).all(nowMs);
20233
+ for (const row of rows) {
20234
+ const deathCount = Number(row.zero_credit_deaths) + Number(row.credited_deaths);
20235
+ const ageS = Math.floor(Math.max(0, nowMs - Number(row.suspended_since_ms)) / 1000);
20236
+ suspensions.push({
20237
+ root: row.root_id,
20238
+ domain: row.domain,
20239
+ reason: row.suspended_reason,
20240
+ deathCount,
20241
+ ageS,
20242
+ fingerprint: row.corpus_fingerprint
20243
+ });
20244
+ }
20245
+ } catch {} finally {
20246
+ database?.close();
20247
+ }
20248
+ }
20249
+ return suspensions;
20250
+ }
20251
+ function formatBuildBreakerSuspension(suspension) {
20252
+ return [
20253
+ ` build suspended: root=${suspension.root}`,
20254
+ `domain=${suspension.domain}`,
20255
+ `deaths=${suspension.deathCount}`,
20256
+ `age_s=${suspension.ageS}`,
20257
+ `reason=${suspension.reason};`,
20258
+ `reset with \`${DOCTOR_BUILD_BREAKER_RESET_COMMAND} --root ${suspension.root} --domain ${suspension.domain} --fingerprint ${suspension.fingerprint}\``
20259
+ ].join(" ");
20260
+ }
20261
+ function resetBuildBreakerSuspension(storageRoot, target) {
20262
+ let reset = 0;
20263
+ for (const databasePath of buildBreakerDatabases(storageRoot)) {
20264
+ let database;
20265
+ try {
20266
+ database = new DatabaseSync(databasePath);
20267
+ const result = database.prepare(`UPDATE breaker_records
20268
+ SET zero_credit_deaths = 0,
20269
+ credited_deaths = 0,
20270
+ in_build_burn_ms = 0,
20271
+ suspended_reason = NULL,
20272
+ suspended_since_ms = NULL,
20273
+ suspended_until_ms = NULL
20274
+ WHERE root_id = ?
20275
+ AND domain = ?
20276
+ AND corpus_fingerprint = ?`).run(target.root, target.domain, target.fingerprint);
20277
+ reset += Number(result.changes ?? 0);
20278
+ } catch {} finally {
20279
+ database?.close();
20280
+ }
20281
+ }
20282
+ return reset;
20283
+ }
20284
+ var DOCTOR_BUILD_BREAKER_RESET_COMMAND;
20285
+ var init_build_breaker = __esm(() => {
20286
+ DOCTOR_BUILD_BREAKER_RESET_COMMAND = `${CLI} doctor reset-build-breaker`;
20287
+ });
20288
+
20289
+ // src/lib/legacy-storage.ts
20290
+ import { existsSync as existsSync19, readdirSync as readdirSync8, statSync as statSync12 } from "node:fs";
20291
+ import { join as join20 } from "node:path";
21219
20292
  function summarizeLegacyPartitionDuplication(storageRoot) {
21220
- if (!existsSync18(storageRoot)) {
20293
+ if (!existsSync19(storageRoot)) {
21221
20294
  return { totalPartitions: 0, totalBytes: 0, byHarness: [] };
21222
20295
  }
21223
20296
  const byHarness = [];
21224
20297
  for (const harness of safeReadDir(storageRoot)) {
21225
- const harnessPath = join19(storageRoot, harness);
20298
+ const harnessPath = join20(storageRoot, harness);
21226
20299
  if (!isDirectory(harnessPath))
21227
20300
  continue;
21228
20301
  const partitions = new Map;
21229
- collectCallgraphPartitions(join19(harnessPath, "callgraph"), partitions);
21230
- collectInspectPartitions(join19(harnessPath, "inspect"), partitions);
20302
+ collectCallgraphPartitions(join20(harnessPath, "callgraph"), partitions);
20303
+ collectInspectPartitions(join20(harnessPath, "inspect"), partitions);
21231
20304
  if (partitions.size === 0)
21232
20305
  continue;
21233
20306
  let bytes = 0;
@@ -21246,7 +20319,7 @@ function collectCallgraphPartitions(domainPath, partitions) {
21246
20319
  if (!isDirectory(domainPath))
21247
20320
  return;
21248
20321
  for (const name of safeReadDir(domainPath)) {
21249
- const path2 = join19(domainPath, name);
20322
+ const path2 = join20(domainPath, name);
21250
20323
  if (isDirectory(path2)) {
21251
20324
  if (!looksLikePartitionKey(name))
21252
20325
  continue;
@@ -21263,7 +20336,7 @@ function collectInspectPartitions(domainPath, partitions) {
21263
20336
  if (!isDirectory(domainPath))
21264
20337
  return;
21265
20338
  for (const name of safeReadDir(domainPath)) {
21266
- const path2 = join19(domainPath, name);
20339
+ const path2 = join20(domainPath, name);
21267
20340
  if (isDirectory(path2)) {
21268
20341
  if (!looksLikePartitionKey(name))
21269
20342
  continue;
@@ -21312,7 +20385,7 @@ function looksLikePartitionKey(value) {
21312
20385
  }
21313
20386
  function safeReadDir(path2) {
21314
20387
  try {
21315
- return readdirSync7(path2).sort((left, right) => left.localeCompare(right));
20388
+ return readdirSync8(path2).sort((left, right) => left.localeCompare(right));
21316
20389
  } catch {
21317
20390
  return [];
21318
20391
  }
@@ -21338,22 +20411,22 @@ var init_legacy_storage = __esm(() => {
21338
20411
  });
21339
20412
 
21340
20413
  // src/lib/lsp-cache.ts
21341
- import { existsSync as existsSync19, readdirSync as readdirSync8, rmSync as rmSync5, statSync as statSync13 } from "node:fs";
21342
- import { join as join20 } from "node:path";
20414
+ import { existsSync as existsSync20, readdirSync as readdirSync9, rmSync as rmSync5, statSync as statSync13 } from "node:fs";
20415
+ import { join as join21 } from "node:path";
21343
20416
  function inspectDir(path2) {
21344
- if (!existsSync19(path2)) {
20417
+ if (!existsSync20(path2)) {
21345
20418
  return { entries: [], totalSize: 0 };
21346
20419
  }
21347
20420
  const entries = [];
21348
20421
  let totalSize = 0;
21349
20422
  let names;
21350
20423
  try {
21351
- names = readdirSync8(path2);
20424
+ names = readdirSync9(path2);
21352
20425
  } catch {
21353
20426
  return { entries: [], totalSize: 0 };
21354
20427
  }
21355
20428
  for (const name of names) {
21356
- const full = join20(path2, name);
20429
+ const full = join21(path2, name);
21357
20430
  try {
21358
20431
  if (!statSync13(full).isDirectory())
21359
20432
  continue;
@@ -21366,7 +20439,7 @@ function inspectDir(path2) {
21366
20439
  totalSize += size;
21367
20440
  } catch {}
21368
20441
  }
21369
- entries.sort((a3, b2) => b2.size - a3.size);
20442
+ entries.sort((a3, b) => b.size - a3.size);
21370
20443
  return { entries, totalSize };
21371
20444
  }
21372
20445
  function getLspCacheReport() {
@@ -21411,8 +20484,8 @@ var init_lsp_cache = __esm(() => {
21411
20484
  });
21412
20485
 
21413
20486
  // src/lib/onnx.ts
21414
- import { existsSync as existsSync20, readdirSync as readdirSync9, readlinkSync as readlinkSync2, realpathSync as realpathSync4 } from "node:fs";
21415
- import { basename as basename3, isAbsolute as isAbsolute6, join as join21, resolve as resolve10, win32 as win322 } from "node:path";
20487
+ import { existsSync as existsSync21, readdirSync as readdirSync10, readlinkSync as readlinkSync2, realpathSync as realpathSync4 } from "node:fs";
20488
+ import { basename as basename3, isAbsolute as isAbsolute6, join as join22, resolve as resolve11, win32 as win322 } from "node:path";
21416
20489
  function getOnnxLibraryName() {
21417
20490
  if (process.platform === "darwin")
21418
20491
  return "libonnxruntime.dylib";
@@ -21421,20 +20494,20 @@ function getOnnxLibraryName() {
21421
20494
  return "libonnxruntime.so";
21422
20495
  }
21423
20496
  function getManualInstallHint2() {
21424
- const p2 = process.platform;
20497
+ const p = process.platform;
21425
20498
  const a3 = process.arch;
21426
- if (p2 === "darwin") {
20499
+ if (p === "darwin") {
21427
20500
  if (a3 === "arm64")
21428
20501
  return "brew install onnxruntime (Apple Silicon)";
21429
20502
  return "Intel Mac requires manual install — see docs";
21430
20503
  }
21431
- if (p2 === "linux") {
20504
+ if (p === "linux") {
21432
20505
  if (a3 === "x64" || a3 === "arm64") {
21433
20506
  return "AFT auto-downloads ONNX Runtime on supported Linux (glibc)";
21434
20507
  }
21435
20508
  return "manual install required for this Linux arch";
21436
20509
  }
21437
- if (p2 === "win32") {
20510
+ if (p === "win32") {
21438
20511
  if (a3 === "x64" || a3 === "arm64")
21439
20512
  return "AFT auto-downloads ONNX Runtime on Windows";
21440
20513
  return "manual install required for this Windows arch";
@@ -21465,7 +20538,7 @@ function isWindowsSystem32Directory2(dir) {
21465
20538
  }
21466
20539
  function directoryContainsLibrary2(dir, libName) {
21467
20540
  try {
21468
- const entries = readdirSync9(dir);
20541
+ const entries = readdirSync10(dir);
21469
20542
  if (process.platform === "win32") {
21470
20543
  const expected = libName.toLowerCase();
21471
20544
  return entries.some((entry) => entry.toLowerCase() === expected);
@@ -21483,7 +20556,7 @@ function findIgnoredWindowsSystemOnnxRuntime() {
21483
20556
  for (const root of windowsRoots) {
21484
20557
  if (!root)
21485
20558
  continue;
21486
- const systemDir = join21(root, "System32");
20559
+ const systemDir = join22(root, "System32");
21487
20560
  const key = win322.resolve(systemDir).toLowerCase();
21488
20561
  if (seen.has(key))
21489
20562
  continue;
@@ -21504,21 +20577,21 @@ function findSystemOnnxRuntime2() {
21504
20577
  searchPaths.push(...pathEntriesForPlatform2());
21505
20578
  const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
21506
20579
  const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
21507
- searchPaths.push(join21(programFiles, "onnxruntime", "lib"), join21(programFiles, "Microsoft ONNX Runtime", "lib"), join21(programFiles, "Microsoft Machine Learning", "lib"), join21(programFilesX86, "onnxruntime", "lib"), ...(() => {
20580
+ searchPaths.push(join22(programFiles, "onnxruntime", "lib"), join22(programFiles, "Microsoft ONNX Runtime", "lib"), join22(programFiles, "Microsoft Machine Learning", "lib"), join22(programFilesX86, "onnxruntime", "lib"), ...(() => {
21508
20581
  const nugetPaths = [];
21509
20582
  const userProfile = process.env.USERPROFILE ?? "";
21510
20583
  if (!userProfile)
21511
20584
  return nugetPaths;
21512
- const nugetPackageDir = join21(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
21513
- if (!existsSync20(nugetPackageDir))
20585
+ const nugetPackageDir = join22(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
20586
+ if (!existsSync21(nugetPackageDir))
21514
20587
  return nugetPaths;
21515
20588
  try {
21516
- for (const entry of readdirSync9(nugetPackageDir, { withFileTypes: true })) {
20589
+ for (const entry of readdirSync10(nugetPackageDir, { withFileTypes: true })) {
21517
20590
  if (!entry.isDirectory())
21518
20591
  continue;
21519
20592
  if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
21520
20593
  continue;
21521
- nugetPaths.push(join21(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join21(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
20594
+ nugetPaths.push(join22(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join22(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
21522
20595
  }
21523
20596
  } catch {}
21524
20597
  return nugetPaths;
@@ -21528,7 +20601,7 @@ function findSystemOnnxRuntime2() {
21528
20601
  const seen = new Set;
21529
20602
  const unknownVersionPaths = [];
21530
20603
  for (const dir of searchPaths) {
21531
- let key = resolve10(dir).replace(/[/\\]+$/, "");
20604
+ let key = resolve11(dir).replace(/[/\\]+$/, "");
21532
20605
  if (normalizeCase)
21533
20606
  key = key.toLowerCase();
21534
20607
  if (seen.has(key))
@@ -21550,12 +20623,12 @@ function findSystemOnnxRuntime2() {
21550
20623
  return unknownVersionPaths[0] ?? null;
21551
20624
  }
21552
20625
  function findCachedOnnxRuntime(storageDir) {
21553
- const ortDir = join21(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
20626
+ const ortDir = join22(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
21554
20627
  const libName = getOnnxLibraryName();
21555
- if (existsSync20(join21(ortDir, libName)))
20628
+ if (existsSync21(join22(ortDir, libName)))
21556
20629
  return ortDir;
21557
- const libSubdir = join21(ortDir, "lib");
21558
- if (existsSync20(join21(libSubdir, libName)))
20630
+ const libSubdir = join22(ortDir, "lib");
20631
+ if (existsSync21(join22(libSubdir, libName)))
21559
20632
  return libSubdir;
21560
20633
  return null;
21561
20634
  }
@@ -21576,11 +20649,11 @@ function parseOrtVersionFromDirectoryPath(value) {
21576
20649
  return null;
21577
20650
  }
21578
20651
  function detectOrtVersion(libDir) {
21579
- if (!existsSync20(libDir))
20652
+ if (!existsSync21(libDir))
21580
20653
  return null;
21581
20654
  const libName = getOnnxLibraryName();
21582
20655
  try {
21583
- const entries = readdirSync9(libDir);
20656
+ const entries = readdirSync10(libDir);
21584
20657
  const barePrefix = libName.replace(/\.(so|dylib|dll)$/, "");
21585
20658
  const expectedPrefix = process.platform === "win32" ? barePrefix.toLowerCase() : barePrefix;
21586
20659
  for (const entry of entries) {
@@ -21591,8 +20664,8 @@ function detectOrtVersion(libDir) {
21591
20664
  if (version)
21592
20665
  return version;
21593
20666
  }
21594
- const base = join21(libDir, libName);
21595
- if (existsSync20(base)) {
20667
+ const base = join22(libDir, libName);
20668
+ if (existsSync21(base)) {
21596
20669
  try {
21597
20670
  const real = realpathSync4(base);
21598
20671
  const version = parseOrtVersionFromPath(real) ?? parseOrtVersionFromDirectoryPath(real);
@@ -21611,7 +20684,7 @@ function detectOrtVersion(libDir) {
21611
20684
  return null;
21612
20685
  }
21613
20686
  function isOrtVersionCompatible(version) {
21614
- const parts = version.split(".").map((p2) => parseInt(p2, 10));
20687
+ const parts = version.split(".").map((p) => parseInt(p, 10));
21615
20688
  const [major, minor] = parts;
21616
20689
  if (!Number.isFinite(major) || !Number.isFinite(minor))
21617
20690
  return false;
@@ -21627,7 +20700,7 @@ import {
21627
20700
  accessSync,
21628
20701
  closeSync as closeSync6,
21629
20702
  constants,
21630
- existsSync as existsSync21,
20703
+ existsSync as existsSync22,
21631
20704
  openSync as openSync6,
21632
20705
  readSync as readSync3,
21633
20706
  statSync as statSync14
@@ -21648,7 +20721,8 @@ async function collectDiagnostics(adapters) {
21648
20721
  binaryVersion,
21649
20722
  harnesses,
21650
20723
  binaryCache: getBinaryCacheInfo(cliVersion),
21651
- lspCache: getLspCacheReport()
20724
+ lspCache: getLspCacheReport(),
20725
+ buildBreakerSuspensions: harnesses[0] ? readBuildBreakerSuspensions(harnesses[0].storageDir.path) : []
21652
20726
  };
21653
20727
  }
21654
20728
  async function diagnoseHarness(adapter) {
@@ -21665,7 +20739,7 @@ async function diagnoseHarness(adapter) {
21665
20739
  const logPath = adapter.getLogFile();
21666
20740
  const pluginCache = adapter.getPluginCacheInfo();
21667
20741
  const storageAccessible = (() => {
21668
- if (!existsSync21(storage))
20742
+ if (!existsSync22(storage))
21669
20743
  return false;
21670
20744
  try {
21671
20745
  accessSync(storage, constants.R_OK | constants.W_OK);
@@ -21690,7 +20764,7 @@ async function diagnoseHarness(adapter) {
21690
20764
  pluginRegistered: adapter.hasPluginEntry(),
21691
20765
  configPaths,
21692
20766
  aftConfig: {
21693
- exists: existsSync21(configPaths.aftConfig),
20767
+ exists: existsSync22(configPaths.aftConfig),
21694
20768
  ...aftConfigRead.error ? { parseError: aftConfigRead.error } : {},
21695
20769
  enabled: aftEnabled,
21696
20770
  ...aftEnabledSource ? { enabledSource: aftEnabledSource } : {},
@@ -21699,7 +20773,7 @@ async function diagnoseHarness(adapter) {
21699
20773
  pluginCache,
21700
20774
  storageDir: {
21701
20775
  path: storage,
21702
- exists: existsSync21(storage),
20776
+ exists: existsSync22(storage),
21703
20777
  accessible: storageAccessible,
21704
20778
  sizesByKey: describeStorage,
21705
20779
  ...legacyDuplication.totalPartitions > 0 ? { legacyDuplication } : {}
@@ -21720,8 +20794,8 @@ async function diagnoseHarness(adapter) {
21720
20794
  },
21721
20795
  logFile: {
21722
20796
  path: logPath,
21723
- exists: existsSync21(logPath),
21724
- sizeKb: existsSync21(logPath) ? Math.round(statSync14(logPath).size / 1024) : 0
20797
+ exists: existsSync22(logPath),
20798
+ sizeKb: existsSync22(logPath) ? Math.round(statSync14(logPath).size / 1024) : 0
21725
20799
  }
21726
20800
  };
21727
20801
  }
@@ -21794,9 +20868,9 @@ function renderDiagnosticsMarkdown(report) {
21794
20868
  function normalizeVersion(version) {
21795
20869
  return version.trim().replace(/^v/, "");
21796
20870
  }
21797
- function compareLooseSemver(a3, b2) {
20871
+ function compareLooseSemver(a3, b) {
21798
20872
  const aParts = normalizeVersion(a3).split(/[.-]/).slice(0, 3).map((part) => Number.parseInt(part, 10));
21799
- const bParts = normalizeVersion(b2).split(/[.-]/).slice(0, 3).map((part) => Number.parseInt(part, 10));
20873
+ const bParts = normalizeVersion(b).split(/[.-]/).slice(0, 3).map((part) => Number.parseInt(part, 10));
21800
20874
  for (let i2 = 0;i2 < 3; i2 += 1) {
21801
20875
  const av = Number.isFinite(aParts[i2]) ? aParts[i2] : 0;
21802
20876
  const bv = Number.isFinite(bParts[i2]) ? bParts[i2] : 0;
@@ -21828,14 +20902,15 @@ function pluginVersionSkewIssue(harness, cliVersion) {
21828
20902
  }
21829
20903
  function collectDiagnosticIssues(report) {
21830
20904
  const issues = [];
21831
- const hasEnabledRegisteredHarness = report.harnesses.some((h2) => h2.pluginRegistered && h2.aftConfig.enabled);
21832
- if (!report.binaryVersion && hasEnabledRegisteredHarness) {
20905
+ const hasEnabledHarness = report.harnesses.some((h2) => h2.hostInstalled && h2.aftConfig.enabled);
20906
+ const hasMatchingEnabledPlugin = report.harnesses.some((h2) => h2.pluginRegistered && h2.aftConfig.enabled && h2.pluginCache.cached && normalizeVersion(h2.pluginCache.cached) === normalizeVersion(report.cliVersion));
20907
+ if (!report.binaryVersion && hasEnabledHarness) {
21833
20908
  issues.push({
21834
20909
  code: "binary_missing",
21835
- severity: "high",
20910
+ severity: hasMatchingEnabledPlugin ? "info" : "high",
21836
20911
  scope: "AFT binary",
21837
- message: `No aft binary matching CLI ${report.cliVersion} was detected.`,
21838
- remediation: `Run \`${CLI} doctor --fix\` to download the matching binary, or start an AFT-enabled session to trigger plugin-side install.`
20912
+ message: hasMatchingEnabledPlugin ? `No aft binary matching CLI ${report.cliVersion} was detected; it will self-install when the next AFT-enabled session starts.` : `No aft binary matching CLI ${report.cliVersion} was detected.`,
20913
+ remediation: hasMatchingEnabledPlugin ? `Start an AFT-enabled session to install the matching binary automatically, or run \`${CLI} doctor --fix\`.` : `Run \`${CLI} doctor --fix\` to download the matching binary, or start an AFT-enabled session to trigger plugin-side install.`
21839
20914
  });
21840
20915
  }
21841
20916
  for (const h2 of report.harnesses) {
@@ -21917,7 +20992,7 @@ function formatDiagnosticIssuesSection(report) {
21917
20992
  return lines;
21918
20993
  }
21919
20994
  function tailLogFile(path2, lines) {
21920
- if (!existsSync21(path2))
20995
+ if (!existsSync22(path2))
21921
20996
  return "";
21922
20997
  if (lines <= 0)
21923
20998
  return "";
@@ -21956,6 +21031,7 @@ function tailLogFile(path2, lines) {
21956
21031
  var init_diagnostics = __esm(async () => {
21957
21032
  init_dist2();
21958
21033
  init_binary_cache();
21034
+ init_build_breaker();
21959
21035
  init_jsonc();
21960
21036
  init_legacy_storage();
21961
21037
  init_lsp_cache();
@@ -22105,14 +21181,14 @@ var init_issue_body = __esm(() => {
22105
21181
  });
22106
21182
 
22107
21183
  // src/lib/onnx-fix.ts
22108
- import { existsSync as existsSync22, rmSync as rmSync6 } from "node:fs";
22109
- import { join as join22 } from "node:path";
21184
+ import { existsSync as existsSync23, rmSync as rmSync6 } from "node:fs";
21185
+ import { join as join23 } from "node:path";
22110
21186
  function findOnnxFixCandidates(report) {
22111
21187
  const candidates = [];
22112
21188
  for (const harness of report.harnesses) {
22113
21189
  if (!harness.onnxRuntime.required)
22114
21190
  continue;
22115
- const storageOnnxDir = join22(harness.storageDir.path, "onnxruntime");
21191
+ const storageOnnxDir = join23(harness.storageDir.path, "onnxruntime");
22116
21192
  const systemTooOld = harness.onnxRuntime.systemPath !== null && harness.onnxRuntime.systemCompatible === false;
22117
21193
  const cachedTooOld = harness.onnxRuntime.cachedPath !== null && harness.onnxRuntime.cachedCompatible === false;
22118
21194
  const hasCompatibleCached = harness.onnxRuntime.cachedCompatible === true;
@@ -22121,7 +21197,7 @@ function findOnnxFixCandidates(report) {
22121
21197
  harness,
22122
21198
  reason: `cached ONNX Runtime at ${harness.onnxRuntime.cachedPath} is v${harness.onnxRuntime.cachedVersion}, but AFT requires ${harness.onnxRuntime.requirement}. Clearing it allows an immediate managed download.`,
22123
21199
  storageOnnxDir,
22124
- storageOnnxBytes: existsSync22(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
21200
+ storageOnnxBytes: existsSync23(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
22125
21201
  });
22126
21202
  continue;
22127
21203
  }
@@ -22130,7 +21206,7 @@ function findOnnxFixCandidates(report) {
22130
21206
  harness,
22131
21207
  reason: `system ONNX Runtime at ${harness.onnxRuntime.systemPath} is v${harness.onnxRuntime.systemVersion}, but AFT requires ${harness.onnxRuntime.requirement}, and no AFT-managed install is present. AFT will leave the system copy untouched and download v1.24 into managed storage.`,
22132
21208
  storageOnnxDir,
22133
- storageOnnxBytes: existsSync22(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
21209
+ storageOnnxBytes: existsSync23(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
22134
21210
  });
22135
21211
  continue;
22136
21212
  }
@@ -22140,7 +21216,7 @@ function findOnnxFixCandidates(report) {
22140
21216
  harness,
22141
21217
  reason: `no compatible ONNX Runtime is installed.${ignoredCopy} AFT will download v1.24 into managed storage.`,
22142
21218
  storageOnnxDir,
22143
- storageOnnxBytes: existsSync22(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
21219
+ storageOnnxBytes: existsSync23(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
22144
21220
  });
22145
21221
  }
22146
21222
  }
@@ -22170,7 +21246,7 @@ async function runOnnxFix(adapters, report, options = {}) {
22170
21246
  const rmFn = options.rmFn ?? rmSync6;
22171
21247
  const ensureFn = options.ensureFn ?? ensureOnnxRuntime;
22172
21248
  for (const candidate of candidates) {
22173
- if (existsSync22(candidate.storageOnnxDir)) {
21249
+ if (existsSync23(candidate.storageOnnxDir)) {
22174
21250
  try {
22175
21251
  rmFn(candidate.storageOnnxDir, { recursive: true, force: true });
22176
21252
  result.cleared += 1;
@@ -22212,10 +21288,10 @@ var init_onnx_fix = __esm(() => {
22212
21288
  });
22213
21289
 
22214
21290
  // src/lib/sessions.ts
22215
- import { existsSync as existsSync23, readdirSync as readdirSync10, readFileSync as readFileSync10, statSync as statSync15 } from "node:fs";
21291
+ import { existsSync as existsSync24, readdirSync as readdirSync11, readFileSync as readFileSync10, statSync as statSync15 } from "node:fs";
22216
21292
  import { createRequire as createRequire5 } from "node:module";
22217
21293
  import { homedir as homedir18 } from "node:os";
22218
- import { basename as basename4, join as join23 } from "node:path";
21294
+ import { basename as basename4, join as join24 } from "node:path";
22219
21295
  function listRecentSessions(adapter) {
22220
21296
  try {
22221
21297
  if (adapter.kind === "opencode")
@@ -22241,11 +21317,11 @@ function mapOpenCodeSessionRows(rows) {
22241
21317
  title: row.title,
22242
21318
  lastActivity
22243
21319
  };
22244
- }).filter((session) => session !== null).sort((a3, b2) => b2.lastActivity - a3.lastActivity).slice(0, MAX_RECENT_SESSIONS);
21320
+ }).filter((session) => session !== null).sort((a3, b) => b.lastActivity - a3.lastActivity).slice(0, MAX_RECENT_SESSIONS);
22245
21321
  }
22246
21322
  function listRecentOpenCodeSessions() {
22247
- const dbPath = join23(getXdgDataHome(), "opencode", "opencode.db");
22248
- if (!existsSync23(dbPath))
21323
+ const dbPath = join24(getXdgDataHome(), "opencode", "opencode.db");
21324
+ if (!existsSync24(dbPath))
22249
21325
  return [];
22250
21326
  let db = null;
22251
21327
  try {
@@ -22264,10 +21340,10 @@ function listRecentOpenCodeSessions() {
22264
21340
  }
22265
21341
  function getXdgDataHome() {
22266
21342
  const xdgDataHome = process.env.XDG_DATA_HOME;
22267
- return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join23(homedir18(), ".local", "share");
21343
+ return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join24(homedir18(), ".local", "share");
22268
21344
  }
22269
21345
  function listRecentPiSessions() {
22270
- return listPiSessionsFromDir(join23(getHomeDir(), ".pi", "agent", "sessions"));
21346
+ return listPiSessionsFromDir(join24(getHomeDir(), ".pi", "agent", "sessions"));
22271
21347
  }
22272
21348
  function getHomeDir() {
22273
21349
  const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
@@ -22275,7 +21351,7 @@ function getHomeDir() {
22275
21351
  }
22276
21352
  function listPiSessionsFromDir(sessionsDir) {
22277
21353
  try {
22278
- if (!existsSync23(sessionsDir))
21354
+ if (!existsSync24(sessionsDir))
22279
21355
  return [];
22280
21356
  const files = collectJsonlFiles(sessionsDir).map((filePath) => {
22281
21357
  try {
@@ -22284,7 +21360,7 @@ function listPiSessionsFromDir(sessionsDir) {
22284
21360
  } catch {
22285
21361
  return null;
22286
21362
  }
22287
- }).filter((entry) => entry !== null).sort((a3, b2) => b2.mtimeMs - a3.mtimeMs).slice(0, MAX_RECENT_SESSIONS * 4);
21363
+ }).filter((entry) => entry !== null).sort((a3, b) => b.mtimeMs - a3.mtimeMs).slice(0, MAX_RECENT_SESSIONS * 4);
22288
21364
  const sessions = [];
22289
21365
  for (const file of files) {
22290
21366
  const parsed = parsePiSessionJsonl(readFileSync10(file.filePath, "utf8"), basename4(file.filePath));
@@ -22308,12 +21384,12 @@ function collectJsonlFiles(root) {
22308
21384
  continue;
22309
21385
  let entries;
22310
21386
  try {
22311
- entries = readdirSync10(dir, { withFileTypes: true });
21387
+ entries = readdirSync11(dir, { withFileTypes: true });
22312
21388
  } catch {
22313
21389
  continue;
22314
21390
  }
22315
21391
  for (const entry of entries) {
22316
- const path2 = join23(dir, entry.name);
21392
+ const path2 = join24(dir, entry.name);
22317
21393
  if (entry.isDirectory()) {
22318
21394
  stack.push(path2);
22319
21395
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -22397,23 +21473,25 @@ var init_sessions = () => {};
22397
21473
  // src/commands/doctor.ts
22398
21474
  var exports_doctor = {};
22399
21475
  __export(exports_doctor, {
22400
- shouldSkipDoctorFixConfirmation: () => shouldSkipDoctorFixConfirmation,
22401
- runDoctor: () => runDoctor,
22402
- hasDoctorProblems: () => hasDoctorProblems,
22403
- formatDoctorStorageStatus: () => formatDoctorStorageStatus,
22404
- fixPluginEntries: () => fixPluginEntries,
22405
- doctorSkewBinaryDownloadDecision: () => doctorSkewBinaryDownloadDecision,
22406
- deriveIssueTitleFromBody: () => deriveIssueTitleFromBody,
22407
- clearOldBinaries: () => clearOldBinaries,
22408
- clearDoctorCaches: () => clearDoctorCaches,
22409
- buildDoctorFixPlan: () => buildDoctorFixPlan,
21476
+ DOCTOR_CLEAR_TARGET_OPTIONS: () => DOCTOR_CLEAR_TARGET_OPTIONS,
22410
21477
  DOCTOR_FORCE_CLEAR_TARGETS: () => DOCTOR_FORCE_CLEAR_TARGETS,
22411
- DOCTOR_CLEAR_TARGET_OPTIONS: () => DOCTOR_CLEAR_TARGET_OPTIONS
21478
+ buildDoctorFixPlan: () => buildDoctorFixPlan,
21479
+ clearDoctorCaches: () => clearDoctorCaches,
21480
+ clearOldBinaries: () => clearOldBinaries,
21481
+ deriveIssueTitleFromBody: () => deriveIssueTitleFromBody,
21482
+ doctorSkewBinaryDownloadDecision: () => doctorSkewBinaryDownloadDecision,
21483
+ fixPluginEntries: () => fixPluginEntries,
21484
+ formatDoctorStorageStatus: () => formatDoctorStorageStatus,
21485
+ hasDoctorProblems: () => hasDoctorProblems,
21486
+ logBuildBreakerSuspensions: () => logBuildBreakerSuspensions,
21487
+ runDoctor: () => runDoctor,
21488
+ runDoctorBuildBreakerReset: () => runDoctorBuildBreakerReset,
21489
+ shouldSkipDoctorFixConfirmation: () => shouldSkipDoctorFixConfirmation
22412
21490
  });
22413
21491
  import { execFileSync as execFileSync3 } from "node:child_process";
22414
21492
  import {
22415
21493
  chmodSync as chmodSync4,
22416
- existsSync as existsSync24,
21494
+ existsSync as existsSync25,
22417
21495
  mkdirSync as mkdirSync7,
22418
21496
  mkdtempSync,
22419
21497
  readFileSync as readFileSync11,
@@ -22423,7 +21501,7 @@ import {
22423
21501
  writeFileSync as writeFileSync5
22424
21502
  } from "node:fs";
22425
21503
  import { tmpdir as tmpdir2 } from "node:os";
22426
- import { join as join24 } from "node:path";
21504
+ import { join as join25 } from "node:path";
22427
21505
  async function runDoctor(options) {
22428
21506
  if (options.issue) {
22429
21507
  return runIssueFlow(options.argv);
@@ -22444,8 +21522,11 @@ async function runDoctor(options) {
22444
21522
  if (!report.binaryVersion) {
22445
21523
  const hasEnabledRegisteredHarness = report.harnesses.some((h2) => h2.pluginRegistered && h2.aftConfig.enabled);
22446
21524
  const hasRegisteredHarness = report.harnesses.some((h2) => h2.pluginRegistered);
22447
- if (hasEnabledRegisteredHarness) {
22448
- log2.warn(` no matching aft binary detected — run \`${CLI} doctor --fix\` to download, or it will install automatically when an AFT-enabled session makes its first tool call`);
21525
+ const binaryIssue = collectDiagnosticIssues(report).find((issue) => issue.code === "binary_missing");
21526
+ if (hasEnabledRegisteredHarness && binaryIssue?.severity === "info") {
21527
+ log2.info(` no matching aft binary detected — it will self-install when the next AFT-enabled session starts (or run \`${CLI} doctor --fix\`)`);
21528
+ } else if (hasEnabledRegisteredHarness) {
21529
+ log2.warn(` no matching aft binary detected — run \`${CLI} doctor --fix\` to download, or start an AFT-enabled session to trigger plugin-side install`);
22449
21530
  } else if (hasRegisteredHarness) {
22450
21531
  log2.info(" no matching aft binary detected; all registered AFT harnesses are disabled by config");
22451
21532
  } else {
@@ -22454,6 +21535,7 @@ async function runDoctor(options) {
22454
21535
  logUnmatchedBinaryCandidates(report.cliVersion);
22455
21536
  }
22456
21537
  log2.info(`Binary cache: ${report.binaryCache.versions.length} version(s), ${formatBytes(report.binaryCache.totalSize)} at ${report.binaryCache.path}`);
21538
+ logBuildBreakerSuspensions(report);
22457
21539
  const npmCount = report.lspCache.npm.entries.length;
22458
21540
  const ghCount = report.lspCache.github.entries.length;
22459
21541
  if (npmCount + ghCount > 0) {
@@ -22520,7 +21602,41 @@ async function runDoctor(options) {
22520
21602
  return 0;
22521
21603
  }
22522
21604
  function hasDoctorProblems(report) {
22523
- return formatDiagnosticIssuesSection(report).length > 0;
21605
+ return collectDiagnosticIssues(report).some((issue) => issue.severity !== "info") || (report.buildBreakerSuspensions?.length ?? 0) > 0;
21606
+ }
21607
+ function logBuildBreakerSuspensions(report) {
21608
+ for (const suspension of report.buildBreakerSuspensions ?? []) {
21609
+ log2.warn(formatBuildBreakerSuspension(suspension));
21610
+ }
21611
+ }
21612
+ async function runDoctorBuildBreakerReset(argv) {
21613
+ const optionValue = (name) => {
21614
+ const index = argv.indexOf(name);
21615
+ return index >= 0 ? argv[index + 1] : undefined;
21616
+ };
21617
+ const root = optionValue("--root");
21618
+ const domain = optionValue("--domain");
21619
+ const fingerprint = optionValue("--fingerprint");
21620
+ if (!root || !domain || !fingerprint) {
21621
+ log2.error(`Usage: ${DOCTOR_BUILD_BREAKER_RESET_COMMAND} --root <root> --domain <domain> --fingerprint <fingerprint>`);
21622
+ return 2;
21623
+ }
21624
+ const adapters = await resolveAdaptersForCommand(argv, {
21625
+ allowMulti: false,
21626
+ verb: "reset the build breaker for"
21627
+ });
21628
+ const storageRoot = adapters[0]?.getStorageDir();
21629
+ if (!storageRoot) {
21630
+ log2.error("No AFT storage root was found for the selected harness.");
21631
+ return 1;
21632
+ }
21633
+ const reset = resetBuildBreakerSuspension(storageRoot, { root, domain, fingerprint });
21634
+ if (reset === 0) {
21635
+ log2.warn("No matching build-breaker suspension was found; no records were changed.");
21636
+ return 1;
21637
+ }
21638
+ log2.success(`Reset build breaker for root=${root} domain=${domain}.`);
21639
+ return 0;
22524
21640
  }
22525
21641
  async function runClearFlow(argv) {
22526
21642
  const targets = await selectMany("What do you want to clear?", DOCTOR_CLEAR_TARGET_OPTIONS, undefined, false);
@@ -22590,7 +21706,7 @@ function clearOldBinaries() {
22590
21706
  errors: [],
22591
21707
  keptVersion: keepTag
22592
21708
  };
22593
- if (!existsSync24(info.path)) {
21709
+ if (!existsSync25(info.path)) {
22594
21710
  log2.info(`Binary cache: nothing to clear at ${info.path}`);
22595
21711
  return result;
22596
21712
  }
@@ -22600,7 +21716,7 @@ function clearOldBinaries() {
22600
21716
  return result;
22601
21717
  }
22602
21718
  for (const version of stale) {
22603
- const dir = join24(info.path, version);
21719
+ const dir = join25(info.path, version);
22604
21720
  let bytes = 0;
22605
21721
  try {
22606
21722
  bytes = statSync16(dir).isDirectory() ? dirSize(dir) : 0;
@@ -22905,6 +22021,8 @@ function logDoctorIssues(report) {
22905
22021
  const remediation = lines[i2 + 1];
22906
22022
  if (issue.startsWith("[HIGH]")) {
22907
22023
  log2.error(issue);
22024
+ } else if (issue.startsWith("[INFO]")) {
22025
+ log2.info(issue);
22908
22026
  } else {
22909
22027
  log2.warn(issue);
22910
22028
  }
@@ -22945,7 +22063,7 @@ function ensureStorageDirsForRegisteredPlugins(adapters) {
22945
22063
  if (!adapter.isInstalled() || !adapter.hasPluginEntry())
22946
22064
  continue;
22947
22065
  const storageDir = adapter.getStorageDir();
22948
- if (existsSync24(storageDir))
22066
+ if (existsSync25(storageDir))
22949
22067
  continue;
22950
22068
  mkdirSync7(storageDir, { recursive: true });
22951
22069
  summary.created += 1;
@@ -23024,8 +22142,14 @@ function describeAdapterInstallHint(kind) {
23024
22142
  return "(unknown harness)";
23025
22143
  }
23026
22144
  function formatStorageSizes(sizes) {
23027
- const parts = Object.entries(sizes).filter(([, size]) => size > 0).map(([key, size]) => `${key}: ${formatBytes(size)}`);
23028
- return parts.length > 0 ? parts.join(", ") : "empty";
22145
+ const projectParts = Object.entries(sizes).filter(([key, size]) => key !== "logs" && size > 0).map(([key, size]) => `${key}: ${formatBytes(size)}`);
22146
+ const logsSize = sizes.logs ?? 0;
22147
+ const parts = [...projectParts];
22148
+ if (logsSize > 0)
22149
+ parts.push(`logs: ${formatBytes(logsSize)}`);
22150
+ if (projectParts.length > 0)
22151
+ return parts.join(", ");
22152
+ return logsSize > 0 ? `${parts[0]}; no project data yet` : "empty";
23029
22153
  }
23030
22154
  function formatLegacyDuplication(summary) {
23031
22155
  if (!summary || summary.totalPartitions === 0)
@@ -23064,11 +22188,11 @@ function deriveIssueTitleFromBody(body) {
23064
22188
  function writeIssueReviewFile(body) {
23065
22189
  let reviewDir = null;
23066
22190
  try {
23067
- reviewDir = mkdtempSync(join24(tmpdir2(), "aft-issue-"));
22191
+ reviewDir = mkdtempSync(join25(tmpdir2(), "aft-issue-"));
23068
22192
  if (process.platform !== "win32") {
23069
22193
  chmodSync4(reviewDir, 448);
23070
22194
  }
23071
- const outPath = join24(reviewDir, "issue.md");
22195
+ const outPath = join25(reviewDir, "issue.md");
23072
22196
  writeFileSync5(outPath, `${body}
23073
22197
  `, { encoding: "utf8", mode: 384, flag: "wx" });
23074
22198
  return { path: outPath, realPath: realpathSync5(outPath) };
@@ -23232,6 +22356,7 @@ var init_doctor = __esm(async () => {
23232
22356
  init_dist2();
23233
22357
  init_binary_cache();
23234
22358
  init_bridge_tool_failures();
22359
+ init_build_breaker();
23235
22360
  init_fs_util();
23236
22361
  init_github();
23237
22362
  init_harness_select();
@@ -23280,6 +22405,7 @@ function printHelp() {
23280
22405
  console.log(" doctor --fix Auto-fix common issues (e.g. ONNX Runtime mismatch)");
23281
22406
  console.log(" doctor --clear Select caches to clear with an interactive prompt");
23282
22407
  console.log(" doctor --issue Collect diagnostics and open a GitHub issue");
22408
+ console.log(" doctor reset-build-breaker --root <root> --domain <domain> --fingerprint <fingerprint>");
23283
22409
  console.log("");
23284
22410
  console.log(" Harness selection:");
23285
22411
  console.log(" --harness opencode Target OpenCode only");
@@ -23292,6 +22418,7 @@ function printHelp() {
23292
22418
  console.log(` ${CLI} doctor lsp ./src/main.py`);
23293
22419
  console.log(` ${CLI} doctor --clear`);
23294
22420
  console.log(` ${CLI} doctor --issue`);
22421
+ console.log(` ${CLI} doctor reset-build-breaker --root <root> --domain <domain> --fingerprint <fingerprint>`);
23295
22422
  console.log("");
23296
22423
  }
23297
22424
  async function main() {
@@ -23312,6 +22439,10 @@ async function main() {
23312
22439
  const { runDoctorFilters: runDoctorFilters2 } = await init_doctor_filters().then(() => exports_doctor_filters);
23313
22440
  return runDoctorFilters2({ argv: args.slice(1) });
23314
22441
  }
22442
+ if (args[0] === "reset-build-breaker") {
22443
+ const { runDoctorBuildBreakerReset: runDoctorBuildBreakerReset2 } = await init_doctor().then(() => exports_doctor);
22444
+ return runDoctorBuildBreakerReset2(args.slice(1));
22445
+ }
23315
22446
  const { runDoctor: runDoctor2 } = await init_doctor().then(() => exports_doctor);
23316
22447
  const force = args.includes("--force");
23317
22448
  const clear = args.includes("--clear");