@cortexkit/opencode-openai-auth 0.6.1 → 0.6.2

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/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{F as q,K as B,L as V,r as Y,y as Z,z as $}from"./index-cxze8h26.js";import"./index-n00ybbbq.js";import"./index-hxpv25e8.js";import{Ha as X}from"./index-s2vhsb2v.js";import{execFileSync as E}from"node:child_process";function Q(C,H=process.platform,D=E){try{if(H==="win32"){D("cmd",["/c","start","",C],{stdio:"ignore",timeout:3000});return}D(H==="darwin"?"open":"xdg-open",[C],{stdio:"ignore",timeout:3000})}catch{}}function T(){console.log(`Usage:
2
+ import{F as q,K as B,L as V,r as Y,y as Z,z as $}from"./index-srgn00yp.js";import"./index-n00ybbbq.js";import"./index-hxpv25e8.js";import{Ha as X}from"./index-s2vhsb2v.js";import{execFileSync as E}from"node:child_process";function Q(C,H=process.platform,D=E){try{if(H==="win32"){D("cmd",["/c","start","",C],{stdio:"ignore",timeout:3000});return}D(H==="darwin"?"open":"xdg-open",[C],{stdio:"ignore",timeout:3000})}catch{}}function T(){console.log(`Usage:
3
3
  npx @cortexkit/opencode-openai-auth login [--label <name>] [--headless]
4
4
  npx @cortexkit/opencode-openai-auth list
5
5
  npx @cortexkit/opencode-openai-auth remove <id>
@@ -2,7 +2,7 @@ export declare const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
2
2
  export declare const ISSUER = "https://auth.openai.com";
3
3
  export declare const OAUTH_PORT = 1455;
4
4
  export declare const OAUTH_POLLING_SAFETY_MARGIN_MS = 3000;
5
- export declare const USER_AGENT = "cortexkit-opencode-openai-auth/0.6.1";
5
+ export declare const USER_AGENT = "cortexkit-opencode-openai-auth/0.6.2";
6
6
  export declare const RESERVED_ACCOUNT_ID = "main";
7
7
  export declare const RESERVED_ACCOUNT_ID_ERROR = "\"main\" is a reserved account id; choose a different label.";
8
8
  export interface PkceCodes {
@@ -0,0 +1,89 @@
1
+ import{ua as T}from"./index-n00ybbbq.js";import{Aa as h}from"./index-hxpv25e8.js";import{Ha as j2}from"./index-s2vhsb2v.js";import{createHash as d0}from"node:crypto";var g0=86400000,i0=300000,u0=3600000,s0=60000,r0=900000,n0=300000;function e(B){return B instanceof Error?B.message:String(B)}function c0(B){let Z=B?.status;if(typeof Z==="number")return Z===429||Z>=500;if(!(B instanceof Error))return!1;return B.name==="AbortError"||B.name==="TimeoutError"||B.message.includes("fetch failed")||"code"in B&&(B.code==="ECONNRESET"||B.code==="ECONNREFUSED"||B.code==="ETIMEDOUT"||B.code==="UND_ERR_CONNECT_TIMEOUT")}function B0(B){let Z=e(B),$=B?.status;if(typeof $==="number")return $===429||$>=500;if(!(B instanceof Error))return!1;let W=B.code;return B.name==="AbortError"||B.name==="TimeoutError"||Z.includes("fetch failed")||W==="ECONNRESET"||W==="ECONNREFUSED"||W==="ETIMEDOUT"||W==="UND_ERR_CONNECT_TIMEOUT"}function N0(B){return d0("sha256").update(B).digest("hex")}function P0(B){let Z=N0(B.refreshToken),W=(B.previous?.tokenHash===Z?B.previous.retryCount??0:0)+1,X,z=B.error?.retryAfter;if(typeof z==="number"&&z>0)X=z*1000;else if(c0(B.error))X=Math.min(u0,i0*2**Math.min(W-1,6));else X=g0;return{message:e(B.error),checkedAt:B.now,nextRetryAt:B.now+X,retryCount:W,tokenHash:Z}}function U(B,Z,$){if(!B?.nextRetryAt||B.nextRetryAt<=$)return!1;if(!Z)return!0;return B.tokenHash===N0(Z)}function i(B,Z){return`Codex OAuth refresh is backed off for ${Math.max(1,Math.ceil(((B.nextRetryAt??Z)-Z)/1000))}s after: ${B.message}`}function I(B){let $=(B.previous?.retryCount??0)+1,W,X=B.error?.retryAfter;if(typeof X==="number"&&X>0)W=X*1000;else if(B0(B.error))W=Math.min(r0,s0*2**Math.min($-1,6));else W=n0;return{message:e(B.error),checkedAt:B.now,nextRetryAt:B.now+W,retryCount:$}}function x(B,Z){if(!B?.nextRetryAt||B.nextRetryAt<=Z)return!1;return!0}function Z0(B){if(!B)return;let Z=Number(B);if(Number.isFinite(Z)&&Z>0)return Math.ceil(Z);let $=Date.parse(B);if(Number.isFinite($)){let W=Math.ceil(($-Date.now())/1000);return W>0?W:void 0}return}import{createServer as o0}from"node:http";import{setTimeout as a0}from"node:timers/promises";var V0="0.6.2";var r="app_EMoamEEZ73f0CkXaXp7hrann",q="https://auth.openai.com",w=1455,t0=3000,O0=`cortexkit-opencode-openai-auth/${V0}`,b0="main",e0=`"${b0}" is a reserved account id; choose a different label.`;function D0(B){let Z=new Uint8Array(B),$=String.fromCharCode(...Z);return btoa($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function B2(){let Z=Array.from(crypto.getRandomValues(new Uint8Array(43))).map((W)=>"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"[W%66]).join(""),$=D0(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(Z)));return{verifier:Z,challenge:$}}function L0(B){if(B.length>16384)return;let Z=B.split(".");if(Z.length!==3)return;let $=Z[1];if(!$||$.length>8192)return;try{return JSON.parse(Buffer.from($,"base64url").toString())}catch{return}}function F0(B){let Z=B.chatgpt_account_id;if(typeof Z==="string"&&Z.length>0)return Z;let $=B["https://api.openai.com/auth"];if($&&typeof $==="object"&&!Array.isArray($)&&typeof $.chatgpt_account_id==="string"&&$.chatgpt_account_id.length>0)return $.chatgpt_account_id;let W=B.organizations;if(Array.isArray(W)){let X=W[0];if(X&&typeof X==="object"&&!Array.isArray(X)&&typeof X.id==="string"&&X.id.length>0)return X.id}return}function s(B){if(B.id_token){let Z=L0(B.id_token),$=Z&&F0(Z);if($)return $}if(B.access_token){let Z=L0(B.access_token);return Z?F0(Z):void 0}return}function Z2(B){return typeof B==="string"&&B.toLowerCase()===b0}function $0(B){if(Z2(B))throw Error(e0);return B}function $2(B,Z,$){let W=new URLSearchParams({response_type:"code",client_id:r,redirect_uri:B,scope:"openid profile email offline_access",code_challenge:Z.challenge,code_challenge_method:"S256",id_token_add_organizations:"true",codex_cli_simplified_flow:"true",state:$,originator:"opencode"});return`${q}/oauth/authorize?${W.toString()}`}async function W2(B,Z,$){let W=await fetch(`${q}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",code:B,redirect_uri:Z,client_id:r,code_verifier:$.verifier}).toString()});if(!W.ok)throw Error(`Token exchange failed: ${W.status}`);return await W.json()}function X2(B){return B.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;")}var z2=`<!doctype html>
2
+ <html>
3
+ <head>
4
+ <title>CortexKit OpenAI Auth - Authorization Successful</title>
5
+ <style>
6
+ body {
7
+ font-family:
8
+ system-ui,
9
+ -apple-system,
10
+ sans-serif;
11
+ display: flex;
12
+ justify-content: center;
13
+ align-items: center;
14
+ height: 100vh;
15
+ margin: 0;
16
+ background: #131010;
17
+ color: #f1ecec;
18
+ }
19
+ .container {
20
+ text-align: center;
21
+ padding: 2rem;
22
+ }
23
+ h1 {
24
+ color: #f1ecec;
25
+ margin-bottom: 1rem;
26
+ }
27
+ p {
28
+ color: #b7b1b1;
29
+ }
30
+ </style>
31
+ </head>
32
+ <body>
33
+ <div class="container">
34
+ <h1>Authorization Successful</h1>
35
+ <p>You can close this window and return to OpenCode.</p>
36
+ </div>
37
+ <script>
38
+ setTimeout(() => window.close(), 2000)
39
+ </script>
40
+ </body>
41
+ </html>`,u=(B)=>`<!doctype html>
42
+ <html>
43
+ <head>
44
+ <title>CortexKit OpenAI Auth - Authorization Failed</title>
45
+ <style>
46
+ body {
47
+ font-family:
48
+ system-ui,
49
+ -apple-system,
50
+ sans-serif;
51
+ display: flex;
52
+ justify-content: center;
53
+ align-items: center;
54
+ height: 100vh;
55
+ margin: 0;
56
+ background: #131010;
57
+ color: #f1ecec;
58
+ }
59
+ .container {
60
+ text-align: center;
61
+ padding: 2rem;
62
+ }
63
+ h1 {
64
+ color: #fc533a;
65
+ margin-bottom: 1rem;
66
+ }
67
+ p {
68
+ color: #b7b1b1;
69
+ }
70
+ .error {
71
+ color: #ff917b;
72
+ font-family: monospace;
73
+ margin-top: 1rem;
74
+ padding: 1rem;
75
+ background: #3c140d;
76
+ border-radius: 0.5rem;
77
+ }
78
+ </style>
79
+ </head>
80
+ <body>
81
+ <div class="container">
82
+ <h1>Authorization Failed</h1>
83
+ <p>An error occurred during authorization.</p>
84
+ <div class="error">${X2(B)}</div>
85
+ </div>
86
+ </body>
87
+ </html>`,k,m,L=new Map;function M(){return L.size}function C(B){if(L.delete(B),M()===0)_()}async function G2(){let B=`http://localhost:${w}/auth/callback`;if(k)return{port:w,redirectUri:B};if(m)return m;m=(async()=>{let Z=o0(($,W)=>{let X=new URL($.url||"/",`http://127.0.0.1:${w}`);if(X.pathname==="/auth/callback"){let z=X.searchParams.get("code"),G=X.searchParams.get("state"),K=X.searchParams.get("error"),Y=X.searchParams.get("error_description");if(K){let j=Y||K;if(G){let Q=L.get(G);if(Q)Q.reject(Error(j)),C(G);else if(M()===0)_()}else if(M()===0)_();W.writeHead(200,{"Content-Type":"text/html"}),W.end(u(j));return}if(!G){if(M()===0)_();W.writeHead(400,{"Content-Type":"text/html"}),W.end(u("Missing state parameter"));return}if(!z){if(M()===0)_();W.writeHead(400,{"Content-Type":"text/html"}),W.end(u("Missing authorization code"));return}let J=L.get(G);if(!J){if(M()===0)_();W.writeHead(400,{"Content-Type":"text/html"}),W.end(u("Unknown state — authorization may have expired"));return}C(G),W2(z,B,J.pkce).then((j)=>J.resolve(j)).catch((j)=>J.reject(j)),W.writeHead(200,{"Content-Type":"text/html"}),W.end(z2);return}if(X.pathname==="/cancel"){let z=X.searchParams.get("state"),G=z?[z]:[...L.keys()];W.writeHead(200),W.end("Login cancelled");for(let K of G){let Y=L.get(K);if(!Y)continue;Y.reject(Error("Login cancelled")),C(K)}if(M()===0)_();return}W.writeHead(404),W.end("Not found")});return await new Promise(($,W)=>{Z.once("error",W),Z.listen(w,"127.0.0.1",()=>{Z.off("error",W),$()})}),k=Z,{port:w,redirectUri:B}})();try{return await m}finally{m=void 0}}function _(){if(k){let B=k;k=void 0,B.close(()=>{}),B.closeIdleConnections?.(),setTimeout(()=>{B.closeAllConnections?.()},25).unref?.()}}function K2(B,Z,$=300000,W){return new Promise((X,z)=>{if(W?.aborted){C(Z),z(Error("Login cancelled"));return}let G=setTimeout(()=>{if(L.get(Z))C(Z),z(Error("OAuth callback timeout — authorization took too long"))},$),K=()=>{if(clearTimeout(G),L.get(Z))C(Z),z(Error("Login cancelled"))};if(W)W.addEventListener("abort",K);L.set(Z,{pkce:B,state:Z,resolve:(Y)=>{if(clearTimeout(G),W)W.removeEventListener("abort",K);X(Y)},reject:(Y)=>{if(clearTimeout(G),W)W.removeEventListener("abort",K);z(Y)}})})}async function Y2(){let B=await fetch(`${q}/api/accounts/deviceauth/usercode`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":O0},body:JSON.stringify({client_id:r})});if(!B.ok)throw Error("Failed to initiate device authorization");let Z=await B.json();return{deviceData:Z,url:`${q}/codex/device`,instructions:`Enter code: ${Z.user_code}`}}async function J2(B,Z){let $=Math.max(parseInt(B.interval,10)||5,1)*1000,W=typeof B.expires_in==="number"?B.expires_in:parseInt(B.expires_in||"",10),X=!Number.isNaN(W)&&W>0?W*1000:900000,z=Date.now();while(!0){if(Z?.aborted)throw Error("Device authorization cancelled");if(Date.now()-z>X)throw Error("Device authorization expired");let G=await fetch(`${q}/api/accounts/deviceauth/token`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":O0},body:JSON.stringify({device_auth_id:B.device_auth_id,user_code:B.user_code})});if(G.ok){let J=await G.json(),j=await fetch(`${q}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",code:J.authorization_code,redirect_uri:`${q}/deviceauth/callback`,client_id:r,code_verifier:J.code_verifier}).toString()});if(!j.ok)throw Error(`Token exchange failed: ${j.status}`);return await j.json()}if(G.status!==403&&G.status!==404)throw Error(`Device authorization failed: ${G.status}`);let K=X-(Date.now()-z);if(K<=0)throw Error("Device authorization expired");let Y=Math.min($+t0,K);try{await a0(Y,void 0,{signal:Z})}catch(J){if(J instanceof Error&&J.name==="AbortError")throw Error("Device authorization cancelled");throw J}}}function y6(B,Z){let $=-1;if(Z.accountId)$=B.findIndex((W)=>W.accountId&&W.accountId===Z.accountId);if($<0)$=B.findIndex((W)=>W.id===Z.id);if($<0&&Z.label&&!Z.accountId)$=B.findIndex((W)=>W.label===Z.label);if($>=0)return B[$]={...B[$],...Z,addedAt:B[$]?.addedAt??Z.addedAt},$;return B.push(Z),B.length-1}async function x6(B={}){let{label:Z,headless:$=!1,signal:W}=B;if($0(Z),$){let{deviceData:J,url:j,instructions:Q}=await Y2(),y=(async()=>{let V=await J2(J,W),F=Date.now(),Q0=s(V);return{id:$0(Z||Q0||crypto.randomUUID()),label:Z||void 0,type:"oauth",access:V.access_token,refresh:V.refresh_token,expires:F+(V.expires_in??3600)*1000,enabled:!0,addedAt:F,lastUsed:F,lastRefreshedAt:F,accountId:Q0}})();return{url:j,instructions:Q,completion:y}}let{redirectUri:X}=await G2(),z=await B2(),G=D0(crypto.getRandomValues(new Uint8Array(32)).buffer),K=$2(X,z,G),Y=(async()=>{try{if(W?.aborted)throw Error("Login cancelled");let J=await K2(z,G,void 0,W),j=Date.now(),Q=s(J);return{id:$0(Z||Q||crypto.randomUUID()),label:Z||void 0,type:"oauth",access:J.access_token,refresh:J.refresh_token,expires:j+(J.expires_in??3600)*1000,enabled:!0,addedAt:j,lastUsed:j,lastRefreshedAt:j,accountId:Q}}finally{C(G)}})();return{url:K,instructions:"Complete authorization in your browser. This window will close automatically.",completion:Y}}function U0(B){if(B instanceof Error)return B.message;if(typeof B==="string")return B;try{return JSON.stringify(B)}catch{return String(B)}}var H2=h("quota"),W0="primary",X0="secondary",Q2="app_EMoamEEZ73f0CkXaXp7hrann",N2="https://auth.openai.com";async function m6(B){let Z=await B.fetchImpl(`${N2}/oauth/token`,{method:"POST",signal:AbortSignal.timeout(15000),headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:B.refreshToken,client_id:Q2}).toString()});if(!Z.ok){let W=Z0(Z.headers.get("retry-after"));throw Object.assign(Error(`Token refresh failed: ${Z.status}`),{status:Z.status,retryAfter:W,isRefreshError:!0})}let $=await Z.json();if(!$||typeof $.access_token!=="string"||!$.access_token||typeof $.refresh_token!=="string"||!$.refresh_token||typeof $.expires_in!=="number")throw Object.assign(Error("Token refresh failed: malformed response"),{status:Z.status,isRefreshError:!0});return{access:$.access_token,refresh:$.refresh_token,expires:B.now()+$.expires_in*1000,expiresIn:$.expires_in}}var P2="https://chatgpt.com/backend-api/wham/usage";async function k6(B){let Z=B.logger??H2,$=B.accountKey??"unknown",W=Date.now();Z.debug("wham usage fetch started",{pid:process.pid,accountId:$});try{let X=await B.fetchImpl(P2,{signal:AbortSignal.timeout(15000),headers:{authorization:`Bearer ${B.accessToken}`,"chatgpt-account-id":B.accountId??"","oai-client-platform":"web","oai-client-version":"0","x-openai-target-path":"/backend-api/wham/usage"}});if(!X.ok){let K=Z0(X.headers.get("retry-after"));throw Object.assign(Error(`wham usage check failed: ${X.status}`),{status:X.status,retryAfter:K})}let{normalizeWham:z}=await import("./quota-normalize-vf2pj6n7.js"),G=z(await X.json());return Z.debug("wham usage fetch succeeded",{pid:process.pid,accountId:$,status:X.status,elapsedMs:Date.now()-W}),G}catch(X){throw Z.warn("wham usage fetch failed",{pid:process.pid,accountId:$,status:typeof X?.status==="number"?X.status:"error",elapsedMs:Date.now()-W,error:U0(X)}),X}}import{createHash as V2}from"node:crypto";var L2=globalThis.setTimeout,F2=5;function v(B){let Z=B?.quota?.checkIntervalMinutes??F2;return Math.max(1,Z)*60000}function O2(B){return B?.quota?.enabled!==!1}function n(B,Z){if(!B?.resetsAt)return!1;let $=Date.parse(B.resetsAt);return Number.isFinite($)&&$<=Z}function g6(B,Z,$,W,X){if(X!==void 0&&Number.isFinite(X)&&X>$)return X;let z=Z===W0?B?.primary:Z===X0?B?.secondary:void 0,G=z?.resetsAt?Date.parse(z.resetsAt):NaN;if(Number.isFinite(G)&&G>$)return G;return $+W}function b2(B){let Z=B?.quota?.minimumRemaining||{};return{primary:Z.primary??Z["5h"]??15,secondary:Z.secondary??Z["1w"]??10}}function M0(B,Z,$){if(!O2(Z))return $+v(Z);let W=b2(Z),X=[];for(let z of["primary","secondary"]){let G=B?.[z];if(!G)continue;if(G.remainingPercent>=W[z])continue;let K=G.resetsAt?Date.parse(G.resetsAt):Number.NaN;if(!Number.isFinite(K)||K<=$)return $+v(Z);X.push(K)}if(!X.length)return $+v(Z);return Math.min(...X)+60000}function D2(B){if(!B?.quota?.mainQuota||!B.quota.mainQuotaCheckedAt)return null;return{quota:B.quota.mainQuota,checkedAt:B.quota.mainQuotaCheckedAt,tokenFingerprint:B.quota.mainQuotaToken}}function U2(B){let Z=B?.quota?.refreshEveryNRequests;return typeof Z==="number"&&Number.isFinite(Z)&&Z>0?Math.floor(Z):0}function P(B){return V2("sha256").update(B).digest("hex").slice(0,16)}class O{main=null;mainTokenFp=null;mainQuotaAccountId=null;fallbacks=new Map;fallbackTokenFps=new Map;inflightMain=null;inflightMainFp=null;inflightFallbacks=new Map;mainLastApiError=void 0;fallbackApiErrors=new Map;fallbackErrorTokenFps=new Map;rateLimitedUntilMap=new Map;apiGate=Promise.resolve();lastApiCallAt=0;storage;fetchImpl;now;fetchQuotaFn;onMainQuotaFetched;onApiError;constructor(B){this.storage=B.storage,this.fetchImpl=B.fetchImpl??fetch,this.now=B.now??Date.now,this.fetchQuotaFn=B.fetchQuotaFn,this.onMainQuotaFetched=B.onMainQuotaFetched,this.onApiError=B.onApiError,this.seedMainFromStorage(B.storage),this.seedMainBackoffFromStorage(B.storage)}getMain(B){if(B&&this.main&&this.mainTokenFp&&this.mainTokenFp!==P(B))this.main=null,this.mainTokenFp=null;return this.main}getFallback(B,Z){let $=this.fallbacks.get(B)??null;if(!Z||!$)return $;if(this.fallbackTokenFps.get(B)!==P(Z))return this.fallbacks.delete(B),this.fallbackTokenFps.delete(B),null;return $}getAllFallbacks(){return this.fallbacks}setMain(B,Z,$,W=!1){if(!W&&!_0(Z.quota))return;if(this.mainTokenFp=P(B),$&&this.mainQuotaAccountId&&this.mainQuotaAccountId!==$)this.clearRateLimited("main");if($)this.mainQuotaAccountId=$;if(this.main=Z,z0(Z.quota))this.clearRateLimited("main")}peekMainForPolicy(B){if(B&&this.mainQuotaAccountId&&this.mainQuotaAccountId!==B)return null;return this.main}peekFallbackForPolicy(B,Z){let $=this.fallbacks.get(B)??null;if(Z&&$?.accountId&&$.accountId!==Z)return null;return $}setFallback(B,Z,$,W=!1,X){if(!W&&!_0(Z.quota))return;let z=this.fallbacks.get(B)?.accountId;if(X&&z&&X!==z)this.clearRateLimited(B);let G=X??z;if(this.fallbacks.set(B,{...Z,accountId:G}),$)this.fallbackTokenFps.set(B,P($));else this.fallbackTokenFps.delete(B);if(z0(Z.quota))this.clearRateLimited(B)}markRateLimited(B,Z){let $=this.rateLimitedUntilMap.get(B);if($!==void 0&&$>Z)return;this.rateLimitedUntilMap.set(B,Z)}isRateLimited(B){let Z=this.rateLimitedUntilMap.get(B);return Z!==void 0&&this.now()<Z}rateLimitedUntil(B){return this.rateLimitedUntilMap.get(B)}clearRateLimited(B){this.rateLimitedUntilMap.delete(B)}async refreshMain(B){let Z=P(B);if(this.mainTokenFp&&this.mainTokenFp!==Z)this.main=null,this.mainTokenFp=null;if(this.inflightMain&&this.inflightMainFp===Z)return this.inflightMain;if(this.isBackedOff()){if(this.main)return this.main.quota;throw Error("Quota API rate-limited — try again later")}return this.inflightMainFp=Z,this.inflightMain=this._fetchMain(B),this.inflightMain}async refreshFallback(B,Z){let $=O.fallbackInflightKey(B,Z),W=this.inflightFallbacks.get($);if(W)return W;if(this.isFallbackBackedOff(B,Z)){let z=this.getFallback(B,Z);if(z)return z.quota;throw Error("Quota API rate-limited — try again later")}let X=this._fetchFallback(B,Z);return this.inflightFallbacks.set($,X),X}async refreshAllFallbacks(B){let Z=this.now();for(let $ of B){if($.enabled===!1)continue;if(!$.access)continue;let W=this.getFallback($.id,$.access);if(W&&Z<W.refreshAfter)continue;try{await this.refreshFallback($.id,$.access)}catch{}}}refreshMainInBackground(B){let Z=P(B);if(this.inflightMain&&this.inflightMainFp===Z)return;if(this.isBackedOff())return;this.refreshMain(B).catch(()=>{})}isMainStale(){if(!this.main)return!0;return this.now()>=this.main.refreshAfter}isFallbackStale(B,Z){let $=this.getFallback(B,Z);if(!$)return!0;return this.now()>=$.refreshAfter}shouldRefreshOnRequestCount(B){let Z=U2(this.storage);if(Z<=0)return!1;return B>0&&B%Z===0}needsRefresh(B){return this.isMainStale()||this.shouldRefreshOnRequestCount(B)}updateStorage(B){this.storage=B,this.seedMainFromStorage(B),this.seedMainBackoffFromStorage(B)}seedMainFromStorage(B,Z){let $=D2(B);if(!$)return;let W=Z?P(Z):null;if(W&&$.tokenFingerprint&&$.tokenFingerprint!==W)return;let X={quota:$.quota,refreshAfter:M0($.quota,B,$.checkedAt),checkedAt:$.checkedAt};if(this.main&&this.main.checkedAt>=X.checkedAt&&(!W||!this.mainTokenFp||this.mainTokenFp===W))return;if(this.main=X,this.mainTokenFp=$.tokenFingerprint??null,B?.mainAccountId){if(this.mainQuotaAccountId&&this.mainQuotaAccountId!==B.mainAccountId)this.clearRateLimited("main");this.mainQuotaAccountId=B.mainAccountId}}seedMainBackoffFromStorage(B){let Z=B?.quota?.mainLastQuotaApiError;this.mainLastApiError=Z&&x(Z,this.now())?Z:void 0}seedFallbacksFromAccounts(B){let Z=v(this.storage);for(let $ of B){if($.enabled===!1)continue;if(!$.quota)continue;let W=Math.max($.quota.primary?.checkedAt??0,$.quota.secondary?.checkedAt??0);if(W<=0)continue;let X=this.getFallback($.id,$.access);if(X&&X.checkedAt>=W)continue;this.setFallback($.id,{quota:$.quota,refreshAfter:W+Z,checkedAt:W},$.access,!1,$.accountId)}}isBackedOff(){return x(this.mainLastApiError,this.now())}isFallbackBackedOff(B,Z){if(Z){if(this.fallbackErrorTokenFps.get(B)!==P(Z))return!1}return x(this.fallbackApiErrors.get(B),this.now())}getLastApiError(){return this.mainLastApiError}static API_CALL_GAP_MS=1000;static fallbackInflightKey(B,Z){return JSON.stringify([B,P(Z)])}static quotaLockName(B){return`opencode-fallback-quota-refresh-${B.replace(/[^a-zA-Z0-9._-]+/g,"-")||"account"}`}_enqueueApiFetch(B){let Z=async()=>{let W=this.now()-this.lastApiCallAt;if(W<O.API_CALL_GAP_MS)await new Promise((X)=>{let z=L2(X,O.API_CALL_GAP_MS-W);if(typeof z==="object"&&"unref"in z)z.unref()});return this.lastApiCallAt=this.now(),B()},$=this.apiGate.then(Z,Z);return this.apiGate=$.catch(()=>{}),$}async _fetchMain(B){let Z=P(B);return this._enqueueApiFetch(async()=>{try{if(this.isBackedOff()){if(this.main)return this.main.quota;throw Error("Quota API rate-limited — try again later")}let $=await T({name:"opencode-main-quota-refresh",ttlMs:30000});if(!$){let W=this.main;if(W&&this.now()<W.refreshAfter)return W.quota;throw Error("Quota refresh is already in progress")}try{let W=this.now(),X=await this._fetchQuota(B),z=this.now();if(this.mainTokenFp=P(B),this.main={quota:X,refreshAfter:M0(X,this.storage,z),checkedAt:z},z0(X))this.clearRateLimited("main");return this.mainLastApiError=void 0,this.onMainQuotaFetched?.(X,z,this.mainTokenFp,W),X}catch(W){throw this._handleMainFetchError(W),W}finally{await $.release()}}finally{if(this.inflightMainFp===Z)this.inflightMain=null,this.inflightMainFp=null}})}async _fetchFallback(B,Z){return this._enqueueApiFetch(async()=>{try{if(this.isFallbackBackedOff(B,Z)){let W=this.getFallback(B,Z);if(W)return W.quota;throw Error("Quota API rate-limited — try again later")}let $=await T({name:O.quotaLockName(B),ttlMs:30000});if(!$){let W=this.getFallback(B,Z);if(W&&this.now()<W.refreshAfter)return W.quota;throw Error("Quota refresh is already in progress")}try{let W=await this._fetchQuota(Z),X=this.now();return this.setFallback(B,{quota:W,refreshAfter:X+v(this.storage),checkedAt:X},Z,!0),this.fallbackApiErrors.delete(B),this.fallbackErrorTokenFps.delete(B),W}finally{await $.release()}}catch($){throw this._handleFallbackFetchError(B,Z,$),$}finally{this.inflightFallbacks.delete(O.fallbackInflightKey(B,Z))}})}async _fetchQuota(B){if(!this.fetchQuotaFn)throw Error("Quota fetch not available — no fetchQuotaFn injected (push-only mode)");return this.fetchQuotaFn({accessToken:B,fetchImpl:this.fetchImpl,now:this.now})}static isAuthError(B){return B?.status===401}_handleMainFetchError(B){if(O.isAuthError(B))return;this.mainLastApiError=I({error:B,now:this.now(),previous:this.mainLastApiError}),this.onApiError?.(this.mainLastApiError)}_handleFallbackFetchError(B,Z,$){if(O.isAuthError($))return;let W=P(Z),X=this.fallbackErrorTokenFps.get(B)===W?this.fallbackApiErrors.get(B):void 0;this.fallbackApiErrors.set(B,I({error:$,now:this.now(),previous:X})),this.fallbackErrorTokenFps.set(B,W)}}function _0(B){return Boolean(B.primary||B.secondary)}function z0(B){let{primary:Z,secondary:$}=B;if(!Z&&!$)return!1;if(Z&&Z.usedPercent>=100)return!1;if($&&$.usedPercent>=100)return!1;return!0}import{createHash as R2,randomUUID as y2}from"node:crypto";import{homedir as x2}from"node:os";import{dirname as T2,join as c}from"node:path";import{setTimeout as f2}from"node:timers/promises";import{randomUUID as M2}from"node:crypto";import{mkdir as _2,rename as q2,rm as C2,writeFile as E2}from"node:fs/promises";import{dirname as S2}from"node:path";async function f(B,Z){await _2(S2(B),{recursive:!0});let $=`${B}.${M2()}.tmp`;await E2($,`${JSON.stringify(Z,null,2)}
88
+ `,{encoding:"utf8",mode:384});try{await q2($,B)}catch(W){throw await C2($,{force:!0}).catch(()=>{}),W}}import{readFile as r2}from"node:fs/promises";var E=h("refresh"),q0=h("accounts"),A2=1e4,I2=15000,G0=50,T0="openai-auth.json",w2="openai-auth-state.json";function m2(){if(process.env.OPENCODE_CONFIG_DIR?.trim())return process.env.OPENCODE_CONFIG_DIR.trim();return c(process.env.XDG_CONFIG_HOME||c(x2(),".config"),"opencode")}function A(){return process.env.OPENCODE_OPENAI_AUTH_FILE?.trim()||c(m2(),T0)}function t(B=A()){let Z=process.env.OPENCODE_OPENAI_AUTH_STATE_FILE?.trim();if(Z)return Z;return k2(B)}function k2(B){return B.endsWith(T0)?c(T2(B),w2):`${B}.state.json`}function b(B){return B.type==="oauth"}function h2(B){let Z=B?.trim();if(!Z)return!1;try{let $=new URL(Z);return($.protocol==="http:"||$.protocol==="https:")&&!$.username&&!$.password}catch{return!1}}function GB(B){return B.costZeroing?.enabled!==!1}class o extends Error{code="ACCOUNT_REMOVED_DURING_REFRESH";constructor(B){super(`Fallback account ${B} was removed before refresh`);this.name="AccountRemovedDuringRefreshError"}}var v2=[401,403,429],C0={primary:0,secondary:0},p2=!1,Y0={primary:5,secondary:10};function H(B){return B!=null&&typeof B==="object"&&!Array.isArray(B)}var l2=new Set(["__proto__","constructor","prototype"]);function d2(B){return B.length>0&&!l2.has(B)}function g2(B){return B instanceof o||H(B)&&B.name==="AccountRemovedDuringRefreshError"&&B.code==="ACCOUNT_REMOVED_DURING_REFRESH"}function E0(B){return{id:typeof B.id==="string"&&B.id.trim()?B.id.trim():y2(),label:typeof B.label==="string"?B.label:void 0,enabled:typeof B.enabled==="boolean"?B.enabled:void 0,addedAt:typeof B.addedAt==="number"?B.addedAt:void 0,lastUsed:typeof B.lastUsed==="number"?B.lastUsed:void 0,accountId:typeof B.accountId==="string"?B.accountId:void 0}}function S0(B){if(!H(B))return;if(typeof B.message!=="string")return;let Z=Number(B.checkedAt);if(!Number.isFinite(Z))return;let $=Number(B.nextRetryAt),W=Number(B.retryCount);return{message:B.message,checkedAt:Z,nextRetryAt:Number.isFinite($)?$:void 0,retryCount:Number.isFinite(W)?W:void 0,tokenHash:typeof B.tokenHash==="string"?B.tokenHash:void 0}}function i2(B){if(!H(B))return;let Z={};for(let $ of["primary","secondary"]){let W=B[$];if(!H(W))continue;let X=Number(W.usedPercent),z=Number(W.remainingPercent),G=Number(W.checkedAt);if(!Number.isFinite(X)||!Number.isFinite(z)||!Number.isFinite(G))continue;let K=typeof W.windowMinutes==="number"?W.windowMinutes:Number.NaN;Z[$]={usedPercent:X,remainingPercent:z,checkedAt:G,resetsAt:typeof W.resetsAt==="string"?W.resetsAt:void 0,...Number.isFinite(K)&&K>0?{windowMinutes:K}:{}}}for(let $ of["resetCreditsAvailable","resetCreditsApplicable"]){let W=typeof B[$]==="number"?B[$]:Number.NaN;if(Number.isFinite(W)&&W>=0)Z[$]=W}return Object.keys(Z).length?Z:void 0}function u2(B){if(!H(B))return null;if(B.type==="api"){let Z=typeof B.baseURL==="string"?B.baseURL.trim():"",$=typeof B.apiKey==="string"?B.apiKey.trim():"";if(!h2(Z))return null;let W=B.authHeader==="x-api-key"?"x-api-key":"authorization-bearer";return{...E0(B),type:"api",apiKey:$||void 0,baseURL:Z,authHeader:W}}if(B.type!=="oauth")return null;if(typeof B.refresh!=="string"||!B.refresh.trim())return null;return{...E0(B),type:"oauth",access:typeof B.access==="string"?B.access:void 0,refresh:B.refresh,expires:typeof B.expires==="number"?B.expires:void 0,lastRefreshedAt:typeof B.lastRefreshedAt==="number"?B.lastRefreshedAt:void 0,lastRefreshError:S0(B.lastRefreshError),lastQuotaRefreshError:S0(B.lastQuotaRefreshError),quota:i2(B.quota)}}function s2(B){if(!H(B))return;let Z=Object.create(null);for(let[$,W]of Object.entries(B)){if(!d2($)||!H(W))continue;let X={};if(H(W.inFlight))X.inFlight={...W.inFlight};if(H(W.lastOutcome)&&typeof W.lastOutcome.code==="string"&&W.lastOutcome.code.length>0&&typeof W.lastOutcome.at==="number"&&Number.isFinite(W.lastOutcome.at))X.lastOutcome={code:W.lastOutcome.code,at:W.lastOutcome.at,...H(W.lastOutcome.previousOutcome)&&typeof W.lastOutcome.previousOutcome.code==="string"&&W.lastOutcome.previousOutcome.code.length>0&&typeof W.lastOutcome.previousOutcome.at==="number"&&Number.isFinite(W.lastOutcome.previousOutcome.at)?{previousOutcome:{code:W.lastOutcome.previousOutcome.code,at:W.lastOutcome.previousOutcome.at}}:{}};if(typeof W.cooldownUntil==="number"&&Number.isFinite(W.cooldownUntil))X.cooldownUntil=W.cooldownUntil;if(Object.keys(X).length>0)Z[$]=X}return Object.keys(Z).length>0?Z:void 0}function f0(B){if(!H(B)||!Array.isArray(B.accounts))return null;return{version:1,main:{type:"opencode",provider:"openai"},routing:H(B.routing)?B.routing:void 0,fallbackOn:Array.isArray(B.fallbackOn)?B.fallbackOn.filter((Z)=>Number.isInteger(Z)):void 0,refresh:H(B.refresh)?B.refresh:void 0,quota:H(B.quota)?B.quota:void 0,reset:s2(B.reset),dump:H(B.dump)?B.dump:void 0,costZeroing:H(B.costZeroing)?B.costZeroing:void 0,killswitch:H(B.killswitch)?B.killswitch:void 0,logging:H(B.logging)?B.logging:void 0,cachekeep:H(B.cachekeep)?B.cachekeep:void 0,mainAccountId:typeof B.mainAccountId==="string"?B.mainAccountId:void 0,accounts:B.accounts.map(u2).filter((Z)=>Z!=null)}}async function R(B){try{return{exists:!0,value:JSON.parse(await r2(B,"utf8"))}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,value:null};throw Z}}function D(B){return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0))}async function n2(B){let Z;try{Z=(await R(B)).value}catch{return null}if(!H(Z)||!Array.isArray(Z.accounts))return null;let $=new Set;for(let W of Z.accounts)if(H(W)&&typeof W.id==="string")$.add(W.id);return $}function A0(B,Z){if(!H(B))return B;let $=H(Z)?Z:{},W=H($.main)?$.main:void 0,X=H($.accounts)?$.accounts:{},z=H(B.quota)?B.quota:{},G=H(B.refresh)?B.refresh:{},K=W??z,Y=W??G,j=Array.isArray(B.accounts)?B.accounts.map((Q)=>{if(!H(Q))return Q;let y=typeof Q.id==="string"&&H(X[Q.id])?X[Q.id]:{};return{...Q,...y}}):void 0;return I0({...B,refresh:D({...G,mainLastRefreshError:Y.lastRefreshError,mainRefreshLeaseId:Y.refreshLeaseId,mainRefreshLeaseUntil:Y.refreshLeaseUntil,mainRefreshLeaseTokenHash:Y.refreshLeaseTokenHash}),quota:D({...z,mainQuota:K.quota,mainQuotaCheckedAt:K.quotaCheckedAt,mainQuotaToken:K.quotaToken,mainLastQuotaApiError:K.lastQuotaApiError}),accounts:j})}async function c2(B=A()){let Z=await R(B);if(!Z.exists)return null;let $=await R(t(B));return f0(A0(Z.value,$.value))}function I0(B){return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0))}function o2(B){return D({id:B.id,label:B.label,type:B.type,enabled:B.enabled,addedAt:B.addedAt,accountId:B.accountId,baseURL:B.type==="api"?B.baseURL:void 0,authHeader:B.type==="api"?B.authHeader:void 0})}function w0(B){if(B.type==="api")return D({apiKey:B.apiKey,lastUsed:B.lastUsed});return D({access:B.access,refresh:B.refresh,expires:B.expires,lastUsed:B.lastUsed,lastRefreshedAt:B.lastRefreshedAt,lastRefreshError:B.lastRefreshError,lastQuotaRefreshError:B.lastQuotaRefreshError,quota:B.quota})}function a(B){return Math.max(B?.primary?.checkedAt??0,B?.secondary?.checkedAt??0)}function p(B,Z,$){if($ in Z)B[$]=Z[$];else delete B[$]}function a2(B,Z){return B.access===Z.access&&B.refresh===Z.refresh&&B.expires===Z.expires&&B.lastRefreshedAt===Z.lastRefreshedAt}function t2(B,Z){if(!a2(B,Z))return Z;if(!("lastRefreshError"in Z))return B;if(!("lastRefreshError"in B))return Z;return(Z.lastRefreshError?.checkedAt??0)>(B.lastRefreshError?.checkedAt??0)?Z:B}function e2(B,Z,$){let W=Z.lastRefreshedAt??0,X=$.lastRefreshedAt??0,z=Z.expires??0,G=$.expires??0,K=X>W?$:W>X?Z:G>z?$:z>G?Z:t2(Z,$);p(B,K,"access"),p(B,K,"refresh"),p(B,K,"expires"),p(B,K,"lastRefreshedAt"),p(B,K,"lastRefreshError")}function B6(B,Z){if(!H(B))return Z;let $=B,W=a($.quota),X=a(Z.quota),z=W>X,G=z?{...$,...Z,quota:$.quota,lastQuotaRefreshError:$.lastQuotaRefreshError}:{...$,...Z};if(!z&&!("lastQuotaRefreshError"in Z))delete G.lastQuotaRefreshError;if(!("lastRefreshError"in Z))delete G.lastRefreshError;if(typeof $.lastUsed==="number"&&(typeof Z.lastUsed!=="number"||$.lastUsed>Z.lastUsed))G.lastUsed=$.lastUsed;return e2(G,$,Z),G}function m0(B){let Z=B.refresh?D({enabled:B.refresh.enabled,intervalMinutes:B.refresh.intervalMinutes,refreshBeforeExpiryMinutes:B.refresh.refreshBeforeExpiryMinutes}):void 0,$=B.quota?D({enabled:B.quota.enabled,checkIntervalMinutes:B.quota.checkIntervalMinutes,refreshEveryNRequests:B.quota.refreshEveryNRequests,minimumRemaining:B.quota.minimumRemaining,failClosedOnUnknownQuota:B.quota.failClosedOnUnknownQuota,showToasts:B.quota.showToasts}):void 0;return I0({version:1,main:B.main,routing:B.routing,fallbackOn:B.fallbackOn,refresh:Z,quota:$,reset:B.reset,dump:B.dump,costZeroing:B.costZeroing,killswitch:B.killswitch,logging:B.logging,cachekeep:B.cachekeep,mainAccountId:B.mainAccountId,accounts:B.accounts.map(o2)})}async function d(B){let Z=Date.now(),$=Z+I2,W=0;while(Date.now()<=$){W++;let G=await T({name:"save",ttlMs:A2,path:B});if(G)return G;let K=$-Date.now();if(K<=0)break;await f2(Math.min(G0+l0(G0),K))}let X=Date.now()-Z,z=Math.round(X/Math.max(1,W));throw Error(`Timed out after ${X}ms waiting for the account store lock on ${B} (${W} attempts, ~${z}ms apart; retry interval is ${G0}ms). A gap near the retry interval means lock contention; a much larger one means this process's event loop was saturated and the wait expired without getting scheduled.`)}function k0(B){let Z=Object.fromEntries(B.accounts.map(($)=>[$.id,w0($)]));return{version:1,main:D({quota:B.quota?.mainQuota,quotaCheckedAt:B.quota?.mainQuotaCheckedAt,quotaToken:B.quota?.mainQuotaToken,lastQuotaApiError:B.quota?.mainLastQuotaApiError,lastRefreshError:B.refresh?.mainLastRefreshError,refreshLeaseId:B.refresh?.mainRefreshLeaseId,refreshLeaseUntil:B.refresh?.mainRefreshLeaseUntil,refreshLeaseTokenHash:B.refresh?.mainRefreshLeaseTokenHash}),accounts:Z}}async function YB(B,Z=A()){let $=t(Z),W=await d(Z);try{let X=await d($);try{let z=await R(Z),G=await R($),K=(z.exists?f0(A0(z.value,G.value)):null)??Z6(),Y=B(K)??K,j={...H(z.value)?z.value:{},...m0(Y)};return await f(Z,j),await f($,k0(Y)),Y}finally{await X.release()}}finally{await W.release()}}function Z6(){return{version:1,main:{type:"opencode",provider:"openai"},accounts:[]}}function $6(B,Z){B.main=B.main??{};let $=typeof B.main.quotaCheckedAt==="number"?B.main.quotaCheckedAt:a(B.main.quota),W=typeof Z.quota?.mainQuotaCheckedAt==="number"?Z.quota.mainQuotaCheckedAt:a(Z.quota?.mainQuota);if($>W)return;B.main.quota=Z.quota?.mainQuota,B.main.quotaCheckedAt=Z.quota?.mainQuotaCheckedAt,B.main.quotaToken=Z.quota?.mainQuotaToken,B.main.lastQuotaApiError=Z.quota?.mainLastQuotaApiError}function W6(B,Z){B.main=B.main??{},B.main.lastRefreshError=Z.refresh?.mainLastRefreshError,B.main.refreshLeaseId=Z.refresh?.mainRefreshLeaseId,B.main.refreshLeaseUntil=Z.refresh?.mainRefreshLeaseUntil,B.main.refreshLeaseTokenHash=Z.refresh?.mainRefreshLeaseTokenHash}function J0(B){if(Array.isArray(B))return B.map(J0);if(!H(B))return B;return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0).map(([Z,$])=>[Z,J0($)]))}async function X6(B,Z=A(),$={mainQuota:!0,mainRefresh:!0,accounts:!0}){let W=t(Z),X=await d(W);try{let z=(await R(W)).value,G=H(z)?{...z,version:1}:{version:1};if($.mainQuota)$6(G,B);if($.mainRefresh)W6(G,B);if($.accounts){let K=$.accounts===!0?null:new Set($.accounts),Y=await n2(Z);G.accounts={...H(G.accounts)?G.accounts:{}};for(let J of B.accounts){if(K&&!K.has(J.id))continue;if(Y&&!Y.has(J.id))continue;G.accounts[J.id]=B6(G.accounts[J.id],w0(J))}if(K){for(let J of K)if(!B.accounts.some((j)=>j.id===J))delete G.accounts[J]}if(Y){for(let J of Object.keys(G.accounts))if(!Y.has(J))delete G.accounts[J]}}await f(W,J0(G))}finally{await X.release()}}function z6(B){return B?.fallbackOn?.length?B.fallbackOn:v2}function JB(B,Z){return z6(Z).includes(B)}function G6(B){let Z=B?.quota?.minimumRemaining||{};return{primary:Z.primary??Z["5h"]??C0.primary,secondary:Z.secondary??Z["1w"]??C0.secondary}}function j0(B){return B?.quota?.enabled!==!1}function g(B){return B?.quota?.failClosedOnUnknownQuota??p2}function h0(B,Z,$=Date.now()){if(!j0(Z))return!0;if(!B)return!g(Z);let W=G6(Z),X=g(Z);for(let z of["primary","secondary"]){let G=B[z];if(!G)continue;if(n(G,$)){if(X)return!1;continue}if(G.remainingPercent<W[z])return!1}return!0}function v0(B){return B?.killswitch?.enabled===!0}function R0(B){return{primary:B?.primary??B?.["5h"]??Y0.primary,secondary:B?.secondary??B?.["1w"]??Y0.secondary}}function p0(B,Z){if(!B?.killswitch)return Y0;if(Z&&B.killswitch.accounts?.[Z])return R0(B.killswitch.accounts[Z]);return R0(B.killswitch.main)}function jB(B,Z,$,W=Date.now()){if(!v0(Z))return!0;if(!B)return!g(Z);let X=p0(Z,$),z=g(Z);for(let G of["primary","secondary"]){let K=B[G];if(!K)continue;if(n(K,W)){if(z)return!1;continue}if(K.remainingPercent<X[G])return!1}return!0}function HB(B,Z,$,W){if(!v0(W))return 300;let X=[],z=[{accountId:void 0,quota:B},...Z];for(let{accountId:K,quota:Y}of z){if(!Y)continue;let J=p0(W,K),j=[],Q=!1;for(let y of["primary","secondary"]){let V=Y[y];if(!V||n(V,$))continue;if(V.remainingPercent>=J[y])continue;let F=V.resetsAt?Date.parse(V.resetsAt):NaN;if(!Number.isFinite(F)||F<=$){Q=!0;break}j.push(F)}if(Q||j.length===0)continue;X.push(Math.max(...j))}if(X.length===0)return 300;let G=Math.min(...X);return Math.max(1,Math.ceil((G-$)/1000))}function K6(B){return typeof B.version==="number"&&Array.isArray(B.accounts)}async function QB(B,Z=A()){let $=t(Z),W=await d(Z);try{let X=await d($);try{let z=await R(Z);if(z.exists&&H(z.value)){if(K6(z.value))return}if(!B)return;let G={version:1,main:{type:"opencode",provider:"openai"},accounts:[]};if(B.access){let J=s({id_token:"",access_token:B.access,refresh_token:B.refresh});if(J)G.mainAccountId=J}let Y={...z.exists&&H(z.value)?z.value:{},...m0(G)};await f(Z,Y),await f($,k0(G))}finally{await X.release()}}finally{await W.release()}}function Y6(B){return B?.refresh?.enabled!==!1}function J6(B){return(B?.refresh?.refreshBeforeExpiryMinutes??240)*60000}function l0(B){return Math.floor(Math.random()*(B+1))}function S(B,Z,$){return!B.access||!B.expires||B.expires-$<=J6(Z)}function j6(B,Z){return Boolean(B.access&&typeof B.expires==="number"&&B.expires>Z)}function H6(B,Z){return Boolean(B.mainAccountId&&Z.accountId&&Z.accountId===B.mainAccountId)}function N(B,Z){let $=B.accounts.findIndex((W)=>W.id===Z.id);if($!==-1)B.accounts[$]=Z}function l(B){return B instanceof Error?B.message:String(B)}function H0(B,Z,$){B.lastRefreshError=P0({error:Z,now:$,refreshToken:B.refresh,previous:B.lastRefreshError})}function K0(B,Z,$){if(B.lastQuotaRefreshError=I({error:Z,now:$,previous:B.lastQuotaRefreshError}),Z?.isRefreshError===!0)H0(B,Z,$)}function Q6(B){return`fallback-oauth-refresh-${R2("sha256").update(B).digest("base64url").slice(0,16)}`}function y0(B,Z){if(!B)return!1;if(!B.resetsAt)return!0;let $=Date.parse(B.resetsAt);return Number.isFinite($)?$>Z:!0}function N6(B,Z){if(!B)return!1;return y0(B.primary,Z)||y0(B.secondary,Z)}function P6(B,Z,$){if(!B)return!1;let W=Z?.quota?.checkIntervalMinutes??5,X=Math.max(1,W)*60000,z=Math.max(B.primary?.checkedAt??0,B.secondary?.checkedAt??0);return $-z<X}function x0(B,Z,$){return!P6(B.quota,Z,$)}function V6(B,Z,$,W){return B0($)&&h0(B.quota,Z,W)&&N6(B.quota,W)}function L6(B){let Z=B?.quota?.checkIntervalMinutes??5;return Math.max(1,Z)*60000}var F6=60000,O6=60000,b6=600000,D6=1e4,U6=100;var NB=globalThis.setTimeout.bind(globalThis),PB=globalThis.clearTimeout.bind(globalThis);class M6{now;fetchImpl;configPath;refreshPromises=new Map;refreshTimer=null;quotaTimer=null;quotaManager;onFallbackStorageChanged;options;constructor(B={}){this.options=B,this.now=B.now??Date.now,this.fetchImpl=B.fetchImpl??fetch,this.configPath=B.configPath??A(),this.quotaManager=B.quotaManager??null,this.onFallbackStorageChanged=B.onFallbackStorageChanged}seedFallbackQuota(B,Z){if(!this.quotaManager)return;if(!B.quota)return;let $=Math.max(B.quota.primary?.checkedAt??0,B.quota.secondary?.checkedAt??0);if($<=0)return;let W=this.quotaManager.getFallback(B.id,B.access);if(W&&W.checkedAt>=$)return;this.quotaManager.setFallback(B.id,{quota:B.quota,refreshAfter:$+L6(Z),checkedAt:$},B.access,!1,B.accountId)}async load(){return c2(this.configPath)}async save(B,Z){await X6(B,this.configPath,{accounts:Z??!0})}startBackgroundRefresh(){let B=async()=>{if(await this.refreshDueAccounts(),this.options.fetchQuotaFn)await this.refreshQuotaForDueAccounts()};if(B().catch(()=>{}),!this.refreshTimer){if(this.refreshTimer=setInterval(()=>{B().catch(()=>{})},F6+l0(O6)),"unref"in this.refreshTimer)this.refreshTimer.unref()}}stopBackgroundRefresh(){if(this.refreshTimer)clearInterval(this.refreshTimer);if(this.quotaTimer)clearInterval(this.quotaTimer);this.refreshTimer=null,this.quotaTimer=null}async getUsableFallbackAccounts(B){let Z=B!==void 0?B:await this.load();if(!Z)return[];let $=[],W=!1;for(let X of Z.accounts){if(X.enabled===!1||!b(X))continue;if(H6(Z,X))continue;let z=!1,G=X;try{if(S(G,Z,this.now())){let K=G.lastRefreshError;if(K&&U(K,G.refresh,this.now()))throw z=!0,Error(i(K,this.now()));try{G=await this.refreshAccount(G,Z),W=!0}catch(Y){if(g2(Y))continue;z=!0;let J=Z.accounts.find((j)=>j.id===X.id&&b(j));if(J&&!U(J.lastRefreshError,J.refresh,this.now()))H0(J,Y,this.now()),N(Z,J),W=!0;throw Y}}if(this.seedFallbackQuota(G,Z),this.accountPassesQuotaPolicy(this.quotaPolicyAccount(G),Z))$.push(G)}catch(K){let Y=j6(G,this.now());if(z){if(!Y)continue}else if(!Y)continue;if(V6(G,Z,K,this.now()))E.debug("fallback quota using cached quota after refresh error",{pid:process.pid,accountId:G.id,error:l(K)}),$.push(G);else if(!g(Z))$.push(G)}}if(W)try{await this.save(Z)}catch(X){q0.warn("fallback selection bookkeeping not persisted",{pid:process.pid,error:l(X)})}return $}async markUsed(B){try{let Z=await this.load();if(!Z)return;let $=Z.accounts.find((W)=>W.id===B.id);if(!$)return;$.lastUsed=this.now(),await this.save(Z,[$.id])}catch(Z){q0.warn("lastUsed stamp not persisted",{pid:process.pid,accountId:B.id,error:l(Z)})}}accountPassesQuotaPolicy(B,Z){return h0(B.quota,Z,this.now())}quotaPolicyAccount(B){if(!this.quotaManager)return B;let Z=this.quotaManager.getFallback(B.id,B.access)?.quota;return Z?{...B,quota:Z}:B}async refreshDueAccounts(){let B=await this.load();if(!B||!Y6(B))return;let Z=!1;for(let $ of B.accounts){if($.enabled===!1||!b($))continue;if(!S($,B,this.now()))continue;if(U($.lastRefreshError,$.refresh,this.now()))continue;try{E.debug("fallback oauth background due",{pid:process.pid,accountId:$.id,expiresInMs:$.expires?$.expires-this.now():void 0}),await this.refreshAccount($,B),Z=!0}catch(W){E.warn("fallback oauth background failed",{pid:process.pid,accountId:$.id,error:l(W)}),H0($,W,this.now()),N(B,$),Z=!0}}if(Z)await this.save(B)}async refreshQuotaForDueAccounts(){let B=await this.load();if(!B||!j0(B))return;if(!this.options.fetchQuotaFn)return;let Z=!1;for(let $ of B.accounts){if($.enabled===!1||!b($))continue;let W=$;try{if(S(W,B,this.now())){if(U(W.lastRefreshError,W.refresh,this.now()))continue;W=await this.refreshAccount(W,B),Z=!0}if(x(W.lastQuotaRefreshError,this.now()))continue;if(this.seedFallbackQuota(W,B),!(this.quotaManager?this.quotaManager.isFallbackStale(W.id,W.access):x0(W,B,this.now())))continue;await this.refreshAccountQuota(W,B),Z=!0}catch(X){K0($,X,this.now()),N(B,$),Z=!0}}if(Z)await this.save(B),this.onFallbackStorageChanged?.()}async refreshQuotaForAllAccounts(B={}){let Z=await this.load(),$=[];if(!Z||!j0(Z))return{storage:Z,errors:$};if(!this.options.fetchQuotaFn)return{storage:Z,errors:$};let W=B.force??!1,X=!1;for(let z of Z.accounts){if(z.enabled===!1||!b(z))continue;let G=z;try{if(S(G,Z,this.now())){let K=G.lastRefreshError;if(K&&U(K,G.refresh,this.now()))throw Error(i(K,this.now()));G=await this.refreshAccount(G,Z),X=!0}if(!W&&!x0(G,Z,this.now())){if(G.lastQuotaRefreshError)G.lastQuotaRefreshError=void 0,N(Z,G),X=!0;continue}await this.refreshAccountQuota(G,Z),X=!0}catch(K){K0(z,K,this.now()),N(Z,z),X=!0,$.push({accountId:z.id,message:l(K)})}}if(X)await this.save(Z);return{storage:Z,errors:$}}async refreshAccount(B,Z,$={}){let W=this.refreshPromises.get(B.id);if(W){let G=await W;return N(Z,G),G}let X=this.refreshAccountNow(B,Z,$).finally(()=>{this.refreshPromises.delete(B.id)});this.refreshPromises.set(B.id,X);let z=await X;return N(Z,z),z}async waitForConcurrentFallbackRefresh(B,Z,$,W){let X=Date.now()+D6;while(Date.now()<X){await new Promise((J)=>setTimeout(J,U6));let z=await this.load(),G=z?.accounts.find((J)=>J.id===B.id&&b(J));if(!G)continue;if((G.access!==$.access||G.refresh!==$.refresh||(G.expires??0)>($.expires??0)+60000)&&(W.force||!S(G,z,this.now())))return N(Z,G),E.debug("fallback oauth joined concurrent refresh",{pid:process.pid,accountId:G.id,expiresInMs:G.expires?G.expires-this.now():void 0}),G;let Y=G.lastRefreshError;if(Y&&U(Y,G.refresh,this.now()))throw N(Z,G),Error(i(Y,this.now()))}return null}async refreshAccountNow(B,Z,$){let W=await this.load(),X=W?.accounts.find((K)=>K.id===B.id&&b(K));if(X&&!$.force&&!S(X,W,this.now()))return N(Z,X),X;let z=X??B,G=await T({name:Q6(z.id),ttlMs:b6,path:this.configPath,now:this.now,renew:!0});if(!G){E.debug("fallback oauth refresh skipped file lock",{pid:process.pid,accountId:z.id});let K=await this.waitForConcurrentFallbackRefresh(B,Z,z,$);if(K)return K;throw Error("Fallback OAuth refresh is already in progress")}try{if(W=await this.load(),X=W?.accounts.find((j)=>j.id===B.id&&b(j)),X&&!$.force&&!S(X,W,this.now()))return N(Z,X),X;if(!X)throw new o(B.id);z=X;let K=this.options.refreshFn??(async()=>{throw Error("No refreshFn injected into FallbackAccountManager")});E.debug("fallback oauth refresh request start",{pid:process.pid,accountId:z.id,force:$.force===!0,expiresInMs:z.expires?z.expires-this.now():void 0});let Y=await K({refreshToken:z.refresh,fetchImpl:this.fetchImpl,now:this.now});if(z.access=Y.access,z.refresh=Y.refresh,z.expires=Y.expires,z.lastRefreshedAt=Y.expires-Y.expiresIn*1000,z.lastRefreshError=void 0,N(Z,z),await this.save(Z),!(await this.load())?.accounts.some((j)=>j.id===B.id))throw new o(B.id);return E.debug("fallback oauth refresh succeeded",{pid:process.pid,accountId:z.id,expiresInMs:z.expires?z.expires-this.now():void 0}),z}finally{await G.release()}}async refreshAccountQuota(B,Z){let $=B;if(!$.access)throw Error(`Fallback account ${B.id} has no access token`);if(!this.options.fetchQuotaFn)throw Error("No fetchQuotaFn injected — wham/usage supplement is disabled");let W=this.options.fetchQuotaFn??(async()=>{throw Error("No fetchQuotaFn injected — wham/usage supplement is disabled")}),X=(z)=>this.quotaManager?this.quotaManager.refreshFallback($.id,z):W({accessToken:z,fetchImpl:this.fetchImpl,now:this.now});try{if(!$.access)throw Error(`Fallback account ${B.id} has no access token`);let z=await X($.access);$.quota=z,$.lastQuotaRefreshError=void 0,N(Z,$),await this.save(Z)}catch(z){throw K0(B,z,this.now()),N(Z,B),z}}}
89
+ export{N0 as h,P0 as i,U as j,i as k,O0 as l,D0 as m,B2 as n,L0 as o,F0 as p,s as q,$0 as r,$2 as s,C as t,G2 as u,K2 as v,Y2 as w,J2 as x,y6 as y,x6 as z,U0 as A,m6 as B,k6 as C,g6 as D,O as E,A as F,b as G,GB as H,Y0 as I,d2 as J,c2 as K,YB as L,JB as M,v0 as N,p0 as O,jB as P,HB as Q,QB as R,M6 as S};
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{d as x1,e as FY,f as XW}from"./index-87145jkw.js";import{A as $1,B as R1,C as Q1,D as lW,E as dW,G as u0,H as iW,I as F1,J as y0,K as q0,L as J0,M as jY,N as DY,O as XX,P as PY,Q as nW,R as oW,S as rW,h as SW,i as kW,j as bW,k as xW,l as vW,m as hW,n as gW,o as l1,p as d1,q as V8,s as yW,t as fW,u as mW,v as cW,w as uW,x as pW,y as fX,z as mX}from"./index-cxze8h26.js";import{$ as D1,U as f8,X as MY,Y as sW,da as aW,ea as tW,fa as eW,ka as Y5,la as N8,ma as X5,na as J5,oa as Q5,pa as $5}from"./index-meg0ng0z.js";import{ua as bY}from"./index-n00ybbbq.js";import{va as AJ,wa as TJ}from"./index-e08r33g5.js";import{Aa as L0,ya as kY,za as $J}from"./index-hxpv25e8.js";import{Da as G5}from"./index-dz9a4xwy.js";import{Ga as X9}from"./index-s2vhsb2v.js";import{mkdirSync as RB,readFileSync as CB,renameSync as _B,statSync as IB,writeFileSync as SB}from"node:fs";import e9 from"node:os";import{join as kB}from"node:path";import{readFileSync as O5}from"node:fs";import{homedir as q5,tmpdir as F5}from"node:os";import{join as RY}from"node:path";var j5="https://chatgpt.com/backend-api/codex/responses",D5="openai-auth.json",o0={noWebSearch:"CORTEXKIT_OPENAI_AUTH_NO_WEB_SEARCH",webSockets:"CORTEXKIT_OPENAI_AUTH_WEBSOCKETS",rawWebSocket:"CORTEXKIT_OPENAI_AUTH_RAW_WS",responsesLite:"CORTEXKIT_OPENAI_AUTH_RESPONSES_LITE",dump:"CORTEXKIT_OPENAI_AUTH_DUMP",dumpDir:"OPENCODE_OPENAI_AUTH_DUMP_DIR",codexApiEndpoint:"CORTEXKIT_OPENAI_AUTH_CODEX_ENDPOINT",configFile:"OPENCODE_OPENAI_AUTH_FILE",stateFile:"OPENCODE_OPENAI_AUTH_STATE_FILE",configDir:"OPENCODE_CONFIG_DIR"};function CY(){let Y=process.env[o0.configDir]?.trim();if(Y)return Y;return RY(process.env.XDG_CONFIG_HOME||RY(q5(),".config"),"opencode")}function $0(){return process.env[o0.configFile]?.trim()||RY(CY(),D5)}function P5(){try{let Y=JSON.parse(O5($0(),"utf8"));return Y!=null&&typeof Y==="object"&&!Array.isArray(Y)?Y:{}}catch{return{}}}function MX(Y){let X=process.env[Y];if(X===void 0)return;let J=X.trim().toLowerCase();if(J==="1"||J==="true"||J==="yes"||J==="on")return!0;if(J===""||J==="0"||J==="false"||J==="no"||J==="off")return!1;return}function TY(Y,X,J){let Q=MX(Y);if(Q!==void 0)return Q;if(typeof X==="boolean")return X;return J}function M5(){let Y=P5(),X=MX(o0.noWebSearch),J=X!==void 0?!X:typeof Y.webSearch==="boolean"?Y.webSearch:!0,Q;if(Y.dump!==void 0&&Y.dump!==null){if(typeof Y.dump==="object")Q=Y.dump.enabled;else if(typeof Y.dump==="boolean")Q=Y.dump}return{webSearch:J,webSockets:TY(o0.webSockets,Y.webSockets,!1),rawWebSocket:TY(o0.rawWebSocket,Y.rawWebSocket,!1),responsesLite:TY(o0.responsesLite,Y.responsesLite,!1),dump:TY(o0.dump,Q,!1),dumpDir:process.env[o0.dumpDir]?.trim()||(typeof Y.dumpDir==="string"&&Y.dumpDir.trim()?Y.dumpDir.trim():RY(F5(),"opencode-openai-auth-dumps")),codexApiEndpoint:process.env[o0.codexApiEndpoint]?.trim()||(typeof Y.codexApiEndpoint==="string"&&Y.codexApiEndpoint.trim()?Y.codexApiEndpoint.trim():j5)}}var q8;function M0(){if(!q8)q8=M5();return q8}var F8="/backend-api/wham/rate-limit-reset-credits",w5=`https://chatgpt.com${F8}`,RX=`${F8}/consume`,E5=`https://chatgpt.com${RX}`,A5=300000,T5=60000,R5=15000,C5=60000;class _0 extends Error{kind;cooldownUntil;constructor(Y,X,J){super(X);this.name="ResetRedemptionError",this.kind=Y,this.cooldownUntil=J}}class q1 extends Error{kind;status;constructor(Y,X,J){super(X);this.name="ResetCreditError",this.kind=Y,this.status=J}}function CX(Y,X,J){return{authorization:`Bearer ${Y}`,...J?{"chatgpt-account-id":J}:{},"oai-client-platform":"web","oai-client-version":"0","x-openai-target-path":X}}function _Y(Y){return typeof Y==="object"&&Y!==null&&!Array.isArray(Y)}function _X(Y){if(!Y)return;return{...Y.inFlight?{inFlight:{...Y.inFlight}}:{},...Y.lastOutcome?{lastOutcome:{...Y.lastOutcome}}:{},...Y.cooldownUntil!==void 0?{cooldownUntil:Y.cooldownUntil}:{}}}function j8(Y){if(!_Y(Y)||typeof Y.redeemRequestId!=="string"||Y.redeemRequestId.length===0||typeof Y.creditId!=="string"||Y.creditId.length===0||typeof Y.startedAt!=="number"||!Number.isFinite(Y.startedAt))return;return{redeemRequestId:Y.redeemRequestId,creditId:Y.creditId,startedAt:Y.startedAt}}function IX(Y){return Boolean(Y&&Object.hasOwn(Y,"inFlight"))}function SX(Y,X){return X-Y.startedAt<A5}function IY(Y,X){if(!y0(X))return;return Y.reset?.[X]}function kX(Y){if(!Y.reset)Y.reset=Object.create(null);return Y.reset}function bX(Y,X,J){if(!y0(X))return;let Q=kX(Y),$=Q[X]??{},G=$.lastOutcome;delete $.inFlight,$.lastOutcome={code:"ambiguous_local",at:J,...G?{previousOutcome:{code:G.code,at:G.at}}:{}},Q[X]=$}function xX(Y,X){let J=_X(Y),Q=j8(Y?.inFlight);if(IX(Y)&&!Q)return{kind:"corrupt",beforeState:J};if(Y?.cooldownUntil!==void 0&&Y.cooldownUntil>X)return{kind:"cooldown",beforeState:J,cooldownUntil:Y.cooldownUntil};if(Q&&SX(Q,X))return{kind:"claim",beforeState:J,claim:{inFlight:Q,selectedCredit:{id:Q.creditId}}};if(Q)return{kind:"expired_unreconciled",beforeState:J,claim:{inFlight:Q,selectedCredit:{id:Q.creditId}}};return{kind:"fresh",beforeState:J}}async function _5(Y,X){if(!y0(X))return{kind:"fresh",beforeState:void 0};let J=await Y.loadAccountsFn(Y.configPath);return xX(J?IY(J,X):void 0,Y.now())}async function I5(Y,X){let J;if(await Y.mutateAccountsFn((Q)=>{let $=Y.now(),G=IY(Q,X);if(J=xX(G,$),J.kind==="corrupt")bX(Q,X,$);return Q},Y.configPath),!J)throw Error("corrupt reset state mutation did not run");return J}async function S5(Y,X,J){if(!y0(X))return{kind:"fresh",beforeState:void 0};let Q;if(await Y.mutateAccountsFn(($)=>{let G=Y.now(),W=IY($,X),U=_X(W),L=j8(W?.inFlight);if(IX(W)&&!L)return bX($,X,G),Q={kind:"corrupt",beforeState:U},$;if(W?.cooldownUntil!==void 0&&W.cooldownUntil>G)return Q={kind:"cooldown",beforeState:U,cooldownUntil:W.cooldownUntil},$;if(L&&SX(L,G))return Q={kind:"claim",beforeState:U,claim:{inFlight:L,selectedCredit:{id:L.creditId}}},$;if(L)return Q={kind:"expired_unreconciled",beforeState:U,claim:{inFlight:L,selectedCredit:{id:L.creditId}}},$;let H=SY(J);if(!H)return Q={kind:"fresh",beforeState:U},$;let N={redeemRequestId:Y.randomUUID(),creditId:H.id,startedAt:G},O=kX($);return O[X]={...W,inFlight:N},Q={kind:"claim",beforeState:U,claim:{inFlight:N,selectedCredit:H}},$},Y.configPath),!Q)throw Error("reset claim mutation did not run");return Q}async function k5(Y,X,J,Q){if(!y0(X))return;if(!M8(Q.kind))return;await Y.mutateAccountsFn(($)=>{let G=IY($,X),W=j8(G?.inFlight);if(!G||!W||W.redeemRequestId!==J.redeemRequestId||W.creditId!==J.creditId)return $;let U=Y.now();if(delete G.inFlight,G.lastOutcome={code:Q.kind,at:U},Q.kind==="reset"||Q.kind==="already_redeemed")G.cooldownUntil=U+C5;else delete G.cooldownUntil;return $},Y.configPath)}function s1(Y,X){if(!Y||Y.usedPercent<100)return!1;if(!Y.resetsAt)return!0;let J=Date.parse(Y.resetsAt);return!Number.isFinite(J)||J>X}function D8(Y,X,J,Q){if(!(X||s1(Y.primary,Q)||s1(Y.secondary,Q)))return{ok:!1,reason:"not exhausted"};if(J<=0)return{ok:!1,reason:"no applicable credits"};return{ok:!0}}function wX(Y,X){let J=Y[X];if(J===void 0||J===null)return;return typeof J==="string"?J:null}function b5(Y){if(!_Y(Y))return;let X=wX(Y,"granted_at"),J=wX(Y,"reset_type");if(typeof Y.id!=="string"||typeof Y.status!=="string"||typeof Y.expires_at!=="string"||Number.isNaN(Date.parse(Y.expires_at))||typeof Y.is_supported_by_plan!=="boolean"||X===null||J===null)return;return{id:Y.id,status:Y.status,...X===void 0?{}:{grantedAt:X},expiresAt:Y.expires_at,...J===void 0?{}:{resetType:J},isSupportedByPlan:Y.is_supported_by_plan}}async function P8(Y,X,J){let Q;try{Q=await Y(w5,{method:"GET",headers:CX(X,F8,J),signal:AbortSignal.timeout(R5)})}catch{throw new q1("http_error","reset credit list request failed")}if(!Q.ok)throw new q1("http_error",`reset credit list request failed: ${Q.status}`,Q.status);let $;try{$=await Q.json()}catch{throw new q1("invalid_response","reset credit list response was not valid JSON",Q.status)}if(!_Y($))throw new q1("invalid_response","reset credit list response was not an object",Q.status);return{credits:(Array.isArray($.credits)?$.credits:[]).flatMap((W)=>{let U=b5(W);return U===void 0?[]:[U]}),availableCount:typeof $.available_count==="number"&&Number.isFinite($.available_count)?$.available_count:void 0}}function SY(Y){return[...Y].filter((X)=>X.status==="available"&&X.isSupportedByPlan&&X.resetType==="codex_rate_limits").sort((X,J)=>Date.parse(X.expiresAt)-Date.parse(J.expiresAt))[0]}function M8(Y){return Y==="reset"||Y==="already_redeemed"||Y==="nothing_to_reset"||Y==="no_credit"}async function x5(Y,X,J,Q,$){let G;try{G=await Y(E5,{method:"POST",headers:{...CX(X,RX,J),"content-type":"application/json"},body:JSON.stringify({redeem_request_id:$,credit_id:Q}),signal:AbortSignal.timeout(T5)})}catch(H){return{kind:"ambiguous",raw:H}}let W;try{W=await G.text()}catch(H){return G.ok?{kind:"ambiguous",raw:H}:{kind:"http_error",raw:H,status:G.status}}let U=W,L=!1;try{U=JSON.parse(W),L=!0}catch{}if(!G.ok)return{kind:"http_error",raw:U,status:G.status};if(!L||!_Y(U)||!M8(U.code))return{kind:"ambiguous",raw:U};return{kind:U.code,raw:U}}function EX(Y){if(Y.kind==="cooldown")throw new _0("cooldown_active","reset credit redemption is cooling down",Y.cooldownUntil);throw Error(`unexpected reset state decision: ${Y.kind}`)}function AX(){throw new _0("expired_unreconciled","the previous reset attempt outcome is unknown")}function TX(Y,X){return{target:Y,selectedCredit:void 0,beforeState:X,outcome:{kind:"ambiguous_local",raw:{reason:"corrupt_in_flight"}},retrySafety:"No request was sent because the saved redemption identity was incomplete."}}function v5(Y){if(Y.kind==="reset"||Y.kind==="already_redeemed")return"The server returned a terminal result; cooldown blocks an immediate new redemption.";if(Y.kind==="nothing_to_reset"||Y.kind==="no_credit")return"The server returned a terminal no-op. No cooldown was set; a new attempt starts fresh and remains gated by fresh preconditions.";return"The outcome is uncertain. A retry within five minutes reuses the same request and credit identifiers; this does not prove the server did nothing."}async function vX(Y,X){if(!y0(X.accountKey))throw new _0("invalid_account_key","the reset account key is reserved");let J=await Y.resolveTarget(X.accountKey);if(J.chatgptAccountId!==X.expectedChatgptAccountId)throw new _0("identity_mismatch","the resolved ChatGPT account identity changed before redemption");let Q=J.accountKey==="main"?void 0:J.chatgptAccountId,$=await _5(Y,X.accountKey);if($.kind==="corrupt"){if($=await I5(Y,X.accountKey),$.kind==="corrupt")return TX(J,$.beforeState)}if($.kind==="cooldown")EX($);let G;if($.kind==="claim")G=$.claim;else if($.kind==="expired_unreconciled"){if(!X.retry)AX();G=$.claim}else{if(X.retry)throw new _0("retry_without_inflight","there is no active reset credit redemption to retry");let[L,H]=await Promise.all([Y.fetchUsage(J),P8(Y.fetchImpl,J.accessToken,Q)]),N=D8(L,Y.hasActiveRateLimitMark(X.accountKey),L.resetCreditsApplicable??0,Y.now());if(!N.ok)throw new _0(N.reason==="not exhausted"?"not_exhausted":"no_applicable_credits",N.reason);if(!SY(H.credits))throw new _0("no_eligible_credit","no eligible reset credit was returned");let O=await S5(Y,X.accountKey,H.credits);if(O.kind==="corrupt")return TX(J,O.beforeState);if(O.kind==="cooldown")EX(O);if(O.kind==="expired_unreconciled")AX();if(O.kind!=="claim")throw new _0("no_eligible_credit","no eligible reset credit was available while claiming");G=O.claim}let W=await x5(Y.fetchImpl,J.accessToken,Q,G.inFlight.creditId,G.inFlight.redeemRequestId),U=!1;try{await k5(Y,X.accountKey,G.inFlight,W)}catch{U=M8(W.kind)}return{target:J,selectedCredit:G.selectedCredit,beforeState:$.beforeState,outcome:W,retrySafety:U?"The server returned a terminal result, but the state write failed. A retry within five minutes reuses the same request and credit identifiers.":v5(W),...U?{finalizeStateWriteFailed:!0}:{}}}function C(Y){return typeof Y==="object"&&Y!==null&&!Array.isArray(Y)}var A8="openai-quota",T8="openai-account",R8="openai-routing",C8="openai-killswitch",_8="openai-dump",I8="openai-logging",S8="openai-cachekeep",j1="openai-reset",cX=["openai-quota","openai-account","openai-routing","openai-killswitch","openai-dump","openai-logging","openai-cachekeep","openai-reset"],i=L0("commands");function hX(Y){if(Y==="fallback-first")return"Try usable fallback accounts before the main account.";if(Y==="sticky-balanced")return"Keep each session on its assigned account while balancing new sessions.";return"Try the main account first. Use fallback accounts only when required."}async function h5(Y){let X=await Y.refreshAllQuota?.(),J=Y.quotaManager.getMain(),Q=["## OpenAI Quota",""];if(J?.quota){let W=J.quota;Q.push("### Main account");for(let U of["primary","secondary"]){let L=W[U];if(L){let H=Math.round(L.usedPercent),N="█".repeat(Math.max(0,Math.min(Math.round(H/10),10)))+"░".repeat(Math.max(0,10-Math.min(Math.round(H/10),10)));Q.push(`- ${U}: ${N} ${H}% used (${Math.round(L.remainingPercent)}% remaining)`)}}if(W.resetCreditsAvailable!==void 0)Q.push(`- resets: ${W.resetCreditsAvailable}`)}else Q.push("No main quota snapshot available. Send a request first.");let G=[...Y.quotaManager.getAllFallbacks().entries()].filter(([,W])=>W);if(G.length>0){Q.push(""),Q.push("### Fallback accounts");for(let[W,U]of G){if(!U?.quota)continue;Q.push(`**${W}**`);for(let L of["primary","secondary"]){let H=U.quota[L];if(H){let N=Math.round(H.usedPercent);Q.push(` - ${L}: ${N}% used (${Math.round(H.remainingPercent)}% remaining)`)}}if(U.quota.resetCreditsAvailable!==void 0)Q.push(` - resets: ${U.quota.resetCreditsAvailable}`)}}if(X?.length){let W=X.filter((U)=>!U.ok);if(W.length>0){Q.push("");for(let U of W)Q.push(`- ${U.account}: fetch failed — Refresh to retry`)}}return{command:"openai-quota",text:Q.join(`
1
+ import{d as x1,e as FY,f as XW}from"./index-87145jkw.js";import{A as $1,B as R1,C as Q1,D as lW,E as dW,G as u0,H as iW,I as F1,J as y0,K as q0,L as J0,M as jY,N as DY,O as XX,P as PY,Q as nW,R as oW,S as rW,h as SW,i as kW,j as bW,k as xW,l as vW,m as hW,n as gW,o as l1,p as d1,q as V8,s as yW,t as fW,u as mW,v as cW,w as uW,x as pW,y as fX,z as mX}from"./index-srgn00yp.js";import{$ as D1,U as f8,X as MY,Y as sW,da as aW,ea as tW,fa as eW,ka as Y5,la as N8,ma as X5,na as J5,oa as Q5,pa as $5}from"./index-meg0ng0z.js";import{ua as bY}from"./index-n00ybbbq.js";import{va as AJ,wa as TJ}from"./index-e08r33g5.js";import{Aa as L0,ya as kY,za as $J}from"./index-hxpv25e8.js";import{Da as G5}from"./index-dz9a4xwy.js";import{Ga as X9}from"./index-s2vhsb2v.js";import{mkdirSync as RB,readFileSync as CB,renameSync as _B,statSync as IB,writeFileSync as SB}from"node:fs";import e9 from"node:os";import{join as kB}from"node:path";import{readFileSync as O5}from"node:fs";import{homedir as q5,tmpdir as F5}from"node:os";import{join as RY}from"node:path";var j5="https://chatgpt.com/backend-api/codex/responses",D5="openai-auth.json",o0={noWebSearch:"CORTEXKIT_OPENAI_AUTH_NO_WEB_SEARCH",webSockets:"CORTEXKIT_OPENAI_AUTH_WEBSOCKETS",rawWebSocket:"CORTEXKIT_OPENAI_AUTH_RAW_WS",responsesLite:"CORTEXKIT_OPENAI_AUTH_RESPONSES_LITE",dump:"CORTEXKIT_OPENAI_AUTH_DUMP",dumpDir:"OPENCODE_OPENAI_AUTH_DUMP_DIR",codexApiEndpoint:"CORTEXKIT_OPENAI_AUTH_CODEX_ENDPOINT",configFile:"OPENCODE_OPENAI_AUTH_FILE",stateFile:"OPENCODE_OPENAI_AUTH_STATE_FILE",configDir:"OPENCODE_CONFIG_DIR"};function CY(){let Y=process.env[o0.configDir]?.trim();if(Y)return Y;return RY(process.env.XDG_CONFIG_HOME||RY(q5(),".config"),"opencode")}function $0(){return process.env[o0.configFile]?.trim()||RY(CY(),D5)}function P5(){try{let Y=JSON.parse(O5($0(),"utf8"));return Y!=null&&typeof Y==="object"&&!Array.isArray(Y)?Y:{}}catch{return{}}}function MX(Y){let X=process.env[Y];if(X===void 0)return;let J=X.trim().toLowerCase();if(J==="1"||J==="true"||J==="yes"||J==="on")return!0;if(J===""||J==="0"||J==="false"||J==="no"||J==="off")return!1;return}function TY(Y,X,J){let Q=MX(Y);if(Q!==void 0)return Q;if(typeof X==="boolean")return X;return J}function M5(){let Y=P5(),X=MX(o0.noWebSearch),J=X!==void 0?!X:typeof Y.webSearch==="boolean"?Y.webSearch:!0,Q;if(Y.dump!==void 0&&Y.dump!==null){if(typeof Y.dump==="object")Q=Y.dump.enabled;else if(typeof Y.dump==="boolean")Q=Y.dump}return{webSearch:J,webSockets:TY(o0.webSockets,Y.webSockets,!1),rawWebSocket:TY(o0.rawWebSocket,Y.rawWebSocket,!1),responsesLite:TY(o0.responsesLite,Y.responsesLite,!1),dump:TY(o0.dump,Q,!1),dumpDir:process.env[o0.dumpDir]?.trim()||(typeof Y.dumpDir==="string"&&Y.dumpDir.trim()?Y.dumpDir.trim():RY(F5(),"opencode-openai-auth-dumps")),codexApiEndpoint:process.env[o0.codexApiEndpoint]?.trim()||(typeof Y.codexApiEndpoint==="string"&&Y.codexApiEndpoint.trim()?Y.codexApiEndpoint.trim():j5)}}var q8;function M0(){if(!q8)q8=M5();return q8}var F8="/backend-api/wham/rate-limit-reset-credits",w5=`https://chatgpt.com${F8}`,RX=`${F8}/consume`,E5=`https://chatgpt.com${RX}`,A5=300000,T5=60000,R5=15000,C5=60000;class _0 extends Error{kind;cooldownUntil;constructor(Y,X,J){super(X);this.name="ResetRedemptionError",this.kind=Y,this.cooldownUntil=J}}class q1 extends Error{kind;status;constructor(Y,X,J){super(X);this.name="ResetCreditError",this.kind=Y,this.status=J}}function CX(Y,X,J){return{authorization:`Bearer ${Y}`,...J?{"chatgpt-account-id":J}:{},"oai-client-platform":"web","oai-client-version":"0","x-openai-target-path":X}}function _Y(Y){return typeof Y==="object"&&Y!==null&&!Array.isArray(Y)}function _X(Y){if(!Y)return;return{...Y.inFlight?{inFlight:{...Y.inFlight}}:{},...Y.lastOutcome?{lastOutcome:{...Y.lastOutcome}}:{},...Y.cooldownUntil!==void 0?{cooldownUntil:Y.cooldownUntil}:{}}}function j8(Y){if(!_Y(Y)||typeof Y.redeemRequestId!=="string"||Y.redeemRequestId.length===0||typeof Y.creditId!=="string"||Y.creditId.length===0||typeof Y.startedAt!=="number"||!Number.isFinite(Y.startedAt))return;return{redeemRequestId:Y.redeemRequestId,creditId:Y.creditId,startedAt:Y.startedAt}}function IX(Y){return Boolean(Y&&Object.hasOwn(Y,"inFlight"))}function SX(Y,X){return X-Y.startedAt<A5}function IY(Y,X){if(!y0(X))return;return Y.reset?.[X]}function kX(Y){if(!Y.reset)Y.reset=Object.create(null);return Y.reset}function bX(Y,X,J){if(!y0(X))return;let Q=kX(Y),$=Q[X]??{},G=$.lastOutcome;delete $.inFlight,$.lastOutcome={code:"ambiguous_local",at:J,...G?{previousOutcome:{code:G.code,at:G.at}}:{}},Q[X]=$}function xX(Y,X){let J=_X(Y),Q=j8(Y?.inFlight);if(IX(Y)&&!Q)return{kind:"corrupt",beforeState:J};if(Y?.cooldownUntil!==void 0&&Y.cooldownUntil>X)return{kind:"cooldown",beforeState:J,cooldownUntil:Y.cooldownUntil};if(Q&&SX(Q,X))return{kind:"claim",beforeState:J,claim:{inFlight:Q,selectedCredit:{id:Q.creditId}}};if(Q)return{kind:"expired_unreconciled",beforeState:J,claim:{inFlight:Q,selectedCredit:{id:Q.creditId}}};return{kind:"fresh",beforeState:J}}async function _5(Y,X){if(!y0(X))return{kind:"fresh",beforeState:void 0};let J=await Y.loadAccountsFn(Y.configPath);return xX(J?IY(J,X):void 0,Y.now())}async function I5(Y,X){let J;if(await Y.mutateAccountsFn((Q)=>{let $=Y.now(),G=IY(Q,X);if(J=xX(G,$),J.kind==="corrupt")bX(Q,X,$);return Q},Y.configPath),!J)throw Error("corrupt reset state mutation did not run");return J}async function S5(Y,X,J){if(!y0(X))return{kind:"fresh",beforeState:void 0};let Q;if(await Y.mutateAccountsFn(($)=>{let G=Y.now(),W=IY($,X),U=_X(W),L=j8(W?.inFlight);if(IX(W)&&!L)return bX($,X,G),Q={kind:"corrupt",beforeState:U},$;if(W?.cooldownUntil!==void 0&&W.cooldownUntil>G)return Q={kind:"cooldown",beforeState:U,cooldownUntil:W.cooldownUntil},$;if(L&&SX(L,G))return Q={kind:"claim",beforeState:U,claim:{inFlight:L,selectedCredit:{id:L.creditId}}},$;if(L)return Q={kind:"expired_unreconciled",beforeState:U,claim:{inFlight:L,selectedCredit:{id:L.creditId}}},$;let H=SY(J);if(!H)return Q={kind:"fresh",beforeState:U},$;let N={redeemRequestId:Y.randomUUID(),creditId:H.id,startedAt:G},O=kX($);return O[X]={...W,inFlight:N},Q={kind:"claim",beforeState:U,claim:{inFlight:N,selectedCredit:H}},$},Y.configPath),!Q)throw Error("reset claim mutation did not run");return Q}async function k5(Y,X,J,Q){if(!y0(X))return;if(!M8(Q.kind))return;await Y.mutateAccountsFn(($)=>{let G=IY($,X),W=j8(G?.inFlight);if(!G||!W||W.redeemRequestId!==J.redeemRequestId||W.creditId!==J.creditId)return $;let U=Y.now();if(delete G.inFlight,G.lastOutcome={code:Q.kind,at:U},Q.kind==="reset"||Q.kind==="already_redeemed")G.cooldownUntil=U+C5;else delete G.cooldownUntil;return $},Y.configPath)}function s1(Y,X){if(!Y||Y.usedPercent<100)return!1;if(!Y.resetsAt)return!0;let J=Date.parse(Y.resetsAt);return!Number.isFinite(J)||J>X}function D8(Y,X,J,Q){if(!(X||s1(Y.primary,Q)||s1(Y.secondary,Q)))return{ok:!1,reason:"not exhausted"};if(J<=0)return{ok:!1,reason:"no applicable credits"};return{ok:!0}}function wX(Y,X){let J=Y[X];if(J===void 0||J===null)return;return typeof J==="string"?J:null}function b5(Y){if(!_Y(Y))return;let X=wX(Y,"granted_at"),J=wX(Y,"reset_type");if(typeof Y.id!=="string"||typeof Y.status!=="string"||typeof Y.expires_at!=="string"||Number.isNaN(Date.parse(Y.expires_at))||typeof Y.is_supported_by_plan!=="boolean"||X===null||J===null)return;return{id:Y.id,status:Y.status,...X===void 0?{}:{grantedAt:X},expiresAt:Y.expires_at,...J===void 0?{}:{resetType:J},isSupportedByPlan:Y.is_supported_by_plan}}async function P8(Y,X,J){let Q;try{Q=await Y(w5,{method:"GET",headers:CX(X,F8,J),signal:AbortSignal.timeout(R5)})}catch{throw new q1("http_error","reset credit list request failed")}if(!Q.ok)throw new q1("http_error",`reset credit list request failed: ${Q.status}`,Q.status);let $;try{$=await Q.json()}catch{throw new q1("invalid_response","reset credit list response was not valid JSON",Q.status)}if(!_Y($))throw new q1("invalid_response","reset credit list response was not an object",Q.status);return{credits:(Array.isArray($.credits)?$.credits:[]).flatMap((W)=>{let U=b5(W);return U===void 0?[]:[U]}),availableCount:typeof $.available_count==="number"&&Number.isFinite($.available_count)?$.available_count:void 0}}function SY(Y){return[...Y].filter((X)=>X.status==="available"&&X.isSupportedByPlan&&X.resetType==="codex_rate_limits").sort((X,J)=>Date.parse(X.expiresAt)-Date.parse(J.expiresAt))[0]}function M8(Y){return Y==="reset"||Y==="already_redeemed"||Y==="nothing_to_reset"||Y==="no_credit"}async function x5(Y,X,J,Q,$){let G;try{G=await Y(E5,{method:"POST",headers:{...CX(X,RX,J),"content-type":"application/json"},body:JSON.stringify({redeem_request_id:$,credit_id:Q}),signal:AbortSignal.timeout(T5)})}catch(H){return{kind:"ambiguous",raw:H}}let W;try{W=await G.text()}catch(H){return G.ok?{kind:"ambiguous",raw:H}:{kind:"http_error",raw:H,status:G.status}}let U=W,L=!1;try{U=JSON.parse(W),L=!0}catch{}if(!G.ok)return{kind:"http_error",raw:U,status:G.status};if(!L||!_Y(U)||!M8(U.code))return{kind:"ambiguous",raw:U};return{kind:U.code,raw:U}}function EX(Y){if(Y.kind==="cooldown")throw new _0("cooldown_active","reset credit redemption is cooling down",Y.cooldownUntil);throw Error(`unexpected reset state decision: ${Y.kind}`)}function AX(){throw new _0("expired_unreconciled","the previous reset attempt outcome is unknown")}function TX(Y,X){return{target:Y,selectedCredit:void 0,beforeState:X,outcome:{kind:"ambiguous_local",raw:{reason:"corrupt_in_flight"}},retrySafety:"No request was sent because the saved redemption identity was incomplete."}}function v5(Y){if(Y.kind==="reset"||Y.kind==="already_redeemed")return"The server returned a terminal result; cooldown blocks an immediate new redemption.";if(Y.kind==="nothing_to_reset"||Y.kind==="no_credit")return"The server returned a terminal no-op. No cooldown was set; a new attempt starts fresh and remains gated by fresh preconditions.";return"The outcome is uncertain. A retry within five minutes reuses the same request and credit identifiers; this does not prove the server did nothing."}async function vX(Y,X){if(!y0(X.accountKey))throw new _0("invalid_account_key","the reset account key is reserved");let J=await Y.resolveTarget(X.accountKey);if(J.chatgptAccountId!==X.expectedChatgptAccountId)throw new _0("identity_mismatch","the resolved ChatGPT account identity changed before redemption");let Q=J.accountKey==="main"?void 0:J.chatgptAccountId,$=await _5(Y,X.accountKey);if($.kind==="corrupt"){if($=await I5(Y,X.accountKey),$.kind==="corrupt")return TX(J,$.beforeState)}if($.kind==="cooldown")EX($);let G;if($.kind==="claim")G=$.claim;else if($.kind==="expired_unreconciled"){if(!X.retry)AX();G=$.claim}else{if(X.retry)throw new _0("retry_without_inflight","there is no active reset credit redemption to retry");let[L,H]=await Promise.all([Y.fetchUsage(J),P8(Y.fetchImpl,J.accessToken,Q)]),N=D8(L,Y.hasActiveRateLimitMark(X.accountKey),L.resetCreditsApplicable??0,Y.now());if(!N.ok)throw new _0(N.reason==="not exhausted"?"not_exhausted":"no_applicable_credits",N.reason);if(!SY(H.credits))throw new _0("no_eligible_credit","no eligible reset credit was returned");let O=await S5(Y,X.accountKey,H.credits);if(O.kind==="corrupt")return TX(J,O.beforeState);if(O.kind==="cooldown")EX(O);if(O.kind==="expired_unreconciled")AX();if(O.kind!=="claim")throw new _0("no_eligible_credit","no eligible reset credit was available while claiming");G=O.claim}let W=await x5(Y.fetchImpl,J.accessToken,Q,G.inFlight.creditId,G.inFlight.redeemRequestId),U=!1;try{await k5(Y,X.accountKey,G.inFlight,W)}catch{U=M8(W.kind)}return{target:J,selectedCredit:G.selectedCredit,beforeState:$.beforeState,outcome:W,retrySafety:U?"The server returned a terminal result, but the state write failed. A retry within five minutes reuses the same request and credit identifiers.":v5(W),...U?{finalizeStateWriteFailed:!0}:{}}}function C(Y){return typeof Y==="object"&&Y!==null&&!Array.isArray(Y)}var A8="openai-quota",T8="openai-account",R8="openai-routing",C8="openai-killswitch",_8="openai-dump",I8="openai-logging",S8="openai-cachekeep",j1="openai-reset",cX=["openai-quota","openai-account","openai-routing","openai-killswitch","openai-dump","openai-logging","openai-cachekeep","openai-reset"],i=L0("commands");function hX(Y){if(Y==="fallback-first")return"Try usable fallback accounts before the main account.";if(Y==="sticky-balanced")return"Keep each session on its assigned account while balancing new sessions.";return"Try the main account first. Use fallback accounts only when required."}async function h5(Y){let X=await Y.refreshAllQuota?.(),J=Y.quotaManager.getMain(),Q=["## OpenAI Quota",""];if(J?.quota){let W=J.quota;Q.push("### Main account");for(let U of["primary","secondary"]){let L=W[U];if(L){let H=Math.round(L.usedPercent),N="█".repeat(Math.max(0,Math.min(Math.round(H/10),10)))+"░".repeat(Math.max(0,10-Math.min(Math.round(H/10),10)));Q.push(`- ${U}: ${N} ${H}% used (${Math.round(L.remainingPercent)}% remaining)`)}}if(W.resetCreditsAvailable!==void 0)Q.push(`- resets: ${W.resetCreditsAvailable}`)}else Q.push("No main quota snapshot available. Send a request first.");let G=[...Y.quotaManager.getAllFallbacks().entries()].filter(([,W])=>W);if(G.length>0){Q.push(""),Q.push("### Fallback accounts");for(let[W,U]of G){if(!U?.quota)continue;Q.push(`**${W}**`);for(let L of["primary","secondary"]){let H=U.quota[L];if(H){let N=Math.round(H.usedPercent);Q.push(` - ${L}: ${N}% used (${Math.round(H.remainingPercent)}% remaining)`)}}if(U.quota.resetCreditsAvailable!==void 0)Q.push(` - resets: ${U.quota.resetCreditsAvailable}`)}}if(X?.length){let W=X.filter((U)=>!U.ok);if(W.length>0){Q.push("");for(let U of W)Q.push(`- ${U.account}: fetch failed — Refresh to retry`)}}return{command:"openai-quota",text:Q.join(`
2
2
  `),knobs:{}}}function k1(Y){return{id:Y.id,type:Y.type??"oauth",enabled:Y.enabled,label:Y.label}}async function g5(Y,X){let J=Y.trim().split(/\s+/).filter(Boolean),Q=await X.loadAccounts(X.accountStoragePath)??{version:1,accounts:[]},$=Q.accounts??[];if(J.length===0){let G=["## OpenAI Accounts",""];if($.length===0)G.push("No accounts configured. Use `/login openai` to add your main account, or `/openai-account add` to add a fallback account.");else{let W=Q.routing?.mode??"main-first";G.push(`Routing: \`${W}\` (set with \`/openai-routing\`). Modes: main-first, fallback-first, or sticky-balanced. \`/openai-routing reset\` clears this session's pin.`),G.push("");for(let U of $){let L=U.type??"oauth";G.push(`- \`${U.id}\` (${L})`)}}return G.push(""),G.push("Commands: `/openai-account add [label]` | `/openai-account remove <id>`"),{command:"openai-account",text:G.join(`
3
3
  `),knobs:{accounts:$.map(k1)}}}if(J[0]==="remove"&&J[1]){let G=J[1],W=!1,U=await J0((L)=>{let H=L.accounts.findIndex((N)=>N.id===G);if(H===-1)return L;return W=!0,L.accounts.splice(H,1),L},X.accountStoragePath);if(!W)return{command:"openai-account",text:`## Account Not Found
4
4
 
@@ -215,4 +215,4 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
215
215
  `)}
216
216
 
217
217
  `)),W=!0,V("idle timeout waiting for websocket"),!Y0)return;if(Y0.type==="response.completed"||Y0.type==="response.done"){G=!0,QB(Y0,L),Y.onComplete?.(Y0,L),Y.onTerminal?.(Y0),O();return}if(Y0.type==="response.failed"||Y0.type==="response.incomplete"||Y0.type==="error")G=!0,Y.onTerminal?.(Y0),O()}function j(R){Z(new R0($1(R),{cause:R}))}function M(R){if(G)return;Z(new R0(GW("WebSocket closed before response.completed",R.code,R.reason)))}function I(){let R=n9(Y.signal);if(G)return;G=!0,H(),N(),Y.onAbort?.(R),Q?.error(R)}function E(R){if(G)return;G=!0,H(),N(),Y.onAbort?.(GB(R))}function x(R){$(),J=R,J.addEventListener("message",K),J.addEventListener("error",j,{once:!0}),J.addEventListener("close",M,{once:!0}),$=()=>{J.removeEventListener("message",K),J.removeEventListener("error",j),J.removeEventListener("close",M)};let{background:p,...m}=Y.body;V("idle timeout sending websocket request");try{J.send(JSON.stringify({type:"response.create",...m})),V("idle timeout waiting for websocket")}catch(d){if(G)return;Z(new R0(d instanceof Error?d.message:String(d),{cause:d}))}}return new Response(new ReadableStream({start(R){if(Q=R,Y.signal?.addEventListener("abort",I,{once:!0}),Y.signal?.aborted){I();return}x(J)},cancel(R){E(R)}}),{status:200,headers:{"content-type":"text/event-stream"}})}async function YB(Y,X){if(!XB(Y))return;await r0({component:"ws",event:"provider_native_web_search_event",sessionID:X,serverEventType:Y.type,itemType:C(Y.item)?Y.item.type:void 0,serverEvent:Y})}function XB(Y){if(typeof Y.type==="string"&&(Y.type.startsWith("response.web_search_call.")||Y.type.startsWith("response.web_search_preview_call.")))return!0;if(C(Y.item)&&typeof Y.item.type==="string")return Y.item.type==="web_search_call"||Y.item.type==="web_search_preview_call";return!1}function JB(Y,X){if(Y.type!=="response.output_item.done")return;if(!C(Y.item))return;$W(Y.item,X)}function QB(Y,X){let J=Y.response;if(!C(J)||!Array.isArray(J.output))return;for(let Q of J.output)if(C(Q))$W(Q,X)}function $W(Y,X){if(Y.type!=="function_call"&&Y.type!=="custom_tool_call")return;let J=typeof Y.call_id==="string"?Y.call_id:typeof Y.id==="string"?Y.id:void 0;if(J)X.add(J)}function $B(Y,X){if(Y?.type!=="error")return;let J=Y.status??Y.status_code;if(typeof J!=="number"||J>=200&&J<300)return;return{status:J,headers:C(Y.headers)?Object.fromEntries(Object.entries(Y.headers).flatMap(([Q,$])=>typeof $==="string"||typeof $==="number"||typeof $==="boolean"?[[Q,String($)]]:[])):void 0,body:X,message:C(Y.error)&&typeof Y.error.message==="string"?Y.error.message:`${J}`}}function OY(Y){if(typeof Y==="string")try{return OY(JSON.parse(Y))}catch{return}if(!C(Y))return;let X=OY(Y.cause);if(X)return X;let J=OY(Y.body);if(J)return J;let Q=C(Y.error)?Y.error:Y,$=typeof Q.type==="string"?Q.type:void 0,G=Y.status??Y.status_code;if($!=="usage_limit_reached"&&G!==429)return;let{resets_at:W,resets_in_seconds:U}=Q,L=typeof W==="number"&&Number.isFinite(W)&&W>0?W*1000:typeof U==="number"&&Number.isFinite(U)&&U>0?Date.now()+U*1000:void 0;return{window:$??"primary",resetAt:L}}function GB(Y){if(o9(Y))return Y;if(Y instanceof Error)return Y;return new DOMException(typeof Y==="string"?Y:"Aborted","AbortError")}function n9(Y){let X=Y?.reason;if(o9(X))return X;if(WB(X))return X;return new DOMException(X instanceof Error?X.message:"Aborted","AbortError")}function WB(Y){return Y instanceof Error&&(Y.name==="ProviderHeaderTimeoutError"||Y.name==="ProviderResponseStreamError")}function GW(Y,X,J){let Q=[`code ${X}`];if(X===1009)Q.push("message too big");if(J.length>0)Q.push(J.toString());return`${Y} (${Q.join(": ")})`}var s9="x-opencode-title",H8="x-openai-auth-quota-account",r9=new Set([s9,G1,H8,"x-opencode-session"]),UB=15000,HB=300000,LB=3300000,WW="websocket_connection_limit_reached";function VB(Y){let X=typeof Y["chatgpt-account-id"]==="string"?Y["chatgpt-account-id"]:"",J=typeof Y.authorization==="string"&&Y.authorization.startsWith("Bearer ")?Y.authorization.slice(7):"",Q=X?`acct:${X}`:`tok:${J}`;return zB("sha256").update(Q).digest("hex").slice(0,12)}function NB(Y){let X=Y?.httpFetch??globalThis.fetch,J=new Map,Q=Y?.connectTimeout??UB,$=Y?.idleTimeout??HB,G=Y?.maxConnectionAge??LB,W=Y?.streamRetries??5,U=Y?.firstEventGraceMs??250,L=Y?.rawWebSocket??!1,H=Y?.onQuota,N=Y?.onRateLimitReached,O=setInterval(()=>j(),Math.min($,60000));if(typeof O==="object"&&"unref"in O&&typeof O.unref==="function")O.unref();function Z(E,x,R){if(!x||!R)return R;a9(E,zW(x));let p=new Headers(R.headers),m=p.get("x-codex-turn-metadata");if(!m)return R;let d=KW(m,E.turnID,E.turnStartedAt);if(!d)return R;return p.set("x-codex-turn-metadata",d),{...R,headers:p}}async function V(E,x){let R=E instanceof URL?E.toString():typeof E==="string"?E:E.url,p=D0.normalizeHeaders(x?.headers),m=FW(x),d=xY(m);if(x?.method!=="POST"||!new URL(R).pathname.endsWith("/responses"))return X(E,d);let y=(()=>{try{if(typeof x?.body!=="string")return;let r=JSON.parse(x.body);return typeof r==="object"&&r!==null?r:void 0}catch{return}})();if(!y?.stream)return X(E,d);if(p[s9]==="true")return X(E,d);let Y0=p[G1]??p["x-session-affinity"]??p["session-id"],p0=Y0;if(!Y0)return X(E,d);let c=D0.normalizeHeaders(m?.headers),X1=VB(c),i1=`${Y0}:${X1}:conversation`,n1=typeof p[H8]==="string"?p[H8]:void 0,C1=N?(r,B0)=>N(r,n1,B0):void 0,h=J.get(i1)??{lastUsedAt:Date.now(),busy:!1,fallback:!1,streamFailures:0};if(J.set(i1,h),h.fallback)return X(E,Z(h,y,d));if(h.busy)return X(E,Z(h,y,d));h.busy=!0,h.lastUsedAt=Date.now();try{let r=zW(y),B0=D0.normalizeHeaders(m?.headers),B8=typeof B0.authorization==="string"&&B0.authorization.startsWith("Bearer ")?B0.authorization.slice(7):"",_1=typeof B0["chatgpt-account-id"]==="string"?B0["chatgpt-account-id"]:void 0,wY=H?(Q0)=>H(Q0,B8,n1,_1):void 0,l0=!h.socket&&!h.continuation?DB(B0):B0;if(h.socket=await KB(h,Y?.url??R,l0,Q,G,L,x?.signal),EB(h,r))await OB(h,r,$,{signal:x?.signal??void 0,sessionID:p0,url:Y?.url??R,headers:m?.headers,onRateLimitReached:C1});let J1=()=>{},d0=()=>{},K1=new Promise((Q0,T0)=>{J1=Q0,d0=T0}),Z8=wB(h,r),i0=qY(ZW(h,Z8,r)),F0=typeof i0.previous_response_id==="string";await h1({sessionID:p0,transport:"websocket",phase:"main",bodyText:JSON.stringify(i0),url:Y?.url??R,method:m?.method,headers:m?.headers});let x0=D0.streamResponsesWebSocket({socket:h.socket,body:i0,sessionID:p0??void 0,idleTimeout:$,signal:x?.signal??void 0,onQuota:wY,onRateLimitReached:C1,onFirstEvent:(Q0)=>J1(Q0??!0),onComplete:(Q0,T0)=>{let I1=LW(Q0);r0({component:"ws-pool",event:"main_completed",sessionID:p0,responseID:HW(Q0),usage:I1}),BW(h,r,Q0,T0,F0)},onTerminal:(Q0)=>{if(h.busy=!1,h.lastUsedAt=Date.now(),h.streamFailures=0,Q0.type!=="response.completed"&&Q0.type!=="response.done")h.continuation=void 0,Y1(h)},onConnectionInvalid:()=>{if(h.busy=!1,h.lastUsedAt=Date.now(),!h.fallback)K(h);h.continuation=void 0,Y1(h),J1(!1)},onAbort:(Q0)=>{h.busy=!1,h.lastUsedAt=Date.now(),h.streamFailures=0,h.continuation=void 0,Y1(h),d0(Q0)},onRetryableTerminal:async(Q0)=>{let T0=UW(Q0);if(!T0)return;throw h.fallback=!0,T0}}),v0=await BB(K1,U);if(v0!==!1){if(v0===!0||v0.status<200||v0.status>599)return x0;return new Response(v0.body,{status:v0.status,headers:{"content-type":"application/json",...v0.headers}})}if(!h.fallback)return x0;return X(E,Z(h,y,d))}catch(r){if(h.busy=!1,h.lastUsedAt=Date.now(),D0.isAbortError(r))throw h.streamFailures=0,h.continuation=void 0,Y1(h),r;let B0=D0.parseRateLimitSignal(r);if(B0)C1?.(B0.window,B0.resetAt);if(D0.isUpgradeFailure(r)&&!L)h.fallback=!0;if(K(h),h.continuation=void 0,Y1(h),h.fallback)return X(E,Z(h,y,d));return ZB(new R0(r instanceof Error?r.message:String(r),{cause:r}))}}function K(E){if(E.streamFailures++,E.streamFailures>W)E.fallback=!0}function j(){let E=Date.now();for(let[x,R]of J){if(R.busy)continue;if(E-R.lastUsedAt<$)continue;Y1(R),J.delete(x)}}function M(){clearInterval(O);for(let E of J.values())Y1(E);J.clear()}function I(E){let x=`${E}:`;for(let[R,p]of J){if(!R.startsWith(x))continue;Y1(p),J.delete(R)}}return Object.assign(V,{close:M,remove:I})}function UW(Y){if(Y.type!=="error"||!C(Y.error)||Y.error.code!==WW)return;return Error(typeof Y.error.message==="string"?Y.error.message:WW)}async function BB(Y,X){if(X<=0)return!1;return new Promise((J,Q)=>{let $=setTimeout(()=>J(!1),X);Y.then((G)=>{clearTimeout($),J(G)},(G)=>{clearTimeout($),Q(G)})})}function ZB(Y){return new Response(new ReadableStream({start(X){X.error(Y)}}),{status:200,headers:{"content-type":"text/event-stream"}})}async function KB(Y,X,J,Q,$,G,W){if(Y.socket?.readyState===WebSocket.OPEN&&Y.connectedAt&&Date.now()-Y.connectedAt<$)return Y.socket;Y1(Y);let U=await D0.connectResponsesWebSocket({url:D0.toWebSocketUrl(X),headers:J,timeout:Q,rawWebSocket:G,signal:W??void 0});return Y.connectedAt=Date.now(),U}function Y1(Y){if(Y.socket)Y.socket.close(),Y.socket=void 0;Y.connectedAt=void 0,Y.continuation=void 0}async function OB(Y,X,J,Q){if(!Y.socket||!Array.isArray(X.input)||X.input.length===0)return;let $=FB(X);await h1({sessionID:Q.sessionID,transport:"websocket",phase:"prewarm",bodyText:JSON.stringify($),url:Q.url,method:"POST",headers:Q.headers});let G=D0.streamResponsesWebSocket({socket:Y.socket,body:$,sessionID:Q.sessionID,idleTimeout:J,signal:Q.signal,onRateLimitReached:Q.onRateLimitReached,onComplete:(W,U)=>{r0({component:"ws-pool",event:"prewarm_completed",sessionID:Q.sessionID,responseID:HW(W),usage:LW(W)}),BW(Y,$,W,U,!1)},onTerminal:(W)=>{if(W.type!=="response.completed"&&W.type!=="response.done")Y.continuation=void 0},onConnectionInvalid:()=>{Y.continuation=void 0},onAbort:()=>{Y.continuation=void 0},onRetryableTerminal:async(W)=>{let U=UW(W);if(!U)return;throw Y.fallback=!0,U}});await qB(G)}function HW(Y){let X=Y.response;if(!C(X))return;return typeof X.id==="string"?X.id:void 0}function LW(Y){let X=Y.response;if(!C(X))return;return C(X.usage)?X.usage:void 0}async function qB(Y){let X=Y.body?.getReader();if(!X)return;while(!0)if((await X.read()).done)return}function FB(Y){return qY({...Y,generate:!1,input:[],previous_response_id:void 0,client_metadata:jB(Y.client_metadata)})}function VW(Y){return JSON.stringify({session_id:Y.session_id,thread_id:Y.thread_id,thread_source:Y.thread_source,turn_id:"",sandbox:Y.sandbox,request_kind:"prewarm",window_id:Y.window_id})}function jB(Y){if(!C(Y))return Y;if(typeof Y["x-codex-turn-metadata"]!=="string")return Y;try{let X=JSON.parse(Y["x-codex-turn-metadata"]);if(!C(X))return Y;return{...Y,"x-codex-turn-metadata":VW(X),"x-codex-ws-stream-request-start-ms":String(Date.now())}}catch{return Y}}function DB(Y){let X=Y["x-codex-turn-metadata"];if(!X)return Y;try{let J=JSON.parse(X);if(!C(J))return Y;return{...Y,"x-codex-turn-metadata":VW(J)}}catch{return Y}}var NW=["type","model","instructions","previous_response_id","input","tools","tool_choice","parallel_tool_calls","reasoning","store","stream","include","prompt_cache_key","text","generate","client_metadata"];function zW(Y){let X={...Y};if(Array.isArray(Y.input))X.input=Y.input.map(PB);return X}function qY(Y){let X={};for(let J of NW)if(J in Y)X[J]=Y[J];for(let J of Object.keys(Y))if(!(J in X))X[J]=Y[J];return X}function PB(Y){if(!C(Y))return Y;if(typeof Y.type==="string")return Y;if(typeof Y.role!=="string")return Y;if(!("content"in Y))return Y;return{...Y,type:"message"}}function BW(Y,X,J,Q,$){let G=J.response,W=C(G)&&typeof G.id==="string"?G.id:void 0;if(!W||!Array.isArray(X.input)){Y.continuation=void 0;return}let U=$?new Set(Y.continuation?.finalizedCallIds):new Set;for(let L of Q)U.add(L);Y.continuation={responseID:W,input:X.input,signature:t9(X),finalizedCallIds:U}}function a9(Y,X,J=X){let Q=Array.isArray(X.input)?X.input:[],$=Array.isArray(J.input)?J.input:Q,G=t9(J),W=Y.turnInput&&Y.turnSignature===G?MB(Y.turnInput,$):void 0,U=W===void 0?Q:$.slice(W);if(U.length>0&&U.some(OW)||!Y.turnID)Y.turnID=P1(),Y.turnStartedAt=Date.now();Y.turnInput=$.slice(),Y.turnSignature=G}function ZW(Y,X,J=X){a9(Y,X,J);let Q=X.client_metadata;if(!C(Q)||typeof Q["x-codex-turn-metadata"]!=="string")return X;let $=KW(Q["x-codex-turn-metadata"],Y.turnID,Y.turnStartedAt);if(!$)return X;return{...X,client_metadata:{...Q,"x-codex-turn-metadata":$}}}function KW(Y,X,J){let Q;try{Q=JSON.parse(Y)}catch{return}if(!C(Q))return;return JSON.stringify({session_id:Q.session_id,thread_id:Q.thread_id,thread_source:Q.thread_source,turn_id:X,sandbox:Q.sandbox,turn_started_at_unix_ms:J,request_kind:"turn",window_id:Q.window_id})}function MB(Y,X){if(Y.length>X.length)return;for(let J=0;J<Y.length;J++)if(s0(Y[J])!==s0(X[J]))return;return Y.length}function wB(Y,X){let J=Array.isArray(X.input)?X.input:void 0;if(!J||!Y.continuation)return X;if(Y.continuation.signature!==t9(X))return Y.continuation=void 0,X;if(!qW(Y.continuation.input,J))return Y.continuation=void 0,X;if(Y.continuation.input.length===0)return{...X,previous_response_id:Y.continuation.responseID};let Q=J.slice(Y.continuation.input.length),$=AB(Q,Y.continuation.finalizedCallIds);if($.length===0)return X;return{...X,previous_response_id:Y.continuation.responseID,input:$}}function EB(Y,X){let J=Array.isArray(X.input)?X.input:void 0;if(!Y.continuation)return!0;if(!J)return!1;if(!qW(Y.continuation.input,J))return!0;return J.slice(Y.continuation.input.length).some(OW)}function OW(Y){if(!C(Y))return!1;if(!(Y.type==="message"||("role"in Y)))return!1;return Y.role==="user"||Y.role==="developer"}function AB(Y,X){return Y.filter((J)=>{if(!C(J))return!0;if(typeof J.type==="string"&&J.type.endsWith("_output"))return!0;if(J.type==="function_call_output"||J.type==="custom_tool_call_output")return!0;if(J.type==="function_call"||J.type==="custom_tool_call"){let Q=typeof J.call_id==="string"?J.call_id:typeof J.id==="string"?J.id:void 0;return Q?!X.has(Q):!0}if(J.type==="message")return J.role!=="assistant";if(typeof J.role==="string")return J.role!=="assistant";return!1})}function t9(Y){return s0(TB(Object.fromEntries(Object.entries(Y).filter(([X])=>X!=="input"&&X!=="stream"&&X!=="background"&&X!=="previous_response_id"&&X!=="generate"))))}function TB(Y){if(!C(Y.client_metadata))return Y;let X=Object.fromEntries(Object.entries(Y.client_metadata).filter(([J])=>J!=="x-codex-turn-metadata"&&J!=="x-codex-ws-stream-request-start-ms"));return{...Y,client_metadata:X}}function qW(Y,X){if(Y.length>=X.length)return!1;for(let J=0;J<Y.length;J++)if(s0(Y[J])!==s0(X[J]))return!1;return!0}function FW(Y){if(!Y?.headers)return Y;if(Y.headers instanceof Headers){let X=new Headers(Y.headers);for(let J of r9)X.delete(J);return{...Y,headers:X}}if(Array.isArray(Y.headers))return{...Y,headers:Y.headers.filter((X)=>!r9.has(X[0].toLowerCase()))};return{...Y,headers:Object.fromEntries(Object.entries(Y.headers).filter(([X])=>!r9.has(X.toLowerCase())))}}var bB=new Set(["gpt-5.5","gpt-5.3-codex-spark","gpt-5.4","gpt-5.4-mini"]),xB=new Set(["gpt-5.6"]),vB=new Set(["gpt-5.6-sol","gpt-5.6-terra","gpt-5.6-luna"]),hB="opencode-oauth-dummy-key",gB="terminal_resize_reflow",JX="0.144.0",yB=`codex_exec/${JX} (Debian 12.0.0; aarch64) unknown (codex_exec; ${JX})`,fB="seccomp",mB="main-refresh",cB=120000,uB=90000,pB=4000,jW=50,DW=3,lB=25,dB=60000,iB="__OPENCODE_OPENAI_AUTH_COMMAND_HANDLED__",PW=!1,MW=L0("models"),wW=!1,EW=!1;class $X extends Error{code="OPENAI_AUTH_PERSIST_FAILED";constructor(Y){super("OpenAI OAuth token refreshed but could not be persisted; re-login required",{cause:Y});this.name="AuthPersistError"}}class c0 extends Error{code;constructor(Y,X){super(X);this.name="ResetTargetResolutionError",this.code=Y}}function AW(Y,X,J,Q){let $=(J?.refresh?.refreshBeforeExpiryMinutes??240)*60000;return!Y||!X||X-Q<=$}function nB(Y){return async(X)=>{if(X==="main"){let U=await Y.loadAccounts(Y.accountStoragePath),L=await Y.getAuth();if(L.type!=="oauth")throw new c0("non_oauth_account","Main OpenAI account is not authenticated with OAuth.");if(AW(L.access,L.expires,U,Y.now()))L={type:"oauth",...await Y.refreshMainWithLease()};if(!L.access)throw new c0("token_unavailable","Main OpenAI account has no usable access token.");let H=l1(L.access),N=H?d1(H):void 0,O=await Y.loadAccounts(Y.accountStoragePath);return{accountKey:X,label:"Main account",accessToken:L.access,chatgptAccountId:N??O?.mainAccountId}}let J=await Y.loadAccounts(Y.accountStoragePath),Q=J?.accounts.find((U)=>U.id===X);if(!J||!Q)throw new c0("unknown_account",`Fallback account ${X} was not found.`);if(Q.enabled===!1)throw new c0("disabled_account",`Fallback account ${X} is disabled.`);if(!u0(Q))throw new c0("non_oauth_account",`Fallback account ${X} is not an OAuth account.`);let $=Q;if(AW($.access,$.expires,J,Y.now()))$=await Y.refreshFallbackAccount($,J);if(!$.access)throw new c0("token_unavailable",`Fallback account ${X} has no usable access token.`);let G=await Y.loadAccounts(Y.accountStoragePath),W=G?.accounts.find((U)=>U.id===X);if(!G||!W)throw new c0("unknown_account",`Fallback account ${X} was not found.`);if(W.enabled===!1)throw new c0("disabled_account",`Fallback account ${X} is disabled.`);if(!u0(W))throw new c0("non_oauth_account",`Fallback account ${X} is not an OAuth account.`);return{accountKey:X,label:$.label??X,accessToken:$.access,chatgptAccountId:W.accountId}}}function oB(){return{fetchImpl:fetch,now:Date.now,randomUUID:()=>crypto.randomUUID()}}function YX(Y){return Y instanceof $X}function TW(){throw Error(iB)}function rB(Y){return Math.floor(Math.random()*Y)}function sB(Y){if(typeof Y!=="string")return;try{let X=JSON.parse(Y);return typeof X==="object"&&X!==null&&!Array.isArray(X)?X:void 0}catch{return}}function aB(Y,X,J){let Q=Y.get(X);if(Q)return Q;let $=P1(),G={threadID:$,turnID:P1(),windowID:`${$}:0`};return Y.set(X,G),J?.(),G}function W5(){return kB(CY(),"openai-auth-sessions.json")}function tB(){let Y=new Map;try{let X=JSON.parse(CB(W5(),"utf8"));if(!C(X.sessions))return Y;for(let[J,Q]of Object.entries(X.sessions)){if(!C(Q)||typeof Q.threadID!=="string")continue;Y.set(J,{threadID:Q.threadID,turnID:P1(),windowID:`${Q.threadID}:0`})}}catch{}return Y}function eB(Y){let X=W5(),J=`${X}.tmp-${process.pid}`;try{RB(CY(),{recursive:!0});let Q={version:1,sessions:Object.fromEntries([...Y.entries()].map(([$,G])=>[$,{threadID:G.threadID}]))};SB(J,`${JSON.stringify(Q,null,2)}
218
- `,"utf8"),_B(J,X)}catch{}}function RW(Y,X){return C(Y)&&(Y.type==="message"||("role"in Y))&&Y.role===X}function YZ(Y,X){if(Y.length>X.length)return!1;for(let J=0;J<Y.length;J++)if(s0(Y[J])!==s0(X[J]))return!1;return!0}function XZ(Y,X){if(!Y.input)return X.length>0;if(!YZ(Y.input,X))return!0;return X.slice(Y.input.length).some((Q)=>RW(Q,"user")||RW(Q,"developer"))}function JZ(Y,X){let J=Array.isArray(X?.input)?X.input:void 0;if(J&&(XZ(Y,J)||!Y.turnID))Y.turnID=P1(),Y.turnStartedAt=Date.now();else if(!Y.turnStartedAt)Y.turnStartedAt=Date.now();if(J)Y.input=J}function QZ(Y){if(!Y.metadata)return{init:Y.init};let X=sB(Y.init?.body);if(!Y.websocket)JZ(Y.metadata,X);else if(!Y.metadata.turnStartedAt)Y.metadata.turnStartedAt=Date.now();if(!Y.metadata.turnStartedAt)Y.metadata.turnStartedAt=Date.now();let J=JSON.stringify({session_id:Y.metadata.threadID,thread_id:Y.metadata.threadID,thread_source:"user",turn_id:Y.metadata.turnID,sandbox:fB,turn_started_at_unix_ms:Y.metadata.turnStartedAt,request_kind:"turn",window_id:Y.metadata.windowID});if(Y.headers.set("originator","codex_exec"),Y.websocket)Y.headers.delete("accept"),Y.headers.delete("content-type");else Y.headers.set("accept","text/event-stream");if(Y.headers.set("session-id",Y.metadata.threadID),Y.headers.delete("x-session-id"),Y.headers.delete("x-session-affinity"),Y.headers.set("thread-id",Y.metadata.threadID),Y.headers.set("x-codex-window-id",Y.metadata.windowID),Y.headers.set("x-client-request-id",Y.metadata.threadID),Y.headers.set("x-codex-beta-features",gB),Y.headers.set("x-codex-turn-metadata",J),Y.headers.set("user-agent",yB),Y.headers.set("version",JX),Y.dumpSessionID)Y.headers.set(G1,Y.dumpSessionID);let Q=X;if(!Q)return{init:Y.init};let $=Y.responsesLite&&typeof Q.model==="string"&&vB.has(Q.model);if($&&!Y.websocket)Y.headers.set("x-openai-internal-codex-responses-lite","true");if(Q.prompt_cache_key=Y.metadata.threadID,Q.parallel_tool_calls??=!0,Array.isArray(Q.tools))Q.tools=Q.tools.map(LZ);if(UZ(Q),HZ(Q),NJ(Q),WZ(Q),$)zZ(Q);let G={...typeof Q.client_metadata==="object"&&Q.client_metadata!==null?Q.client_metadata:{},"x-codex-installation-id":Y.installationID,"x-codex-window-id":Y.metadata.windowID};if(Y.websocket){if(G["x-codex-turn-metadata"]=J,G["x-codex-ws-stream-request-start-ms"]=String(Date.now()),$)G.ws_request_header_x_openai_internal_codex_responses_lite="true"}return Q.client_metadata=G,Y.headers.delete("content-length"),Y.headers.delete("Content-Length"),{init:{...Y.init,body:JSON.stringify(qY(Q))}}}function $Z(Y,X){return Y.find((J)=>J.enabled!==!1&&u0(J)&&(J.id===X||J.accountId===X))}function CW(Y,X){if(!X)return Y;let J={...Y};for(let Q of["resetCreditsAvailable","resetCreditsApplicable"]){let $=X[Q];if(J[Q]===void 0&&$!==void 0)J[Q]=$}return J}function L8(Y,X){if(!Y)return Y;if(typeof Y.checkedAt==="number"&&Number.isFinite(Y.checkedAt))return Y;return{...Y,checkedAt:X}}function z5(Y,X,J=Date.now(),Q=X.mainAccountId){let $=Y.getMain(),G=$?.quota;return{main:{quota:G?{...G,checkedAt:$.checkedAt,primary:L8(G.primary,$.checkedAt),secondary:L8(G.secondary,$.checkedAt)}:null,...typeof Q==="string"?{mainAccountId:Q}:{},killed:!1,...G?.resetCreditsAvailable!==void 0?{resetCredits:G.resetCreditsAvailable}:{}},fallbacks:X.accounts.filter((W)=>W.enabled).map((W)=>{let U=Y.getFallback(W.id),L=U?.quota;return{id:W.id,label:W.label,accountId:U?.accountId??W.accountId,quota:L?{...L,checkedAt:U.checkedAt,primary:L8(L.primary,U.checkedAt),secondary:L8(L.secondary,U.checkedAt)}:null,killed:!1,enabled:!0,...L?.resetCreditsAvailable!==void 0?{resetCredits:L.resetCreditsAvailable}:{}}}),route:X.routing?.mode??"main-first",lastUpdated:J}}function MF(Y,X,J,Q=Date.now()){return{...z5(Y,X,Q),activeId:J}}function _W(Y,X){if(X?.headers!==void 0)return new Headers(X.headers);if(Y instanceof Request)return new Headers(Y.headers);return new Headers}async function GZ(Y,X){if(!(Y instanceof Request))return X;let J=new Request(Y,X),Q=J.method.toUpperCase(),$=Q==="GET"||Q==="HEAD"||J.body===null?void 0:await J.text();return{method:J.method,headers:new Headers(J.headers),body:$,signal:J.signal,cache:J.cache,credentials:J.credentials,integrity:J.integrity,keepalive:J.keepalive,mode:J.mode,redirect:J.redirect,referrer:J.referrer,referrerPolicy:J.referrerPolicy}}function IW(Y){return Y.get("x-session-affinity")??Y.get("x-opencode-session")??Y.get("x-session-id")??Y.get("session-id")??void 0}function WZ(Y){if(!M0().webSearch)return;if(!Array.isArray(Y.tools)||Y.tools.length===0)return;if(Y.tools.some((X)=>C(X)&&X.type==="web_search"))return;Y.tools=[...Y.tools,{type:"web_search",external_web_access:!1,search_content_types:["text","image"]}]}function QX(Y){if(Array.isArray(Y)){for(let X of Y)QX(X);return}if(!C(Y))return;if(Y.type==="input_image")delete Y.detail;for(let X of Object.values(Y))QX(X)}function zZ(Y){let X=C(Y.reasoning)?{...Y.reasoning}:{};X.context="all_turns",Y.reasoning=X,Y.parallel_tool_calls=!1;let J=Array.isArray(Y.input)?Y.input:[];QX(J);let $=[{type:"additional_tools",role:"developer",tools:Array.isArray(Y.tools)?Y.tools.filter((G)=>!(C(G)&&G.type==="web_search")):[]}];if(typeof Y.instructions==="string"&&Y.instructions.length>0)$.push({type:"message",role:"developer",content:[{type:"input_text",text:Y.instructions}]});Y.input=[...$,...J],delete Y.tools,delete Y.instructions}function UZ(Y){if(!Array.isArray(Y.tools))return;Y.tools=Y.tools.filter((X)=>!(C(X)&&X.type==="function"&&X.name==="web_search"))}function HZ(Y){if(!Array.isArray(Y.tools))return;Y.tools=Y.tools.filter((X)=>!(C(X)&&X.type==="function"&&X.name==="websearch_web_search_exa"))}function LZ(Y){if(!C(Y))return Y;if(Y.type!=="function")return Y;let X=C(Y.parameters)&&"$schema"in Y.parameters?(()=>{let{$schema:L,...H}=Y.parameters;return H})():Y.parameters,{type:J,name:Q,description:$,strict:G,parameters:W,...U}=Y;return{type:J,name:Q,description:$,strict:G??!1,parameters:X,...U}}async function VZ(Y,X={}){let J=X.codexApiEndpoint??M0().codexApiEndpoint,Q=crypto.randomUUID(),$=tB(),G=()=>eB($),W=!1,U=[],L=null,H=null,N,O=new b8;async function Z(V,K){let j=Y.client.session;if(typeof j?.promptAsync==="function"){let M=await DJ(Y.client,V),I={noReply:!0,parts:[{type:"text",text:K,ignored:!0}]};if(M?.agent)I.agent=M.agent;if(M?.model)I.model=M.model;if(M?.variant)I.variant=M.variant;await j.promptAsync({path:{id:V},body:I});return}}return{async dispose(){O.stop();for(let V of U)V.close();if(U.length=0,H){await H.stop().catch(()=>{});let V=globalThis;if(V.__openaiAuthRpcServer===H)V.__openaiAuthRpcServer=void 0;H=null}},async event(V){if(V.event.type!=="session.deleted")return;let K=V.event.properties.info,j=$.get(K.id);if(j)L?.cacheKeepManager?.remove(j.threadID);if($.delete(K.id))G();if(N){let M=(await q0($0()))?.accounts;await J5(K.id,M,N)}for(let M of U)M.remove(K.id)},provider:{id:"openai",async models(V,K){if(K.auth?.type!=="oauth")return V.models;let j=await q0($0()),M=!j||iW(j),I=M?null:await OJ();if(!M&&I&&!wW)wW=!0,MW.debug("restoring OAuth model costs from models.dev catalog");if(!M&&!I&&!EW)EW=!0,MW.warn("models.dev catalog unavailable; OAuth model costs could not be restored");return Object.fromEntries(Object.entries(V.models).filter(([,E])=>{if(E.options.reasoningMode==="pro")return!1;if(bB.has(E.api.id))return!0;if(xB.has(E.api.id))return!1;let R=E.api.id.match(/^gpt-(\d+\.\d+)/)?.[1];return R?parseFloat(R)>5.4:!1}).map(([E,x])=>[E,{...x,cost:M?{input:0,output:0,cache:{read:0,write:0}}:I?.[x.api.id]??I?.[E]??x.cost,limit:x.id.includes("gpt-5.5")?{context:400000,input:272000,output:128000}:x.id.includes("gpt-5.6")?{context:372000,input:244000,output:128000}:x.limit}]))}},tool:{web_search:LJ},auth:{provider:"openai",async loader(V){let K=await V();if(K.type!=="oauth")return{};await oW({type:"oauth",access:K.access??"",refresh:K.refresh??"",expires:K.expires??0},$0());let j=await q0($0()).catch((B)=>{let q=$0();throw Error(`OpenAI auth store at ${q} is corrupt or unreadable: ${B instanceof Error?B.message:String(B)}. Fix or remove it to continue.`,{cause:B})}),M;async function I(){let B=$0();try{let q=IB(B);if(M?.path===B&&M.mtimeMs===q.mtimeMs&&M.size===q.size)return M.storage;let D=await q0(B);return M={path:B,mtimeMs:q.mtimeMs,size:q.size,storage:D},D}catch{return M=void 0,q0(B)}}function E(){M=void 0}if(j&&K.access){let B=V8({id_token:"",access_token:K.access,refresh_token:K.refresh??""});if(B&&B!==j.mainAccountId)await J0((q)=>{return q.mainAccountId=B,q},$0()),j.mainAccountId=B,E()}let x=j?.logging?.level;if(x&&typeof x==="string")kY(x);let R=L0("transport"),p=L0("quota"),m=L0("refresh"),d=L0("accounts");R.info("codex auth loader ready",{codexApiEndpoint:J,transport:M0().rawWebSocket?"raw-websocket":M0().webSockets?"websocket":"http",webSearch:M0().webSearch});let y=new dW({storage:j,fetchQuotaFn:void 0}),Y0,p0=0,c=new rW({refreshFn:(B)=>R1({refreshToken:B.refreshToken,fetchImpl:B.fetchImpl,now:B.now}),quotaManager:y,onFallbackStorageChanged:E});if(j&&j.accounts.length>0)c.startBackgroundRefresh();let X1=L0("cachekeep"),i1=j?.cachekeep?.enabled===!0,n1=j?.cachekeep?.subagents===!0,C1=j?.cachekeep?.sustain===!0,h=rX(j),r;async function B0(B){await new Promise((q)=>setTimeout(q,B))}async function B8(B){let q;for(let D=1;D<=DW;D++)try{await Y.client.auth.set({path:{id:"openai"},body:{type:"oauth",refresh:B.refresh,access:B.access,expires:B.expires}});return}catch(T){if(q=T,D<DW)await B0(lB*D)}throw new $X(q)}async function _1(B){await J0((q)=>{return q.refresh=q.refresh??{},B(q),q},$0()),E()}async function wY(B){let q=Date.now()+pB;while(Date.now()<q){await new Promise((k)=>setTimeout(k,jW+rB(jW)));let D=await V();if(D.type!=="oauth"||!D.access)continue;if((D.access!==B.access||D.refresh!==B.refresh||(D.expires??0)>(B.expires??0)+60000)&&(!D.expires||D.expires>Date.now()))return m.debug("joined concurrent main refresh",{pid:process.pid,expiresInMs:D.expires?D.expires-Date.now():void 0}),{access:D.access,refresh:D.refresh??B.refresh??"",expires:D.expires??0}}return null}async function l0(){if(!r)r=(async()=>{let B=await V();if(B.type!=="oauth")throw Error("not oauth");if(!B.refresh)throw Error("Token refresh failed: missing refresh token");let q=SW(B.refresh),D=await q0($0()),T=D?.refresh?.mainLastRefreshError;if(T&&bW(T,B.refresh,Date.now()))throw Error(xW(T,Date.now()));if(D?.refresh?.mainRefreshLeaseUntil&&D.refresh.mainRefreshLeaseUntil>Date.now()&&D.refresh.mainRefreshLeaseTokenHash===q){let S=await wY(B);if(S)return S;throw Error("Codex OAuth refresh is already in progress")}let k=await bY({name:mB,ttlMs:cB,path:$0(),renew:!0});if(!k){let S=await wY(B);if(S)return S;throw Error("Codex OAuth refresh is already in progress")}let _=crypto.randomUUID(),w=q;try{await _1((g)=>{g.refresh=g.refresh??{},g.refresh.mainRefreshLeaseId=_,g.refresh.mainRefreshLeaseUntil=Date.now()+uB,g.refresh.mainRefreshLeaseTokenHash=q});let S=await q0($0());if(S?.refresh?.mainRefreshLeaseId!==_||S.refresh.mainRefreshLeaseTokenHash!==q)throw Error("Codex OAuth refresh is already in progress");let P=await R1({refreshToken:B.refresh,fetchImpl:fetch,now:Date.now});return await B8(P),await _1((g)=>{if(g.refresh=g.refresh??{},g.refresh.mainLastRefreshError=void 0,g.refresh.mainRefreshLeaseId===_)g.refresh.mainRefreshLeaseId=void 0,g.refresh.mainRefreshLeaseUntil=void 0,g.refresh.mainRefreshLeaseTokenHash=void 0}).catch(()=>{}),w=void 0,P}catch(S){if(B.refresh&&!YX(S))await _1((P)=>{P.refresh=P.refresh??{},P.refresh.mainLastRefreshError=kW({error:S,now:Date.now(),refreshToken:B.refresh??"",previous:P.refresh.mainLastRefreshError})}).catch(()=>{});throw S}finally{if(w)await _1((S)=>{if(S.refresh?.mainRefreshLeaseId===_&&S.refresh.mainRefreshLeaseTokenHash===w)S.refresh.mainRefreshLeaseId=void 0,S.refresh.mainRefreshLeaseUntil=void 0,S.refresh.mainRefreshLeaseTokenHash=void 0}).catch(()=>{});await k.release().catch(()=>{})}})().finally(()=>{r=void 0});return r}let J1=globalThis;J1.__openaiAuthCacheKeepManager?.stop();let d0=new y8({fetchImpl:fetch,getMainToken:async()=>{let B=await V();if(B.type!=="oauth")throw Error("not oauth");if(!B.access||(B.expires??0)<Date.now())try{return(await l0()).access}catch(q){if(YX(q))throw q;if(B.access)return B.access;throw Error("main token refresh failed")}return B.access},refreshFallback:async(B)=>{let q=await I(),D=q?$Z(q.accounts,B):void 0;if(!D)throw Error(`fallback account ${B} not found`);let T=await c.refreshAccount(D,q??{version:1,accounts:[D]});if(!T.access)throw Error(`no access token for ${B}`);return T.access},codexResponsesUrl:J,logger:X1,now:Date.now,getWindow:()=>h,getSustain:()=>C1});J1.__openaiAuthCacheKeepManager=d0;async function K1(B,q,D,T,k=!1){if(Object.keys(B).length===0&&!k)return;let _=Date.now(),w=B,S={quota:w,refreshAfter:_+300000,checkedAt:_},P;if(D&&D!=="main"){let b=q?l1(q):null,X0=b?d1(b):void 0,Z0=y.peekFallbackForPolicy(D)?.quota,h0=CW(w,Z0);S={...S,quota:h0},y.setFallback(D,S,q,k,X0)}else{if(P=T,!P&&q){let Z0=l1(q);P=Z0?d1(Z0):void 0}if(P&&Y0&&P!==Y0){p.debug("stale main quota frame dropped",{pid:process.pid,frameAccountId:P,currentMainIdentity:Y0});return}let b=y.peekMainForPolicy(P)?.quota,X0=CW(w,b);S={...S,quota:X0},y.setMain(q,S,P,k)}p.debug("quota pushed",{pid:process.pid,accountId:D??"main",snapshot:S.quota});let g=await I();await x0(y,g,D&&D!=="main"?g?.mainAccountId:P)}function Z8(B,q,D){let T=B==="main"?y.peekMainForPolicy()?.quota:y.peekFallbackForPolicy(B)?.quota;return lW(T,q,Date.now(),dB,D)}let i0=X.experimentalWebSockets?Z1.createWebSocketFetch({httpFetch:fetch,rawWebSocket:M0().rawWebSocket,onQuota:(B,q,D,T)=>{K1(B,q,D,!D||D==="main"?T:void 0,!0)},onRateLimitReached:(B,q,D)=>{if(!q)p.warn("mid-stream rate-limit mark missing internal account id; defaulting to main",{pid:process.pid,window:B});let T=q??"main",k=Z8(T,B,D);y.markRateLimited(T,k),p.debug("mid-stream rate limit mark",{pid:process.pid,accountId:T,window:B})}}):void 0;if(i0)U.push(i0),W=!0;let F0=sW();N=F0;async function x0(B,q,D=q?.mainAccountId){if(!q)return;await Y5(z5(B,q,Date.now(),D),F0)}async function v0(B,q,D,T,k){let _={activeId:D,route:T,updatedAt:Date.now()};if(B){if(await N8({sessionId:B,..._},k,F0),q&&q!==B){if(T==="sticky-balanced"){let w=(await D1(F0)).stickyAssignments?.[MY(q)]?.accountId,S=k===void 0||w==="main"||k.some((P)=>P.enabled!==!1&&P.id===w);if(!w||!S)return;await N8({sessionId:q,activeId:w,route:T,updatedAt:Date.now()},k,F0);return}await N8({sessionId:q,..._},k,F0)}return}await X5(_,F0)}L={accountStoragePath:$0(),quotaManager:y,loadAccounts:q0,client:Y.client,resolveResetTarget:nB({getAuth:V,refreshMainWithLease:l0,refreshFallbackAccount:(B,q)=>c.refreshAccount(B,q),loadAccounts:q0,accountStoragePath:$0(),now:Date.now}),...oB(),cacheKeepManager:d0,setCacheKeepEnabled:(B)=>{i1=B},setCacheKeepSubagents:(B)=>{n1=B},setCacheKeepSustain:(B)=>{C1=B},setCacheKeepWindow:(B)=>{h=B},clearStickyRouting:(B)=>$5(B,F0),getStickyRouting:async(B)=>eW(await D1(F0),B),refreshSidebar:async()=>{let B=await q0($0());await x0(y,B)},refreshAllQuota:async()=>b1({getAuth:V,codexRefreshFn:R1,refreshMainWithLease:l0,fallbackManager:c,quotaManager:y,loadAccounts:q0,writeSidebarState:x0,client:Y.client,fetchImpl:fetch,now:Date.now,configPath:$0(),storageMainAccountId:j?.mainAccountId,isOAuthAccountFn:u0,whamFn:Q1}),refreshResetTargetQuota:async(B)=>{return(await b1({getAuth:V,codexRefreshFn:R1,refreshMainWithLease:l0,fallbackManager:c,quotaManager:y,loadAccounts:q0,writeSidebarState:x0,client:Y.client,fetchImpl:fetch,now:Date.now,configPath:$0(),storageMainAccountId:j?.mainAccountId,isOAuthAccountFn:u0,whamFn:Q1,respectBackoff:!1},{accountKey:B})).find((D)=>D.account===B)??{account:B,ok:!1,error:"targeted quota refresh returned no result"}}};let Q0=null;if(Y.directory){let B=await G5(Y.directory),q=globalThis;if(q.__openaiAuthRpcServer)await q.__openaiAuthRpcServer.stop().catch(()=>{}),q.__openaiAuthRpcServer=void 0;try{Q0=await RJ({dir:B.dir,secureDir:B.secureDir,sweepRoot:B.sweepRoot,drain:MJ,apply:async(D)=>{let T={...L,sessionId:D.sessionId},k=await k8(D.command,D.arguments,T);return{text:k.text,knobs:k.knobs}}}),q.__openaiAuthRpcServer=Q0,H=Q0}catch{}}async function T0(B,q,D,T,k="main"){let _=_W(B,q);if(_.delete("x-api-key"),_.delete("api-key"),_.set("authorization",`Bearer ${D}`),T)_.set("ChatGPT-Account-Id",T);_.set(Z1.QUOTA_ACCOUNT_HEADER,k);let w=IW(_),S=w?aB($,w,G):void 0,P=B instanceof URL?B:new URL(typeof B==="string"?B:B.url),g=P.pathname.includes("/v1/responses")||P.pathname.includes("/chat/completions")?new URL(J):P,X0=QZ({init:{...q,headers:_},headers:_,metadata:S,installationID:Q,websocket:Boolean(i0&&P.pathname.endsWith("/responses")),responsesLite:X.responsesLite??!1,dumpSessionID:w}).init,Z0=i1,h0=new Headers(X0?.headers),W0=oX({enabled:Z0,includeSubagents:n1,headers:h0,body:X0?.body});if(Z0)X1.trace("cachekeep headers",{pid:process.pid,hasParent:h0.has("x-parent-session-id"),sessionKey:W0?.sessionKey,captured:Boolean(W0),affinity:h0.get("x-session-affinity"),opencodeSession:h0.get("x-opencode-session"),sessionId:h0.get("session-id")});if(i0&&P.pathname.endsWith("/responses")){if(R.debug("WS transport",{pid:process.pid,pathname:P.pathname,accountId:k}),W0)d0.track(W0.sessionKey,W0.bodyText,k,T,W0.replayHeaders,W0.isSubagent);return i0(g,X0)}let N0=Z1.withoutInternalHeaders(X0);if(typeof N0?.body!=="string")return fetch(g,N0);if(W0)d0.track(W0.sessionKey,W0.bodyText,k,T,W0.replayHeaders,W0.isSubagent);R.debug("HTTP transport",{pid:process.pid,pathname:P.pathname,accountId:k});try{let C0=await fetch(g,N0);return await h1({sessionID:w,transport:"http",phase:"http",bodyText:N0.body,accountId:k,url:g.toString(),method:N0.method,headers:N0.headers,status:C0.status}),VJ(C0)}catch(C0){throw await h1({sessionID:w,transport:"http",phase:"http",bodyText:N0.body,accountId:k,url:g.toString(),method:N0.method,headers:N0.headers,error:C0 instanceof Error?C0.message:String(C0)}),C0}}function I1(B,q){if((q?.method??(B instanceof Request?B.method:"GET")).toUpperCase()!=="POST")return!1;if(typeof q?.body!=="string")return!1;try{let T=B instanceof URL?B.toString():typeof B==="string"?B:B.url;return new URL(T).pathname.endsWith("/responses")}catch{return!1}}function U5(B){return y.peekMainForPolicy(B)?.quota}function GX(B,q){for(let D of[B?.primary?.checkedAt,B?.secondary?.checkedAt,B?.checkedAt,q])if(typeof D==="number"&&Number.isFinite(D))return D;return}function o1(B,q,D,T,k){let _=GX(B,q),w=GX(D),S=T===k&&D!=null&&(B===void 0||w!==void 0&&(_===void 0||w>_));return{quota:S?D:B,quotaCheckedAt:S?w:_,source:S?"file":"memory"}}function WX(B,q,D,T,k){let _=B?.quota,w=o1(_,B?.checkedAt,q,T,k),S=w.source,P=w.quota;if(!tW(P,D))return{exhausted:!1};let g=aW(P,D);if(!g)return{exhausted:!1};return{exhausted:!0,source:S,...g}}function zX(B,q){p.debug("admission skip: exhausted account",{accountId:B,source:q.source,resetsAt:q.resetsAt})}function H5(B,q="killswitch",D){let T=Date.now(),k=y.getMain()?.quota,_=(B?.accounts??[]).filter((b)=>b.enabled!==!1&&u0(b)).map((b)=>({accountId:b.id,quota:y.getFallback(b.id)?.quota})),w=nW(k,_,T,B);if(q==="quota-exhausted"&&D!==void 0)w=Math.max(1,Math.ceil((D-T)/1000));else if(q==="mid-stream-rate-limit"&&D!==void 0){let b=Math.max(1,Math.ceil((D-T)/1000));w=Math.min(w,b)}let S=Math.floor(w/60),P=w%60,g=q==="mid-stream-rate-limit"?`OpenAI rate limit reached — retrying on another account. Retry in ${S}m ${P}s.`:q==="quota-exhausted"?`OpenAI quota exhausted — retrying on another account. Retry in ${S}m ${P}s.`:`Killswitch: all OpenAI accounts are below their configured quota threshold. Retry in ${S}m ${P}s.`;return new Response(JSON.stringify({error:{message:g,type:"rate_limit_exceeded",code:"rate_limit_exceeded"}}),{status:429,headers:{"content-type":"application/json","retry-after":String(w)}})}function UX(B){let q=B?.resetCreditsAvailable;return typeof q==="number"&&Number.isFinite(q)?q:void 0}async function L5(B){let q=DY(B.storage),D=Date.now(),T=y.peekMainForPolicy(B.mainAccountIdentity),k=o1(T?.quota,T?.checkedAt,B.sidebarState.main.quota,B.sidebarState.main.mainAccountId,B.mainAccountIdentity),_=q?PY(T?.quota,B.storage,void 0,D):void 0,w=[{accountId:"main",wireAccountId:B.mainAccountIdentity,access:B.primaryAccess,keepwarmAccountKey:"main",quota:k.quota,quotaCheckedAt:k.quotaCheckedAt,reservePercent:XX(B.storage),configuredOrder:0,resetCreditsApplicable:UX(k.quota),killswitchPasses:_}],S=await c.getUsableFallbackAccounts(B.storage);for(let P of S){if(!P.access)continue;let g=B.sidebarState.fallbacks.find((h0)=>h0.id===P.id),b=y.peekFallbackForPolicy(P.id,P.accountId),X0=o1(b?.quota,b?.checkedAt,g?.quota,g?.accountId,P.accountId),Z0=q?PY(b?.quota,B.storage,P.id,D):void 0;w.push({accountId:P.id,wireAccountId:P.accountId,access:P.access,keepwarmAccountKey:P.id,fallback:P,quota:X0.quota,quotaCheckedAt:X0.quotaCheckedAt,reservePercent:XX(B.storage,P.id),configuredOrder:w.length,resetCreditsApplicable:UX(X0.quota),killswitchPasses:Z0})}return w}function HX(B,q,D,T,k){let _=DY(k)?B.killswitchPasses:void 0;if(B.accountId==="main"){let g=y.peekMainForPolicy(B.wireAccountId),b=o1(g?.quota,g?.checkedAt,q.main.quota,q.main.mainAccountId,B.wireAccountId);return c8({quota:b.quota,quotaCheckedAt:b.quotaCheckedAt,status:D,now:T,killswitchPasses:_})}let w=q.fallbacks.find((g)=>g.id===B.accountId),S=y.peekFallbackForPolicy(B.accountId,B.wireAccountId),P=o1(S?.quota,S?.checkedAt,w?.quota,w?.accountId,B.wireAccountId);return c8({quota:P.quota,quotaCheckedAt:P.quotaCheckedAt,status:D,now:T,killswitchPasses:_})}function V5(B){return B.accountId==="main"?"main":B.keepwarmAccountKey}function LX(B){return y.isRateLimited(V5(B))}async function K8(B){let q=B.candidates.filter((P)=>!LX(P)),D=new Map(q.map((P)=>[P.accountId,P])),T=Object.fromEntries(q.map((P)=>[P.accountId,P.quotaCheckedAt])),k=Object.fromEntries(q.map((P)=>[P.accountId,P.wireAccountId])),_=new Set(B.excludeAccountIds),w,S=await Q5({sessionId:B.sessionId,requestBytes:B.requestBytes,now:B.now,validPinnedAccountIds:[...D.keys()],excludeAccountIds:B.excludeAccountIds,quotaCheckedAtByAccount:T,wireAccountIdByAccount:k,choose:(P)=>{let g=q.filter((X0)=>!_.has(X0.accountId));if(g.length===0)return;let b=JJ({candidates:g,pendingBytes:P,requestBytes:B.requestBytes,now:B.now,onEmptyWeightedSet:()=>{d.debug("sticky routing: no fresh weighted candidates; using configured order")}});if(!b)return;return w={accountId:b.accountId,source:b.source,pendingBytes:P.get(b.accountId)??0},b}},F0);if(w&&S?.accountId===w.accountId)d.debug("sticky routing: placed session pin",{pid:process.pid,sessionHash:MY(B.sessionId),accountId:w.accountId,source:w.source,requestBytes:B.requestBytes,pendingBytes:w.pendingBytes});return S?D.get(S.accountId):void 0}async function N5(B,q){let D=await c.getUsableFallbackAccounts(B),T=[];for(let b of D)if(b.access)T.push({access:b.access,accountId:b.accountId,keepwarmAccountKey:b.id,quotaAccountId:b.id,fallback:b});let k=T.filter((b)=>!y.isRateLimited(b.quotaAccountId)),_=DY(B)?k.filter((b)=>PY(y.peekFallbackForPolicy(b.quotaAccountId,b.accountId)?.quota,B,b.quotaAccountId,Date.now())):k,w=new Map(q.fallbacks.map((b)=>[b.id,{quota:b.quota,accountId:b.accountId}])),S=[],P=[],g=Date.now();for(let b of _){let X0=w.get(b.quotaAccountId),Z0=WX(y.peekFallbackForPolicy(b.quotaAccountId,b.accountId),X0?.quota,g,X0?.accountId,b.accountId);if(Z0.exhausted)P.push({candidate:b,decision:Z0});else S.push(b)}return{current:_,retained:S,skipped:P}}function VX(B,q){if(B.retained.length===0&&!q)return B.current;for(let{candidate:D,decision:T}of B.skipped)zX(D.quotaAccountId,T);return B.retained}async function NX(B,q){try{let D=x1(B.headers);await K1(D,q.access,q.quotaAccountId,void 0,FY(B.headers))}catch{}}async function B5(B,q,D,T){for(let k of T){let _;try{_=await T0(B,q,k.access,k.accountId,k.keepwarmAccountKey)}catch(w){if(w instanceof DOMException&&w.name==="AbortError")throw w;if(q?.signal?.aborted)throw w;throw d.debug("fallback-first transport failed; request not replayed",{pid:process.pid,accountId:k.quotaAccountId}),w}if(!jY(_.status,D))return await c.markUsed(k.fallback),{response:_,accessToken:k.access,quotaAccountId:k.quotaAccountId,activeId:k.keepwarmAccountKey};await NX(_,k),_.body?.cancel().catch(()=>{})}return}async function Z5(B,q,D,T,k){if(!I1(B,q))return{response:D};if(!k.length)return{response:D};let _=D,w;for(let S of k){let P;try{P=await T0(B,q,S.access,S.accountId,S.keepwarmAccountKey)}catch(g){if(g instanceof DOMException&&g.name==="AbortError")throw g;if(q?.signal?.aborted)throw g;return d.debug("reactive fallback candidate threw; stopping",{pid:process.pid,accountId:S.quotaAccountId}),{response:_,...w}}if(_.body?.cancel().catch(()=>{}),_=P,w={accessToken:S.access,accountId:S.quotaAccountId},!jY(P.status,T))return await c.markUsed(S.fallback),{response:P,...w};await NX(P,S)}return{response:_,...w}}if(!PW){if(PW=!0,j){let B=[];for(let q of j.accounts)if(u0(q))B.push(q);y.seedFallbacksFromAccounts(B)}x0(y,j).catch(()=>{}),b1({getAuth:V,codexRefreshFn:R1,refreshMainWithLease:l0,fallbackManager:c,quotaManager:y,loadAccounts:q0,writeSidebarState:x0,client:Y.client,fetchImpl:fetch,now:Date.now,configPath:$0(),storageMainAccountId:j?.mainAccountId,isOAuthAccountFn:u0,whamFn:Q1,respectBackoff:!0}).catch((B)=>p.warn("boot quota seed failed",{pid:process.pid,error:$1(B)}))}return O.start(async()=>{let q=(await pX({getAuth:V,codexRefreshFn:R1,refreshMainWithLease:l0,fallbackManager:c,quotaManager:y,loadAccounts:q0,writeSidebarState:(D,T)=>O.isStopped()?Promise.resolve():x0(D,T),client:Y.client,fetchImpl:fetch,now:Date.now,configPath:$0(),storageMainAccountId:j?.mainAccountId,isOAuthAccountFn:u0,whamFn:Q1,readSidebarState:()=>D1(F0)})).filter((D)=>!D.ok);if(q.length>0)p.warn("background quota refresh completed with failures",{pid:process.pid,failures:q})},(B)=>{p.warn("background quota refresh failed",{pid:process.pid,error:B instanceof Error?B.message:String(B)})}),{apiKey:hB,async fetch(B,q){let D=_W(B,q),T=IW(D),k=D.get("x-parent-session-id")?.trim()||void 0,_=await I(),w=await V(),S=++p0;if(w.type!=="oauth")return fetch(B,q);q=await GZ(B,q);let P=w.access??"";if(!w.access||(w.expires??0)<Date.now()){m.debug("token refresh triggered",{pid:process.pid,hasAccess:Boolean(w.access),expiresInMs:w.expires?w.expires-Date.now():void 0});try{let e=await l0();w.access=e.access,w.refresh=e.refresh,w.expires=e.expires}catch(e){if(YX(e))throw e}}P=w.access??"";let b=w.accountId??(P?d1(l1(P)??{}):void 0);if(S===p0)Y0=b;let X0=_?.routing?.mode??"main-first",Z0,W0=await(()=>{return Z0??=D1(F0),Z0})();if(X0==="sticky-balanced"&&T&&I1(B,q)&&typeof q?.body==="string"){let e=Buffer.byteLength(q.body,"utf8"),H0=await L5({storage:_,sidebarState:W0,primaryAccess:P,mainAccountIdentity:b}),U0=await K8({sessionId:T,requestBytes:e,candidates:H0,now:Date.now()});if(U0){let jX=LX(U0)?{action:"migrate",reason:"exhausted"}:HX(U0,W0,void 0,Date.now(),_);if(jX.action==="migrate"){let P0=await K8({sessionId:T,requestBytes:e,candidates:H0,excludeAccountIds:[U0.accountId],now:Date.now()});if(P0)d.debug("sticky routing: migrated session pin",{pid:process.pid,sessionHash:MY(T),fromAccountId:U0.accountId,toAccountId:P0.accountId,reason:jX.reason}),U0=P0}let g0=await T0(B,q,U0.access,U0.wireAccountId,U0.keepwarmAccountKey),DX=async(P0,O1)=>{try{let K5=x1(P0.headers);await K1(K5,O1.access,O1.accountId==="main"?void 0:O1.accountId,O1.accountId==="main"?O1.wireAccountId:void 0,FY(P0.headers))}catch{}};await DX(g0,U0);let PX=HX(U0,W0,g0.status,Date.now(),_);if((g0.status===401||g0.status===403||g0.status===429)&&PX.action==="migrate"){let P0=await K8({sessionId:T,requestBytes:e,candidates:H0,excludeAccountIds:[U0.accountId],now:Date.now()});if(P0){d.debug("sticky routing: migrated session pin",{pid:process.pid,sessionHash:MY(T),fromAccountId:U0.accountId,toAccountId:P0.accountId,reason:PX.reason});let O1=g0;g0=await T0(B,q,P0.access,P0.wireAccountId,P0.keepwarmAccountKey),O1.body?.cancel().catch(()=>{}),U0=P0,await DX(g0,U0)}}if(U0.fallback&&!jY(g0.status,_))await c.markUsed(U0.fallback);return await v0(T,k,U0.accountId,X0,_?.accounts).catch(()=>{}),g0}}let N0=WX(y.peekMainForPolicy(b),W0.main.quota,Date.now(),W0.main.mainAccountId,b),C0=DY(_)&&!PY(U5(b),_,void 0,Date.now()),EY=y.isRateLimited("main"),BX,O8=()=>{return BX??=N5(_,W0),BX},n0,S1,ZX=!1,AY;if(X0==="fallback-first"&&I1(B,q)){ZX=!0;let e=await O8();AY=VX(e,!C0&&!EY&&!N0.exhausted);let H0=await B5(B,q,_,AY);if(H0)n0=H0.response,S1={accessToken:H0.accessToken,accountId:H0.quotaAccountId,activeId:H0.activeId}}if(!n0){let e=N0.exhausted&&I1(B,q)&&(await O8()).retained.length>0;if(C0||EY||e){let H0=C0?"killswitch":EY?"mid-stream-rate-limit":"quota-exhausted";if(H0==="quota-exhausted"&&N0.exhausted)zX("main",N0);d.debug("admission blocked primary",{pid:process.pid,activeId:"main",reason:H0}),n0=H5(_,H0,H0==="quota-exhausted"&&N0.exhausted?N0.resetAtMs:EY?y.rateLimitedUntil("main"):void 0)}else n0=await T0(B,q,P,b,"main")}let KX=Boolean(S1),r1=n0,OX=S1?.accessToken??P,qX=S1?.accountId,FX=S1?.activeId??"main";if(!S1&&!ZX&&jY(n0.status,_)){d.debug("reactive fallback triggered",{pid:process.pid,status:n0.status}),AY??=VX(await O8(),!1);let e=await Z5(B,q,n0,_,AY),H0=e.response;if(H0!==n0){if(KX=!0,r1=H0,OX=e.accessToken??P,qX=e.accountId,e.accountId)FX=e.accountId}}try{let e=x1(r1.headers);if(KX)await K1(e,OX,qX,void 0,FY(r1.headers));else await K1(e,P,void 0,b,FY(r1.headers))}catch{}return await v0(T,k,FX,X0,_?.accounts).catch(()=>{}),r1},async dispose(){if(O.stop(),d0.stop(),J1.__openaiAuthCacheKeepManager===d0)J1.__openaiAuthCacheKeepManager=void 0;if(c.stopBackgroundRefresh(),H){await H.stop().catch(()=>{});let B=globalThis;if(B.__openaiAuthRpcServer===H)B.__openaiAuthRpcServer=void 0;H=null}}}},methods:[{label:"ChatGPT Pro/Plus (browser)",type:"oauth",authorize:async()=>{let{redirectUri:V}=await mW(),K=await gW(),j=hW(crypto.getRandomValues(new Uint8Array(32)).buffer),M=yW(V,K,j),I=cW(K,j);return{url:M,instructions:"Complete authorization in your browser. This window will close automatically.",method:"auto",callback:async()=>{try{let E=await I,x=V8(E);return{type:"success",refresh:E.refresh_token,access:E.access_token,expires:Date.now()+(E.expires_in??3600)*1000,accountId:x}}finally{fW(j)}}}}},{label:"ChatGPT Pro/Plus (headless)",type:"oauth",authorize:async()=>{let{deviceData:V,url:K,instructions:j}=await uW();return{url:K,instructions:j,method:"auto",async callback(){try{let M=await pW(V);return{type:"success",refresh:M.refresh_token,access:M.access_token,expires:Date.now()+(M.expires_in??3600)*1000,accountId:V8(M)}}catch{return{type:"failed"}}}}}},{label:"Manually enter API Key",type:"api"}]},"chat.headers":async(V,K)=>{if(V.model.providerID!=="openai")return;if(K.headers.originator="opencode",K.headers["User-Agent"]=`${vW} (${e9.platform()} ${e9.release()}; ${e9.arch()})`,K.headers["session-id"]=V.sessionID,W&&V.agent==="title")K.headers[Z1.TITLE_HEADER]="true"},"chat.params":async(V,K)=>{if(V.model.providerID!=="openai")return;K.maxOutputTokens=void 0},config:async(V)=>{V.command={...V.command??{},[A8]:{template:A8,description:"Show current OpenAI Codex OAuth quota usage for all accounts."},[T8]:{template:T8,description:"Manage OpenAI accounts — add, switch, remove, or reorder."},[R8]:{template:R8,description:"Show or change OpenAI account routing between main-first, fallback-first, and sticky-balanced."},[C8]:{template:C8,description:"Manage killswitch — hard-block requests when quota drops below per-account thresholds."},[_8]:{template:_8,description:"Show or toggle OpenAI Codex request dump capture for debugging."},[I8]:{template:I8,description:"Show or change the plugin log level (error, warn, info, debug, trace)."},[S8]:{template:S8,description:"Keep Codex prompt cache alive during idle by shadow-replaying the last request."},[j1]:{template:j1,description:"Spend one reset credit on an exhausted Codex account."}}},"command.execute.before":async(V)=>{if(!cX.includes(V.command))return;if(!L)await Z(V.sessionID,"OpenAI auth plugin is still initializing. Send a request first, then try again."),TW();let K=V.command,j={...L,sessionId:V.sessionID,notify:(I)=>{a8(I,V.sessionID)}},M=await k8(K,V.arguments,j);if(wJ(V.sessionID))a8(M,V.sessionID);else await Z(V.sessionID,M.text);TW()}}}var NZ=async(Y)=>{let X=M0();return VZ(Y,{codexApiEndpoint:X.codexApiEndpoint,experimentalWebSockets:X.webSockets,responsesLite:X.responsesLite})},wF={id:"cortexkit-openai-auth",server:NZ};export{IW as resolveSidebarSessionId,l1 as parseJwtClaims,CW as mergePushedQuotaMetadata,$Z as findCachekeepFallbackAccount,d1 as extractAccountIdFromClaims,wF as default,nB as createResetTargetResolver,MF as buildSidebarState,z5 as buildSidebarMachineState,oB as buildResetRedemptionDeps,c0 as ResetTargetResolutionError,NZ as OpenAIAuthPlugin,cB as MAIN_REFRESH_LOCK_TTL_MS,uB as MAIN_REFRESH_LEASE_TTL_MS,VZ as CodexAuthPlugin,$X as AuthPersistError};
218
+ `,"utf8"),_B(J,X)}catch{}}function RW(Y,X){return C(Y)&&(Y.type==="message"||("role"in Y))&&Y.role===X}function YZ(Y,X){if(Y.length>X.length)return!1;for(let J=0;J<Y.length;J++)if(s0(Y[J])!==s0(X[J]))return!1;return!0}function XZ(Y,X){if(!Y.input)return X.length>0;if(!YZ(Y.input,X))return!0;return X.slice(Y.input.length).some((Q)=>RW(Q,"user")||RW(Q,"developer"))}function JZ(Y,X){let J=Array.isArray(X?.input)?X.input:void 0;if(J&&(XZ(Y,J)||!Y.turnID))Y.turnID=P1(),Y.turnStartedAt=Date.now();else if(!Y.turnStartedAt)Y.turnStartedAt=Date.now();if(J)Y.input=J}function QZ(Y){if(!Y.metadata)return{init:Y.init};let X=sB(Y.init?.body);if(!Y.websocket)JZ(Y.metadata,X);else if(!Y.metadata.turnStartedAt)Y.metadata.turnStartedAt=Date.now();if(!Y.metadata.turnStartedAt)Y.metadata.turnStartedAt=Date.now();let J=JSON.stringify({session_id:Y.metadata.threadID,thread_id:Y.metadata.threadID,thread_source:"user",turn_id:Y.metadata.turnID,sandbox:fB,turn_started_at_unix_ms:Y.metadata.turnStartedAt,request_kind:"turn",window_id:Y.metadata.windowID});if(Y.headers.set("originator","codex_exec"),Y.websocket)Y.headers.delete("accept"),Y.headers.delete("content-type");else Y.headers.set("accept","text/event-stream");if(Y.headers.set("session-id",Y.metadata.threadID),Y.headers.delete("x-session-id"),Y.headers.delete("x-session-affinity"),Y.headers.set("thread-id",Y.metadata.threadID),Y.headers.set("x-codex-window-id",Y.metadata.windowID),Y.headers.set("x-client-request-id",Y.metadata.threadID),Y.headers.set("x-codex-beta-features",gB),Y.headers.set("x-codex-turn-metadata",J),Y.headers.set("user-agent",yB),Y.headers.set("version",JX),Y.dumpSessionID)Y.headers.set(G1,Y.dumpSessionID);let Q=X;if(!Q)return{init:Y.init};let $=Y.responsesLite&&typeof Q.model==="string"&&vB.has(Q.model);if($&&!Y.websocket)Y.headers.set("x-openai-internal-codex-responses-lite","true");if(Q.prompt_cache_key=Y.metadata.threadID,Q.parallel_tool_calls??=!0,Array.isArray(Q.tools))Q.tools=Q.tools.map(LZ);if(UZ(Q),HZ(Q),NJ(Q),WZ(Q),$)zZ(Q);let G={...typeof Q.client_metadata==="object"&&Q.client_metadata!==null?Q.client_metadata:{},"x-codex-installation-id":Y.installationID,"x-codex-window-id":Y.metadata.windowID};if(Y.websocket){if(G["x-codex-turn-metadata"]=J,G["x-codex-ws-stream-request-start-ms"]=String(Date.now()),$)G.ws_request_header_x_openai_internal_codex_responses_lite="true"}return Q.client_metadata=G,Y.headers.delete("content-length"),Y.headers.delete("Content-Length"),{init:{...Y.init,body:JSON.stringify(qY(Q))}}}function $Z(Y,X){return Y.find((J)=>J.enabled!==!1&&u0(J)&&(J.id===X||J.accountId===X))}function CW(Y,X){if(!X)return Y;let J={...Y};for(let Q of["resetCreditsAvailable","resetCreditsApplicable"]){let $=X[Q];if(J[Q]===void 0&&$!==void 0)J[Q]=$}return J}function L8(Y,X){if(!Y)return Y;if(typeof Y.checkedAt==="number"&&Number.isFinite(Y.checkedAt))return Y;return{...Y,checkedAt:X}}function z5(Y,X,J=Date.now(),Q=X.mainAccountId){let $=Y.getMain(),G=$?.quota;return{main:{quota:G?{...G,checkedAt:$.checkedAt,primary:L8(G.primary,$.checkedAt),secondary:L8(G.secondary,$.checkedAt)}:null,...typeof Q==="string"?{mainAccountId:Q}:{},killed:!1,...G?.resetCreditsAvailable!==void 0?{resetCredits:G.resetCreditsAvailable}:{}},fallbacks:X.accounts.filter((W)=>W.enabled).map((W)=>{let U=Y.getFallback(W.id),L=U?.quota;return{id:W.id,label:W.label,accountId:U?.accountId??W.accountId,quota:L?{...L,checkedAt:U.checkedAt,primary:L8(L.primary,U.checkedAt),secondary:L8(L.secondary,U.checkedAt)}:null,killed:!1,enabled:!0,...L?.resetCreditsAvailable!==void 0?{resetCredits:L.resetCreditsAvailable}:{}}}),route:X.routing?.mode??"main-first",lastUpdated:J}}function MF(Y,X,J,Q=Date.now()){return{...z5(Y,X,Q),activeId:J}}function _W(Y,X){if(X?.headers!==void 0)return new Headers(X.headers);if(Y instanceof Request)return new Headers(Y.headers);return new Headers}async function GZ(Y,X){if(!(Y instanceof Request))return X;let J=new Request(Y,X),Q=J.method.toUpperCase(),$=Q==="GET"||Q==="HEAD"||J.body===null?void 0:await J.text();return{method:J.method,headers:new Headers(J.headers),body:$,signal:J.signal,cache:J.cache,credentials:J.credentials,integrity:J.integrity,keepalive:J.keepalive,mode:J.mode,redirect:J.redirect,referrer:J.referrer,referrerPolicy:J.referrerPolicy}}function IW(Y){return Y.get("x-session-affinity")??Y.get("x-opencode-session")??Y.get("x-session-id")??Y.get("session-id")??void 0}function WZ(Y){if(!M0().webSearch)return;if(!Array.isArray(Y.tools)||Y.tools.length===0)return;if(Y.tools.some((X)=>C(X)&&X.type==="web_search"))return;Y.tools=[...Y.tools,{type:"web_search",external_web_access:!1,search_content_types:["text","image"]}]}function QX(Y){if(Array.isArray(Y)){for(let X of Y)QX(X);return}if(!C(Y))return;if(Y.type==="input_image")delete Y.detail;for(let X of Object.values(Y))QX(X)}function zZ(Y){let X=C(Y.reasoning)?{...Y.reasoning}:{};X.context="all_turns",Y.reasoning=X,Y.parallel_tool_calls=!1;let J=Array.isArray(Y.input)?Y.input:[];QX(J);let $=[{type:"additional_tools",role:"developer",tools:Array.isArray(Y.tools)?Y.tools.filter((G)=>!(C(G)&&G.type==="web_search")):[]}];if(typeof Y.instructions==="string"&&Y.instructions.length>0)$.push({type:"message",role:"developer",content:[{type:"input_text",text:Y.instructions}]});Y.input=[...$,...J],delete Y.tools,delete Y.instructions}function UZ(Y){if(!Array.isArray(Y.tools))return;Y.tools=Y.tools.filter((X)=>!(C(X)&&X.type==="function"&&X.name==="web_search"))}function HZ(Y){if(!Array.isArray(Y.tools))return;Y.tools=Y.tools.filter((X)=>!(C(X)&&X.type==="function"&&X.name==="websearch_web_search_exa"))}function LZ(Y){if(!C(Y))return Y;if(Y.type!=="function")return Y;let X=C(Y.parameters)&&"$schema"in Y.parameters?(()=>{let{$schema:L,...H}=Y.parameters;return H})():Y.parameters,{type:J,name:Q,description:$,strict:G,parameters:W,...U}=Y;return{type:J,name:Q,description:$,strict:G??!1,parameters:X,...U}}async function VZ(Y,X={}){let J=X.codexApiEndpoint??M0().codexApiEndpoint,Q=crypto.randomUUID(),$=tB(),G=()=>eB($),W=!1,U=[],L=null,H=null,N,O=new b8;async function Z(V,K){let j=Y.client.session;if(typeof j?.promptAsync==="function"){let M=await DJ(Y.client,V),I={noReply:!0,parts:[{type:"text",text:K,ignored:!0}]};if(M?.agent)I.agent=M.agent;if(M?.model)I.model=M.model;if(M?.variant)I.variant=M.variant;await j.promptAsync({path:{id:V},body:I});return}}return{async dispose(){O.stop();for(let V of U)V.close();if(U.length=0,H){await H.stop().catch(()=>{});let V=globalThis;if(V.__openaiAuthRpcServer===H)V.__openaiAuthRpcServer=void 0;H=null}},async event(V){if(V.event.type!=="session.deleted")return;let K=V.event.properties.info,j=$.get(K.id);if(j)L?.cacheKeepManager?.remove(j.threadID);if($.delete(K.id))G();if(N){let M=(await q0($0()))?.accounts;await J5(K.id,M,N)}for(let M of U)M.remove(K.id)},provider:{id:"openai",async models(V,K){if(K.auth?.type!=="oauth")return V.models;let j=await q0($0()),M=!j||iW(j),I=M?null:await OJ();if(!M&&I&&!wW)wW=!0,MW.debug("restoring OAuth model costs from models.dev catalog");if(!M&&!I&&!EW)EW=!0,MW.warn("models.dev catalog unavailable; OAuth model costs could not be restored");return Object.fromEntries(Object.entries(V.models).filter(([,E])=>{if(E.options.reasoningMode==="pro")return!1;if(bB.has(E.api.id))return!0;if(xB.has(E.api.id))return!1;let R=E.api.id.match(/^gpt-(\d+\.\d+)/)?.[1];return R?parseFloat(R)>5.4:!1}).map(([E,x])=>[E,{...x,cost:M?{input:0,output:0,cache:{read:0,write:0}}:I?.[x.api.id]??I?.[E]??x.cost,limit:x.id.includes("gpt-5.5")?{context:400000,input:272000,output:128000}:x.id.includes("gpt-5.6")?{context:372000,input:244000,output:128000}:x.limit}]))}},tool:{web_search:LJ},auth:{provider:"openai",async loader(V){let K=await V();if(K.type!=="oauth")return{};await oW({type:"oauth",access:K.access??"",refresh:K.refresh??"",expires:K.expires??0},$0());let j=await q0($0()).catch((B)=>{let q=$0();throw Error(`OpenAI auth store at ${q} is corrupt or unreadable: ${B instanceof Error?B.message:String(B)}. Fix or remove it to continue.`,{cause:B})}),M;async function I(){let B=$0();try{let q=IB(B);if(M?.path===B&&M.mtimeMs===q.mtimeMs&&M.size===q.size)return M.storage;let D=await q0(B);return M={path:B,mtimeMs:q.mtimeMs,size:q.size,storage:D},D}catch{return M=void 0,q0(B)}}function E(){M=void 0}if(j&&K.access){let B=V8({id_token:"",access_token:K.access,refresh_token:K.refresh??""});if(B&&B!==j.mainAccountId)await J0((q)=>{return q.mainAccountId=B,q},$0()),j.mainAccountId=B,E()}let x=j?.logging?.level;if(x&&typeof x==="string")kY(x);let R=L0("transport"),p=L0("quota"),m=L0("refresh"),d=L0("accounts");R.info("codex auth loader ready",{codexApiEndpoint:J,transport:M0().rawWebSocket?"raw-websocket":M0().webSockets?"websocket":"http",webSearch:M0().webSearch});let y=new dW({storage:j,fetchQuotaFn:void 0}),Y0,p0=0,c=new rW({refreshFn:(B)=>R1({refreshToken:B.refreshToken,fetchImpl:B.fetchImpl,now:B.now}),quotaManager:y,onFallbackStorageChanged:E});if(j&&j.accounts.length>0)c.startBackgroundRefresh();let X1=L0("cachekeep"),i1=j?.cachekeep?.enabled===!0,n1=j?.cachekeep?.subagents===!0,C1=j?.cachekeep?.sustain===!0,h=rX(j),r;async function B0(B){await new Promise((q)=>setTimeout(q,B))}async function B8(B){let q;for(let D=1;D<=DW;D++)try{await Y.client.auth.set({path:{id:"openai"},body:{type:"oauth",refresh:B.refresh,access:B.access,expires:B.expires}});return}catch(T){if(q=T,D<DW)await B0(lB*D)}throw new $X(q)}async function _1(B){await J0((q)=>{return q.refresh=q.refresh??{},B(q),q},$0()),E()}async function wY(B){let q=Date.now()+pB;while(Date.now()<q){await new Promise((k)=>setTimeout(k,jW+rB(jW)));let D=await V();if(D.type!=="oauth"||!D.access)continue;if((D.access!==B.access||D.refresh!==B.refresh||(D.expires??0)>(B.expires??0)+60000)&&(!D.expires||D.expires>Date.now()))return m.debug("joined concurrent main refresh",{pid:process.pid,expiresInMs:D.expires?D.expires-Date.now():void 0}),{access:D.access,refresh:D.refresh??B.refresh??"",expires:D.expires??0}}return null}async function l0(){if(!r)r=(async()=>{let B=await V();if(B.type!=="oauth")throw Error("not oauth");if(!B.refresh)throw Error("Token refresh failed: missing refresh token");let q=SW(B.refresh),D=await q0($0()),T=D?.refresh?.mainLastRefreshError;if(T&&bW(T,B.refresh,Date.now()))throw Error(xW(T,Date.now()));if(D?.refresh?.mainRefreshLeaseUntil&&D.refresh.mainRefreshLeaseUntil>Date.now()&&D.refresh.mainRefreshLeaseTokenHash===q){let S=await wY(B);if(S)return S;throw Error("Codex OAuth refresh is already in progress")}let k=await bY({name:mB,ttlMs:cB,path:$0(),renew:!0});if(!k){let S=await wY(B);if(S)return S;throw Error("Codex OAuth refresh is already in progress")}let _=crypto.randomUUID(),w=q;try{await _1((g)=>{g.refresh=g.refresh??{},g.refresh.mainRefreshLeaseId=_,g.refresh.mainRefreshLeaseUntil=Date.now()+uB,g.refresh.mainRefreshLeaseTokenHash=q});let S=await q0($0());if(S?.refresh?.mainRefreshLeaseId!==_||S.refresh.mainRefreshLeaseTokenHash!==q)throw Error("Codex OAuth refresh is already in progress");let P=await R1({refreshToken:B.refresh,fetchImpl:fetch,now:Date.now});return await B8(P),await _1((g)=>{if(g.refresh=g.refresh??{},g.refresh.mainLastRefreshError=void 0,g.refresh.mainRefreshLeaseId===_)g.refresh.mainRefreshLeaseId=void 0,g.refresh.mainRefreshLeaseUntil=void 0,g.refresh.mainRefreshLeaseTokenHash=void 0}).catch(()=>{}),w=void 0,P}catch(S){if(B.refresh&&!YX(S))await _1((P)=>{P.refresh=P.refresh??{},P.refresh.mainLastRefreshError=kW({error:S,now:Date.now(),refreshToken:B.refresh??"",previous:P.refresh.mainLastRefreshError})}).catch(()=>{});throw S}finally{if(w)await _1((S)=>{if(S.refresh?.mainRefreshLeaseId===_&&S.refresh.mainRefreshLeaseTokenHash===w)S.refresh.mainRefreshLeaseId=void 0,S.refresh.mainRefreshLeaseUntil=void 0,S.refresh.mainRefreshLeaseTokenHash=void 0}).catch(()=>{});await k.release().catch(()=>{})}})().finally(()=>{r=void 0});return r}let J1=globalThis;J1.__openaiAuthCacheKeepManager?.stop();let d0=new y8({fetchImpl:fetch,getMainToken:async()=>{let B=await V();if(B.type!=="oauth")throw Error("not oauth");if(!B.access||(B.expires??0)<Date.now())try{return(await l0()).access}catch(q){if(YX(q))throw q;if(B.access)return B.access;throw Error("main token refresh failed")}return B.access},refreshFallback:async(B)=>{let q=await I(),D=q?$Z(q.accounts,B):void 0;if(!D)throw Error(`fallback account ${B} not found`);let T=await c.refreshAccount(D,q??{version:1,accounts:[D]});if(!T.access)throw Error(`no access token for ${B}`);return T.access},codexResponsesUrl:J,logger:X1,now:Date.now,getWindow:()=>h,getSustain:()=>C1});J1.__openaiAuthCacheKeepManager=d0;async function K1(B,q,D,T,k=!1){if(Object.keys(B).length===0&&!k)return;let _=Date.now(),w=B,S={quota:w,refreshAfter:_+300000,checkedAt:_},P;if(D&&D!=="main"){let b=q?l1(q):null,X0=b?d1(b):void 0,Z0=y.peekFallbackForPolicy(D)?.quota,h0=CW(w,Z0);S={...S,quota:h0},y.setFallback(D,S,q,k,X0)}else{if(P=T,!P&&q){let Z0=l1(q);P=Z0?d1(Z0):void 0}if(P&&Y0&&P!==Y0){p.debug("stale main quota frame dropped",{pid:process.pid,frameAccountId:P,currentMainIdentity:Y0});return}let b=y.peekMainForPolicy(P)?.quota,X0=CW(w,b);S={...S,quota:X0},y.setMain(q,S,P,k)}p.debug("quota pushed",{pid:process.pid,accountId:D??"main",snapshot:S.quota});let g=await I();await x0(y,g,D&&D!=="main"?g?.mainAccountId:P)}function Z8(B,q,D){let T=B==="main"?y.peekMainForPolicy()?.quota:y.peekFallbackForPolicy(B)?.quota;return lW(T,q,Date.now(),dB,D)}let i0=X.experimentalWebSockets?Z1.createWebSocketFetch({httpFetch:fetch,rawWebSocket:M0().rawWebSocket,onQuota:(B,q,D,T)=>{K1(B,q,D,!D||D==="main"?T:void 0,!0)},onRateLimitReached:(B,q,D)=>{if(!q)p.warn("mid-stream rate-limit mark missing internal account id; defaulting to main",{pid:process.pid,window:B});let T=q??"main",k=Z8(T,B,D);y.markRateLimited(T,k),p.debug("mid-stream rate limit mark",{pid:process.pid,accountId:T,window:B})}}):void 0;if(i0)U.push(i0),W=!0;let F0=sW();N=F0;async function x0(B,q,D=q?.mainAccountId){if(!q)return;await Y5(z5(B,q,Date.now(),D),F0)}async function v0(B,q,D,T,k){let _={activeId:D,route:T,updatedAt:Date.now()};if(B){if(await N8({sessionId:B,..._},k,F0),q&&q!==B){if(T==="sticky-balanced"){let w=(await D1(F0)).stickyAssignments?.[MY(q)]?.accountId,S=k===void 0||w==="main"||k.some((P)=>P.enabled!==!1&&P.id===w);if(!w||!S)return;await N8({sessionId:q,activeId:w,route:T,updatedAt:Date.now()},k,F0);return}await N8({sessionId:q,..._},k,F0)}return}await X5(_,F0)}L={accountStoragePath:$0(),quotaManager:y,loadAccounts:q0,client:Y.client,resolveResetTarget:nB({getAuth:V,refreshMainWithLease:l0,refreshFallbackAccount:(B,q)=>c.refreshAccount(B,q),loadAccounts:q0,accountStoragePath:$0(),now:Date.now}),...oB(),cacheKeepManager:d0,setCacheKeepEnabled:(B)=>{i1=B},setCacheKeepSubagents:(B)=>{n1=B},setCacheKeepSustain:(B)=>{C1=B},setCacheKeepWindow:(B)=>{h=B},clearStickyRouting:(B)=>$5(B,F0),getStickyRouting:async(B)=>eW(await D1(F0),B),refreshSidebar:async()=>{let B=await q0($0());await x0(y,B)},refreshAllQuota:async()=>b1({getAuth:V,codexRefreshFn:R1,refreshMainWithLease:l0,fallbackManager:c,quotaManager:y,loadAccounts:q0,writeSidebarState:x0,client:Y.client,fetchImpl:fetch,now:Date.now,configPath:$0(),storageMainAccountId:j?.mainAccountId,isOAuthAccountFn:u0,whamFn:Q1}),refreshResetTargetQuota:async(B)=>{return(await b1({getAuth:V,codexRefreshFn:R1,refreshMainWithLease:l0,fallbackManager:c,quotaManager:y,loadAccounts:q0,writeSidebarState:x0,client:Y.client,fetchImpl:fetch,now:Date.now,configPath:$0(),storageMainAccountId:j?.mainAccountId,isOAuthAccountFn:u0,whamFn:Q1,respectBackoff:!1},{accountKey:B})).find((D)=>D.account===B)??{account:B,ok:!1,error:"targeted quota refresh returned no result"}}};let Q0=null;if(Y.directory){let B=await G5(Y.directory),q=globalThis;if(q.__openaiAuthRpcServer)await q.__openaiAuthRpcServer.stop().catch(()=>{}),q.__openaiAuthRpcServer=void 0;try{Q0=await RJ({dir:B.dir,secureDir:B.secureDir,sweepRoot:B.sweepRoot,drain:MJ,apply:async(D)=>{let T={...L,sessionId:D.sessionId},k=await k8(D.command,D.arguments,T);return{text:k.text,knobs:k.knobs}}}),q.__openaiAuthRpcServer=Q0,H=Q0}catch{}}async function T0(B,q,D,T,k="main"){let _=_W(B,q);if(_.delete("x-api-key"),_.delete("api-key"),_.set("authorization",`Bearer ${D}`),T)_.set("ChatGPT-Account-Id",T);_.set(Z1.QUOTA_ACCOUNT_HEADER,k);let w=IW(_),S=w?aB($,w,G):void 0,P=B instanceof URL?B:new URL(typeof B==="string"?B:B.url),g=P.pathname.includes("/v1/responses")||P.pathname.includes("/chat/completions")?new URL(J):P,X0=QZ({init:{...q,headers:_},headers:_,metadata:S,installationID:Q,websocket:Boolean(i0&&P.pathname.endsWith("/responses")),responsesLite:X.responsesLite??!1,dumpSessionID:w}).init,Z0=i1,h0=new Headers(X0?.headers),W0=oX({enabled:Z0,includeSubagents:n1,headers:h0,body:X0?.body});if(Z0)X1.trace("cachekeep headers",{pid:process.pid,hasParent:h0.has("x-parent-session-id"),sessionKey:W0?.sessionKey,captured:Boolean(W0),affinity:h0.get("x-session-affinity"),opencodeSession:h0.get("x-opencode-session"),sessionId:h0.get("session-id")});if(i0&&P.pathname.endsWith("/responses")){if(R.debug("WS transport",{pid:process.pid,pathname:P.pathname,accountId:k}),W0)d0.track(W0.sessionKey,W0.bodyText,k,T,W0.replayHeaders,W0.isSubagent);return i0(g,X0)}let N0=Z1.withoutInternalHeaders(X0);if(typeof N0?.body!=="string")return fetch(g,N0);if(W0)d0.track(W0.sessionKey,W0.bodyText,k,T,W0.replayHeaders,W0.isSubagent);R.debug("HTTP transport",{pid:process.pid,pathname:P.pathname,accountId:k});try{let C0=await fetch(g,N0);return await h1({sessionID:w,transport:"http",phase:"http",bodyText:N0.body,accountId:k,url:g.toString(),method:N0.method,headers:N0.headers,status:C0.status}),VJ(C0)}catch(C0){throw await h1({sessionID:w,transport:"http",phase:"http",bodyText:N0.body,accountId:k,url:g.toString(),method:N0.method,headers:N0.headers,error:C0 instanceof Error?C0.message:String(C0)}),C0}}function I1(B,q){if((q?.method??(B instanceof Request?B.method:"GET")).toUpperCase()!=="POST")return!1;if(typeof q?.body!=="string")return!1;try{let T=B instanceof URL?B.toString():typeof B==="string"?B:B.url;return new URL(T).pathname.endsWith("/responses")}catch{return!1}}function U5(B){return y.peekMainForPolicy(B)?.quota}function GX(B,q){for(let D of[B?.primary?.checkedAt,B?.secondary?.checkedAt,B?.checkedAt,q])if(typeof D==="number"&&Number.isFinite(D))return D;return}function o1(B,q,D,T,k){let _=GX(B,q),w=GX(D),S=T===k&&D!=null&&(B===void 0||w!==void 0&&(_===void 0||w>_));return{quota:S?D:B,quotaCheckedAt:S?w:_,source:S?"file":"memory"}}function WX(B,q,D,T,k){let _=B?.quota,w=o1(_,B?.checkedAt,q,T,k),S=w.source,P=w.quota;if(!tW(P,D))return{exhausted:!1};let g=aW(P,D);if(!g)return{exhausted:!1};return{exhausted:!0,source:S,...g}}function zX(B,q){p.debug("admission skip: exhausted account",{accountId:B,source:q.source,resetsAt:q.resetsAt})}function H5(B,q="killswitch",D){let T=Date.now(),k=y.getMain()?.quota,_=(B?.accounts??[]).filter((b)=>b.enabled!==!1&&u0(b)).map((b)=>({accountId:b.id,quota:y.getFallback(b.id)?.quota})),w=nW(k,_,T,B);if(q==="quota-exhausted"&&D!==void 0)w=Math.max(1,Math.ceil((D-T)/1000));else if(q==="mid-stream-rate-limit"&&D!==void 0){let b=Math.max(1,Math.ceil((D-T)/1000));w=Math.min(w,b)}let S=Math.floor(w/60),P=w%60,g=q==="mid-stream-rate-limit"?`OpenAI rate limit reached — retrying on another account. Retry in ${S}m ${P}s.`:q==="quota-exhausted"?`OpenAI quota exhausted — retrying on another account. Retry in ${S}m ${P}s.`:`Killswitch: all OpenAI accounts are below their configured quota threshold. Retry in ${S}m ${P}s.`;return new Response(JSON.stringify({error:{message:g,type:"rate_limit_exceeded",code:"rate_limit_exceeded"}}),{status:429,headers:{"content-type":"application/json","retry-after":String(w)}})}function UX(B){let q=B?.resetCreditsAvailable;return typeof q==="number"&&Number.isFinite(q)?q:void 0}async function L5(B){let q=DY(B.storage),D=Date.now(),T=y.peekMainForPolicy(B.mainAccountIdentity),k=o1(T?.quota,T?.checkedAt,B.sidebarState.main.quota,B.sidebarState.main.mainAccountId,B.mainAccountIdentity),_=q?PY(T?.quota,B.storage,void 0,D):void 0,w=[{accountId:"main",wireAccountId:B.mainAccountIdentity,access:B.primaryAccess,keepwarmAccountKey:"main",quota:k.quota,quotaCheckedAt:k.quotaCheckedAt,reservePercent:XX(B.storage),configuredOrder:0,resetCreditsApplicable:UX(k.quota),killswitchPasses:_}],S=await c.getUsableFallbackAccounts(B.storage);for(let P of S){if(!P.access)continue;let g=B.sidebarState.fallbacks.find((h0)=>h0.id===P.id),b=y.peekFallbackForPolicy(P.id,P.accountId),X0=o1(b?.quota,b?.checkedAt,g?.quota,g?.accountId,P.accountId),Z0=q?PY(b?.quota,B.storage,P.id,D):void 0;w.push({accountId:P.id,wireAccountId:P.accountId,access:P.access,keepwarmAccountKey:P.id,fallback:P,quota:X0.quota,quotaCheckedAt:X0.quotaCheckedAt,reservePercent:XX(B.storage,P.id),configuredOrder:w.length,resetCreditsApplicable:UX(X0.quota),killswitchPasses:Z0})}return w}function HX(B,q,D,T,k){let _=DY(k)?B.killswitchPasses:void 0;if(B.accountId==="main"){let g=y.peekMainForPolicy(B.wireAccountId),b=o1(g?.quota,g?.checkedAt,q.main.quota,q.main.mainAccountId,B.wireAccountId);return c8({quota:b.quota,quotaCheckedAt:b.quotaCheckedAt,status:D,now:T,killswitchPasses:_})}let w=q.fallbacks.find((g)=>g.id===B.accountId),S=y.peekFallbackForPolicy(B.accountId,B.wireAccountId),P=o1(S?.quota,S?.checkedAt,w?.quota,w?.accountId,B.wireAccountId);return c8({quota:P.quota,quotaCheckedAt:P.quotaCheckedAt,status:D,now:T,killswitchPasses:_})}function V5(B){return B.accountId==="main"?"main":B.keepwarmAccountKey}function LX(B){return y.isRateLimited(V5(B))}async function K8(B){let q=B.candidates.filter((P)=>!LX(P)),D=new Map(q.map((P)=>[P.accountId,P])),T=Object.fromEntries(q.map((P)=>[P.accountId,P.quotaCheckedAt])),k=Object.fromEntries(q.map((P)=>[P.accountId,P.wireAccountId])),_=new Set(B.excludeAccountIds),w,S=await Q5({sessionId:B.sessionId,requestBytes:B.requestBytes,now:B.now,validPinnedAccountIds:[...D.keys()],excludeAccountIds:B.excludeAccountIds,quotaCheckedAtByAccount:T,wireAccountIdByAccount:k,choose:(P)=>{let g=q.filter((X0)=>!_.has(X0.accountId));if(g.length===0)return;let b=JJ({candidates:g,pendingBytes:P,requestBytes:B.requestBytes,now:B.now,onEmptyWeightedSet:()=>{d.debug("sticky routing: no fresh weighted candidates; using configured order")}});if(!b)return;return w={accountId:b.accountId,source:b.source,pendingBytes:P.get(b.accountId)??0},b}},F0);if(w&&S?.accountId===w.accountId)d.debug("sticky routing: placed session pin",{pid:process.pid,sessionHash:MY(B.sessionId),accountId:w.accountId,source:w.source,requestBytes:B.requestBytes,pendingBytes:w.pendingBytes});return S?D.get(S.accountId):void 0}async function N5(B,q){let D=await c.getUsableFallbackAccounts(B),T=[];for(let b of D)if(b.access)T.push({access:b.access,accountId:b.accountId,keepwarmAccountKey:b.id,quotaAccountId:b.id,fallback:b});let k=T.filter((b)=>!y.isRateLimited(b.quotaAccountId)),_=DY(B)?k.filter((b)=>PY(y.peekFallbackForPolicy(b.quotaAccountId,b.accountId)?.quota,B,b.quotaAccountId,Date.now())):k,w=new Map(q.fallbacks.map((b)=>[b.id,{quota:b.quota,accountId:b.accountId}])),S=[],P=[],g=Date.now();for(let b of _){let X0=w.get(b.quotaAccountId),Z0=WX(y.peekFallbackForPolicy(b.quotaAccountId,b.accountId),X0?.quota,g,X0?.accountId,b.accountId);if(Z0.exhausted)P.push({candidate:b,decision:Z0});else S.push(b)}return{current:_,retained:S,skipped:P}}function VX(B,q){if(B.retained.length===0&&!q)return B.current;for(let{candidate:D,decision:T}of B.skipped)zX(D.quotaAccountId,T);return B.retained}async function NX(B,q){try{let D=x1(B.headers);await K1(D,q.access,q.quotaAccountId,void 0,FY(B.headers))}catch{}}async function B5(B,q,D,T){for(let k of T){let _;try{_=await T0(B,q,k.access,k.accountId,k.keepwarmAccountKey)}catch(w){if(w instanceof DOMException&&w.name==="AbortError")throw w;if(q?.signal?.aborted)throw w;throw d.debug("fallback-first transport failed; request not replayed",{pid:process.pid,accountId:k.quotaAccountId}),w}if(!jY(_.status,D))return c.markUsed(k.fallback),{response:_,accessToken:k.access,quotaAccountId:k.quotaAccountId,activeId:k.keepwarmAccountKey};await NX(_,k),_.body?.cancel().catch(()=>{})}return}async function Z5(B,q,D,T,k){if(!I1(B,q))return{response:D};if(!k.length)return{response:D};let _=D,w;for(let S of k){let P;try{P=await T0(B,q,S.access,S.accountId,S.keepwarmAccountKey)}catch(g){if(g instanceof DOMException&&g.name==="AbortError")throw g;if(q?.signal?.aborted)throw g;return d.debug("reactive fallback candidate threw; stopping",{pid:process.pid,accountId:S.quotaAccountId}),{response:_,...w}}if(_.body?.cancel().catch(()=>{}),_=P,w={accessToken:S.access,accountId:S.quotaAccountId},!jY(P.status,T))return c.markUsed(S.fallback),{response:P,...w};await NX(P,S)}return{response:_,...w}}if(!PW){if(PW=!0,j){let B=[];for(let q of j.accounts)if(u0(q))B.push(q);y.seedFallbacksFromAccounts(B)}x0(y,j).catch(()=>{}),b1({getAuth:V,codexRefreshFn:R1,refreshMainWithLease:l0,fallbackManager:c,quotaManager:y,loadAccounts:q0,writeSidebarState:x0,client:Y.client,fetchImpl:fetch,now:Date.now,configPath:$0(),storageMainAccountId:j?.mainAccountId,isOAuthAccountFn:u0,whamFn:Q1,respectBackoff:!0}).catch((B)=>p.warn("boot quota seed failed",{pid:process.pid,error:$1(B)}))}return O.start(async()=>{let q=(await pX({getAuth:V,codexRefreshFn:R1,refreshMainWithLease:l0,fallbackManager:c,quotaManager:y,loadAccounts:q0,writeSidebarState:(D,T)=>O.isStopped()?Promise.resolve():x0(D,T),client:Y.client,fetchImpl:fetch,now:Date.now,configPath:$0(),storageMainAccountId:j?.mainAccountId,isOAuthAccountFn:u0,whamFn:Q1,readSidebarState:()=>D1(F0)})).filter((D)=>!D.ok);if(q.length>0)p.warn("background quota refresh completed with failures",{pid:process.pid,failures:q})},(B)=>{p.warn("background quota refresh failed",{pid:process.pid,error:B instanceof Error?B.message:String(B)})}),{apiKey:hB,async fetch(B,q){let D=_W(B,q),T=IW(D),k=D.get("x-parent-session-id")?.trim()||void 0,_=await I(),w=await V(),S=++p0;if(w.type!=="oauth")return fetch(B,q);q=await GZ(B,q);let P=w.access??"";if(!w.access||(w.expires??0)<Date.now()){m.debug("token refresh triggered",{pid:process.pid,hasAccess:Boolean(w.access),expiresInMs:w.expires?w.expires-Date.now():void 0});try{let e=await l0();w.access=e.access,w.refresh=e.refresh,w.expires=e.expires}catch(e){if(YX(e))throw e}}P=w.access??"";let b=w.accountId??(P?d1(l1(P)??{}):void 0);if(S===p0)Y0=b;let X0=_?.routing?.mode??"main-first",Z0,W0=await(()=>{return Z0??=D1(F0),Z0})();if(X0==="sticky-balanced"&&T&&I1(B,q)&&typeof q?.body==="string"){let e=Buffer.byteLength(q.body,"utf8"),H0=await L5({storage:_,sidebarState:W0,primaryAccess:P,mainAccountIdentity:b}),U0=await K8({sessionId:T,requestBytes:e,candidates:H0,now:Date.now()});if(U0){let jX=LX(U0)?{action:"migrate",reason:"exhausted"}:HX(U0,W0,void 0,Date.now(),_);if(jX.action==="migrate"){let P0=await K8({sessionId:T,requestBytes:e,candidates:H0,excludeAccountIds:[U0.accountId],now:Date.now()});if(P0)d.debug("sticky routing: migrated session pin",{pid:process.pid,sessionHash:MY(T),fromAccountId:U0.accountId,toAccountId:P0.accountId,reason:jX.reason}),U0=P0}let g0=await T0(B,q,U0.access,U0.wireAccountId,U0.keepwarmAccountKey),DX=async(P0,O1)=>{try{let K5=x1(P0.headers);await K1(K5,O1.access,O1.accountId==="main"?void 0:O1.accountId,O1.accountId==="main"?O1.wireAccountId:void 0,FY(P0.headers))}catch{}};await DX(g0,U0);let PX=HX(U0,W0,g0.status,Date.now(),_);if((g0.status===401||g0.status===403||g0.status===429)&&PX.action==="migrate"){let P0=await K8({sessionId:T,requestBytes:e,candidates:H0,excludeAccountIds:[U0.accountId],now:Date.now()});if(P0){d.debug("sticky routing: migrated session pin",{pid:process.pid,sessionHash:MY(T),fromAccountId:U0.accountId,toAccountId:P0.accountId,reason:PX.reason});let O1=g0;g0=await T0(B,q,P0.access,P0.wireAccountId,P0.keepwarmAccountKey),O1.body?.cancel().catch(()=>{}),U0=P0,await DX(g0,U0)}}if(U0.fallback&&!jY(g0.status,_))c.markUsed(U0.fallback);return await v0(T,k,U0.accountId,X0,_?.accounts).catch(()=>{}),g0}}let N0=WX(y.peekMainForPolicy(b),W0.main.quota,Date.now(),W0.main.mainAccountId,b),C0=DY(_)&&!PY(U5(b),_,void 0,Date.now()),EY=y.isRateLimited("main"),BX,O8=()=>{return BX??=N5(_,W0),BX},n0,S1,ZX=!1,AY;if(X0==="fallback-first"&&I1(B,q)){ZX=!0;let e=await O8();AY=VX(e,!C0&&!EY&&!N0.exhausted);let H0=await B5(B,q,_,AY);if(H0)n0=H0.response,S1={accessToken:H0.accessToken,accountId:H0.quotaAccountId,activeId:H0.activeId}}if(!n0){let e=N0.exhausted&&I1(B,q)&&(await O8()).retained.length>0;if(C0||EY||e){let H0=C0?"killswitch":EY?"mid-stream-rate-limit":"quota-exhausted";if(H0==="quota-exhausted"&&N0.exhausted)zX("main",N0);d.debug("admission blocked primary",{pid:process.pid,activeId:"main",reason:H0}),n0=H5(_,H0,H0==="quota-exhausted"&&N0.exhausted?N0.resetAtMs:EY?y.rateLimitedUntil("main"):void 0)}else n0=await T0(B,q,P,b,"main")}let KX=Boolean(S1),r1=n0,OX=S1?.accessToken??P,qX=S1?.accountId,FX=S1?.activeId??"main";if(!S1&&!ZX&&jY(n0.status,_)){d.debug("reactive fallback triggered",{pid:process.pid,status:n0.status}),AY??=VX(await O8(),!1);let e=await Z5(B,q,n0,_,AY),H0=e.response;if(H0!==n0){if(KX=!0,r1=H0,OX=e.accessToken??P,qX=e.accountId,e.accountId)FX=e.accountId}}try{let e=x1(r1.headers);if(KX)await K1(e,OX,qX,void 0,FY(r1.headers));else await K1(e,P,void 0,b,FY(r1.headers))}catch{}return await v0(T,k,FX,X0,_?.accounts).catch(()=>{}),r1},async dispose(){if(O.stop(),d0.stop(),J1.__openaiAuthCacheKeepManager===d0)J1.__openaiAuthCacheKeepManager=void 0;if(c.stopBackgroundRefresh(),H){await H.stop().catch(()=>{});let B=globalThis;if(B.__openaiAuthRpcServer===H)B.__openaiAuthRpcServer=void 0;H=null}}}},methods:[{label:"ChatGPT Pro/Plus (browser)",type:"oauth",authorize:async()=>{let{redirectUri:V}=await mW(),K=await gW(),j=hW(crypto.getRandomValues(new Uint8Array(32)).buffer),M=yW(V,K,j),I=cW(K,j);return{url:M,instructions:"Complete authorization in your browser. This window will close automatically.",method:"auto",callback:async()=>{try{let E=await I,x=V8(E);return{type:"success",refresh:E.refresh_token,access:E.access_token,expires:Date.now()+(E.expires_in??3600)*1000,accountId:x}}finally{fW(j)}}}}},{label:"ChatGPT Pro/Plus (headless)",type:"oauth",authorize:async()=>{let{deviceData:V,url:K,instructions:j}=await uW();return{url:K,instructions:j,method:"auto",async callback(){try{let M=await pW(V);return{type:"success",refresh:M.refresh_token,access:M.access_token,expires:Date.now()+(M.expires_in??3600)*1000,accountId:V8(M)}}catch{return{type:"failed"}}}}}},{label:"Manually enter API Key",type:"api"}]},"chat.headers":async(V,K)=>{if(V.model.providerID!=="openai")return;if(K.headers.originator="opencode",K.headers["User-Agent"]=`${vW} (${e9.platform()} ${e9.release()}; ${e9.arch()})`,K.headers["session-id"]=V.sessionID,W&&V.agent==="title")K.headers[Z1.TITLE_HEADER]="true"},"chat.params":async(V,K)=>{if(V.model.providerID!=="openai")return;K.maxOutputTokens=void 0},config:async(V)=>{V.command={...V.command??{},[A8]:{template:A8,description:"Show current OpenAI Codex OAuth quota usage for all accounts."},[T8]:{template:T8,description:"Manage OpenAI accounts — add, switch, remove, or reorder."},[R8]:{template:R8,description:"Show or change OpenAI account routing between main-first, fallback-first, and sticky-balanced."},[C8]:{template:C8,description:"Manage killswitch — hard-block requests when quota drops below per-account thresholds."},[_8]:{template:_8,description:"Show or toggle OpenAI Codex request dump capture for debugging."},[I8]:{template:I8,description:"Show or change the plugin log level (error, warn, info, debug, trace)."},[S8]:{template:S8,description:"Keep Codex prompt cache alive during idle by shadow-replaying the last request."},[j1]:{template:j1,description:"Spend one reset credit on an exhausted Codex account."}}},"command.execute.before":async(V)=>{if(!cX.includes(V.command))return;if(!L)await Z(V.sessionID,"OpenAI auth plugin is still initializing. Send a request first, then try again."),TW();let K=V.command,j={...L,sessionId:V.sessionID,notify:(I)=>{a8(I,V.sessionID)}},M=await k8(K,V.arguments,j);if(wJ(V.sessionID))a8(M,V.sessionID);else await Z(V.sessionID,M.text);TW()}}}var NZ=async(Y)=>{let X=M0();return VZ(Y,{codexApiEndpoint:X.codexApiEndpoint,experimentalWebSockets:X.webSockets,responsesLite:X.responsesLite})},wF={id:"cortexkit-openai-auth",server:NZ};export{IW as resolveSidebarSessionId,l1 as parseJwtClaims,CW as mergePushedQuotaMetadata,$Z as findCachekeepFallbackAccount,d1 as extractAccountIdFromClaims,wF as default,nB as createResetTargetResolver,MF as buildSidebarState,z5 as buildSidebarMachineState,oB as buildResetRedemptionDeps,c0 as ResetTargetResolutionError,NZ as OpenAIAuthPlugin,cB as MAIN_REFRESH_LOCK_TTL_MS,uB as MAIN_REFRESH_LEASE_TTL_MS,VZ as CodexAuthPlugin,$X as AuthPersistError};
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const PackageVersion = "0.6.1";
1
+ export declare const PackageVersion = "0.6.2";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-openai-auth",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -1,89 +0,0 @@
1
- import{ua as T}from"./index-n00ybbbq.js";import{Aa as h}from"./index-hxpv25e8.js";import{Ha as H1}from"./index-s2vhsb2v.js";import{createHash as g0}from"node:crypto";var i0=86400000,u0=300000,s0=3600000,r0=60000,n0=900000,c0=300000;function e(B){return B instanceof Error?B.message:String(B)}function o0(B){let Z=B?.status;if(typeof Z==="number")return Z===429||Z>=500;if(!(B instanceof Error))return!1;return B.name==="AbortError"||B.name==="TimeoutError"||B.message.includes("fetch failed")||"code"in B&&(B.code==="ECONNRESET"||B.code==="ECONNREFUSED"||B.code==="ETIMEDOUT"||B.code==="UND_ERR_CONNECT_TIMEOUT")}function B0(B){let Z=e(B),$=B?.status;if(typeof $==="number")return $===429||$>=500;if(!(B instanceof Error))return!1;let W=B.code;return B.name==="AbortError"||B.name==="TimeoutError"||Z.includes("fetch failed")||W==="ECONNRESET"||W==="ECONNREFUSED"||W==="ETIMEDOUT"||W==="UND_ERR_CONNECT_TIMEOUT"}function Q0(B){return g0("sha256").update(B).digest("hex")}function N0(B){let Z=Q0(B.refreshToken),W=(B.previous?.tokenHash===Z?B.previous.retryCount??0:0)+1,X,G=B.error?.retryAfter;if(typeof G==="number"&&G>0)X=G*1000;else if(o0(B.error))X=Math.min(s0,u0*2**Math.min(W-1,6));else X=i0;return{message:e(B.error),checkedAt:B.now,nextRetryAt:B.now+X,retryCount:W,tokenHash:Z}}function U(B,Z,$){if(!B?.nextRetryAt||B.nextRetryAt<=$)return!1;if(!Z)return!0;return B.tokenHash===Q0(Z)}function i(B,Z){return`Codex OAuth refresh is backed off for ${Math.max(1,Math.ceil(((B.nextRetryAt??Z)-Z)/1000))}s after: ${B.message}`}function I(B){let $=(B.previous?.retryCount??0)+1,W,X=B.error?.retryAfter;if(typeof X==="number"&&X>0)W=X*1000;else if(B0(B.error))W=Math.min(n0,r0*2**Math.min($-1,6));else W=c0;return{message:e(B.error),checkedAt:B.now,nextRetryAt:B.now+W,retryCount:$}}function x(B,Z){if(!B?.nextRetryAt||B.nextRetryAt<=Z)return!1;return!0}function Z0(B){if(!B)return;let Z=Number(B);if(Number.isFinite(Z)&&Z>0)return Math.ceil(Z);let $=Date.parse(B);if(Number.isFinite($)){let W=Math.ceil(($-Date.now())/1000);return W>0?W:void 0}return}import{createServer as a0}from"node:http";import{setTimeout as t0}from"node:timers/promises";var P0="0.6.1";var r="app_EMoamEEZ73f0CkXaXp7hrann",q="https://auth.openai.com",w=1455,e0=3000,F0=`cortexkit-opencode-openai-auth/${P0}`,O0="main",B1=`"${O0}" is a reserved account id; choose a different label.`;function b0(B){let Z=new Uint8Array(B),$=String.fromCharCode(...Z);return btoa($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function Z1(){let Z=Array.from(crypto.getRandomValues(new Uint8Array(43))).map((W)=>"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"[W%66]).join(""),$=b0(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(Z)));return{verifier:Z,challenge:$}}function V0(B){if(B.length>16384)return;let Z=B.split(".");if(Z.length!==3)return;let $=Z[1];if(!$||$.length>8192)return;try{return JSON.parse(Buffer.from($,"base64url").toString())}catch{return}}function L0(B){let Z=B.chatgpt_account_id;if(typeof Z==="string"&&Z.length>0)return Z;let $=B["https://api.openai.com/auth"];if($&&typeof $==="object"&&!Array.isArray($)&&typeof $.chatgpt_account_id==="string"&&$.chatgpt_account_id.length>0)return $.chatgpt_account_id;let W=B.organizations;if(Array.isArray(W)){let X=W[0];if(X&&typeof X==="object"&&!Array.isArray(X)&&typeof X.id==="string"&&X.id.length>0)return X.id}return}function s(B){if(B.id_token){let Z=V0(B.id_token),$=Z&&L0(Z);if($)return $}if(B.access_token){let Z=V0(B.access_token);return Z?L0(Z):void 0}return}function $1(B){return typeof B==="string"&&B.toLowerCase()===O0}function $0(B){if($1(B))throw Error(B1);return B}function W1(B,Z,$){let W=new URLSearchParams({response_type:"code",client_id:r,redirect_uri:B,scope:"openid profile email offline_access",code_challenge:Z.challenge,code_challenge_method:"S256",id_token_add_organizations:"true",codex_cli_simplified_flow:"true",state:$,originator:"opencode"});return`${q}/oauth/authorize?${W.toString()}`}async function X1(B,Z,$){let W=await fetch(`${q}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",code:B,redirect_uri:Z,client_id:r,code_verifier:$.verifier}).toString()});if(!W.ok)throw Error(`Token exchange failed: ${W.status}`);return await W.json()}function G1(B){return B.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;")}var z1=`<!doctype html>
2
- <html>
3
- <head>
4
- <title>CortexKit OpenAI Auth - Authorization Successful</title>
5
- <style>
6
- body {
7
- font-family:
8
- system-ui,
9
- -apple-system,
10
- sans-serif;
11
- display: flex;
12
- justify-content: center;
13
- align-items: center;
14
- height: 100vh;
15
- margin: 0;
16
- background: #131010;
17
- color: #f1ecec;
18
- }
19
- .container {
20
- text-align: center;
21
- padding: 2rem;
22
- }
23
- h1 {
24
- color: #f1ecec;
25
- margin-bottom: 1rem;
26
- }
27
- p {
28
- color: #b7b1b1;
29
- }
30
- </style>
31
- </head>
32
- <body>
33
- <div class="container">
34
- <h1>Authorization Successful</h1>
35
- <p>You can close this window and return to OpenCode.</p>
36
- </div>
37
- <script>
38
- setTimeout(() => window.close(), 2000)
39
- </script>
40
- </body>
41
- </html>`,u=(B)=>`<!doctype html>
42
- <html>
43
- <head>
44
- <title>CortexKit OpenAI Auth - Authorization Failed</title>
45
- <style>
46
- body {
47
- font-family:
48
- system-ui,
49
- -apple-system,
50
- sans-serif;
51
- display: flex;
52
- justify-content: center;
53
- align-items: center;
54
- height: 100vh;
55
- margin: 0;
56
- background: #131010;
57
- color: #f1ecec;
58
- }
59
- .container {
60
- text-align: center;
61
- padding: 2rem;
62
- }
63
- h1 {
64
- color: #fc533a;
65
- margin-bottom: 1rem;
66
- }
67
- p {
68
- color: #b7b1b1;
69
- }
70
- .error {
71
- color: #ff917b;
72
- font-family: monospace;
73
- margin-top: 1rem;
74
- padding: 1rem;
75
- background: #3c140d;
76
- border-radius: 0.5rem;
77
- }
78
- </style>
79
- </head>
80
- <body>
81
- <div class="container">
82
- <h1>Authorization Failed</h1>
83
- <p>An error occurred during authorization.</p>
84
- <div class="error">${G1(B)}</div>
85
- </div>
86
- </body>
87
- </html>`,k,m,L=new Map;function M(){return L.size}function C(B){if(L.delete(B),M()===0)_()}async function K1(){let B=`http://localhost:${w}/auth/callback`;if(k)return{port:w,redirectUri:B};if(m)return m;m=(async()=>{let Z=a0(($,W)=>{let X=new URL($.url||"/",`http://127.0.0.1:${w}`);if(X.pathname==="/auth/callback"){let G=X.searchParams.get("code"),z=X.searchParams.get("state"),K=X.searchParams.get("error"),Y=X.searchParams.get("error_description");if(K){let j=Y||K;if(z){let Q=L.get(z);if(Q)Q.reject(Error(j)),C(z);else if(M()===0)_()}else if(M()===0)_();W.writeHead(200,{"Content-Type":"text/html"}),W.end(u(j));return}if(!z){if(M()===0)_();W.writeHead(400,{"Content-Type":"text/html"}),W.end(u("Missing state parameter"));return}if(!G){if(M()===0)_();W.writeHead(400,{"Content-Type":"text/html"}),W.end(u("Missing authorization code"));return}let J=L.get(z);if(!J){if(M()===0)_();W.writeHead(400,{"Content-Type":"text/html"}),W.end(u("Unknown state — authorization may have expired"));return}C(z),X1(G,B,J.pkce).then((j)=>J.resolve(j)).catch((j)=>J.reject(j)),W.writeHead(200,{"Content-Type":"text/html"}),W.end(z1);return}if(X.pathname==="/cancel"){let G=X.searchParams.get("state"),z=G?[G]:[...L.keys()];W.writeHead(200),W.end("Login cancelled");for(let K of z){let Y=L.get(K);if(!Y)continue;Y.reject(Error("Login cancelled")),C(K)}if(M()===0)_();return}W.writeHead(404),W.end("Not found")});return await new Promise(($,W)=>{Z.once("error",W),Z.listen(w,"127.0.0.1",()=>{Z.off("error",W),$()})}),k=Z,{port:w,redirectUri:B}})();try{return await m}finally{m=void 0}}function _(){if(k){let B=k;k=void 0,B.close(()=>{}),B.closeIdleConnections?.(),setTimeout(()=>{B.closeAllConnections?.()},25).unref?.()}}function Y1(B,Z,$=300000,W){return new Promise((X,G)=>{if(W?.aborted){C(Z),G(Error("Login cancelled"));return}let z=setTimeout(()=>{if(L.get(Z))C(Z),G(Error("OAuth callback timeout — authorization took too long"))},$),K=()=>{if(clearTimeout(z),L.get(Z))C(Z),G(Error("Login cancelled"))};if(W)W.addEventListener("abort",K);L.set(Z,{pkce:B,state:Z,resolve:(Y)=>{if(clearTimeout(z),W)W.removeEventListener("abort",K);X(Y)},reject:(Y)=>{if(clearTimeout(z),W)W.removeEventListener("abort",K);G(Y)}})})}async function J1(){let B=await fetch(`${q}/api/accounts/deviceauth/usercode`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":F0},body:JSON.stringify({client_id:r})});if(!B.ok)throw Error("Failed to initiate device authorization");let Z=await B.json();return{deviceData:Z,url:`${q}/codex/device`,instructions:`Enter code: ${Z.user_code}`}}async function j1(B,Z){let $=Math.max(parseInt(B.interval,10)||5,1)*1000,W=typeof B.expires_in==="number"?B.expires_in:parseInt(B.expires_in||"",10),X=!Number.isNaN(W)&&W>0?W*1000:900000,G=Date.now();while(!0){if(Z?.aborted)throw Error("Device authorization cancelled");if(Date.now()-G>X)throw Error("Device authorization expired");let z=await fetch(`${q}/api/accounts/deviceauth/token`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":F0},body:JSON.stringify({device_auth_id:B.device_auth_id,user_code:B.user_code})});if(z.ok){let J=await z.json(),j=await fetch(`${q}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",code:J.authorization_code,redirect_uri:`${q}/deviceauth/callback`,client_id:r,code_verifier:J.code_verifier}).toString()});if(!j.ok)throw Error(`Token exchange failed: ${j.status}`);return await j.json()}if(z.status!==403&&z.status!==404)throw Error(`Device authorization failed: ${z.status}`);let K=X-(Date.now()-G);if(K<=0)throw Error("Device authorization expired");let Y=Math.min($+e0,K);try{await t0(Y,void 0,{signal:Z})}catch(J){if(J instanceof Error&&J.name==="AbortError")throw Error("Device authorization cancelled");throw J}}}function y6(B,Z){let $=-1;if(Z.accountId)$=B.findIndex((W)=>W.accountId&&W.accountId===Z.accountId);if($<0)$=B.findIndex((W)=>W.id===Z.id);if($<0&&Z.label&&!Z.accountId)$=B.findIndex((W)=>W.label===Z.label);if($>=0)return B[$]={...B[$],...Z,addedAt:B[$]?.addedAt??Z.addedAt},$;return B.push(Z),B.length-1}async function x6(B={}){let{label:Z,headless:$=!1,signal:W}=B;if($0(Z),$){let{deviceData:J,url:j,instructions:Q}=await J1(),y=(async()=>{let V=await j1(J,W),F=Date.now(),H0=s(V);return{id:$0(Z||H0||crypto.randomUUID()),label:Z||void 0,type:"oauth",access:V.access_token,refresh:V.refresh_token,expires:F+(V.expires_in??3600)*1000,enabled:!0,addedAt:F,lastUsed:F,lastRefreshedAt:F,accountId:H0}})();return{url:j,instructions:Q,completion:y}}let{redirectUri:X}=await K1(),G=await Z1(),z=b0(crypto.getRandomValues(new Uint8Array(32)).buffer),K=W1(X,G,z),Y=(async()=>{try{if(W?.aborted)throw Error("Login cancelled");let J=await Y1(G,z,void 0,W),j=Date.now(),Q=s(J);return{id:$0(Z||Q||crypto.randomUUID()),label:Z||void 0,type:"oauth",access:J.access_token,refresh:J.refresh_token,expires:j+(J.expires_in??3600)*1000,enabled:!0,addedAt:j,lastUsed:j,lastRefreshedAt:j,accountId:Q}}finally{C(z)}})();return{url:K,instructions:"Complete authorization in your browser. This window will close automatically.",completion:Y}}function D0(B){if(B instanceof Error)return B.message;if(typeof B==="string")return B;try{return JSON.stringify(B)}catch{return String(B)}}var Q1=h("quota"),W0="primary",X0="secondary",N1="app_EMoamEEZ73f0CkXaXp7hrann",P1="https://auth.openai.com";async function m6(B){let Z=await B.fetchImpl(`${P1}/oauth/token`,{method:"POST",signal:AbortSignal.timeout(15000),headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:B.refreshToken,client_id:N1}).toString()});if(!Z.ok){let W=Z0(Z.headers.get("retry-after"));throw Object.assign(Error(`Token refresh failed: ${Z.status}`),{status:Z.status,retryAfter:W,isRefreshError:!0})}let $=await Z.json();if(!$||typeof $.access_token!=="string"||!$.access_token||typeof $.refresh_token!=="string"||!$.refresh_token||typeof $.expires_in!=="number")throw Object.assign(Error("Token refresh failed: malformed response"),{status:Z.status,isRefreshError:!0});return{access:$.access_token,refresh:$.refresh_token,expires:B.now()+$.expires_in*1000,expiresIn:$.expires_in}}var V1="https://chatgpt.com/backend-api/wham/usage";async function k6(B){let Z=B.logger??Q1,$=B.accountKey??"unknown",W=Date.now();Z.debug("wham usage fetch started",{pid:process.pid,accountId:$});try{let X=await B.fetchImpl(V1,{signal:AbortSignal.timeout(15000),headers:{authorization:`Bearer ${B.accessToken}`,"chatgpt-account-id":B.accountId??"","oai-client-platform":"web","oai-client-version":"0","x-openai-target-path":"/backend-api/wham/usage"}});if(!X.ok){let K=Z0(X.headers.get("retry-after"));throw Object.assign(Error(`wham usage check failed: ${X.status}`),{status:X.status,retryAfter:K})}let{normalizeWham:G}=await import("./quota-normalize-vf2pj6n7.js"),z=G(await X.json());return Z.debug("wham usage fetch succeeded",{pid:process.pid,accountId:$,status:X.status,elapsedMs:Date.now()-W}),z}catch(X){throw Z.warn("wham usage fetch failed",{pid:process.pid,accountId:$,status:typeof X?.status==="number"?X.status:"error",elapsedMs:Date.now()-W,error:D0(X)}),X}}import{createHash as L1}from"node:crypto";var F1=globalThis.setTimeout,O1=5;function v(B){let Z=B?.quota?.checkIntervalMinutes??O1;return Math.max(1,Z)*60000}function b1(B){return B?.quota?.enabled!==!1}function n(B,Z){if(!B?.resetsAt)return!1;let $=Date.parse(B.resetsAt);return Number.isFinite($)&&$<=Z}function g6(B,Z,$,W,X){if(X!==void 0&&Number.isFinite(X)&&X>$)return X;let G=Z===W0?B?.primary:Z===X0?B?.secondary:void 0,z=G?.resetsAt?Date.parse(G.resetsAt):NaN;if(Number.isFinite(z)&&z>$)return z;return $+W}function D1(B){let Z=B?.quota?.minimumRemaining||{};return{primary:Z.primary??Z["5h"]??15,secondary:Z.secondary??Z["1w"]??10}}function U0(B,Z,$){if(!b1(Z))return $+v(Z);let W=D1(Z),X=[];for(let G of["primary","secondary"]){let z=B?.[G];if(!z)continue;if(z.remainingPercent>=W[G])continue;let K=z.resetsAt?Date.parse(z.resetsAt):Number.NaN;if(!Number.isFinite(K)||K<=$)return $+v(Z);X.push(K)}if(!X.length)return $+v(Z);return Math.min(...X)+60000}function U1(B){if(!B?.quota?.mainQuota||!B.quota.mainQuotaCheckedAt)return null;return{quota:B.quota.mainQuota,checkedAt:B.quota.mainQuotaCheckedAt,tokenFingerprint:B.quota.mainQuotaToken}}function M1(B){let Z=B?.quota?.refreshEveryNRequests;return typeof Z==="number"&&Number.isFinite(Z)&&Z>0?Math.floor(Z):0}function P(B){return L1("sha256").update(B).digest("hex").slice(0,16)}class O{main=null;mainTokenFp=null;mainQuotaAccountId=null;fallbacks=new Map;fallbackTokenFps=new Map;inflightMain=null;inflightMainFp=null;inflightFallbacks=new Map;mainLastApiError=void 0;fallbackApiErrors=new Map;fallbackErrorTokenFps=new Map;rateLimitedUntilMap=new Map;apiGate=Promise.resolve();lastApiCallAt=0;storage;fetchImpl;now;fetchQuotaFn;onMainQuotaFetched;onApiError;constructor(B){this.storage=B.storage,this.fetchImpl=B.fetchImpl??fetch,this.now=B.now??Date.now,this.fetchQuotaFn=B.fetchQuotaFn,this.onMainQuotaFetched=B.onMainQuotaFetched,this.onApiError=B.onApiError,this.seedMainFromStorage(B.storage),this.seedMainBackoffFromStorage(B.storage)}getMain(B){if(B&&this.main&&this.mainTokenFp&&this.mainTokenFp!==P(B))this.main=null,this.mainTokenFp=null;return this.main}getFallback(B,Z){let $=this.fallbacks.get(B)??null;if(!Z||!$)return $;if(this.fallbackTokenFps.get(B)!==P(Z))return this.fallbacks.delete(B),this.fallbackTokenFps.delete(B),null;return $}getAllFallbacks(){return this.fallbacks}setMain(B,Z,$,W=!1){if(!W&&!M0(Z.quota))return;if(this.mainTokenFp=P(B),$&&this.mainQuotaAccountId&&this.mainQuotaAccountId!==$)this.clearRateLimited("main");if($)this.mainQuotaAccountId=$;if(this.main=Z,G0(Z.quota))this.clearRateLimited("main")}peekMainForPolicy(B){if(B&&this.mainQuotaAccountId&&this.mainQuotaAccountId!==B)return null;return this.main}peekFallbackForPolicy(B,Z){let $=this.fallbacks.get(B)??null;if(Z&&$?.accountId&&$.accountId!==Z)return null;return $}setFallback(B,Z,$,W=!1,X){if(!W&&!M0(Z.quota))return;let G=this.fallbacks.get(B)?.accountId;if(X&&G&&X!==G)this.clearRateLimited(B);let z=X??G;if(this.fallbacks.set(B,{...Z,accountId:z}),$)this.fallbackTokenFps.set(B,P($));else this.fallbackTokenFps.delete(B);if(G0(Z.quota))this.clearRateLimited(B)}markRateLimited(B,Z){let $=this.rateLimitedUntilMap.get(B);if($!==void 0&&$>Z)return;this.rateLimitedUntilMap.set(B,Z)}isRateLimited(B){let Z=this.rateLimitedUntilMap.get(B);return Z!==void 0&&this.now()<Z}rateLimitedUntil(B){return this.rateLimitedUntilMap.get(B)}clearRateLimited(B){this.rateLimitedUntilMap.delete(B)}async refreshMain(B){let Z=P(B);if(this.mainTokenFp&&this.mainTokenFp!==Z)this.main=null,this.mainTokenFp=null;if(this.inflightMain&&this.inflightMainFp===Z)return this.inflightMain;if(this.isBackedOff()){if(this.main)return this.main.quota;throw Error("Quota API rate-limited — try again later")}return this.inflightMainFp=Z,this.inflightMain=this._fetchMain(B),this.inflightMain}async refreshFallback(B,Z){let $=O.fallbackInflightKey(B,Z),W=this.inflightFallbacks.get($);if(W)return W;if(this.isFallbackBackedOff(B,Z)){let G=this.getFallback(B,Z);if(G)return G.quota;throw Error("Quota API rate-limited — try again later")}let X=this._fetchFallback(B,Z);return this.inflightFallbacks.set($,X),X}async refreshAllFallbacks(B){let Z=this.now();for(let $ of B){if($.enabled===!1)continue;if(!$.access)continue;let W=this.getFallback($.id,$.access);if(W&&Z<W.refreshAfter)continue;try{await this.refreshFallback($.id,$.access)}catch{}}}refreshMainInBackground(B){let Z=P(B);if(this.inflightMain&&this.inflightMainFp===Z)return;if(this.isBackedOff())return;this.refreshMain(B).catch(()=>{})}isMainStale(){if(!this.main)return!0;return this.now()>=this.main.refreshAfter}isFallbackStale(B,Z){let $=this.getFallback(B,Z);if(!$)return!0;return this.now()>=$.refreshAfter}shouldRefreshOnRequestCount(B){let Z=M1(this.storage);if(Z<=0)return!1;return B>0&&B%Z===0}needsRefresh(B){return this.isMainStale()||this.shouldRefreshOnRequestCount(B)}updateStorage(B){this.storage=B,this.seedMainFromStorage(B),this.seedMainBackoffFromStorage(B)}seedMainFromStorage(B,Z){let $=U1(B);if(!$)return;let W=Z?P(Z):null;if(W&&$.tokenFingerprint&&$.tokenFingerprint!==W)return;let X={quota:$.quota,refreshAfter:U0($.quota,B,$.checkedAt),checkedAt:$.checkedAt};if(this.main&&this.main.checkedAt>=X.checkedAt&&(!W||!this.mainTokenFp||this.mainTokenFp===W))return;if(this.main=X,this.mainTokenFp=$.tokenFingerprint??null,B?.mainAccountId){if(this.mainQuotaAccountId&&this.mainQuotaAccountId!==B.mainAccountId)this.clearRateLimited("main");this.mainQuotaAccountId=B.mainAccountId}}seedMainBackoffFromStorage(B){let Z=B?.quota?.mainLastQuotaApiError;this.mainLastApiError=Z&&x(Z,this.now())?Z:void 0}seedFallbacksFromAccounts(B){let Z=v(this.storage);for(let $ of B){if($.enabled===!1)continue;if(!$.quota)continue;let W=Math.max($.quota.primary?.checkedAt??0,$.quota.secondary?.checkedAt??0);if(W<=0)continue;let X=this.getFallback($.id,$.access);if(X&&X.checkedAt>=W)continue;this.setFallback($.id,{quota:$.quota,refreshAfter:W+Z,checkedAt:W},$.access,!1,$.accountId)}}isBackedOff(){return x(this.mainLastApiError,this.now())}isFallbackBackedOff(B,Z){if(Z){if(this.fallbackErrorTokenFps.get(B)!==P(Z))return!1}return x(this.fallbackApiErrors.get(B),this.now())}getLastApiError(){return this.mainLastApiError}static API_CALL_GAP_MS=1000;static fallbackInflightKey(B,Z){return JSON.stringify([B,P(Z)])}static quotaLockName(B){return`opencode-fallback-quota-refresh-${B.replace(/[^a-zA-Z0-9._-]+/g,"-")||"account"}`}_enqueueApiFetch(B){let Z=async()=>{let W=this.now()-this.lastApiCallAt;if(W<O.API_CALL_GAP_MS)await new Promise((X)=>{let G=F1(X,O.API_CALL_GAP_MS-W);if(typeof G==="object"&&"unref"in G)G.unref()});return this.lastApiCallAt=this.now(),B()},$=this.apiGate.then(Z,Z);return this.apiGate=$.catch(()=>{}),$}async _fetchMain(B){let Z=P(B);return this._enqueueApiFetch(async()=>{try{if(this.isBackedOff()){if(this.main)return this.main.quota;throw Error("Quota API rate-limited — try again later")}let $=await T({name:"opencode-main-quota-refresh",ttlMs:30000});if(!$){let W=this.main;if(W&&this.now()<W.refreshAfter)return W.quota;throw Error("Quota refresh is already in progress")}try{let W=this.now(),X=await this._fetchQuota(B),G=this.now();if(this.mainTokenFp=P(B),this.main={quota:X,refreshAfter:U0(X,this.storage,G),checkedAt:G},G0(X))this.clearRateLimited("main");return this.mainLastApiError=void 0,this.onMainQuotaFetched?.(X,G,this.mainTokenFp,W),X}catch(W){throw this._handleMainFetchError(W),W}finally{await $.release()}}finally{if(this.inflightMainFp===Z)this.inflightMain=null,this.inflightMainFp=null}})}async _fetchFallback(B,Z){return this._enqueueApiFetch(async()=>{try{if(this.isFallbackBackedOff(B,Z)){let W=this.getFallback(B,Z);if(W)return W.quota;throw Error("Quota API rate-limited — try again later")}let $=await T({name:O.quotaLockName(B),ttlMs:30000});if(!$){let W=this.getFallback(B,Z);if(W&&this.now()<W.refreshAfter)return W.quota;throw Error("Quota refresh is already in progress")}try{let W=await this._fetchQuota(Z),X=this.now();return this.setFallback(B,{quota:W,refreshAfter:X+v(this.storage),checkedAt:X},Z,!0),this.fallbackApiErrors.delete(B),this.fallbackErrorTokenFps.delete(B),W}finally{await $.release()}}catch($){throw this._handleFallbackFetchError(B,Z,$),$}finally{this.inflightFallbacks.delete(O.fallbackInflightKey(B,Z))}})}async _fetchQuota(B){if(!this.fetchQuotaFn)throw Error("Quota fetch not available — no fetchQuotaFn injected (push-only mode)");return this.fetchQuotaFn({accessToken:B,fetchImpl:this.fetchImpl,now:this.now})}static isAuthError(B){return B?.status===401}_handleMainFetchError(B){if(O.isAuthError(B))return;this.mainLastApiError=I({error:B,now:this.now(),previous:this.mainLastApiError}),this.onApiError?.(this.mainLastApiError)}_handleFallbackFetchError(B,Z,$){if(O.isAuthError($))return;let W=P(Z),X=this.fallbackErrorTokenFps.get(B)===W?this.fallbackApiErrors.get(B):void 0;this.fallbackApiErrors.set(B,I({error:$,now:this.now(),previous:X})),this.fallbackErrorTokenFps.set(B,W)}}function M0(B){return Boolean(B.primary||B.secondary)}function G0(B){let{primary:Z,secondary:$}=B;if(!Z&&!$)return!1;if(Z&&Z.usedPercent>=100)return!1;if($&&$.usedPercent>=100)return!1;return!0}import{createHash as y1,randomUUID as x1}from"node:crypto";import{homedir as T1}from"node:os";import{dirname as f1,join as c}from"node:path";import{setTimeout as A1}from"node:timers/promises";import{randomUUID as _1}from"node:crypto";import{mkdir as q1,rename as C1,rm as E1,writeFile as S1}from"node:fs/promises";import{dirname as R1}from"node:path";async function f(B,Z){await q1(R1(B),{recursive:!0});let $=`${B}.${_1()}.tmp`;await S1($,`${JSON.stringify(Z,null,2)}
88
- `,{encoding:"utf8",mode:384});try{await C1($,B)}catch(W){throw await E1($,{force:!0}).catch(()=>{}),W}}import{readFile as r1}from"node:fs/promises";var E=h("refresh"),_0=h("accounts"),I1=1e4,q0=15000,C0=50,f0="openai-auth.json",w1="openai-auth-state.json";function m1(){if(process.env.OPENCODE_CONFIG_DIR?.trim())return process.env.OPENCODE_CONFIG_DIR.trim();return c(process.env.XDG_CONFIG_HOME||c(T1(),".config"),"opencode")}function A(){return process.env.OPENCODE_OPENAI_AUTH_FILE?.trim()||c(m1(),f0)}function t(B=A()){let Z=process.env.OPENCODE_OPENAI_AUTH_STATE_FILE?.trim();if(Z)return Z;return k1(B)}function k1(B){return B.endsWith(f0)?c(f1(B),w1):`${B}.state.json`}function b(B){return B.type==="oauth"}function h1(B){let Z=B?.trim();if(!Z)return!1;try{let $=new URL(Z);return($.protocol==="http:"||$.protocol==="https:")&&!$.username&&!$.password}catch{return!1}}function zB(B){return B.costZeroing?.enabled!==!1}class o extends Error{code="ACCOUNT_REMOVED_DURING_REFRESH";constructor(B){super(`Fallback account ${B} was removed before refresh`);this.name="AccountRemovedDuringRefreshError"}}var v1=[401,403,429],E0={primary:0,secondary:0},p1=!1,K0={primary:5,secondary:10};function H(B){return B!=null&&typeof B==="object"&&!Array.isArray(B)}var l1=new Set(["__proto__","constructor","prototype"]);function d1(B){return B.length>0&&!l1.has(B)}function g1(B){return B instanceof o||H(B)&&B.name==="AccountRemovedDuringRefreshError"&&B.code==="ACCOUNT_REMOVED_DURING_REFRESH"}function S0(B){return{id:typeof B.id==="string"&&B.id.trim()?B.id.trim():x1(),label:typeof B.label==="string"?B.label:void 0,enabled:typeof B.enabled==="boolean"?B.enabled:void 0,addedAt:typeof B.addedAt==="number"?B.addedAt:void 0,lastUsed:typeof B.lastUsed==="number"?B.lastUsed:void 0,accountId:typeof B.accountId==="string"?B.accountId:void 0}}function R0(B){if(!H(B))return;if(typeof B.message!=="string")return;let Z=Number(B.checkedAt);if(!Number.isFinite(Z))return;let $=Number(B.nextRetryAt),W=Number(B.retryCount);return{message:B.message,checkedAt:Z,nextRetryAt:Number.isFinite($)?$:void 0,retryCount:Number.isFinite(W)?W:void 0,tokenHash:typeof B.tokenHash==="string"?B.tokenHash:void 0}}function i1(B){if(!H(B))return;let Z={};for(let $ of["primary","secondary"]){let W=B[$];if(!H(W))continue;let X=Number(W.usedPercent),G=Number(W.remainingPercent),z=Number(W.checkedAt);if(!Number.isFinite(X)||!Number.isFinite(G)||!Number.isFinite(z))continue;let K=typeof W.windowMinutes==="number"?W.windowMinutes:Number.NaN;Z[$]={usedPercent:X,remainingPercent:G,checkedAt:z,resetsAt:typeof W.resetsAt==="string"?W.resetsAt:void 0,...Number.isFinite(K)&&K>0?{windowMinutes:K}:{}}}for(let $ of["resetCreditsAvailable","resetCreditsApplicable"]){let W=typeof B[$]==="number"?B[$]:Number.NaN;if(Number.isFinite(W)&&W>=0)Z[$]=W}return Object.keys(Z).length?Z:void 0}function u1(B){if(!H(B))return null;if(B.type==="api"){let Z=typeof B.baseURL==="string"?B.baseURL.trim():"",$=typeof B.apiKey==="string"?B.apiKey.trim():"";if(!h1(Z))return null;let W=B.authHeader==="x-api-key"?"x-api-key":"authorization-bearer";return{...S0(B),type:"api",apiKey:$||void 0,baseURL:Z,authHeader:W}}if(B.type!=="oauth")return null;if(typeof B.refresh!=="string"||!B.refresh.trim())return null;return{...S0(B),type:"oauth",access:typeof B.access==="string"?B.access:void 0,refresh:B.refresh,expires:typeof B.expires==="number"?B.expires:void 0,lastRefreshedAt:typeof B.lastRefreshedAt==="number"?B.lastRefreshedAt:void 0,lastRefreshError:R0(B.lastRefreshError),lastQuotaRefreshError:R0(B.lastQuotaRefreshError),quota:i1(B.quota)}}function s1(B){if(!H(B))return;let Z=Object.create(null);for(let[$,W]of Object.entries(B)){if(!d1($)||!H(W))continue;let X={};if(H(W.inFlight))X.inFlight={...W.inFlight};if(H(W.lastOutcome)&&typeof W.lastOutcome.code==="string"&&W.lastOutcome.code.length>0&&typeof W.lastOutcome.at==="number"&&Number.isFinite(W.lastOutcome.at))X.lastOutcome={code:W.lastOutcome.code,at:W.lastOutcome.at,...H(W.lastOutcome.previousOutcome)&&typeof W.lastOutcome.previousOutcome.code==="string"&&W.lastOutcome.previousOutcome.code.length>0&&typeof W.lastOutcome.previousOutcome.at==="number"&&Number.isFinite(W.lastOutcome.previousOutcome.at)?{previousOutcome:{code:W.lastOutcome.previousOutcome.code,at:W.lastOutcome.previousOutcome.at}}:{}};if(typeof W.cooldownUntil==="number"&&Number.isFinite(W.cooldownUntil))X.cooldownUntil=W.cooldownUntil;if(Object.keys(X).length>0)Z[$]=X}return Object.keys(Z).length>0?Z:void 0}function A0(B){if(!H(B)||!Array.isArray(B.accounts))return null;return{version:1,main:{type:"opencode",provider:"openai"},routing:H(B.routing)?B.routing:void 0,fallbackOn:Array.isArray(B.fallbackOn)?B.fallbackOn.filter((Z)=>Number.isInteger(Z)):void 0,refresh:H(B.refresh)?B.refresh:void 0,quota:H(B.quota)?B.quota:void 0,reset:s1(B.reset),dump:H(B.dump)?B.dump:void 0,costZeroing:H(B.costZeroing)?B.costZeroing:void 0,killswitch:H(B.killswitch)?B.killswitch:void 0,logging:H(B.logging)?B.logging:void 0,cachekeep:H(B.cachekeep)?B.cachekeep:void 0,mainAccountId:typeof B.mainAccountId==="string"?B.mainAccountId:void 0,accounts:B.accounts.map(u1).filter((Z)=>Z!=null)}}async function R(B){try{return{exists:!0,value:JSON.parse(await r1(B,"utf8"))}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,value:null};throw Z}}function D(B){return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0))}async function n1(B){let Z;try{Z=(await R(B)).value}catch{return null}if(!H(Z)||!Array.isArray(Z.accounts))return null;let $=new Set;for(let W of Z.accounts)if(H(W)&&typeof W.id==="string")$.add(W.id);return $}function I0(B,Z){if(!H(B))return B;let $=H(Z)?Z:{},W=H($.main)?$.main:void 0,X=H($.accounts)?$.accounts:{},G=H(B.quota)?B.quota:{},z=H(B.refresh)?B.refresh:{},K=W??G,Y=W??z,j=Array.isArray(B.accounts)?B.accounts.map((Q)=>{if(!H(Q))return Q;let y=typeof Q.id==="string"&&H(X[Q.id])?X[Q.id]:{};return{...Q,...y}}):void 0;return w0({...B,refresh:D({...z,mainLastRefreshError:Y.lastRefreshError,mainRefreshLeaseId:Y.refreshLeaseId,mainRefreshLeaseUntil:Y.refreshLeaseUntil,mainRefreshLeaseTokenHash:Y.refreshLeaseTokenHash}),quota:D({...G,mainQuota:K.quota,mainQuotaCheckedAt:K.quotaCheckedAt,mainQuotaToken:K.quotaToken,mainLastQuotaApiError:K.lastQuotaApiError}),accounts:j})}async function c1(B=A()){let Z=await R(B);if(!Z.exists)return null;let $=await R(t(B));return A0(I0(Z.value,$.value))}function w0(B){return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0))}function o1(B){return D({id:B.id,label:B.label,type:B.type,enabled:B.enabled,addedAt:B.addedAt,accountId:B.accountId,baseURL:B.type==="api"?B.baseURL:void 0,authHeader:B.type==="api"?B.authHeader:void 0})}function m0(B){if(B.type==="api")return D({apiKey:B.apiKey,lastUsed:B.lastUsed});return D({access:B.access,refresh:B.refresh,expires:B.expires,lastUsed:B.lastUsed,lastRefreshedAt:B.lastRefreshedAt,lastRefreshError:B.lastRefreshError,lastQuotaRefreshError:B.lastQuotaRefreshError,quota:B.quota})}function a(B){return Math.max(B?.primary?.checkedAt??0,B?.secondary?.checkedAt??0)}function p(B,Z,$){if($ in Z)B[$]=Z[$];else delete B[$]}function a1(B,Z){return B.access===Z.access&&B.refresh===Z.refresh&&B.expires===Z.expires&&B.lastRefreshedAt===Z.lastRefreshedAt}function t1(B,Z){if(!a1(B,Z))return Z;if(!("lastRefreshError"in Z))return B;if(!("lastRefreshError"in B))return Z;return(Z.lastRefreshError?.checkedAt??0)>(B.lastRefreshError?.checkedAt??0)?Z:B}function e1(B,Z,$){let W=Z.lastRefreshedAt??0,X=$.lastRefreshedAt??0,G=Z.expires??0,z=$.expires??0,K=X>W?$:W>X?Z:z>G?$:G>z?Z:t1(Z,$);p(B,K,"access"),p(B,K,"refresh"),p(B,K,"expires"),p(B,K,"lastRefreshedAt"),p(B,K,"lastRefreshError")}function B6(B,Z){if(!H(B))return Z;let $=B,W=a($.quota),X=a(Z.quota),G=W>X,z=G?{...$,...Z,quota:$.quota,lastQuotaRefreshError:$.lastQuotaRefreshError}:{...$,...Z};if(!G&&!("lastQuotaRefreshError"in Z))delete z.lastQuotaRefreshError;if(!("lastRefreshError"in Z))delete z.lastRefreshError;if(typeof $.lastUsed==="number"&&(typeof Z.lastUsed!=="number"||$.lastUsed>Z.lastUsed))z.lastUsed=$.lastUsed;return e1(z,$,Z),z}function k0(B){let Z=B.refresh?D({enabled:B.refresh.enabled,intervalMinutes:B.refresh.intervalMinutes,refreshBeforeExpiryMinutes:B.refresh.refreshBeforeExpiryMinutes}):void 0,$=B.quota?D({enabled:B.quota.enabled,checkIntervalMinutes:B.quota.checkIntervalMinutes,refreshEveryNRequests:B.quota.refreshEveryNRequests,minimumRemaining:B.quota.minimumRemaining,failClosedOnUnknownQuota:B.quota.failClosedOnUnknownQuota,showToasts:B.quota.showToasts}):void 0;return w0({version:1,main:B.main,routing:B.routing,fallbackOn:B.fallbackOn,refresh:Z,quota:$,reset:B.reset,dump:B.dump,costZeroing:B.costZeroing,killswitch:B.killswitch,logging:B.logging,cachekeep:B.cachekeep,mainAccountId:B.mainAccountId,accounts:B.accounts.map(o1)})}async function d(B){let Z=Date.now()+q0,$=0;while(Date.now()<=Z){$++;let W=await T({name:"save",ttlMs:I1,path:B});if(W)return W;let X=Z-Date.now();if(X<=0)break;await A1(Math.min(C0+d0(C0),X))}throw Error(`Timed out after ${q0}ms waiting for the account store lock on ${B} (${$} attempts); another writer held it for the whole window`)}function h0(B){let Z=Object.fromEntries(B.accounts.map(($)=>[$.id,m0($)]));return{version:1,main:D({quota:B.quota?.mainQuota,quotaCheckedAt:B.quota?.mainQuotaCheckedAt,quotaToken:B.quota?.mainQuotaToken,lastQuotaApiError:B.quota?.mainLastQuotaApiError,lastRefreshError:B.refresh?.mainLastRefreshError,refreshLeaseId:B.refresh?.mainRefreshLeaseId,refreshLeaseUntil:B.refresh?.mainRefreshLeaseUntil,refreshLeaseTokenHash:B.refresh?.mainRefreshLeaseTokenHash}),accounts:Z}}async function YB(B,Z=A()){let $=t(Z),W=await d(Z);try{let X=await d($);try{let G=await R(Z),z=await R($),K=(G.exists?A0(I0(G.value,z.value)):null)??Z6(),Y=B(K)??K,j={...H(G.value)?G.value:{},...k0(Y)};return await f(Z,j),await f($,h0(Y)),Y}finally{await X.release()}}finally{await W.release()}}function Z6(){return{version:1,main:{type:"opencode",provider:"openai"},accounts:[]}}function $6(B,Z){B.main=B.main??{};let $=typeof B.main.quotaCheckedAt==="number"?B.main.quotaCheckedAt:a(B.main.quota),W=typeof Z.quota?.mainQuotaCheckedAt==="number"?Z.quota.mainQuotaCheckedAt:a(Z.quota?.mainQuota);if($>W)return;B.main.quota=Z.quota?.mainQuota,B.main.quotaCheckedAt=Z.quota?.mainQuotaCheckedAt,B.main.quotaToken=Z.quota?.mainQuotaToken,B.main.lastQuotaApiError=Z.quota?.mainLastQuotaApiError}function W6(B,Z){B.main=B.main??{},B.main.lastRefreshError=Z.refresh?.mainLastRefreshError,B.main.refreshLeaseId=Z.refresh?.mainRefreshLeaseId,B.main.refreshLeaseUntil=Z.refresh?.mainRefreshLeaseUntil,B.main.refreshLeaseTokenHash=Z.refresh?.mainRefreshLeaseTokenHash}function Y0(B){if(Array.isArray(B))return B.map(Y0);if(!H(B))return B;return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0).map(([Z,$])=>[Z,Y0($)]))}async function X6(B,Z=A(),$={mainQuota:!0,mainRefresh:!0,accounts:!0}){let W=t(Z),X=await d(W);try{let G=(await R(W)).value,z=H(G)?{...G,version:1}:{version:1};if($.mainQuota)$6(z,B);if($.mainRefresh)W6(z,B);if($.accounts){let K=$.accounts===!0?null:new Set($.accounts),Y=await n1(Z);z.accounts={...H(z.accounts)?z.accounts:{}};for(let J of B.accounts){if(K&&!K.has(J.id))continue;if(Y&&!Y.has(J.id))continue;z.accounts[J.id]=B6(z.accounts[J.id],m0(J))}if(K){for(let J of K)if(!B.accounts.some((j)=>j.id===J))delete z.accounts[J]}if(Y){for(let J of Object.keys(z.accounts))if(!Y.has(J))delete z.accounts[J]}}await f(W,Y0(z))}finally{await X.release()}}function G6(B){return B?.fallbackOn?.length?B.fallbackOn:v1}function JB(B,Z){return G6(Z).includes(B)}function z6(B){let Z=B?.quota?.minimumRemaining||{};return{primary:Z.primary??Z["5h"]??E0.primary,secondary:Z.secondary??Z["1w"]??E0.secondary}}function J0(B){return B?.quota?.enabled!==!1}function g(B){return B?.quota?.failClosedOnUnknownQuota??p1}function v0(B,Z,$=Date.now()){if(!J0(Z))return!0;if(!B)return!g(Z);let W=z6(Z),X=g(Z);for(let G of["primary","secondary"]){let z=B[G];if(!z)continue;if(n(z,$)){if(X)return!1;continue}if(z.remainingPercent<W[G])return!1}return!0}function p0(B){return B?.killswitch?.enabled===!0}function y0(B){return{primary:B?.primary??B?.["5h"]??K0.primary,secondary:B?.secondary??B?.["1w"]??K0.secondary}}function l0(B,Z){if(!B?.killswitch)return K0;if(Z&&B.killswitch.accounts?.[Z])return y0(B.killswitch.accounts[Z]);return y0(B.killswitch.main)}function jB(B,Z,$,W=Date.now()){if(!p0(Z))return!0;if(!B)return!g(Z);let X=l0(Z,$),G=g(Z);for(let z of["primary","secondary"]){let K=B[z];if(!K)continue;if(n(K,W)){if(G)return!1;continue}if(K.remainingPercent<X[z])return!1}return!0}function HB(B,Z,$,W){if(!p0(W))return 300;let X=[],G=[{accountId:void 0,quota:B},...Z];for(let{accountId:K,quota:Y}of G){if(!Y)continue;let J=l0(W,K),j=[],Q=!1;for(let y of["primary","secondary"]){let V=Y[y];if(!V||n(V,$))continue;if(V.remainingPercent>=J[y])continue;let F=V.resetsAt?Date.parse(V.resetsAt):NaN;if(!Number.isFinite(F)||F<=$){Q=!0;break}j.push(F)}if(Q||j.length===0)continue;X.push(Math.max(...j))}if(X.length===0)return 300;let z=Math.min(...X);return Math.max(1,Math.ceil((z-$)/1000))}function K6(B){return typeof B.version==="number"&&Array.isArray(B.accounts)}async function QB(B,Z=A()){let $=t(Z),W=await d(Z);try{let X=await d($);try{let G=await R(Z);if(G.exists&&H(G.value)){if(K6(G.value))return}if(!B)return;let z={version:1,main:{type:"opencode",provider:"openai"},accounts:[]};if(B.access){let J=s({id_token:"",access_token:B.access,refresh_token:B.refresh});if(J)z.mainAccountId=J}let Y={...G.exists&&H(G.value)?G.value:{},...k0(z)};await f(Z,Y),await f($,h0(z))}finally{await X.release()}}finally{await W.release()}}function Y6(B){return B?.refresh?.enabled!==!1}function J6(B){return(B?.refresh?.refreshBeforeExpiryMinutes??240)*60000}function d0(B){return Math.floor(Math.random()*(B+1))}function S(B,Z,$){return!B.access||!B.expires||B.expires-$<=J6(Z)}function j6(B,Z){return Boolean(B.access&&typeof B.expires==="number"&&B.expires>Z)}function H6(B,Z){return Boolean(B.mainAccountId&&Z.accountId&&Z.accountId===B.mainAccountId)}function N(B,Z){let $=B.accounts.findIndex((W)=>W.id===Z.id);if($!==-1)B.accounts[$]=Z}function l(B){return B instanceof Error?B.message:String(B)}function j0(B,Z,$){B.lastRefreshError=N0({error:Z,now:$,refreshToken:B.refresh,previous:B.lastRefreshError})}function z0(B,Z,$){if(B.lastQuotaRefreshError=I({error:Z,now:$,previous:B.lastQuotaRefreshError}),Z?.isRefreshError===!0)j0(B,Z,$)}function Q6(B){return`fallback-oauth-refresh-${y1("sha256").update(B).digest("base64url").slice(0,16)}`}function x0(B,Z){if(!B)return!1;if(!B.resetsAt)return!0;let $=Date.parse(B.resetsAt);return Number.isFinite($)?$>Z:!0}function N6(B,Z){if(!B)return!1;return x0(B.primary,Z)||x0(B.secondary,Z)}function P6(B,Z,$){if(!B)return!1;let W=Z?.quota?.checkIntervalMinutes??5,X=Math.max(1,W)*60000,G=Math.max(B.primary?.checkedAt??0,B.secondary?.checkedAt??0);return $-G<X}function T0(B,Z,$){return!P6(B.quota,Z,$)}function V6(B,Z,$,W){return B0($)&&v0(B.quota,Z,W)&&N6(B.quota,W)}function L6(B){let Z=B?.quota?.checkIntervalMinutes??5;return Math.max(1,Z)*60000}var F6=60000,O6=60000,b6=600000,D6=1e4,U6=100;var NB=globalThis.setTimeout.bind(globalThis),PB=globalThis.clearTimeout.bind(globalThis);class M6{now;fetchImpl;configPath;refreshPromises=new Map;refreshTimer=null;quotaTimer=null;quotaManager;onFallbackStorageChanged;options;constructor(B={}){this.options=B,this.now=B.now??Date.now,this.fetchImpl=B.fetchImpl??fetch,this.configPath=B.configPath??A(),this.quotaManager=B.quotaManager??null,this.onFallbackStorageChanged=B.onFallbackStorageChanged}seedFallbackQuota(B,Z){if(!this.quotaManager)return;if(!B.quota)return;let $=Math.max(B.quota.primary?.checkedAt??0,B.quota.secondary?.checkedAt??0);if($<=0)return;let W=this.quotaManager.getFallback(B.id,B.access);if(W&&W.checkedAt>=$)return;this.quotaManager.setFallback(B.id,{quota:B.quota,refreshAfter:$+L6(Z),checkedAt:$},B.access,!1,B.accountId)}async load(){return c1(this.configPath)}async save(B,Z){await X6(B,this.configPath,{accounts:Z??!0})}startBackgroundRefresh(){let B=async()=>{if(await this.refreshDueAccounts(),this.options.fetchQuotaFn)await this.refreshQuotaForDueAccounts()};if(B().catch(()=>{}),!this.refreshTimer){if(this.refreshTimer=setInterval(()=>{B().catch(()=>{})},F6+d0(O6)),"unref"in this.refreshTimer)this.refreshTimer.unref()}}stopBackgroundRefresh(){if(this.refreshTimer)clearInterval(this.refreshTimer);if(this.quotaTimer)clearInterval(this.quotaTimer);this.refreshTimer=null,this.quotaTimer=null}async getUsableFallbackAccounts(B){let Z=B!==void 0?B:await this.load();if(!Z)return[];let $=[],W=!1;for(let X of Z.accounts){if(X.enabled===!1||!b(X))continue;if(H6(Z,X))continue;let G=!1,z=X;try{if(S(z,Z,this.now())){let K=z.lastRefreshError;if(K&&U(K,z.refresh,this.now()))throw G=!0,Error(i(K,this.now()));try{z=await this.refreshAccount(z,Z),W=!0}catch(Y){if(g1(Y))continue;G=!0;let J=Z.accounts.find((j)=>j.id===X.id&&b(j));if(J&&!U(J.lastRefreshError,J.refresh,this.now()))j0(J,Y,this.now()),N(Z,J),W=!0;throw Y}}if(this.seedFallbackQuota(z,Z),this.accountPassesQuotaPolicy(this.quotaPolicyAccount(z),Z))$.push(z)}catch(K){let Y=j6(z,this.now());if(G){if(!Y)continue}else if(!Y)continue;if(V6(z,Z,K,this.now()))E.debug("fallback quota using cached quota after refresh error",{pid:process.pid,accountId:z.id,error:l(K)}),$.push(z);else if(!g(Z))$.push(z)}}if(W)try{await this.save(Z)}catch(X){_0.warn("fallback selection bookkeeping not persisted",{pid:process.pid,error:l(X)})}return $}async markUsed(B){try{let Z=await this.load();if(!Z)return;let $=Z.accounts.find((W)=>W.id===B.id);if(!$)return;$.lastUsed=this.now(),await this.save(Z,[$.id])}catch(Z){_0.warn("lastUsed stamp not persisted",{pid:process.pid,accountId:B.id,error:l(Z)})}}accountPassesQuotaPolicy(B,Z){return v0(B.quota,Z,this.now())}quotaPolicyAccount(B){if(!this.quotaManager)return B;let Z=this.quotaManager.getFallback(B.id,B.access)?.quota;return Z?{...B,quota:Z}:B}async refreshDueAccounts(){let B=await this.load();if(!B||!Y6(B))return;let Z=!1;for(let $ of B.accounts){if($.enabled===!1||!b($))continue;if(!S($,B,this.now()))continue;if(U($.lastRefreshError,$.refresh,this.now()))continue;try{E.debug("fallback oauth background due",{pid:process.pid,accountId:$.id,expiresInMs:$.expires?$.expires-this.now():void 0}),await this.refreshAccount($,B),Z=!0}catch(W){E.warn("fallback oauth background failed",{pid:process.pid,accountId:$.id,error:l(W)}),j0($,W,this.now()),N(B,$),Z=!0}}if(Z)await this.save(B)}async refreshQuotaForDueAccounts(){let B=await this.load();if(!B||!J0(B))return;if(!this.options.fetchQuotaFn)return;let Z=!1;for(let $ of B.accounts){if($.enabled===!1||!b($))continue;let W=$;try{if(S(W,B,this.now())){if(U(W.lastRefreshError,W.refresh,this.now()))continue;W=await this.refreshAccount(W,B),Z=!0}if(x(W.lastQuotaRefreshError,this.now()))continue;if(this.seedFallbackQuota(W,B),!(this.quotaManager?this.quotaManager.isFallbackStale(W.id,W.access):T0(W,B,this.now())))continue;await this.refreshAccountQuota(W,B),Z=!0}catch(X){z0($,X,this.now()),N(B,$),Z=!0}}if(Z)await this.save(B),this.onFallbackStorageChanged?.()}async refreshQuotaForAllAccounts(B={}){let Z=await this.load(),$=[];if(!Z||!J0(Z))return{storage:Z,errors:$};if(!this.options.fetchQuotaFn)return{storage:Z,errors:$};let W=B.force??!1,X=!1;for(let G of Z.accounts){if(G.enabled===!1||!b(G))continue;let z=G;try{if(S(z,Z,this.now())){let K=z.lastRefreshError;if(K&&U(K,z.refresh,this.now()))throw Error(i(K,this.now()));z=await this.refreshAccount(z,Z),X=!0}if(!W&&!T0(z,Z,this.now())){if(z.lastQuotaRefreshError)z.lastQuotaRefreshError=void 0,N(Z,z),X=!0;continue}await this.refreshAccountQuota(z,Z),X=!0}catch(K){z0(G,K,this.now()),N(Z,G),X=!0,$.push({accountId:G.id,message:l(K)})}}if(X)await this.save(Z);return{storage:Z,errors:$}}async refreshAccount(B,Z,$={}){let W=this.refreshPromises.get(B.id);if(W){let z=await W;return N(Z,z),z}let X=this.refreshAccountNow(B,Z,$).finally(()=>{this.refreshPromises.delete(B.id)});this.refreshPromises.set(B.id,X);let G=await X;return N(Z,G),G}async waitForConcurrentFallbackRefresh(B,Z,$,W){let X=Date.now()+D6;while(Date.now()<X){await new Promise((J)=>setTimeout(J,U6));let G=await this.load(),z=G?.accounts.find((J)=>J.id===B.id&&b(J));if(!z)continue;if((z.access!==$.access||z.refresh!==$.refresh||(z.expires??0)>($.expires??0)+60000)&&(W.force||!S(z,G,this.now())))return N(Z,z),E.debug("fallback oauth joined concurrent refresh",{pid:process.pid,accountId:z.id,expiresInMs:z.expires?z.expires-this.now():void 0}),z;let Y=z.lastRefreshError;if(Y&&U(Y,z.refresh,this.now()))throw N(Z,z),Error(i(Y,this.now()))}return null}async refreshAccountNow(B,Z,$){let W=await this.load(),X=W?.accounts.find((K)=>K.id===B.id&&b(K));if(X&&!$.force&&!S(X,W,this.now()))return N(Z,X),X;let G=X??B,z=await T({name:Q6(G.id),ttlMs:b6,path:this.configPath,now:this.now,renew:!0});if(!z){E.debug("fallback oauth refresh skipped file lock",{pid:process.pid,accountId:G.id});let K=await this.waitForConcurrentFallbackRefresh(B,Z,G,$);if(K)return K;throw Error("Fallback OAuth refresh is already in progress")}try{if(W=await this.load(),X=W?.accounts.find((j)=>j.id===B.id&&b(j)),X&&!$.force&&!S(X,W,this.now()))return N(Z,X),X;if(!X)throw new o(B.id);G=X;let K=this.options.refreshFn??(async()=>{throw Error("No refreshFn injected into FallbackAccountManager")});E.debug("fallback oauth refresh request start",{pid:process.pid,accountId:G.id,force:$.force===!0,expiresInMs:G.expires?G.expires-this.now():void 0});let Y=await K({refreshToken:G.refresh,fetchImpl:this.fetchImpl,now:this.now});if(G.access=Y.access,G.refresh=Y.refresh,G.expires=Y.expires,G.lastRefreshedAt=Y.expires-Y.expiresIn*1000,G.lastRefreshError=void 0,N(Z,G),await this.save(Z),!(await this.load())?.accounts.some((j)=>j.id===B.id))throw new o(B.id);return E.debug("fallback oauth refresh succeeded",{pid:process.pid,accountId:G.id,expiresInMs:G.expires?G.expires-this.now():void 0}),G}finally{await z.release()}}async refreshAccountQuota(B,Z){let $=B;if(!$.access)throw Error(`Fallback account ${B.id} has no access token`);if(!this.options.fetchQuotaFn)throw Error("No fetchQuotaFn injected — wham/usage supplement is disabled");let W=this.options.fetchQuotaFn??(async()=>{throw Error("No fetchQuotaFn injected — wham/usage supplement is disabled")}),X=(G)=>this.quotaManager?this.quotaManager.refreshFallback($.id,G):W({accessToken:G,fetchImpl:this.fetchImpl,now:this.now});try{if(!$.access)throw Error(`Fallback account ${B.id} has no access token`);let G=await X($.access);$.quota=G,$.lastQuotaRefreshError=void 0,N(Z,$),await this.save(Z)}catch(G){throw z0(B,G,this.now()),N(Z,B),G}}}
89
- export{Q0 as h,N0 as i,U as j,i as k,F0 as l,b0 as m,Z1 as n,V0 as o,L0 as p,s as q,$0 as r,W1 as s,C as t,K1 as u,Y1 as v,J1 as w,j1 as x,y6 as y,x6 as z,D0 as A,m6 as B,k6 as C,g6 as D,O as E,A as F,b as G,zB as H,K0 as I,d1 as J,c1 as K,YB as L,JB as M,p0 as N,l0 as O,jB as P,HB as Q,QB as R,M6 as S};