@cortexkit/aft 0.51.2 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -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,231 +3327,21 @@ 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;
3033
- 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;
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;
3250
3345
  closedErr = null;
3251
3346
  closeStarted = false;
3252
3347
  reconnecting = null;
@@ -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,740 +4150,25 @@ 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
4153
+ timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS,
4154
+ livenessProbeWindowMs: opts.livenessProbeWindowMs ?? LIVENESS_PROBE_WINDOW_MS,
4155
+ onControlPush: opts.onControlPush
4688
4156
  };
4689
4157
  }
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";
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 };
4719
4170
  }
4720
- function errorCode2(err) {
4171
+ function errorCode(err) {
4721
4172
  if (typeof err === "object" && err !== null && "code" in err) {
4722
4173
  const code = err.code;
4723
4174
  if (typeof code === "string")
@@ -4725,168 +4176,50 @@ function errorCode2(err) {
4725
4176
  }
4726
4177
  return;
4727
4178
  }
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"));
4179
+ function causeMessage(cause) {
4180
+ if (cause === undefined)
4181
+ return "";
4182
+ return `: ${cause instanceof Error ? cause.message : String(cause)}`;
4760
4183
  }
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;
4184
+ function pendingKey(handle, corr) {
4185
+ return handle ? `${handle.channel}:${handle.epoch}:${corr}` : `0:0:${corr}`;
4766
4186
  }
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"
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(() => {
4189
+ init_auth();
4190
+ init_connection_file();
4191
+ init_envelope();
4192
+ init_route_handle();
4193
+ init_socket();
4194
+ debug = debuglog("subc-client");
4195
+ EMPTY_BODY = new Uint8Array(0);
4196
+ DEFAULT_RECONNECT_BACKOFF = {
4197
+ baseMs: 100,
4198
+ capMs: 2000,
4199
+ maxAttempts: 6
4778
4200
  };
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
- }
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";
4803
4211
  }
4804
4212
  };
4805
- }
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
- }
4858
- }
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] };
4867
- }
4868
- }
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
4213
+ SubcError = class SubcError extends Error {
4214
+ code;
4215
+ constructor(message, code) {
4216
+ super(message);
4217
+ this.code = code;
4886
4218
  }
4887
4219
  };
4888
- }
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";
4220
+ });
4221
+
4222
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.8.1/node_modules/@cortexkit/subc-client/dist/provider.js
4890
4223
  var init_provider = __esm(() => {
4891
4224
  init_auth();
4892
4225
  init_client();
@@ -4894,16 +4227,9 @@ var init_provider = __esm(() => {
4894
4227
  init_envelope();
4895
4228
  init_route_handle();
4896
4229
  init_socket();
4897
- SubcProviderError = class SubcProviderError extends Error {
4898
- code;
4899
- constructor(message, code) {
4900
- super(message);
4901
- this.code = code;
4902
- }
4903
- };
4904
4230
  });
4905
4231
 
4906
- // ../../node_modules/.bun/@cortexkit+subc-client@0.5.0/node_modules/@cortexkit/subc-client/dist/index.js
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) {
@@ -5734,6 +5064,7 @@ class SubcTransportPool {
5734
5064
  onBgEventsNudge;
5735
5065
  onBgEventsNudgeRef;
5736
5066
  bgBackoffSleep;
5067
+ routeRetrySleep;
5737
5068
  bgDispatchProbeIntervalMs;
5738
5069
  lifecycleDemandCheck;
5739
5070
  onLifecycleEvent;
@@ -5744,6 +5075,8 @@ class SubcTransportPool {
5744
5075
  outerFacadeEvictor;
5745
5076
  client = null;
5746
5077
  connecting = null;
5078
+ routeReopenRetryDelayMs = RECONNECT_RETRY_FLOOR_MS;
5079
+ routeReopenRetry = null;
5747
5080
  sessions = new Map;
5748
5081
  rootIndex = new Map;
5749
5082
  dormantRoots = new Map;
@@ -5764,6 +5097,7 @@ class SubcTransportPool {
5764
5097
  this.onBgEventsNudge = options.onBgEventsNudge;
5765
5098
  this.onBgEventsNudgeRef = options.onBgEventsNudgeRef;
5766
5099
  this.bgBackoffSleep = options.bgBackoffSleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
5100
+ this.routeRetrySleep = options.routeRetrySleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
5767
5101
  this.bgDispatchProbeIntervalMs = options.bgDispatchProbeIntervalMs ?? BG_DISPATCH_PROBE_INTERVAL_MS;
5768
5102
  const lifecycle = options.lifecycle;
5769
5103
  const demandCheck = options.lifecycleDemandCheck ?? options.demandCheck ?? lifecycle?.demandCheck;
@@ -6260,9 +5594,12 @@ class SubcTransportPool {
6260
5594
  throw this.annotateReapError(error2, record);
6261
5595
  if (isRouteProvenAbsentError(error2) && this.isCurrentSession(key, record) && this.client === client) {
6262
5596
  clearRouteEntry(routeAndEntry.entry);
5597
+ await this.waitForRouteReopenBackoff();
6263
5598
  routeAndEntry = await openRoute();
6264
5599
  try {
6265
- return await requestOnRoute(routeAndEntry.route);
5600
+ const reply = await requestOnRoute(routeAndEntry.route);
5601
+ this.resetRouteReopenBackoff();
5602
+ return reply;
6266
5603
  } catch (retryError) {
6267
5604
  if (this.isReapInduced(record))
6268
5605
  throw this.annotateReapError(retryError, record);
@@ -6282,6 +5619,23 @@ class SubcTransportPool {
6282
5619
  this.deleteSessionIfEmpty(key, record);
6283
5620
  }
6284
5621
  }
5622
+ waitForRouteReopenBackoff() {
5623
+ const pending = this.routeReopenRetry;
5624
+ if (pending)
5625
+ return pending;
5626
+ const delay = this.routeReopenRetryDelayMs;
5627
+ this.routeReopenRetryDelayMs = Math.min(delay * 2, RECONNECT_RETRY_CAP_MS);
5628
+ let retry;
5629
+ retry = Promise.resolve().then(() => this.routeRetrySleep(delay)).finally(() => {
5630
+ if (this.routeReopenRetry === retry)
5631
+ this.routeReopenRetry = null;
5632
+ });
5633
+ this.routeReopenRetry = retry;
5634
+ return retry;
5635
+ }
5636
+ resetRouteReopenBackoff() {
5637
+ this.routeReopenRetryDelayMs = RECONNECT_RETRY_FLOOR_MS;
5638
+ }
6285
5639
  async ensureClient() {
6286
5640
  if (this.shuttingDown)
6287
5641
  throw new SubcTransportShuttingDownError;
@@ -6535,7 +5889,7 @@ function resolveBridgeForNudge(pool, ref) {
6535
5889
  currentConcretePoolId: candidate.getConcretePoolId?.()
6536
5890
  });
6537
5891
  }
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;
5892
+ var SubcTransportShuttingDownError, AFT_MODULE_ID = "aft", MAX_CONSECUTIVE_TRANSPORT_FAILURES = 3, RECONNECT_RETRY_FLOOR_MS = 100, RECONNECT_RETRY_CAP_MS = 2000, 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
5893
  var init_subc_transport = __esm(() => {
6540
5894
  init_dist();
6541
5895
  init_active_logger();
@@ -9184,6 +8538,8 @@ class RevivableTransportPool {
9184
8538
  onBinaryReplaced;
9185
8539
  activePool;
9186
8540
  revival = null;
8541
+ revivalRetryDelayMs = REVIVAL_RETRY_FLOOR_MS;
8542
+ revivalRetryNotBefore = 0;
9187
8543
  transports = new Map;
9188
8544
  configureOverrides = new Map;
9189
8545
  editSlotSurvivesCaptured = false;
@@ -9277,12 +8633,30 @@ class RevivableTransportPool {
9277
8633
  return this.activePool;
9278
8634
  if (this.revival)
9279
8635
  return this.revival;
8636
+ const delay = Math.max(0, this.revivalRetryNotBefore - Date.now());
8637
+ if (delay > 0) {
8638
+ let scheduled;
8639
+ scheduled = new Promise((resolve7) => setTimeout(resolve7, delay)).then(() => {
8640
+ if (this.revival === scheduled)
8641
+ this.revival = null;
8642
+ return this.ensureActivePool();
8643
+ });
8644
+ this.revival = scheduled;
8645
+ scheduled.then(() => {
8646
+ return;
8647
+ }, () => {
8648
+ return;
8649
+ });
8650
+ return scheduled;
8651
+ }
9280
8652
  warn("transport was shut down but new demand arrived — reviving (host quit hook fired without process exit?)");
9281
- const revival = this.createPool().then((pool) => {
8653
+ const revival = Promise.resolve().then(() => this.createPool()).then((pool) => {
9282
8654
  for (const [key, value] of this.configureOverrides) {
9283
8655
  pool.setConfigureOverride(key, value);
9284
8656
  }
9285
8657
  this.activePool = pool;
8658
+ this.revivalRetryDelayMs = REVIVAL_RETRY_FLOOR_MS;
8659
+ this.revivalRetryNotBefore = 0;
9286
8660
  for (const [root, transport] of this.transports) {
9287
8661
  transport.refreshStatusSubscription(pool.getActiveBridgeForRoot(root));
9288
8662
  }
@@ -9293,6 +8667,8 @@ class RevivableTransportPool {
9293
8667
  if (this.revival === revival)
9294
8668
  this.revival = null;
9295
8669
  }, () => {
8670
+ this.revivalRetryNotBefore = Date.now() + this.revivalRetryDelayMs;
8671
+ this.revivalRetryDelayMs = Math.min(this.revivalRetryDelayMs * 2, REVIVAL_RETRY_CAP_MS);
9296
8672
  if (this.revival === revival)
9297
8673
  this.revival = null;
9298
8674
  });
@@ -9386,6 +8762,7 @@ class RevivableProjectTransport {
9386
8762
  unsubscribe?.();
9387
8763
  }
9388
8764
  }
8765
+ var REVIVAL_RETRY_FLOOR_MS = 100, REVIVAL_RETRY_CAP_MS = 2000;
9389
8766
  var init_revivable_transport = __esm(() => {
9390
8767
  init_active_logger();
9391
8768
  init_project_identity();
@@ -9684,117 +9061,117 @@ function unwrapRustZoomBatchEnvelope(response) {
9684
9061
  // ../aft-bridge/dist/index.js
9685
9062
  var exports_dist = {};
9686
9063
  __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,
9064
+ AftToolError: () => AftToolError,
9796
9065
  BASH_HOST_FALLBACK_BANNER: () => BASH_HOST_FALLBACK_BANNER,
9797
- AftToolError: () => AftToolError
9066
+ BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES: () => BASH_HOST_FALLBACK_MAX_OUTPUT_BYTES,
9067
+ BASH_HOST_FALLBACK_MAX_TIMEOUT_MS: () => BASH_HOST_FALLBACK_MAX_TIMEOUT_MS,
9068
+ BASH_HOST_FALLBACK_REFUSAL: () => BASH_HOST_FALLBACK_REFUSAL,
9069
+ BASH_TRANSPORT_DISPOSITION: () => BASH_TRANSPORT_DISPOSITION,
9070
+ BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION: () => BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION,
9071
+ BinaryBridge: () => BinaryBridge,
9072
+ BridgePool: () => BridgePool,
9073
+ BridgeTransportTimeoutError: () => BridgeTransportTimeoutError,
9074
+ BridgeTransportUnavailableError: () => BridgeTransportUnavailableError,
9075
+ BridgeTransportUnknownOutcomeError: () => BridgeTransportUnknownOutcomeError,
9076
+ DEFAULT_LOG_BYTES: () => DEFAULT_LOG_BYTES,
9077
+ DEFAULT_LOG_GENERATIONS: () => DEFAULT_LOG_GENERATIONS,
9078
+ HomeProjectRootError: () => HomeProjectRootError,
9079
+ InvalidRequestError: () => InvalidRequestError,
9080
+ LONG_RUNNING_COMMAND_TIMEOUT_MS: () => LONG_RUNNING_COMMAND_TIMEOUT_MS,
9081
+ OPENCODE_ONLY_KEYS: () => OPENCODE_ONLY_KEYS,
9082
+ PI_ONLY_KEYS: () => PI_ONLY_KEYS,
9083
+ PLAIN_CALLGRAPH_THEME: () => PLAIN_CALLGRAPH_THEME,
9084
+ PLATFORM_ARCH_MAP: () => PLATFORM_ARCH_MAP,
9085
+ PLATFORM_ASSET_MAP: () => PLATFORM_ASSET_MAP,
9086
+ RevivableTransportPool: () => RevivableTransportPool,
9087
+ RotatingLogSink: () => RotatingLogSink,
9088
+ SubcTransportPool: () => SubcTransportPool,
9089
+ SubcTransportShuttingDownError: () => SubcTransportShuttingDownError,
9090
+ __onnxTest__: () => __test__,
9091
+ adaptToolError: () => adaptToolError,
9092
+ bashHostFallbackAskPattern: () => bashHostFallbackAskPattern,
9093
+ canonicalizeProjectRoot: () => canonicalizeProjectRoot,
9094
+ cleanupOnnxRuntime: () => cleanupOnnxRuntime,
9095
+ coerceAliasedStringParam: () => coerceAliasedStringParam,
9096
+ coerceBoolean: () => coerceBoolean,
9097
+ coerceOptionalInt: () => coerceOptionalInt,
9098
+ coerceStringArray: () => coerceStringArray,
9099
+ coerceTargetParam: () => coerceTargetParam,
9100
+ commandInvokesCodeSearch: () => commandInvokesCodeSearch,
9101
+ compareSemver: () => compareSemver,
9102
+ compressionSavingsPercent: () => compressionSavingsPercent,
9103
+ createAftTransportPool: () => createAftTransportPool,
9104
+ decodeFileUrl: () => decodeFileUrl,
9105
+ downloadBinary: () => downloadBinary,
9106
+ ensureBinary: () => ensureBinary,
9107
+ ensureOnnxRuntime: () => ensureOnnxRuntime,
9108
+ ensureStorageMigrated: () => ensureStorageMigrated,
9109
+ findBinary: () => findBinary,
9110
+ findBinarySync: () => findBinarySync,
9111
+ formatBridgeErrorMessage: () => formatBridgeErrorMessage,
9112
+ formatCallgraphSections: () => formatCallgraphSections,
9113
+ formatDroppedKeyWarnings: () => formatDroppedKeyWarnings,
9114
+ formatEditSummary: () => formatEditSummary,
9115
+ formatForegroundResult: () => formatForegroundResult,
9116
+ formatReadFooter: () => formatReadFooter,
9117
+ formatSeconds: () => formatSeconds,
9118
+ formatTokenCount: () => formatTokenCount,
9119
+ formatZoomMultiTargetResult: () => formatZoomMultiTargetResult,
9120
+ formatZoomText: () => formatZoomText,
9121
+ getAftBinaryCacheDir: () => getAftBinaryCacheDir,
9122
+ getAftCacheRoot: () => getAftCacheRoot,
9123
+ getAftLspBinariesDir: () => getAftLspBinariesDir,
9124
+ getAftLspPackagesDir: () => getAftLspPackagesDir,
9125
+ getBinaryName: () => getBinaryName,
9126
+ getCacheDir: () => getAftBinaryCacheDir,
9127
+ getCachedBinaryPath: () => getCachedBinaryPath,
9128
+ getManualInstallHint: () => getManualInstallHint,
9129
+ getMigrationStatus: () => getMigrationStatus,
9130
+ inlineUserConfigTier: () => inlineUserConfigTier,
9131
+ isBashTransportDeadError: () => isBashTransportDeadError,
9132
+ isBridgeTransportTimeout: () => isBridgeTransportTimeout,
9133
+ isEmptyParam: () => isEmptyParam,
9134
+ isHomeDirectoryRoot: () => isHomeDirectoryRoot,
9135
+ isNativeExecutable: () => isNativeExecutable,
9136
+ isNpmAvailable: () => isNpmAvailable,
9137
+ isOrtAutoDownloadSupported: () => isOrtAutoDownloadSupported,
9138
+ isRustZoomBatchEnvelope: () => isRustZoomBatchEnvelope,
9139
+ isTerminalStatus: () => isTerminalStatus,
9140
+ isWellFormedUnicodeString: () => isWellFormedUnicodeString,
9141
+ markAnnouncementSeen: () => markAnnouncementSeen,
9142
+ maybeAppendConflictsHint: () => maybeAppendConflictsHint,
9143
+ maybeAppendGrepSearchHint: () => maybeAppendGrepSearchHint,
9144
+ migrateAftConfigFile: () => migrateAftConfigFile,
9145
+ npmSpawnEnv: () => npmSpawnEnv,
9146
+ platformKey: () => platformKey,
9147
+ prepareCanonicalEditArguments: () => prepareCanonicalEditArguments,
9148
+ prepareCanonicalPathArguments: () => prepareCanonicalPathArguments,
9149
+ probeNpmVersion: () => probeNpmVersion,
9150
+ projectRootKeyHash: () => projectRootKeyHash,
9151
+ readConfigTiers: () => readConfigTiers,
9152
+ repairRootScopedStorageFile: () => repairRootScopedStorageFile,
9153
+ resolveAftLogPath: () => resolveAftLogPath,
9154
+ resolveAftStorageRoot: () => resolveAftStorageRoot,
9155
+ resolveBashKillTimeout: () => resolveBashKillTimeout,
9156
+ resolveBridgeForNudge: () => resolveBridgeForNudge,
9157
+ resolveCortexKitConfigPaths: () => resolveCortexKitConfigPaths,
9158
+ resolveCortexKitProjectConfigPath: () => resolveCortexKitProjectConfigPath,
9159
+ resolveCortexKitStorageRoot: () => resolveCortexKitStorageRoot,
9160
+ resolveCortexKitUserConfigPath: () => resolveCortexKitUserConfigPath,
9161
+ resolveHarnessStoragePath: () => resolveHarnessStoragePath,
9162
+ resolveLegacyAftConfigSources: () => resolveLegacyAftConfigSources,
9163
+ resolveLegacyStorageRoot: () => resolveLegacyStorageRoot,
9164
+ resolveNpm: () => resolveNpm,
9165
+ runBashHostFallback: () => runBashHostFallback,
9166
+ setActiveLogger: () => setActiveLogger,
9167
+ shouldShowAnnouncement: () => shouldShowAnnouncement,
9168
+ sleep: () => sleep,
9169
+ stripHarnessSpecificConfigKeys: () => stripHarnessSpecificConfigKeys,
9170
+ stripJsoncSymbols: () => stripJsoncSymbols,
9171
+ tagStderrLine: () => tagStderrLine,
9172
+ timeoutForCommand: () => timeoutForCommand,
9173
+ toolErrorFromResponse: () => toolErrorFromResponse,
9174
+ unwrapRustZoomBatchEnvelope: () => unwrapRustZoomBatchEnvelope
9798
9175
  });
9799
9176
  var init_dist2 = __esm(() => {
9800
9177
  init_active_logger();
@@ -10048,7 +9425,7 @@ function compareVersionLabels(a, b) {
10048
9425
  var init_fs_util = () => {};
10049
9426
 
10050
9427
  // ../../node_modules/.bun/esprima@4.0.1/node_modules/esprima/dist/esprima.js
10051
- var require_esprima = __commonJS((exports, module) => {
9428
+ var require_esprima = __commonJS(function(exports, module) {
10052
9429
  (function webpackUniversalModuleDefinition(root, factory) {
10053
9430
  if (typeof exports === "object" && typeof module === "object")
10054
9431
  module.exports = factory();
@@ -16188,7 +15565,7 @@ var require_esprima = __commonJS((exports, module) => {
16188
15565
  });
16189
15566
 
16190
15567
  // ../../node_modules/.bun/array-timsort@1.0.3/node_modules/array-timsort/src/index.js
16191
- var require_src = __commonJS((exports, module) => {
15568
+ var require_src = __commonJS(function(exports, module) {
16192
15569
  var DEFAULT_MIN_MERGE = 32;
16193
15570
  var DEFAULT_MIN_GALLOPING = 7;
16194
15571
  var DEFAULT_TMP_STORAGE_LENGTH = 256;
@@ -16831,7 +16208,7 @@ var require_src = __commonJS((exports, module) => {
16831
16208
  });
16832
16209
 
16833
16210
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/common.js
16834
- var require_common = __commonJS((exports, module) => {
16211
+ var require_common = __commonJS(function(exports, module) {
16835
16212
  var PREFIX_BEFORE = "before";
16836
16213
  var PREFIX_AFTER_PROP = "after-prop";
16837
16214
  var PREFIX_AFTER_COLON = "after-colon";
@@ -17075,7 +16452,7 @@ var require_common = __commonJS((exports, module) => {
17075
16452
  });
17076
16453
 
17077
16454
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/array.js
17078
- var require_array = __commonJS((exports, module) => {
16455
+ var require_array = __commonJS(function(exports, module) {
17079
16456
  var { sort } = require_src();
17080
16457
  var {
17081
16458
  PROP_SYMBOL_PREFIXES,
@@ -17233,7 +16610,7 @@ var require_array = __commonJS((exports, module) => {
17233
16610
  });
17234
16611
 
17235
16612
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/parse.js
17236
- var require_parse = __commonJS((exports, module) => {
16613
+ var require_parse = __commonJS(function(exports, module) {
17237
16614
  var esprima = require_esprima();
17238
16615
  var {
17239
16616
  CommentArray
@@ -17558,7 +16935,7 @@ var require_parse = __commonJS((exports, module) => {
17558
16935
  });
17559
16936
 
17560
16937
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/stringify.js
17561
- var require_stringify = __commonJS((exports, module) => {
16938
+ var require_stringify = __commonJS(function(exports, module) {
17562
16939
  var {
17563
16940
  PREFIX_BEFORE_ALL,
17564
16941
  PREFIX_BEFORE,
@@ -17770,7 +17147,7 @@ var require_stringify = __commonJS((exports, module) => {
17770
17147
  });
17771
17148
 
17772
17149
  // ../../node_modules/.bun/comment-json@4.6.2/node_modules/comment-json/src/index.js
17773
- var require_src2 = __commonJS((exports, module) => {
17150
+ var require_src2 = __commonJS(function(exports, module) {
17774
17151
  var { parse, tokenize } = require_parse();
17775
17152
  var stringify = require_stringify();
17776
17153
  var { CommentArray } = require_array();
@@ -18201,7 +17578,8 @@ class OpenCodeAdapter {
18201
17578
  semantic: dirSize(join15(storage, "semantic")),
18202
17579
  backups: dirSize(join15(storage, "backups")),
18203
17580
  url_cache: dirSize(join15(storage, "url_cache")),
18204
- onnxruntime: dirSize(join15(storage, "onnxruntime"))
17581
+ onnxruntime: dirSize(join15(storage, "onnxruntime")),
17582
+ logs: dirSize(join15(storage, "logs"))
18205
17583
  };
18206
17584
  }
18207
17585
  }
@@ -18219,8 +17597,11 @@ var init_opencode = __esm(() => {
18219
17597
  import { execSync as execSync4, spawnSync as spawnSync4 } from "node:child_process";
18220
17598
  import { existsSync as existsSync13, readFileSync as readFileSync9 } from "node:fs";
18221
17599
  import { homedir as homedir15 } from "node:os";
18222
- import { join as join16 } from "node:path";
17600
+ import { join as join16, resolve as resolve8 } from "node:path";
18223
17601
  function getPiAgentDir() {
17602
+ const configuredDir = process.env.PI_CODING_AGENT_DIR?.trim();
17603
+ if (configuredDir)
17604
+ return resolve8(configuredDir);
18224
17605
  const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
18225
17606
  const home = envHome && envHome.length > 0 ? envHome : homedir15();
18226
17607
  return join16(home, ".pi", "agent");
@@ -18234,7 +17615,14 @@ function readPiExtensionIndex() {
18234
17615
  const value = JSON.parse(trimmed);
18235
17616
  const packages = value.packages;
18236
17617
  if (Array.isArray(packages)) {
18237
- const installed = packages.filter((p) => typeof p === "string");
17618
+ const installed = packages.flatMap((p) => {
17619
+ if (typeof p === "string")
17620
+ return [p];
17621
+ if (typeof p === "object" && p !== null && typeof p.source === "string") {
17622
+ return [p.source];
17623
+ }
17624
+ return [];
17625
+ });
18238
17626
  return { installed, path: settingsPath };
18239
17627
  }
18240
17628
  } catch {}
@@ -18383,6 +17771,7 @@ class PiAdapter {
18383
17771
  }
18384
17772
  getPluginCacheInfo() {
18385
17773
  const candidates = [
17774
+ join16(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
18386
17775
  join16(getPiAgentDir(), "node_modules", "@cortexkit", "aft-pi", "package.json"),
18387
17776
  join16(getPiAgentDir(), "extensions", "node_modules", "@cortexkit", "aft-pi", "package.json")
18388
17777
  ];
@@ -18401,7 +17790,7 @@ class PiAdapter {
18401
17790
  } catch {}
18402
17791
  }
18403
17792
  return {
18404
- path: join16(getPiAgentDir(), "extensions"),
17793
+ path: join16(getPiAgentDir(), "npm", "node_modules", "@cortexkit", "aft-pi", "package.json"),
18405
17794
  exists: false
18406
17795
  };
18407
17796
  }
@@ -18427,7 +17816,8 @@ class PiAdapter {
18427
17816
  semantic: dirSize(join16(storage, "semantic")),
18428
17817
  backups: dirSize(join16(storage, "backups")),
18429
17818
  url_cache: dirSize(join16(storage, "url_cache")),
18430
- onnxruntime: dirSize(join16(storage, "onnxruntime"))
17819
+ onnxruntime: dirSize(join16(storage, "onnxruntime")),
17820
+ logs: dirSize(join16(storage, "logs"))
18431
17821
  };
18432
17822
  }
18433
17823
  }
@@ -18800,7 +18190,7 @@ var init_main = __esm(() => {
18800
18190
  });
18801
18191
 
18802
18192
  // ../../node_modules/.bun/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
18803
- var require_src3 = __commonJS((exports, module) => {
18193
+ var require_src3 = __commonJS(function(exports, module) {
18804
18194
  var ESC2 = "\x1B";
18805
18195
  var CSI2 = `${ESC2}[`;
18806
18196
  var beep = "\x07";
@@ -18867,25 +18257,6 @@ function findCursor(s, o, l) {
18867
18257
  const t = s + o, n = Math.max(l.length - 1, 0), e = t < 0 ? n : t > n ? 0 : t;
18868
18258
  return l[e].disabled ? findCursor(e, o < 0 ? -1 : 1, l) : e;
18869
18259
  }
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
18260
  function isActionKey(n, e) {
18890
18261
  if (typeof n == "string")
18891
18262
  return settings.aliases.get(n) === e;
@@ -19077,77 +18448,7 @@ class V {
19077
18448
  }
19078
18449
  }
19079
18450
  }
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;
18451
+ 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
18452
  var init_dist5 = __esm(() => {
19152
18453
  init_main();
19153
18454
  import_sisteransi = __toESM(require_src3(), 1);
@@ -19194,72 +18495,6 @@ var init_dist5 = __esm(() => {
19194
18495
  };
19195
18496
  R = globalThis.process.platform.startsWith("win");
19196
18497
  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
18498
  r = class r extends V {
19264
18499
  get cursor() {
19265
18500
  return this.value ? 0 : 1;
@@ -19277,304 +18512,6 @@ var init_dist5 = __esm(() => {
19277
18512
  });
19278
18513
  }
19279
18514
  };
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
18515
  a$1 = class a extends V {
19579
18516
  options;
19580
18517
  cursor = 0;
@@ -19712,34 +18649,34 @@ var import_sisteransi2, unicode, unicodeOr = (o2, e) => unicode ? o2 : e, S_STEP
19712
18649
  case "submit":
19713
18650
  return styleText2("green", S_BAR);
19714
18651
  }
19715
- }, E$1 = (l, o2, g2, c2, h2, O = false) => {
18652
+ }, E$1 = (l, o2, g, c, h2, O = false) => {
19716
18653
  let r2 = o2, w = 0;
19717
18654
  if (O)
19718
- for (let i = c2 - 1;i >= g2 && (r2 -= l[i].length, w++, !(r2 <= h2)); i--)
18655
+ for (let i = c - 1;i >= g && (r2 -= l[i].length, w++, !(r2 <= h2)); i--)
19719
18656
  ;
19720
18657
  else
19721
- for (let i = g2;i < c2 && (r2 -= l[i].length, w++, !(r2 <= h2)); i++)
18658
+ for (let i = g;i < c && (r2 -= l[i].length, w++, !(r2 <= h2)); i++)
19722
18659
  ;
19723
18660
  return { lineCount: r2, removals: w };
19724
18661
  }, limitOptions = ({
19725
18662
  cursor: l,
19726
18663
  options: o2,
19727
- style: g2,
19728
- output: c2 = process.stdout,
18664
+ style: g,
18665
+ output: c = process.stdout,
19729
18666
  maxItems: h2 = Number.POSITIVE_INFINITY,
19730
18667
  columnPadding: O = 0,
19731
18668
  rowPadding: r2 = 4
19732
18669
  }) => {
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 = [];
18670
+ 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);
18671
+ let p = 0;
18672
+ l >= m - 3 && (p = Math.max(Math.min(l - m + 3, o2.length - m), 0));
18673
+ let f = m < o2.length && p > 0, u2 = m < o2.length && p + m < o2.length;
18674
+ const W = Math.min(p + m, o2.length), e = [];
19738
18675
  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, {
18676
+ f && d++, u2 && d++;
18677
+ const v = p + (f ? 1 : 0), P = W - (u2 ? 1 : 0);
18678
+ for (let t2 = v;t2 < P; t2++) {
18679
+ const n2 = wrapAnsi(g(o2[t2], t2 === l), i, {
19743
18680
  hard: true,
19744
18681
  trim: false
19745
18682
  }).split(`
@@ -19748,17 +18685,17 @@ var import_sisteransi2, unicode, unicodeOr = (o2, e) => unicode ? o2 : e, S_STEP
19748
18685
  }
19749
18686
  if (d > x) {
19750
18687
  let t2 = 0, n2 = 0, s = d;
19751
- const M2 = l - v;
18688
+ const M = l - v;
19752
18689
  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));
18690
+ const T = () => E$1(e, s, 0, M, a3), L = () => E$1(e, s, M + 1, e.length, a3, true);
18691
+ 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
18692
  }
19756
- const b2 = [];
19757
- f2 && b2.push(C2);
18693
+ const b = [];
18694
+ f && b.push(C);
19758
18695
  for (const t2 of e)
19759
18696
  for (const n2 of t2)
19760
- b2.push(n2);
19761
- return u3 && b2.push(C2), b2;
18697
+ b.push(n2);
18698
+ return u2 && b.push(C), b;
19762
18699
  }, confirm = (i) => {
19763
18700
  const a3 = i.active ?? "Yes", s = i.inactive ?? "No";
19764
18701
  return new r({
@@ -19769,36 +18706,36 @@ var import_sisteransi2, unicode, unicodeOr = (o2, e) => unicode ? o2 : e, S_STEP
19769
18706
  output: i.output,
19770
18707
  initialValue: i.initialValue ?? true,
19771
18708
  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;
18709
+ 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)}
18710
+ ` : ""}${f}
18711
+ `, c = this.value ? a3 : s;
19775
18712
  switch (this.state) {
19776
18713
  case "submit": {
19777
18714
  const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
19778
- return `${o2}${r2}${styleText2("dim", c2)}`;
18715
+ return `${o2}${r2}${styleText2("dim", c)}`;
19779
18716
  }
19780
18717
  case "cancel": {
19781
18718
  const r2 = e ? `${styleText2("gray", S_BAR)} ` : "";
19782
- return `${o2}${r2}${styleText2(["strikethrough", "dim"], c2)}${e ? `
18719
+ return `${o2}${r2}${styleText2(["strikethrough", "dim"], c)}${e ? `
19783
18720
  ${styleText2("gray", S_BAR)}` : ""}`;
19784
18721
  }
19785
18722
  default: {
19786
- const r2 = e ? `${styleText2("cyan", S_BAR)} ` : "", g2 = e ? styleText2("cyan", S_BAR_END) : "";
18723
+ const r2 = e ? `${styleText2("cyan", S_BAR)} ` : "", g = e ? styleText2("cyan", S_BAR_END) : "";
19787
18724
  return `${o2}${r2}${this.value ? `${styleText2("green", S_RADIO_ACTIVE)} ${a3}` : `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", a3)}`}${i.vertical ? e ? `
19788
18725
  ${styleText2("cyan", S_BAR)} ` : `
19789
18726
  ` : ` ${styleText2("dim", "/")} `}${this.value ? `${styleText2("dim", S_RADIO_INACTIVE)} ${styleText2("dim", s)}` : `${styleText2("green", S_RADIO_ACTIVE)} ${s}`}
19790
- ${g2}
18727
+ ${g}
19791
18728
  `;
19792
18729
  }
19793
18730
  }
19794
18731
  }
19795
18732
  }).prompt();
19796
- }, MULTISELECT_INSTRUCTIONS, m2 = (n2, o2) => n2.split(`
18733
+ }, MULTISELECT_INSTRUCTIONS, m = (n2, o2) => n2.split(`
19797
18734
  `).map((d) => o2(d)).join(`
19798
18735
  `), multiselect = (n2) => {
19799
18736
  const o2 = (t2, a3) => {
19800
18737
  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))}`;
18738
+ 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
18739
  }, d = n2.required ?? true;
19803
18740
  return new a$1({
19804
18741
  options: n2.options,
@@ -19816,30 +18753,30 @@ ${styleText2("reset", styleText2("dim", `Press ${styleText2(["gray", "bgWhite",
19816
18753
  render() {
19817
18754
  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
18755
  ` : ""}${a3}
19819
- `, l = this.value ?? [], p2 = (i, u3) => {
18756
+ `, l = this.value ?? [], p = (i, u2) => {
19820
18757
  if (i.disabled)
19821
18758
  return o2(i, "disabled");
19822
18759
  const s = l.includes(i.value);
19823
- return u3 && s ? o2(i, "active-selected") : s ? o2(i, "selected") : o2(i, u3 ? "active" : "inactive");
18760
+ return u2 && s ? o2(i, "active-selected") : s ? o2(i, "selected") : o2(i, u2 ? "active" : "inactive");
19824
18761
  };
19825
18762
  switch (this.state) {
19826
18763
  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}`;
18764
+ 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)} ` : "");
18765
+ return `${r2}${u2}`;
19829
18766
  }
19830
18767
  case "cancel": {
19831
18768
  const i = this.options.filter(({ value: s }) => l.includes(s)).map((s) => o2(s, "cancelled")).join(styleText2("dim", ", "));
19832
18769
  if (i.trim() === "")
19833
18770
  return `${r2}${styleText2("gray", S_BAR)}`;
19834
- const u3 = wrapTextWithPrefix(n2.output, i, t2 ? `${styleText2("gray", S_BAR)} ` : "");
19835
- return `${r2}${u3}${t2 ? `
18771
+ const u2 = wrapTextWithPrefix(n2.output, i, t2 ? `${styleText2("gray", S_BAR)} ` : "");
18772
+ return `${r2}${u2}${t2 ? `
19836
18773
  ${styleText2("gray", S_BAR)}` : ""}`;
19837
18774
  }
19838
18775
  case "error": {
19839
- const i = t2 ? `${styleText2("yellow", S_BAR)} ` : "", u3 = this.error.split(`
18776
+ const i = t2 ? `${styleText2("yellow", S_BAR)} ` : "", u2 = this.error.split(`
19840
18777
  `).map(($, x) => x === 0 ? `${t2 ? `${styleText2("yellow", S_BAR_END)} ` : ""}${styleText2("yellow", $)}` : ` ${$}`).join(`
19841
18778
  `), s = r2.split(`
19842
- `).length, g2 = u3.split(`
18779
+ `).length, g = u2.split(`
19843
18780
  `).length + 1;
19844
18781
  return `${r2}${i}${limitOptions({
19845
18782
  output: n2.output,
@@ -19847,16 +18784,16 @@ ${styleText2("gray", S_BAR)}` : ""}`;
19847
18784
  cursor: this.cursor,
19848
18785
  maxItems: n2.maxItems,
19849
18786
  columnPadding: i.length,
19850
- rowPadding: s + g2,
19851
- style: p2
18787
+ rowPadding: s + g,
18788
+ style: p
19852
18789
  }).join(`
19853
18790
  ${i}`)}
19854
- ${u3}
18791
+ ${u2}
19855
18792
  `;
19856
18793
  }
19857
18794
  default: {
19858
- const i = t2 ? `${styleText2("cyan", S_BAR)} ` : "", u3 = r2.split(`
19859
- `).length, s = formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t2), g2 = s.join(`
18795
+ const i = t2 ? `${styleText2("cyan", S_BAR)} ` : "", u2 = r2.split(`
18796
+ `).length, s = formatInstructionFooter(MULTISELECT_INSTRUCTIONS, t2), g = s.join(`
19860
18797
  `), $ = s.length + 1;
19861
18798
  return `${r2}${i}${limitOptions({
19862
18799
  output: n2.output,
@@ -19864,11 +18801,11 @@ ${u3}
19864
18801
  cursor: this.cursor,
19865
18802
  maxItems: n2.maxItems,
19866
18803
  columnPadding: i.length,
19867
- rowPadding: u3 + $,
19868
- style: p2
18804
+ rowPadding: u2 + $,
18805
+ style: p
19869
18806
  }).join(`
19870
18807
  ${i}`)}
19871
- ${g2}
18808
+ ${g}
19872
18809
  `;
19873
18810
  }
19874
18811
  }
@@ -19884,42 +18821,42 @@ ${styleText2("gray", S_BAR_END)} ` : "";
19884
18821
  i.write(`${e}${o2}
19885
18822
 
19886
18823
  `);
19887
- }, W$1 = (o2) => o2, C2 = (o2, e, s) => {
18824
+ }, W$1 = (o2) => o2, C = (o2, e, s) => {
19888
18825
  const a3 = {
19889
18826
  hard: true,
19890
18827
  trim: false
19891
18828
  }, 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);
18829
+ `), 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);
18830
+ return wrapAnsi(o2, g, a3);
19894
18831
  }, 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) => {
18832
+ 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(`
18833
+ `).map(c), ""], n2 = dist_default2(e), t2 = Math.max(g.reduce((m2, F) => {
19897
18834
  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)}
18835
+ return O > m2 ? O : m2;
18836
+ }, 0), n2) + 2, h2 = g.map((m2) => `${styleText2("gray", S_BAR)} ${m2}${" ".repeat(t2 - dist_default2(m2))}${styleText2("gray", S_BAR)}`).join(`
18837
+ `), T = i ? `${styleText2("gray", S_BAR)}
19901
18838
  ` : "", 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)}
18839
+ 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
18840
  ${h2}
19904
18841
  ${styleText2("gray", l$1 + S_BAR_H.repeat(t2 + 2) + S_CORNER_BOTTOM_RIGHT)}
19905
18842
  `);
19906
- }, u3, SELECT_INSTRUCTIONS, c2 = (t2, a3) => t2.includes(`
18843
+ }, u2, SELECT_INSTRUCTIONS, c = (t2, a3) => t2.includes(`
19907
18844
  `) ? t2.split(`
19908
18845
  `).map((i) => a3(i)).join(`
19909
18846
  `) : a3(t2), select = (t2) => {
19910
- const a3 = (i, m3) => {
18847
+ const a3 = (i, m2) => {
19911
18848
  const s = i.label ?? String(i.value);
19912
- switch (m3) {
18849
+ switch (m2) {
19913
18850
  case "disabled":
19914
- return `${styleText2("gray", S_RADIO_INACTIVE)} ${c2(s, (n2) => styleText2("gray", n2))}${i.hint ? ` ${styleText2("dim", `(${i.hint ?? "disabled"})`)}` : ""}`;
18851
+ return `${styleText2("gray", S_RADIO_INACTIVE)} ${c(s, (n2) => styleText2("gray", n2))}${i.hint ? ` ${styleText2("dim", `(${i.hint ?? "disabled"})`)}` : ""}`;
19915
18852
  case "selected":
19916
- return `${c2(s, (n2) => styleText2("dim", n2))}`;
18853
+ return `${c(s, (n2) => styleText2("dim", n2))}`;
19917
18854
  case "active":
19918
18855
  return `${styleText2("green", S_RADIO_ACTIVE)} ${s}${i.hint ? ` ${styleText2("dim", `(${i.hint})`)}` : ""}`;
19919
18856
  case "cancelled":
19920
- return `${c2(s, (n2) => styleText2(["strikethrough", "dim"], n2))}`;
18857
+ return `${c(s, (n2) => styleText2(["strikethrough", "dim"], n2))}`;
19921
18858
  default:
19922
- return `${styleText2("dim", S_RADIO_INACTIVE)} ${c2(s, (n2) => styleText2("dim", n2))}`;
18859
+ return `${styleText2("dim", S_RADIO_INACTIVE)} ${c(s, (n2) => styleText2("dim", n2))}`;
19923
18860
  }
19924
18861
  };
19925
18862
  return new a2({
@@ -19929,31 +18866,31 @@ ${styleText2("gray", l$1 + S_BAR_H.repeat(t2 + 2) + S_CORNER_BOTTOM_RIGHT)}
19929
18866
  output: t2.output,
19930
18867
  initialValue: t2.initialValue,
19931
18868
  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)}
18869
+ 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
18870
  ` : ""}${n2}
19934
18871
  `;
19935
18872
  switch (this.state) {
19936
18873
  case "submit": {
19937
18874
  const r2 = i ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(t2.output, a3(this.options[this.cursor], "selected"), r2);
19938
- return `${u4}${o2}`;
18875
+ return `${u3}${o2}`;
19939
18876
  }
19940
18877
  case "cancel": {
19941
18878
  const r2 = i ? `${styleText2("gray", S_BAR)} ` : "", o2 = wrapTextWithPrefix(t2.output, a3(this.options[this.cursor], "cancelled"), r2);
19942
- return `${u4}${o2}${i ? `
18879
+ return `${u3}${o2}${i ? `
19943
18880
  ${styleText2("gray", S_BAR)}` : ""}`;
19944
18881
  }
19945
18882
  default: {
19946
- const r2 = i ? `${styleText2("cyan", S_BAR)} ` : "", o2 = u4.split(`
18883
+ const r2 = i ? `${styleText2("cyan", S_BAR)} ` : "", o2 = u3.split(`
19947
18884
  `).length, $ = formatInstructionFooter(SELECT_INSTRUCTIONS, i), h2 = $.join(`
19948
- `), b2 = $.length + 1;
19949
- return `${u4}${r2}${limitOptions({
18885
+ `), b = $.length + 1;
18886
+ return `${u3}${r2}${limitOptions({
19950
18887
  output: t2.output,
19951
18888
  cursor: this.cursor,
19952
18889
  options: this.options,
19953
18890
  maxItems: t2.maxItems,
19954
18891
  columnPadding: r2.length,
19955
- rowPadding: o2 + b2,
19956
- style: (p2, x) => a3(p2, p2.disabled ? "disabled" : x ? "active" : "inactive")
18892
+ rowPadding: o2 + b,
18893
+ style: (p, x) => a3(p, p.disabled ? "disabled" : x ? "active" : "inactive")
19957
18894
  }).join(`
19958
18895
  ${r2}`)}
19959
18896
  ${h2}
@@ -19973,7 +18910,7 @@ ${h2}
19973
18910
  render() {
19974
18911
  const i2 = t2?.withGuide ?? settings.withGuide, s = `${`${i2 ? `${styleText2("gray", S_BAR)}
19975
18912
  ` : ""}${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 ?? "";
18913
+ `, 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
18914
  switch (this.state) {
19978
18915
  case "error": {
19979
18916
  const n2 = this.error ? ` ${styleText2("yellow", this.error)}` : "", r2 = i2 ? `${styleText2("yellow", S_BAR)} ` : "", d = i2 ? styleText2("yellow", S_BAR_END) : "";
@@ -20041,22 +18978,22 @@ var init_dist6 = __esm(() => {
20041
18978
  message: (s = [], {
20042
18979
  symbol: e = styleText2("gray", S_BAR),
20043
18980
  secondarySymbol: r2 = styleText2("gray", S_BAR),
20044
- output: m3 = process.stdout,
18981
+ output: m2 = process.stdout,
20045
18982
  spacing: l = 1,
20046
- withGuide: c2
18983
+ withGuide: c
20047
18984
  } = {}) => {
20048
- const t2 = [], o2 = c2 ?? settings.withGuide, f2 = o2 ? r2 : "", O = o2 ? `${e} ` : "", u3 = o2 ? `${r2} ` : "";
18985
+ const t2 = [], o2 = c ?? settings.withGuide, f = o2 ? r2 : "", O = o2 ? `${e} ` : "", u2 = o2 ? `${r2} ` : "";
20049
18986
  for (let i = 0;i < l; i++)
20050
- t2.push(f2);
20051
- const g2 = Array.isArray(s) ? s : s.split(`
18987
+ t2.push(f);
18988
+ const g = Array.isArray(s) ? s : s.split(`
20052
18989
  `);
20053
- if (g2.length > 0) {
20054
- const [i, ...y] = g2;
18990
+ if (g.length > 0) {
18991
+ const [i, ...y] = g;
20055
18992
  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 : "");
18993
+ for (const p of y)
18994
+ p.length > 0 ? t2.push(`${u2}${p}`) : t2.push(o2 ? r2 : "");
20058
18995
  }
20059
- m3.write(`${t2.join(`
18996
+ m2.write(`${t2.join(`
20060
18997
  `)}
20061
18998
  `);
20062
18999
  },
@@ -20079,7 +19016,7 @@ var init_dist6 = __esm(() => {
20079
19016
  log2.message(s, { ...e, symbol: styleText2("red", S_ERROR) });
20080
19017
  }
20081
19018
  };
20082
- u3 = {
19019
+ u2 = {
20083
19020
  light: unicodeOr("─", "-"),
20084
19021
  heavy: unicodeOr("━", "="),
20085
19022
  block: unicodeOr("█", "#")
@@ -20344,7 +19281,7 @@ function isResponseForRequest(parsed, expectedIds) {
20344
19281
  return expectedIds.has(id);
20345
19282
  }
20346
19283
  async function sendAftRequests(binaryPath, requests) {
20347
- return new Promise((resolve8, reject) => {
19284
+ return new Promise((resolve9, reject) => {
20348
19285
  const child = spawn3(binaryPath, [], {
20349
19286
  stdio: ["pipe", "pipe", "pipe"]
20350
19287
  });
@@ -20381,7 +19318,7 @@ async function sendAftRequests(binaryPath, requests) {
20381
19318
  const response = parsed;
20382
19319
  responses.push(response);
20383
19320
  if (responses.length === requests.length) {
20384
- finish(() => resolve8(responses));
19321
+ finish(() => resolve9(responses));
20385
19322
  }
20386
19323
  };
20387
19324
  child.stdout.setEncoding("utf-8");
@@ -20411,11 +19348,14 @@ async function sendAftRequests(binaryPath, requests) {
20411
19348
  return;
20412
19349
  finish(() => reject(buildBridgeError({ binaryPath, code, stderr, noiseLines, responses })));
20413
19350
  });
20414
- for (const request of requests) {
20415
- child.stdin.write(`${JSON.stringify(request)}
19351
+ child.stdin.on("error", () => {});
19352
+ try {
19353
+ for (const request of requests) {
19354
+ child.stdin.write(`${JSON.stringify(request)}
20416
19355
  `);
20417
- }
20418
- child.stdin.end();
19356
+ }
19357
+ child.stdin.end();
19358
+ } catch {}
20419
19359
  });
20420
19360
  }
20421
19361
  function buildBridgeError(ctx) {
@@ -20451,17 +19391,17 @@ var init_aft_bridge = () => {};
20451
19391
  // src/commands/lsp.ts
20452
19392
  var exports_lsp = {};
20453
19393
  __export(exports_lsp, {
20454
- typescriptPackageWarning: () => typescriptPackageWarning,
20455
- runLspDoctor: () => runLspDoctor,
20456
- renderLspInspection: () => renderLspInspection,
19394
+ findProjectRootForFile: () => findProjectRootForFile,
20457
19395
  printLspDoctorHelp: () => printLspDoctorHelp,
20458
- findProjectRootForFile: () => findProjectRootForFile
19396
+ renderLspInspection: () => renderLspInspection,
19397
+ runLspDoctor: () => runLspDoctor,
19398
+ typescriptPackageWarning: () => typescriptPackageWarning
20459
19399
  });
20460
19400
  import { existsSync as existsSync14, readdirSync as readdirSync5, statSync as statSync9 } from "node:fs";
20461
19401
  import { createRequire as createRequire4 } from "node:module";
20462
- import { dirname as dirname8, join as join17, resolve as resolve8 } from "node:path";
19402
+ import { dirname as dirname8, join as join17, resolve as resolve9 } from "node:path";
20463
19403
  function findProjectRootForFile(filePath, fallbackCwd = process.cwd()) {
20464
- const resolvedFile = resolve8(fallbackCwd, filePath);
19404
+ const resolvedFile = resolve9(fallbackCwd, filePath);
20465
19405
  let dir = dirname8(resolvedFile);
20466
19406
  try {
20467
19407
  if (existsSync14(resolvedFile) && statSync9(resolvedFile).isDirectory()) {
@@ -20476,7 +19416,7 @@ function findProjectRootForFile(filePath, fallbackCwd = process.cwd()) {
20476
19416
  }
20477
19417
  const parent = dirname8(dir);
20478
19418
  if (parent === dir)
20479
- return resolve8(fallbackCwd);
19419
+ return resolve9(fallbackCwd);
20480
19420
  dir = parent;
20481
19421
  }
20482
19422
  }
@@ -20507,7 +19447,7 @@ async function runLspDoctor(options) {
20507
19447
  log2.error("Could not find the aft binary in the cache, platform package, PATH, or ~/.cargo/bin.");
20508
19448
  return 1;
20509
19449
  }
20510
- const resolvedFile = resolve8(file);
19450
+ const resolvedFile = resolve9(file);
20511
19451
  const projectRoot = findProjectRootForFile(resolvedFile);
20512
19452
  const config = buildConfigureParams(adapter, projectRoot);
20513
19453
  const inspectRequest = {
@@ -20712,15 +19652,15 @@ var init_lsp = __esm(async () => {
20712
19652
  // src/commands/doctor-filters.ts
20713
19653
  var exports_doctor_filters = {};
20714
19654
  __export(exports_doctor_filters, {
20715
- runDoctorFilters: () => runDoctorFilters,
20716
- renderTrustedProjects: () => renderTrustedProjects,
20717
- renderFilterShow: () => renderFilterShow,
19655
+ printDoctorFiltersHelp: () => printDoctorFiltersHelp,
20718
19656
  renderFilterList: () => renderFilterList,
20719
- printDoctorFiltersHelp: () => printDoctorFiltersHelp
19657
+ renderFilterShow: () => renderFilterShow,
19658
+ renderTrustedProjects: () => renderTrustedProjects,
19659
+ runDoctorFilters: () => runDoctorFilters
20720
19660
  });
20721
19661
  import { existsSync as existsSync15 } from "node:fs";
20722
19662
  import { homedir as homedir16 } from "node:os";
20723
- import { relative as relative3, resolve as resolve9 } from "node:path";
19663
+ import { relative as relative3, resolve as resolve10 } from "node:path";
20724
19664
  function printDoctorFiltersHelp() {
20725
19665
  console.log(`Usage: ${CLI} doctor filters [--show <name>] [trust|untrust]`);
20726
19666
  console.log("");
@@ -20755,7 +19695,7 @@ async function runDoctorFilters(options) {
20755
19695
  log2.error("Could not find the aft binary in the cache, platform package, PATH, or ~/.cargo/bin.");
20756
19696
  return 1;
20757
19697
  }
20758
- const projectRoot = resolve9(process.cwd());
19698
+ const projectRoot = resolve10(process.cwd());
20759
19699
  const list = await listFilters(binary, adapter, projectRoot, options.sendRequests ?? sendAftRequests);
20760
19700
  if (!list.success) {
20761
19701
  log2.error(list.message ?? list.code ?? "list_filters failed");
@@ -20999,9 +19939,9 @@ import { homedir as homedir17, userInfo } from "node:os";
20999
19939
  function escapeRegex(value) {
21000
19940
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
21001
19941
  }
21002
- function safeRealpath(p2) {
19942
+ function safeRealpath(p) {
21003
19943
  try {
21004
- return realpathSync3(p2);
19944
+ return realpathSync3(p);
21005
19945
  } catch {
21006
19946
  return null;
21007
19947
  }
@@ -21172,11 +20112,11 @@ function aggregateBridgeToolFailures(logText) {
21172
20112
  }
21173
20113
  return counts;
21174
20114
  }
21175
- function sortFailureKeys(a3, b2, counts) {
21176
- const countDiff = (counts.get(b2) ?? 0) - (counts.get(a3) ?? 0);
20115
+ function sortFailureKeys(a3, b, counts) {
20116
+ const countDiff = (counts.get(b) ?? 0) - (counts.get(a3) ?? 0);
21177
20117
  if (countDiff !== 0)
21178
20118
  return countDiff;
21179
- return a3.localeCompare(b2);
20119
+ return a3.localeCompare(b);
21180
20120
  }
21181
20121
  function formatRecentAftToolFailuresSection(counts, options) {
21182
20122
  const maxClasses = options?.maxClasses ?? MAX_TOOL_FAILURE_CLASSES;
@@ -21185,7 +20125,7 @@ function formatRecentAftToolFailuresSection(counts, options) {
21185
20125
  return `${heading}
21186
20126
  No recent AFT tool failures recorded.`;
21187
20127
  }
21188
- const sorted = [...counts.keys()].sort((a3, b2) => sortFailureKeys(a3, b2, counts));
20128
+ const sorted = [...counts.keys()].sort((a3, b) => sortFailureKeys(a3, b, counts));
21189
20129
  const shown = sorted.slice(0, maxClasses);
21190
20130
  const hidden = sorted.length - shown.length;
21191
20131
  const bullets = shown.map((key) => {
@@ -21213,21 +20153,105 @@ var init_bridge_tool_failures = __esm(() => {
21213
20153
  STRUCTURED_CODE_PATTERN = /"code"\s*:\s*"([^"]+)"/;
21214
20154
  });
21215
20155
 
21216
- // src/lib/legacy-storage.ts
21217
- import { existsSync as existsSync18, readdirSync as readdirSync7, statSync as statSync12 } from "node:fs";
20156
+ // src/lib/build-breaker.ts
20157
+ import { existsSync as existsSync18, readdirSync as readdirSync7 } from "node:fs";
21218
20158
  import { join as join19 } from "node:path";
20159
+ import { DatabaseSync } from "node:sqlite";
20160
+ function buildBreakerDatabases(storageRoot) {
20161
+ const callgraphRoot = join19(storageRoot, "callgraph");
20162
+ if (!existsSync18(callgraphRoot))
20163
+ return [];
20164
+ try {
20165
+ return readdirSync7(callgraphRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join19(callgraphRoot, entry.name, "build-breaker.sqlite")).filter((path2) => existsSync18(path2));
20166
+ } catch {
20167
+ return [];
20168
+ }
20169
+ }
20170
+ function readBuildBreakerSuspensions(storageRoot, nowMs = Date.now()) {
20171
+ const suspensions = [];
20172
+ for (const databasePath of buildBreakerDatabases(storageRoot)) {
20173
+ let database;
20174
+ try {
20175
+ database = new DatabaseSync(databasePath, { readOnly: true });
20176
+ const rows = database.prepare(`SELECT root_id, domain, corpus_fingerprint, zero_credit_deaths, credited_deaths,
20177
+ suspended_reason, suspended_since_ms
20178
+ FROM breaker_records
20179
+ WHERE configuration_version = 'v1'
20180
+ AND suspended_reason IS NOT NULL
20181
+ AND suspended_since_ms IS NOT NULL
20182
+ AND suspended_until_ms > ?
20183
+ ORDER BY root_id, domain`).all(nowMs);
20184
+ for (const row of rows) {
20185
+ const deathCount = Number(row.zero_credit_deaths) + Number(row.credited_deaths);
20186
+ const ageS = Math.floor(Math.max(0, nowMs - Number(row.suspended_since_ms)) / 1000);
20187
+ suspensions.push({
20188
+ root: row.root_id,
20189
+ domain: row.domain,
20190
+ reason: row.suspended_reason,
20191
+ deathCount,
20192
+ ageS,
20193
+ fingerprint: row.corpus_fingerprint
20194
+ });
20195
+ }
20196
+ } catch {} finally {
20197
+ database?.close();
20198
+ }
20199
+ }
20200
+ return suspensions;
20201
+ }
20202
+ function formatBuildBreakerSuspension(suspension) {
20203
+ return [
20204
+ ` build suspended: root=${suspension.root}`,
20205
+ `domain=${suspension.domain}`,
20206
+ `deaths=${suspension.deathCount}`,
20207
+ `age_s=${suspension.ageS}`,
20208
+ `reason=${suspension.reason};`,
20209
+ `reset with \`${DOCTOR_BUILD_BREAKER_RESET_COMMAND} --root ${suspension.root} --domain ${suspension.domain} --fingerprint ${suspension.fingerprint}\``
20210
+ ].join(" ");
20211
+ }
20212
+ function resetBuildBreakerSuspension(storageRoot, target) {
20213
+ let reset = 0;
20214
+ for (const databasePath of buildBreakerDatabases(storageRoot)) {
20215
+ let database;
20216
+ try {
20217
+ database = new DatabaseSync(databasePath);
20218
+ const result = database.prepare(`UPDATE breaker_records
20219
+ SET zero_credit_deaths = 0,
20220
+ credited_deaths = 0,
20221
+ in_build_burn_ms = 0,
20222
+ suspended_reason = NULL,
20223
+ suspended_since_ms = NULL,
20224
+ suspended_until_ms = NULL
20225
+ WHERE root_id = ?
20226
+ AND domain = ?
20227
+ AND corpus_fingerprint = ?`).run(target.root, target.domain, target.fingerprint);
20228
+ reset += Number(result.changes ?? 0);
20229
+ } catch {} finally {
20230
+ database?.close();
20231
+ }
20232
+ }
20233
+ return reset;
20234
+ }
20235
+ var DOCTOR_BUILD_BREAKER_RESET_COMMAND;
20236
+ var init_build_breaker = __esm(() => {
20237
+ DOCTOR_BUILD_BREAKER_RESET_COMMAND = `${CLI} doctor reset-build-breaker`;
20238
+ });
20239
+
20240
+ // src/lib/legacy-storage.ts
20241
+ import { existsSync as existsSync19, readdirSync as readdirSync8, statSync as statSync12 } from "node:fs";
20242
+ import { join as join20 } from "node:path";
21219
20243
  function summarizeLegacyPartitionDuplication(storageRoot) {
21220
- if (!existsSync18(storageRoot)) {
20244
+ if (!existsSync19(storageRoot)) {
21221
20245
  return { totalPartitions: 0, totalBytes: 0, byHarness: [] };
21222
20246
  }
21223
20247
  const byHarness = [];
21224
20248
  for (const harness of safeReadDir(storageRoot)) {
21225
- const harnessPath = join19(storageRoot, harness);
20249
+ const harnessPath = join20(storageRoot, harness);
21226
20250
  if (!isDirectory(harnessPath))
21227
20251
  continue;
21228
20252
  const partitions = new Map;
21229
- collectCallgraphPartitions(join19(harnessPath, "callgraph"), partitions);
21230
- collectInspectPartitions(join19(harnessPath, "inspect"), partitions);
20253
+ collectCallgraphPartitions(join20(harnessPath, "callgraph"), partitions);
20254
+ collectInspectPartitions(join20(harnessPath, "inspect"), partitions);
21231
20255
  if (partitions.size === 0)
21232
20256
  continue;
21233
20257
  let bytes = 0;
@@ -21246,7 +20270,7 @@ function collectCallgraphPartitions(domainPath, partitions) {
21246
20270
  if (!isDirectory(domainPath))
21247
20271
  return;
21248
20272
  for (const name of safeReadDir(domainPath)) {
21249
- const path2 = join19(domainPath, name);
20273
+ const path2 = join20(domainPath, name);
21250
20274
  if (isDirectory(path2)) {
21251
20275
  if (!looksLikePartitionKey(name))
21252
20276
  continue;
@@ -21263,7 +20287,7 @@ function collectInspectPartitions(domainPath, partitions) {
21263
20287
  if (!isDirectory(domainPath))
21264
20288
  return;
21265
20289
  for (const name of safeReadDir(domainPath)) {
21266
- const path2 = join19(domainPath, name);
20290
+ const path2 = join20(domainPath, name);
21267
20291
  if (isDirectory(path2)) {
21268
20292
  if (!looksLikePartitionKey(name))
21269
20293
  continue;
@@ -21312,7 +20336,7 @@ function looksLikePartitionKey(value) {
21312
20336
  }
21313
20337
  function safeReadDir(path2) {
21314
20338
  try {
21315
- return readdirSync7(path2).sort((left, right) => left.localeCompare(right));
20339
+ return readdirSync8(path2).sort((left, right) => left.localeCompare(right));
21316
20340
  } catch {
21317
20341
  return [];
21318
20342
  }
@@ -21338,22 +20362,22 @@ var init_legacy_storage = __esm(() => {
21338
20362
  });
21339
20363
 
21340
20364
  // 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";
20365
+ import { existsSync as existsSync20, readdirSync as readdirSync9, rmSync as rmSync5, statSync as statSync13 } from "node:fs";
20366
+ import { join as join21 } from "node:path";
21343
20367
  function inspectDir(path2) {
21344
- if (!existsSync19(path2)) {
20368
+ if (!existsSync20(path2)) {
21345
20369
  return { entries: [], totalSize: 0 };
21346
20370
  }
21347
20371
  const entries = [];
21348
20372
  let totalSize = 0;
21349
20373
  let names;
21350
20374
  try {
21351
- names = readdirSync8(path2);
20375
+ names = readdirSync9(path2);
21352
20376
  } catch {
21353
20377
  return { entries: [], totalSize: 0 };
21354
20378
  }
21355
20379
  for (const name of names) {
21356
- const full = join20(path2, name);
20380
+ const full = join21(path2, name);
21357
20381
  try {
21358
20382
  if (!statSync13(full).isDirectory())
21359
20383
  continue;
@@ -21366,7 +20390,7 @@ function inspectDir(path2) {
21366
20390
  totalSize += size;
21367
20391
  } catch {}
21368
20392
  }
21369
- entries.sort((a3, b2) => b2.size - a3.size);
20393
+ entries.sort((a3, b) => b.size - a3.size);
21370
20394
  return { entries, totalSize };
21371
20395
  }
21372
20396
  function getLspCacheReport() {
@@ -21411,8 +20435,8 @@ var init_lsp_cache = __esm(() => {
21411
20435
  });
21412
20436
 
21413
20437
  // 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";
20438
+ import { existsSync as existsSync21, readdirSync as readdirSync10, readlinkSync as readlinkSync2, realpathSync as realpathSync4 } from "node:fs";
20439
+ import { basename as basename3, isAbsolute as isAbsolute6, join as join22, resolve as resolve11, win32 as win322 } from "node:path";
21416
20440
  function getOnnxLibraryName() {
21417
20441
  if (process.platform === "darwin")
21418
20442
  return "libonnxruntime.dylib";
@@ -21421,20 +20445,20 @@ function getOnnxLibraryName() {
21421
20445
  return "libonnxruntime.so";
21422
20446
  }
21423
20447
  function getManualInstallHint2() {
21424
- const p2 = process.platform;
20448
+ const p = process.platform;
21425
20449
  const a3 = process.arch;
21426
- if (p2 === "darwin") {
20450
+ if (p === "darwin") {
21427
20451
  if (a3 === "arm64")
21428
20452
  return "brew install onnxruntime (Apple Silicon)";
21429
20453
  return "Intel Mac requires manual install — see docs";
21430
20454
  }
21431
- if (p2 === "linux") {
20455
+ if (p === "linux") {
21432
20456
  if (a3 === "x64" || a3 === "arm64") {
21433
20457
  return "AFT auto-downloads ONNX Runtime on supported Linux (glibc)";
21434
20458
  }
21435
20459
  return "manual install required for this Linux arch";
21436
20460
  }
21437
- if (p2 === "win32") {
20461
+ if (p === "win32") {
21438
20462
  if (a3 === "x64" || a3 === "arm64")
21439
20463
  return "AFT auto-downloads ONNX Runtime on Windows";
21440
20464
  return "manual install required for this Windows arch";
@@ -21465,7 +20489,7 @@ function isWindowsSystem32Directory2(dir) {
21465
20489
  }
21466
20490
  function directoryContainsLibrary2(dir, libName) {
21467
20491
  try {
21468
- const entries = readdirSync9(dir);
20492
+ const entries = readdirSync10(dir);
21469
20493
  if (process.platform === "win32") {
21470
20494
  const expected = libName.toLowerCase();
21471
20495
  return entries.some((entry) => entry.toLowerCase() === expected);
@@ -21483,7 +20507,7 @@ function findIgnoredWindowsSystemOnnxRuntime() {
21483
20507
  for (const root of windowsRoots) {
21484
20508
  if (!root)
21485
20509
  continue;
21486
- const systemDir = join21(root, "System32");
20510
+ const systemDir = join22(root, "System32");
21487
20511
  const key = win322.resolve(systemDir).toLowerCase();
21488
20512
  if (seen.has(key))
21489
20513
  continue;
@@ -21504,21 +20528,21 @@ function findSystemOnnxRuntime2() {
21504
20528
  searchPaths.push(...pathEntriesForPlatform2());
21505
20529
  const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
21506
20530
  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"), ...(() => {
20531
+ searchPaths.push(join22(programFiles, "onnxruntime", "lib"), join22(programFiles, "Microsoft ONNX Runtime", "lib"), join22(programFiles, "Microsoft Machine Learning", "lib"), join22(programFilesX86, "onnxruntime", "lib"), ...(() => {
21508
20532
  const nugetPaths = [];
21509
20533
  const userProfile = process.env.USERPROFILE ?? "";
21510
20534
  if (!userProfile)
21511
20535
  return nugetPaths;
21512
- const nugetPackageDir = join21(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
21513
- if (!existsSync20(nugetPackageDir))
20536
+ const nugetPackageDir = join22(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
20537
+ if (!existsSync21(nugetPackageDir))
21514
20538
  return nugetPaths;
21515
20539
  try {
21516
- for (const entry of readdirSync9(nugetPackageDir, { withFileTypes: true })) {
20540
+ for (const entry of readdirSync10(nugetPackageDir, { withFileTypes: true })) {
21517
20541
  if (!entry.isDirectory())
21518
20542
  continue;
21519
20543
  if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
21520
20544
  continue;
21521
- nugetPaths.push(join21(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join21(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
20545
+ nugetPaths.push(join22(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join22(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
21522
20546
  }
21523
20547
  } catch {}
21524
20548
  return nugetPaths;
@@ -21528,7 +20552,7 @@ function findSystemOnnxRuntime2() {
21528
20552
  const seen = new Set;
21529
20553
  const unknownVersionPaths = [];
21530
20554
  for (const dir of searchPaths) {
21531
- let key = resolve10(dir).replace(/[/\\]+$/, "");
20555
+ let key = resolve11(dir).replace(/[/\\]+$/, "");
21532
20556
  if (normalizeCase)
21533
20557
  key = key.toLowerCase();
21534
20558
  if (seen.has(key))
@@ -21550,12 +20574,12 @@ function findSystemOnnxRuntime2() {
21550
20574
  return unknownVersionPaths[0] ?? null;
21551
20575
  }
21552
20576
  function findCachedOnnxRuntime(storageDir) {
21553
- const ortDir = join21(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
20577
+ const ortDir = join22(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
21554
20578
  const libName = getOnnxLibraryName();
21555
- if (existsSync20(join21(ortDir, libName)))
20579
+ if (existsSync21(join22(ortDir, libName)))
21556
20580
  return ortDir;
21557
- const libSubdir = join21(ortDir, "lib");
21558
- if (existsSync20(join21(libSubdir, libName)))
20581
+ const libSubdir = join22(ortDir, "lib");
20582
+ if (existsSync21(join22(libSubdir, libName)))
21559
20583
  return libSubdir;
21560
20584
  return null;
21561
20585
  }
@@ -21576,11 +20600,11 @@ function parseOrtVersionFromDirectoryPath(value) {
21576
20600
  return null;
21577
20601
  }
21578
20602
  function detectOrtVersion(libDir) {
21579
- if (!existsSync20(libDir))
20603
+ if (!existsSync21(libDir))
21580
20604
  return null;
21581
20605
  const libName = getOnnxLibraryName();
21582
20606
  try {
21583
- const entries = readdirSync9(libDir);
20607
+ const entries = readdirSync10(libDir);
21584
20608
  const barePrefix = libName.replace(/\.(so|dylib|dll)$/, "");
21585
20609
  const expectedPrefix = process.platform === "win32" ? barePrefix.toLowerCase() : barePrefix;
21586
20610
  for (const entry of entries) {
@@ -21591,8 +20615,8 @@ function detectOrtVersion(libDir) {
21591
20615
  if (version)
21592
20616
  return version;
21593
20617
  }
21594
- const base = join21(libDir, libName);
21595
- if (existsSync20(base)) {
20618
+ const base = join22(libDir, libName);
20619
+ if (existsSync21(base)) {
21596
20620
  try {
21597
20621
  const real = realpathSync4(base);
21598
20622
  const version = parseOrtVersionFromPath(real) ?? parseOrtVersionFromDirectoryPath(real);
@@ -21611,7 +20635,7 @@ function detectOrtVersion(libDir) {
21611
20635
  return null;
21612
20636
  }
21613
20637
  function isOrtVersionCompatible(version) {
21614
- const parts = version.split(".").map((p2) => parseInt(p2, 10));
20638
+ const parts = version.split(".").map((p) => parseInt(p, 10));
21615
20639
  const [major, minor] = parts;
21616
20640
  if (!Number.isFinite(major) || !Number.isFinite(minor))
21617
20641
  return false;
@@ -21627,7 +20651,7 @@ import {
21627
20651
  accessSync,
21628
20652
  closeSync as closeSync6,
21629
20653
  constants,
21630
- existsSync as existsSync21,
20654
+ existsSync as existsSync22,
21631
20655
  openSync as openSync6,
21632
20656
  readSync as readSync3,
21633
20657
  statSync as statSync14
@@ -21648,7 +20672,8 @@ async function collectDiagnostics(adapters) {
21648
20672
  binaryVersion,
21649
20673
  harnesses,
21650
20674
  binaryCache: getBinaryCacheInfo(cliVersion),
21651
- lspCache: getLspCacheReport()
20675
+ lspCache: getLspCacheReport(),
20676
+ buildBreakerSuspensions: harnesses[0] ? readBuildBreakerSuspensions(harnesses[0].storageDir.path) : []
21652
20677
  };
21653
20678
  }
21654
20679
  async function diagnoseHarness(adapter) {
@@ -21665,7 +20690,7 @@ async function diagnoseHarness(adapter) {
21665
20690
  const logPath = adapter.getLogFile();
21666
20691
  const pluginCache = adapter.getPluginCacheInfo();
21667
20692
  const storageAccessible = (() => {
21668
- if (!existsSync21(storage))
20693
+ if (!existsSync22(storage))
21669
20694
  return false;
21670
20695
  try {
21671
20696
  accessSync(storage, constants.R_OK | constants.W_OK);
@@ -21690,7 +20715,7 @@ async function diagnoseHarness(adapter) {
21690
20715
  pluginRegistered: adapter.hasPluginEntry(),
21691
20716
  configPaths,
21692
20717
  aftConfig: {
21693
- exists: existsSync21(configPaths.aftConfig),
20718
+ exists: existsSync22(configPaths.aftConfig),
21694
20719
  ...aftConfigRead.error ? { parseError: aftConfigRead.error } : {},
21695
20720
  enabled: aftEnabled,
21696
20721
  ...aftEnabledSource ? { enabledSource: aftEnabledSource } : {},
@@ -21699,7 +20724,7 @@ async function diagnoseHarness(adapter) {
21699
20724
  pluginCache,
21700
20725
  storageDir: {
21701
20726
  path: storage,
21702
- exists: existsSync21(storage),
20727
+ exists: existsSync22(storage),
21703
20728
  accessible: storageAccessible,
21704
20729
  sizesByKey: describeStorage,
21705
20730
  ...legacyDuplication.totalPartitions > 0 ? { legacyDuplication } : {}
@@ -21720,8 +20745,8 @@ async function diagnoseHarness(adapter) {
21720
20745
  },
21721
20746
  logFile: {
21722
20747
  path: logPath,
21723
- exists: existsSync21(logPath),
21724
- sizeKb: existsSync21(logPath) ? Math.round(statSync14(logPath).size / 1024) : 0
20748
+ exists: existsSync22(logPath),
20749
+ sizeKb: existsSync22(logPath) ? Math.round(statSync14(logPath).size / 1024) : 0
21725
20750
  }
21726
20751
  };
21727
20752
  }
@@ -21794,9 +20819,9 @@ function renderDiagnosticsMarkdown(report) {
21794
20819
  function normalizeVersion(version) {
21795
20820
  return version.trim().replace(/^v/, "");
21796
20821
  }
21797
- function compareLooseSemver(a3, b2) {
20822
+ function compareLooseSemver(a3, b) {
21798
20823
  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));
20824
+ const bParts = normalizeVersion(b).split(/[.-]/).slice(0, 3).map((part) => Number.parseInt(part, 10));
21800
20825
  for (let i2 = 0;i2 < 3; i2 += 1) {
21801
20826
  const av = Number.isFinite(aParts[i2]) ? aParts[i2] : 0;
21802
20827
  const bv = Number.isFinite(bParts[i2]) ? bParts[i2] : 0;
@@ -21828,14 +20853,15 @@ function pluginVersionSkewIssue(harness, cliVersion) {
21828
20853
  }
21829
20854
  function collectDiagnosticIssues(report) {
21830
20855
  const issues = [];
21831
- const hasEnabledRegisteredHarness = report.harnesses.some((h2) => h2.pluginRegistered && h2.aftConfig.enabled);
21832
- if (!report.binaryVersion && hasEnabledRegisteredHarness) {
20856
+ const hasEnabledHarness = report.harnesses.some((h2) => h2.hostInstalled && h2.aftConfig.enabled);
20857
+ const hasMatchingEnabledPlugin = report.harnesses.some((h2) => h2.pluginRegistered && h2.aftConfig.enabled && h2.pluginCache.cached && normalizeVersion(h2.pluginCache.cached) === normalizeVersion(report.cliVersion));
20858
+ if (!report.binaryVersion && hasEnabledHarness) {
21833
20859
  issues.push({
21834
20860
  code: "binary_missing",
21835
- severity: "high",
20861
+ severity: hasMatchingEnabledPlugin ? "info" : "high",
21836
20862
  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.`
20863
+ 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.`,
20864
+ 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
20865
  });
21840
20866
  }
21841
20867
  for (const h2 of report.harnesses) {
@@ -21917,7 +20943,7 @@ function formatDiagnosticIssuesSection(report) {
21917
20943
  return lines;
21918
20944
  }
21919
20945
  function tailLogFile(path2, lines) {
21920
- if (!existsSync21(path2))
20946
+ if (!existsSync22(path2))
21921
20947
  return "";
21922
20948
  if (lines <= 0)
21923
20949
  return "";
@@ -21956,6 +20982,7 @@ function tailLogFile(path2, lines) {
21956
20982
  var init_diagnostics = __esm(async () => {
21957
20983
  init_dist2();
21958
20984
  init_binary_cache();
20985
+ init_build_breaker();
21959
20986
  init_jsonc();
21960
20987
  init_legacy_storage();
21961
20988
  init_lsp_cache();
@@ -22105,14 +21132,14 @@ var init_issue_body = __esm(() => {
22105
21132
  });
22106
21133
 
22107
21134
  // src/lib/onnx-fix.ts
22108
- import { existsSync as existsSync22, rmSync as rmSync6 } from "node:fs";
22109
- import { join as join22 } from "node:path";
21135
+ import { existsSync as existsSync23, rmSync as rmSync6 } from "node:fs";
21136
+ import { join as join23 } from "node:path";
22110
21137
  function findOnnxFixCandidates(report) {
22111
21138
  const candidates = [];
22112
21139
  for (const harness of report.harnesses) {
22113
21140
  if (!harness.onnxRuntime.required)
22114
21141
  continue;
22115
- const storageOnnxDir = join22(harness.storageDir.path, "onnxruntime");
21142
+ const storageOnnxDir = join23(harness.storageDir.path, "onnxruntime");
22116
21143
  const systemTooOld = harness.onnxRuntime.systemPath !== null && harness.onnxRuntime.systemCompatible === false;
22117
21144
  const cachedTooOld = harness.onnxRuntime.cachedPath !== null && harness.onnxRuntime.cachedCompatible === false;
22118
21145
  const hasCompatibleCached = harness.onnxRuntime.cachedCompatible === true;
@@ -22121,7 +21148,7 @@ function findOnnxFixCandidates(report) {
22121
21148
  harness,
22122
21149
  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
21150
  storageOnnxDir,
22124
- storageOnnxBytes: existsSync22(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
21151
+ storageOnnxBytes: existsSync23(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
22125
21152
  });
22126
21153
  continue;
22127
21154
  }
@@ -22130,7 +21157,7 @@ function findOnnxFixCandidates(report) {
22130
21157
  harness,
22131
21158
  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
21159
  storageOnnxDir,
22133
- storageOnnxBytes: existsSync22(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
21160
+ storageOnnxBytes: existsSync23(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
22134
21161
  });
22135
21162
  continue;
22136
21163
  }
@@ -22140,7 +21167,7 @@ function findOnnxFixCandidates(report) {
22140
21167
  harness,
22141
21168
  reason: `no compatible ONNX Runtime is installed.${ignoredCopy} AFT will download v1.24 into managed storage.`,
22142
21169
  storageOnnxDir,
22143
- storageOnnxBytes: existsSync22(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
21170
+ storageOnnxBytes: existsSync23(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
22144
21171
  });
22145
21172
  }
22146
21173
  }
@@ -22170,7 +21197,7 @@ async function runOnnxFix(adapters, report, options = {}) {
22170
21197
  const rmFn = options.rmFn ?? rmSync6;
22171
21198
  const ensureFn = options.ensureFn ?? ensureOnnxRuntime;
22172
21199
  for (const candidate of candidates) {
22173
- if (existsSync22(candidate.storageOnnxDir)) {
21200
+ if (existsSync23(candidate.storageOnnxDir)) {
22174
21201
  try {
22175
21202
  rmFn(candidate.storageOnnxDir, { recursive: true, force: true });
22176
21203
  result.cleared += 1;
@@ -22212,10 +21239,10 @@ var init_onnx_fix = __esm(() => {
22212
21239
  });
22213
21240
 
22214
21241
  // src/lib/sessions.ts
22215
- import { existsSync as existsSync23, readdirSync as readdirSync10, readFileSync as readFileSync10, statSync as statSync15 } from "node:fs";
21242
+ import { existsSync as existsSync24, readdirSync as readdirSync11, readFileSync as readFileSync10, statSync as statSync15 } from "node:fs";
22216
21243
  import { createRequire as createRequire5 } from "node:module";
22217
21244
  import { homedir as homedir18 } from "node:os";
22218
- import { basename as basename4, join as join23 } from "node:path";
21245
+ import { basename as basename4, join as join24 } from "node:path";
22219
21246
  function listRecentSessions(adapter) {
22220
21247
  try {
22221
21248
  if (adapter.kind === "opencode")
@@ -22241,11 +21268,11 @@ function mapOpenCodeSessionRows(rows) {
22241
21268
  title: row.title,
22242
21269
  lastActivity
22243
21270
  };
22244
- }).filter((session) => session !== null).sort((a3, b2) => b2.lastActivity - a3.lastActivity).slice(0, MAX_RECENT_SESSIONS);
21271
+ }).filter((session) => session !== null).sort((a3, b) => b.lastActivity - a3.lastActivity).slice(0, MAX_RECENT_SESSIONS);
22245
21272
  }
22246
21273
  function listRecentOpenCodeSessions() {
22247
- const dbPath = join23(getXdgDataHome(), "opencode", "opencode.db");
22248
- if (!existsSync23(dbPath))
21274
+ const dbPath = join24(getXdgDataHome(), "opencode", "opencode.db");
21275
+ if (!existsSync24(dbPath))
22249
21276
  return [];
22250
21277
  let db = null;
22251
21278
  try {
@@ -22264,10 +21291,10 @@ function listRecentOpenCodeSessions() {
22264
21291
  }
22265
21292
  function getXdgDataHome() {
22266
21293
  const xdgDataHome = process.env.XDG_DATA_HOME;
22267
- return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join23(homedir18(), ".local", "share");
21294
+ return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join24(homedir18(), ".local", "share");
22268
21295
  }
22269
21296
  function listRecentPiSessions() {
22270
- return listPiSessionsFromDir(join23(getHomeDir(), ".pi", "agent", "sessions"));
21297
+ return listPiSessionsFromDir(join24(getHomeDir(), ".pi", "agent", "sessions"));
22271
21298
  }
22272
21299
  function getHomeDir() {
22273
21300
  const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
@@ -22275,7 +21302,7 @@ function getHomeDir() {
22275
21302
  }
22276
21303
  function listPiSessionsFromDir(sessionsDir) {
22277
21304
  try {
22278
- if (!existsSync23(sessionsDir))
21305
+ if (!existsSync24(sessionsDir))
22279
21306
  return [];
22280
21307
  const files = collectJsonlFiles(sessionsDir).map((filePath) => {
22281
21308
  try {
@@ -22284,7 +21311,7 @@ function listPiSessionsFromDir(sessionsDir) {
22284
21311
  } catch {
22285
21312
  return null;
22286
21313
  }
22287
- }).filter((entry) => entry !== null).sort((a3, b2) => b2.mtimeMs - a3.mtimeMs).slice(0, MAX_RECENT_SESSIONS * 4);
21314
+ }).filter((entry) => entry !== null).sort((a3, b) => b.mtimeMs - a3.mtimeMs).slice(0, MAX_RECENT_SESSIONS * 4);
22288
21315
  const sessions = [];
22289
21316
  for (const file of files) {
22290
21317
  const parsed = parsePiSessionJsonl(readFileSync10(file.filePath, "utf8"), basename4(file.filePath));
@@ -22308,12 +21335,12 @@ function collectJsonlFiles(root) {
22308
21335
  continue;
22309
21336
  let entries;
22310
21337
  try {
22311
- entries = readdirSync10(dir, { withFileTypes: true });
21338
+ entries = readdirSync11(dir, { withFileTypes: true });
22312
21339
  } catch {
22313
21340
  continue;
22314
21341
  }
22315
21342
  for (const entry of entries) {
22316
- const path2 = join23(dir, entry.name);
21343
+ const path2 = join24(dir, entry.name);
22317
21344
  if (entry.isDirectory()) {
22318
21345
  stack.push(path2);
22319
21346
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -22397,23 +21424,25 @@ var init_sessions = () => {};
22397
21424
  // src/commands/doctor.ts
22398
21425
  var exports_doctor = {};
22399
21426
  __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,
21427
+ DOCTOR_CLEAR_TARGET_OPTIONS: () => DOCTOR_CLEAR_TARGET_OPTIONS,
22410
21428
  DOCTOR_FORCE_CLEAR_TARGETS: () => DOCTOR_FORCE_CLEAR_TARGETS,
22411
- DOCTOR_CLEAR_TARGET_OPTIONS: () => DOCTOR_CLEAR_TARGET_OPTIONS
21429
+ buildDoctorFixPlan: () => buildDoctorFixPlan,
21430
+ clearDoctorCaches: () => clearDoctorCaches,
21431
+ clearOldBinaries: () => clearOldBinaries,
21432
+ deriveIssueTitleFromBody: () => deriveIssueTitleFromBody,
21433
+ doctorSkewBinaryDownloadDecision: () => doctorSkewBinaryDownloadDecision,
21434
+ fixPluginEntries: () => fixPluginEntries,
21435
+ formatDoctorStorageStatus: () => formatDoctorStorageStatus,
21436
+ hasDoctorProblems: () => hasDoctorProblems,
21437
+ logBuildBreakerSuspensions: () => logBuildBreakerSuspensions,
21438
+ runDoctor: () => runDoctor,
21439
+ runDoctorBuildBreakerReset: () => runDoctorBuildBreakerReset,
21440
+ shouldSkipDoctorFixConfirmation: () => shouldSkipDoctorFixConfirmation
22412
21441
  });
22413
21442
  import { execFileSync as execFileSync3 } from "node:child_process";
22414
21443
  import {
22415
21444
  chmodSync as chmodSync4,
22416
- existsSync as existsSync24,
21445
+ existsSync as existsSync25,
22417
21446
  mkdirSync as mkdirSync7,
22418
21447
  mkdtempSync,
22419
21448
  readFileSync as readFileSync11,
@@ -22423,7 +21452,7 @@ import {
22423
21452
  writeFileSync as writeFileSync5
22424
21453
  } from "node:fs";
22425
21454
  import { tmpdir as tmpdir2 } from "node:os";
22426
- import { join as join24 } from "node:path";
21455
+ import { join as join25 } from "node:path";
22427
21456
  async function runDoctor(options) {
22428
21457
  if (options.issue) {
22429
21458
  return runIssueFlow(options.argv);
@@ -22444,8 +21473,11 @@ async function runDoctor(options) {
22444
21473
  if (!report.binaryVersion) {
22445
21474
  const hasEnabledRegisteredHarness = report.harnesses.some((h2) => h2.pluginRegistered && h2.aftConfig.enabled);
22446
21475
  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`);
21476
+ const binaryIssue = collectDiagnosticIssues(report).find((issue) => issue.code === "binary_missing");
21477
+ if (hasEnabledRegisteredHarness && binaryIssue?.severity === "info") {
21478
+ log2.info(` no matching aft binary detected — it will self-install when the next AFT-enabled session starts (or run \`${CLI} doctor --fix\`)`);
21479
+ } else if (hasEnabledRegisteredHarness) {
21480
+ 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
21481
  } else if (hasRegisteredHarness) {
22450
21482
  log2.info(" no matching aft binary detected; all registered AFT harnesses are disabled by config");
22451
21483
  } else {
@@ -22454,6 +21486,7 @@ async function runDoctor(options) {
22454
21486
  logUnmatchedBinaryCandidates(report.cliVersion);
22455
21487
  }
22456
21488
  log2.info(`Binary cache: ${report.binaryCache.versions.length} version(s), ${formatBytes(report.binaryCache.totalSize)} at ${report.binaryCache.path}`);
21489
+ logBuildBreakerSuspensions(report);
22457
21490
  const npmCount = report.lspCache.npm.entries.length;
22458
21491
  const ghCount = report.lspCache.github.entries.length;
22459
21492
  if (npmCount + ghCount > 0) {
@@ -22520,7 +21553,41 @@ async function runDoctor(options) {
22520
21553
  return 0;
22521
21554
  }
22522
21555
  function hasDoctorProblems(report) {
22523
- return formatDiagnosticIssuesSection(report).length > 0;
21556
+ return collectDiagnosticIssues(report).some((issue) => issue.severity !== "info") || (report.buildBreakerSuspensions?.length ?? 0) > 0;
21557
+ }
21558
+ function logBuildBreakerSuspensions(report) {
21559
+ for (const suspension of report.buildBreakerSuspensions ?? []) {
21560
+ log2.warn(formatBuildBreakerSuspension(suspension));
21561
+ }
21562
+ }
21563
+ async function runDoctorBuildBreakerReset(argv) {
21564
+ const optionValue = (name) => {
21565
+ const index = argv.indexOf(name);
21566
+ return index >= 0 ? argv[index + 1] : undefined;
21567
+ };
21568
+ const root = optionValue("--root");
21569
+ const domain = optionValue("--domain");
21570
+ const fingerprint = optionValue("--fingerprint");
21571
+ if (!root || !domain || !fingerprint) {
21572
+ log2.error(`Usage: ${DOCTOR_BUILD_BREAKER_RESET_COMMAND} --root <root> --domain <domain> --fingerprint <fingerprint>`);
21573
+ return 2;
21574
+ }
21575
+ const adapters = await resolveAdaptersForCommand(argv, {
21576
+ allowMulti: false,
21577
+ verb: "reset the build breaker for"
21578
+ });
21579
+ const storageRoot = adapters[0]?.getStorageDir();
21580
+ if (!storageRoot) {
21581
+ log2.error("No AFT storage root was found for the selected harness.");
21582
+ return 1;
21583
+ }
21584
+ const reset = resetBuildBreakerSuspension(storageRoot, { root, domain, fingerprint });
21585
+ if (reset === 0) {
21586
+ log2.warn("No matching build-breaker suspension was found; no records were changed.");
21587
+ return 1;
21588
+ }
21589
+ log2.success(`Reset build breaker for root=${root} domain=${domain}.`);
21590
+ return 0;
22524
21591
  }
22525
21592
  async function runClearFlow(argv) {
22526
21593
  const targets = await selectMany("What do you want to clear?", DOCTOR_CLEAR_TARGET_OPTIONS, undefined, false);
@@ -22590,7 +21657,7 @@ function clearOldBinaries() {
22590
21657
  errors: [],
22591
21658
  keptVersion: keepTag
22592
21659
  };
22593
- if (!existsSync24(info.path)) {
21660
+ if (!existsSync25(info.path)) {
22594
21661
  log2.info(`Binary cache: nothing to clear at ${info.path}`);
22595
21662
  return result;
22596
21663
  }
@@ -22600,7 +21667,7 @@ function clearOldBinaries() {
22600
21667
  return result;
22601
21668
  }
22602
21669
  for (const version of stale) {
22603
- const dir = join24(info.path, version);
21670
+ const dir = join25(info.path, version);
22604
21671
  let bytes = 0;
22605
21672
  try {
22606
21673
  bytes = statSync16(dir).isDirectory() ? dirSize(dir) : 0;
@@ -22905,6 +21972,8 @@ function logDoctorIssues(report) {
22905
21972
  const remediation = lines[i2 + 1];
22906
21973
  if (issue.startsWith("[HIGH]")) {
22907
21974
  log2.error(issue);
21975
+ } else if (issue.startsWith("[INFO]")) {
21976
+ log2.info(issue);
22908
21977
  } else {
22909
21978
  log2.warn(issue);
22910
21979
  }
@@ -22945,7 +22014,7 @@ function ensureStorageDirsForRegisteredPlugins(adapters) {
22945
22014
  if (!adapter.isInstalled() || !adapter.hasPluginEntry())
22946
22015
  continue;
22947
22016
  const storageDir = adapter.getStorageDir();
22948
- if (existsSync24(storageDir))
22017
+ if (existsSync25(storageDir))
22949
22018
  continue;
22950
22019
  mkdirSync7(storageDir, { recursive: true });
22951
22020
  summary.created += 1;
@@ -23024,8 +22093,14 @@ function describeAdapterInstallHint(kind) {
23024
22093
  return "(unknown harness)";
23025
22094
  }
23026
22095
  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";
22096
+ const projectParts = Object.entries(sizes).filter(([key, size]) => key !== "logs" && size > 0).map(([key, size]) => `${key}: ${formatBytes(size)}`);
22097
+ const logsSize = sizes.logs ?? 0;
22098
+ const parts = [...projectParts];
22099
+ if (logsSize > 0)
22100
+ parts.push(`logs: ${formatBytes(logsSize)}`);
22101
+ if (projectParts.length > 0)
22102
+ return parts.join(", ");
22103
+ return logsSize > 0 ? `${parts[0]}; no project data yet` : "empty";
23029
22104
  }
23030
22105
  function formatLegacyDuplication(summary) {
23031
22106
  if (!summary || summary.totalPartitions === 0)
@@ -23064,11 +22139,11 @@ function deriveIssueTitleFromBody(body) {
23064
22139
  function writeIssueReviewFile(body) {
23065
22140
  let reviewDir = null;
23066
22141
  try {
23067
- reviewDir = mkdtempSync(join24(tmpdir2(), "aft-issue-"));
22142
+ reviewDir = mkdtempSync(join25(tmpdir2(), "aft-issue-"));
23068
22143
  if (process.platform !== "win32") {
23069
22144
  chmodSync4(reviewDir, 448);
23070
22145
  }
23071
- const outPath = join24(reviewDir, "issue.md");
22146
+ const outPath = join25(reviewDir, "issue.md");
23072
22147
  writeFileSync5(outPath, `${body}
23073
22148
  `, { encoding: "utf8", mode: 384, flag: "wx" });
23074
22149
  return { path: outPath, realPath: realpathSync5(outPath) };
@@ -23232,6 +22307,7 @@ var init_doctor = __esm(async () => {
23232
22307
  init_dist2();
23233
22308
  init_binary_cache();
23234
22309
  init_bridge_tool_failures();
22310
+ init_build_breaker();
23235
22311
  init_fs_util();
23236
22312
  init_github();
23237
22313
  init_harness_select();
@@ -23280,6 +22356,7 @@ function printHelp() {
23280
22356
  console.log(" doctor --fix Auto-fix common issues (e.g. ONNX Runtime mismatch)");
23281
22357
  console.log(" doctor --clear Select caches to clear with an interactive prompt");
23282
22358
  console.log(" doctor --issue Collect diagnostics and open a GitHub issue");
22359
+ console.log(" doctor reset-build-breaker --root <root> --domain <domain> --fingerprint <fingerprint>");
23283
22360
  console.log("");
23284
22361
  console.log(" Harness selection:");
23285
22362
  console.log(" --harness opencode Target OpenCode only");
@@ -23292,6 +22369,7 @@ function printHelp() {
23292
22369
  console.log(` ${CLI} doctor lsp ./src/main.py`);
23293
22370
  console.log(` ${CLI} doctor --clear`);
23294
22371
  console.log(` ${CLI} doctor --issue`);
22372
+ console.log(` ${CLI} doctor reset-build-breaker --root <root> --domain <domain> --fingerprint <fingerprint>`);
23295
22373
  console.log("");
23296
22374
  }
23297
22375
  async function main() {
@@ -23312,6 +22390,10 @@ async function main() {
23312
22390
  const { runDoctorFilters: runDoctorFilters2 } = await init_doctor_filters().then(() => exports_doctor_filters);
23313
22391
  return runDoctorFilters2({ argv: args.slice(1) });
23314
22392
  }
22393
+ if (args[0] === "reset-build-breaker") {
22394
+ const { runDoctorBuildBreakerReset: runDoctorBuildBreakerReset2 } = await init_doctor().then(() => exports_doctor);
22395
+ return runDoctorBuildBreakerReset2(args.slice(1));
22396
+ }
23315
22397
  const { runDoctor: runDoctor2 } = await init_doctor().then(() => exports_doctor);
23316
22398
  const force = args.includes("--force");
23317
22399
  const clear = args.includes("--clear");