@cortexkit/opencode-openai-auth 0.3.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cli.js +1 -1
- package/dist/codex-http.d.ts +3 -0
- package/dist/config.d.ts +3 -0
- package/dist/core/accounts.d.ts +9 -3
- package/dist/core/oauth.d.ts +1 -1
- package/dist/core/quota-manager.d.ts +2 -2
- package/dist/{index-k5zwf3j1.js → index-1anzb8jh.js} +1 -1
- package/dist/index-1r02s323.js +6 -0
- package/dist/index-2ng03cby.js +2 -0
- package/dist/{index-e7m7qbne.js → index-6y6ss1kc.js} +1 -1
- package/dist/{index-1xmasv0x.js → index-b6kp9ydc.js} +1 -1
- package/dist/index-cz1bkmjz.js +2 -0
- package/dist/index-dzg88nw2.js +89 -0
- package/dist/index-y67qn95a.js +2 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +65 -65
- package/dist/model-costs.d.ts +29 -0
- package/dist/prompt-context.d.ts +1 -1
- package/dist/quota-normalize-8yzxqy78.js +1 -0
- package/dist/quota-normalize.d.ts +13 -4
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/sidebar-state.d.ts +47 -2
- package/dist/sidebar-state.js +1 -1
- package/dist/token-util-h46jb3eg.js +1 -0
- package/dist/token-yzcb1p3e.js +1 -0
- package/dist/tui/command-dialogs.d.ts +8 -1
- package/dist/tui-preferences.js +1 -1
- package/dist/tui.d.ts +18 -1
- package/dist/version.d.ts +1 -1
- package/dist/ws-pool.d.ts +1 -0
- package/package.json +11 -8
- package/src/core/refresh-file-lock.ts +293 -0
- package/src/sidebar-state.ts +392 -13
- package/src/tui/command-dialogs.tsx +43 -25
- package/src/tui/entry.mjs +37 -0
- package/src/tui-compiled/logger.ts +161 -0
- package/src/tui-compiled/rpc/port-file.ts +70 -0
- package/src/tui-compiled/rpc/protocol.ts +31 -0
- package/src/tui-compiled/rpc/rpc-client.ts +78 -0
- package/src/tui-compiled/rpc/rpc-dir.ts +22 -0
- package/src/tui-compiled/sidebar-state.ts +695 -0
- package/src/tui-compiled/tui/command-dialogs.tsx +645 -0
- package/src/tui-compiled/tui-preferences.ts +328 -0
- package/src/tui-compiled/tui.tsx +1098 -0
- package/src/tui-compiled/util/open-url.ts +30 -0
- package/src/tui.tsx +158 -77
- package/dist/index-5s67238f.js +0 -2
- package/dist/index-d9hq0tmc.js +0 -2
- package/dist/index-mrg2fms9.js +0 -2
- package/dist/index-phrx93zy.js +0 -92
- package/dist/index-qdh7pt5a.js +0 -3
- package/dist/quota-normalize-dfdpwwm3.js +0 -1
- package/dist/token-01dcf92a.js +0 -1
- package/dist/token-util-rkqd82q9.js +0 -1
package/dist/index-phrx93zy.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import{ca as g3}from"./index-qdh7pt5a.js";import{ka as U0}from"./index-e7m7qbne.js";import{createHash as e3}from"node:crypto";var B0=86400000,Z0=300000,$0=3600000,z0=60000,W0=900000,X0=300000;function W3(B){return B instanceof Error?B.message:String(B)}function G0(B){let Z=B?.status;if(typeof Z==="number")return Z===429||Z>=500;if(!(B instanceof Error))return!1;return B.message.includes("fetch failed")||"code"in B&&(B.code==="ECONNRESET"||B.code==="ECONNREFUSED"||B.code==="ETIMEDOUT"||B.code==="UND_ERR_CONNECT_TIMEOUT")}function X3(B){let Z=W3(B),$=B?.status;if(typeof $==="number")return $===429||$>=500;if(!(B instanceof Error))return!1;let z=B.code;return Z.includes("fetch failed")||z==="ECONNRESET"||z==="ECONNREFUSED"||z==="ETIMEDOUT"||z==="UND_ERR_CONNECT_TIMEOUT"}function C3(B){return e3("sha256").update(B).digest("hex")}function S3(B){let Z=C3(B.refreshToken),z=(B.previous?.tokenHash===Z?B.previous.retryCount??0:0)+1,X,W=B.error?.retryAfter;if(typeof W==="number"&&W>0)X=W*1000;else if(G0(B.error))X=Math.min($0,Z0*2**Math.min(z-1,6));else X=B0;return{message:W3(B.error),checkedAt:B.now,nextRetryAt:B.now+X,retryCount:z,tokenHash:Z}}function q(B,Z,$){if(!B?.nextRetryAt||B.nextRetryAt<=$)return!1;if(!Z)return!0;return B.tokenHash===C3(Z)}function a(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 l(B){let $=(B.previous?.retryCount??0)+1,z,X=B.error?.retryAfter;if(typeof X==="number"&&X>0)z=X*1000;else if(X3(B.error))z=Math.min(W0,z0*2**Math.min($-1,6));else z=X0;return{message:W3(B.error),checkedAt:B.now,nextRetryAt:B.now+z,retryCount:$}}function I(B,Z){if(!B?.nextRetryAt||B.nextRetryAt<=Z)return!1;return!0}function G3(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 z=Math.ceil(($-Date.now())/1000);return z>0?z:void 0}return}import{createServer as K0}from"node:http";import{setTimeout as Y0}from"node:timers/promises";var R3="0.3.3";var e="app_EMoamEEZ73f0CkXaXp7hrann",R="https://auth.openai.com",d=1455,J0=3000,x3=`cortexkit-opencode-openai-auth/${R3}`,A3="main",H0=`"${A3}" is a reserved account id; choose a different label.`;function I3(B){let Z=new Uint8Array(B),$=String.fromCharCode(...Z);return btoa($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function j0(){let Z=Array.from(crypto.getRandomValues(new Uint8Array(43))).map((z)=>"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"[z%66]).join(""),$=I3(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(Z)));return{verifier:Z,challenge:$}}function E3(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 y3(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 z=B.organizations;if(Array.isArray(z)){let X=z[0];if(X&&typeof X==="object"&&!Array.isArray(X)&&typeof X.id==="string"&&X.id.length>0)return X.id}return}function t(B){if(B.id_token){let Z=E3(B.id_token),$=Z&&y3(Z);if($)return $}if(B.access_token){let Z=E3(B.access_token);return Z?y3(Z):void 0}return}function Q0(B){return typeof B==="string"&&B.toLowerCase()===A3}function K3(B){if(Q0(B))throw Error(H0);return B}function V0(B,Z,$){let z=new URLSearchParams({response_type:"code",client_id:e,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`${R}/oauth/authorize?${z.toString()}`}async function N0(B,Z,$){let z=await fetch(`${R}/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:e,code_verifier:$.verifier}).toString()});if(!z.ok)throw Error(`Token exchange failed: ${z.status}`);return await z.json()}function L0(B){return B.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}var b0=`<!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>`,o=(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">${L0(B)}</div>
|
|
85
|
-
</div>
|
|
86
|
-
</body>
|
|
87
|
-
</html>`,i,g,O=new Map;function C(){return O.size}function E(B){if(O.delete(B),C()===0)S()}async function F0(){let B=`http://localhost:${d}/auth/callback`;if(i)return{port:d,redirectUri:B};if(g)return g;g=(async()=>{let Z=K0(($,z)=>{let X=new URL($.url||"/",`http://127.0.0.1:${d}`);if(X.pathname==="/auth/callback"){let W=X.searchParams.get("code"),G=X.searchParams.get("state"),K=X.searchParams.get("error"),Y=X.searchParams.get("error_description");if(K){let H=Y||K;if(G){let V=O.get(G);if(V)V.reject(Error(H)),E(G);else if(C()===0)S()}else if(C()===0)S();z.writeHead(200,{"Content-Type":"text/html"}),z.end(o(H));return}if(!G){if(C()===0)S();z.writeHead(400,{"Content-Type":"text/html"}),z.end(o("Missing state parameter"));return}if(!W){if(C()===0)S();z.writeHead(400,{"Content-Type":"text/html"}),z.end(o("Missing authorization code"));return}let J=O.get(G);if(!J){if(C()===0)S();z.writeHead(400,{"Content-Type":"text/html"}),z.end(o("Unknown state — authorization may have expired"));return}E(G),N0(W,B,J.pkce).then((H)=>J.resolve(H)).catch((H)=>J.reject(H)),z.writeHead(200,{"Content-Type":"text/html"}),z.end(b0);return}if(X.pathname==="/cancel"){let W=X.searchParams.get("state"),G=W?[W]:[...O.keys()];z.writeHead(200),z.end("Login cancelled");for(let K of G){let Y=O.get(K);if(!Y)continue;Y.reject(Error("Login cancelled")),E(K)}if(C()===0)S();return}z.writeHead(404),z.end("Not found")});return await new Promise(($,z)=>{Z.once("error",z),Z.listen(d,"127.0.0.1",()=>{Z.off("error",z),$()})}),i=Z,{port:d,redirectUri:B}})();try{return await g}finally{g=void 0}}function S(){if(i){let B=i;i=void 0,B.close(()=>{}),B.closeIdleConnections?.(),setTimeout(()=>{B.closeAllConnections?.()},25).unref?.()}}function D0(B,Z,$=300000,z){return new Promise((X,W)=>{if(z?.aborted){E(Z),W(Error("Login cancelled"));return}let G=setTimeout(()=>{if(O.get(Z))E(Z),W(Error("OAuth callback timeout — authorization took too long"))},$),K=()=>{if(clearTimeout(G),O.get(Z))E(Z),W(Error("Login cancelled"))};if(z)z.addEventListener("abort",K);O.set(Z,{pkce:B,state:Z,resolve:(Y)=>{if(clearTimeout(G),z)z.removeEventListener("abort",K);X(Y)},reject:(Y)=>{if(clearTimeout(G),z)z.removeEventListener("abort",K);W(Y)}})})}async function O0(){let B=await fetch(`${R}/api/accounts/deviceauth/usercode`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":x3},body:JSON.stringify({client_id:e})});if(!B.ok)throw Error("Failed to initiate device authorization");let Z=await B.json();return{deviceData:Z,url:`${R}/codex/device`,instructions:`Enter code: ${Z.user_code}`}}async function P0(B,Z){let $=Math.max(parseInt(B.interval,10)||5,1)*1000,z=typeof B.expires_in==="number"?B.expires_in:parseInt(B.expires_in||"",10),X=!Number.isNaN(z)&&z>0?z*1000:900000,W=Date.now();while(!0){if(Z?.aborted)throw Error("Device authorization cancelled");if(Date.now()-W>X)throw Error("Device authorization expired");let G=await fetch(`${R}/api/accounts/deviceauth/token`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":x3},body:JSON.stringify({device_auth_id:B.device_auth_id,user_code:B.user_code})});if(G.ok){let J=await G.json(),H=await fetch(`${R}/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:`${R}/deviceauth/callback`,client_id:e,code_verifier:J.code_verifier}).toString()});if(!H.ok)throw Error(`Token exchange failed: ${H.status}`);return await H.json()}if(G.status!==403&&G.status!==404)throw Error(`Device authorization failed: ${G.status}`);let K=X-(Date.now()-W);if(K<=0)throw Error("Device authorization expired");let Y=Math.min($+J0,K);try{await Y0(Y,void 0,{signal:Z})}catch(J){if(J instanceof Error&&J.name==="AbortError")throw Error("Device authorization cancelled");throw J}}}function aB(B,Z){let $=-1;if(Z.accountId)$=B.findIndex((z)=>z.accountId&&z.accountId===Z.accountId);if($<0)$=B.findIndex((z)=>z.id===Z.id);if($<0&&Z.label&&!Z.accountId)$=B.findIndex((z)=>z.label===Z.label);if($>=0)return B[$]={...B[$],...Z,addedAt:B[$]?.addedAt??Z.addedAt},$;return B.push(Z),B.length-1}async function oB(B={}){let{label:Z,headless:$=!1,signal:z}=B;if(K3(Z),$){let{deviceData:J,url:H,instructions:V}=await O0(),F=(async()=>{let Q=await P0(J,z),N=Date.now(),_=t(Q);return{id:K3(Z||_||crypto.randomUUID()),label:Z||void 0,type:"oauth",access:Q.access_token,refresh:Q.refresh_token,expires:N+(Q.expires_in??3600)*1000,enabled:!0,addedAt:N,lastUsed:N,lastRefreshedAt:N,accountId:_}})();return{url:H,instructions:V,completion:F}}let{redirectUri:X}=await F0(),W=await j0(),G=I3(crypto.getRandomValues(new Uint8Array(32)).buffer),K=V0(X,W,G),Y=(async()=>{try{if(z?.aborted)throw Error("Login cancelled");let J=await D0(W,G,void 0,z),H=Date.now(),V=t(J);return{id:K3(Z||V||crypto.randomUUID()),label:Z||void 0,type:"oauth",access:J.access_token,refresh:J.refresh_token,expires:H+(J.expires_in??3600)*1000,enabled:!0,addedAt:H,lastUsed:H,lastRefreshedAt:H,accountId:V}}finally{E(G)}})();return{url:K,instructions:"Complete authorization in your browser. This window will close automatically.",completion:Y}}var T="primary",f="secondary",M0="app_EMoamEEZ73f0CkXaXp7hrann",_0="https://auth.openai.com";async function BZ(B){let Z=await B.fetchImpl(`${_0}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:B.refreshToken,client_id:M0}).toString()});if(!Z.ok){let z=G3(Z.headers.get("retry-after"));throw Object.assign(Error(`Token refresh failed: ${Z.status}`),{status:Z.status,retryAfter:z,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 q0="https://chatgpt.com/backend-api/wham/usage";async function ZZ(B){let Z=await B.fetchImpl(q0,{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(!Z.ok){let z=G3(Z.headers.get("retry-after"));throw Object.assign(Error(`wham usage check failed: ${Z.status}`),{status:Z.status,retryAfter:z})}let{normalizeWham:$}=await import("./quota-normalize-dfdpwwm3.js");return $(await Z.json())}import{randomUUID as Y3}from"node:crypto";import{mkdir as C0,readFile as J3,rename as S0,rm as u,stat as T3,writeFile as H3}from"node:fs/promises";import{homedir as R0}from"node:os";import{dirname as KZ,join as s}from"node:path";var E0=globalThis.setTimeout.bind(globalThis),y0=globalThis.clearTimeout.bind(globalThis),x0="openai-auth.json";function A0(){if(process.env.OPENCODE_CONFIG_DIR?.trim())return process.env.OPENCODE_CONFIG_DIR.trim();return s(process.env.XDG_CONFIG_HOME||s(R0(),".config"),"opencode")}function I0(B){let Z=B?.code;return Z==="ENOENT"||Z==="EINVAL"||Z==="ENOTDIR"}function T0(){return process.env.OPENCODE_OPENAI_AUTH_FILE?.trim()||s(A0(),x0)}async function m(B){let $=`${B.path??T0()}.${B.name}.lock`,z=s($,"owner.json"),X=Y3(),W=B.now??Date.now,G=null,K=!1;async function Y(){try{return JSON.parse(await J3($,"utf8"))}catch(Q){if(Q.code!=="EISDIR")throw Q;return JSON.parse(await J3(z,"utf8"))}}async function J(){await H3($,`${JSON.stringify({ownerId:X,expiresAt:W()+B.ttlMs})}
|
|
88
|
-
`,{encoding:"utf8",mode:384})}async function H(){try{return await H3($,`${JSON.stringify({ownerId:X,expiresAt:W()+B.ttlMs})}
|
|
89
|
-
`,{encoding:"utf8",mode:384,flag:"wx"}),!0}catch(Q){let N=Q.code;if(N==="EEXIST"||N==="EISDIR")return!1;throw Q}}function V(){if(!B.renew||K)return;let Q=B.renewIntervalMs??Math.max(1000,Math.floor(B.ttlMs/3));if(G=E0(()=>{(async()=>{try{let N=await Y(),_=W();if(K||N?.ownerId!==X||Number(N?.expiresAt)<=_)return;await J(),V()}catch{}})()},Q),"unref"in G)G.unref()}let F=await H();if(!F){let Q=`${$}.evicting`,N=s(Q,"owner.json"),_=Y3(),lB=5000,dB=8;async function c(){await new Promise((D)=>setTimeout(D,Math.floor(Math.random()*4)))}async function P3(){try{let D=await Y();return Number(D?.expiresAt)>W()}catch{try{return(await T3($)).mtimeMs+B.ttlMs>W()}catch{return!1}}}async function v(){try{return JSON.parse(await J3(N,"utf8"))?.ownerId===_}catch{return!1}}async function t3(){await C0(Q);try{await H3(N,`${JSON.stringify({ownerId:_,createdAt:W()})}
|
|
90
|
-
`,{encoding:"utf8",mode:384,flag:"wx"})}catch(D){if(I0(D))return!1;throw await U3(),D}return await B.onStep?.("eviction-marker-acquired"),!0}async function U3(){if(await v())await u(Q,{recursive:!0,force:!0}).catch(()=>{})}for(let D=0;D<8;D++){if(F=await H(),F)break;if(await P3())return null;try{if(!await t3()){await c();continue}}catch(M3){if(M3.code!=="EEXIST")throw M3;let _3;try{_3=await T3(Q)}catch(p){if(p.code==="ENOENT"){await c();continue}throw p}if(_3.mtimeMs+5000>W())return null;await B.onStep?.("stale-marker-stat");let q3=`${Q}.${Y3()}`;try{await S0(Q,q3)}catch(p){if(p.code==="ENOENT"){await c();continue}throw p}await B.onStep?.("stale-marker-claimed"),await u(q3,{recursive:!0,force:!0}).catch(()=>{}),await c();continue}try{if(await P3())return null;if(!await v())return null;if(await B.onStep?.("stale-lock-confirmed"),!await v())return null;if(await u($,{recursive:!0,force:!0}).catch(()=>{}),!await v())return null;if(F=await H(),!F)return null;if(!await v())return await u($,{recursive:!0,force:!0}).catch(()=>{}),F=!1,null;break}finally{await U3()}}}if(!F)return null;return V(),{release:async()=>{if(K=!0,G)y0(G),G=null;try{if((await Y())?.ownerId!==X)return}catch{return}await u($,{recursive:!0,force:!0}).catch(()=>{})}}}import{createHash as f0}from"node:crypto";var m0=globalThis.setTimeout,w0=5;function w(B){let Z=B?.quota?.checkIntervalMinutes??w0;return Math.max(1,Z)*60000}function k0(B){return B?.quota?.enabled!==!1}function Q3(B,Z){if(!B?.resetsAt)return!1;let $=Date.parse(B.resetsAt);return Number.isFinite($)&&$<=Z}function VZ(B,Z,$,z){let X=Z===T?B?.primary:Z===f?B?.secondary:void 0,W=X?.resetsAt?Date.parse(X.resetsAt):NaN;if(Number.isFinite(W)&&W>$)return W;return $+z}function h0(B){let Z=B?.quota?.minimumRemaining||{};return{primary:Z.primary??Z["5h"]??15,secondary:Z.secondary??Z["1w"]??10}}function f3(B,Z,$){if(!k0(Z))return $+w(Z);let z=h0(Z),X=[];for(let W of["primary","secondary"]){let G=B?.[W];if(!G)return $+w(Z);if(G.remainingPercent>=z[W])continue;let K=G.resetsAt?Date.parse(G.resetsAt):Number.NaN;if(!Number.isFinite(K)||K<=$)return $+w(Z);X.push(K)}if(!X.length)return $+w(Z);return Math.min(...X)+60000}function v0(B){if(!B?.quota?.mainQuota||!B.quota.mainQuotaCheckedAt)return null;return{quota:B.quota.mainQuota,checkedAt:B.quota.mainQuotaCheckedAt,tokenFingerprint:B.quota.mainQuotaToken}}function p0(B){let Z=B?.quota?.refreshEveryNRequests;return typeof Z==="number"&&Number.isFinite(Z)&&Z>0?Math.floor(Z):0}function b(B){return f0("sha256").update(B).digest("hex").slice(0,16)}class P{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!==b(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)!==b(Z))return this.fallbacks.delete(B),this.fallbackTokenFps.delete(B),null;return $}getAllFallbacks(){return this.fallbacks}setMain(B,Z,$){if(!m3(Z.quota))return;if(this.mainTokenFp=b(B),$&&this.mainQuotaAccountId&&this.mainQuotaAccountId!==$)this.clearRateLimited("main");if($)this.mainQuotaAccountId=$;if(this.main=Z,j3(Z.quota))this.clearRateLimited("main")}peekMainForPolicy(B){if(B&&this.mainQuotaAccountId&&this.mainQuotaAccountId!==B)return null;return this.main}peekFallbackForPolicy(B){return this.fallbacks.get(B)??null}setFallback(B,Z,$){if(!m3(Z.quota))return;if(this.fallbacks.set(B,Z),$)this.fallbackTokenFps.set(B,b($));else this.fallbackTokenFps.delete(B);if(j3(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=b(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 $=P.fallbackInflightKey(B,Z),z=this.inflightFallbacks.get($);if(z)return z;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 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 z=this.getFallback($.id,$.access);if(z&&Z<z.refreshAfter)continue;try{await this.refreshFallback($.id,$.access)}catch{}}}refreshMainInBackground(B){let Z=b(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=p0(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 $=v0(B);if(!$)return;let z=Z?b(Z):null;if(z&&$.tokenFingerprint&&$.tokenFingerprint!==z)return;let X={quota:$.quota,refreshAfter:f3($.quota,B,$.checkedAt),checkedAt:$.checkedAt};if(this.main&&this.main.checkedAt>=X.checkedAt&&(!z||!this.mainTokenFp||this.mainTokenFp===z))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&&I(Z,this.now())?Z:void 0}seedFallbacksFromAccounts(B){let Z=w(this.storage);for(let $ of B){if($.enabled===!1)continue;if(!$.quota)continue;let z=Math.max($.quota.primary?.checkedAt??0,$.quota.secondary?.checkedAt??0);if(z<=0)continue;let X=this.getFallback($.id,$.access);if(X&&X.checkedAt>=z)continue;this.setFallback($.id,{quota:$.quota,refreshAfter:z+Z,checkedAt:z},$.access)}}isBackedOff(){return I(this.mainLastApiError,this.now())}isFallbackBackedOff(B,Z){if(Z){if(this.fallbackErrorTokenFps.get(B)!==b(Z))return!1}return I(this.fallbackApiErrors.get(B),this.now())}getLastApiError(){return this.mainLastApiError}static API_CALL_GAP_MS=1000;static fallbackInflightKey(B,Z){return JSON.stringify([B,b(Z)])}static quotaLockName(B){return`opencode-fallback-quota-refresh-${B.replace(/[^a-zA-Z0-9._-]+/g,"-")||"account"}`}_enqueueApiFetch(B){let Z=async()=>{let z=this.now()-this.lastApiCallAt;if(z<P.API_CALL_GAP_MS)await new Promise((X)=>{let W=m0(X,P.API_CALL_GAP_MS-z);if(typeof W==="object"&&"unref"in W)W.unref()});return this.lastApiCallAt=this.now(),B()},$=this.apiGate.then(Z,Z);return this.apiGate=$.catch(()=>{}),$}async _fetchMain(B){let Z=b(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 m({name:"opencode-main-quota-refresh",ttlMs:30000});if(!$){let z=this.main;if(z&&this.now()<z.refreshAfter)return z.quota;throw Error("Quota refresh is already in progress")}try{let z=this.now(),X=await this._fetchQuota(B),W=this.now();if(this.mainTokenFp=b(B),this.main={quota:X,refreshAfter:f3(X,this.storage,W),checkedAt:W},j3(X))this.clearRateLimited("main");return this.mainLastApiError=void 0,this.onMainQuotaFetched?.(X,W,this.mainTokenFp,z),X}catch(z){throw this._handleMainFetchError(z),z}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 z=this.getFallback(B,Z);if(z)return z.quota;throw Error("Quota API rate-limited — try again later")}let $=await m({name:P.quotaLockName(B),ttlMs:30000});if(!$){let z=this.getFallback(B,Z);if(z&&this.now()<z.refreshAfter)return z.quota;throw Error("Quota refresh is already in progress")}try{let z=await this._fetchQuota(Z),X=this.now();return this.setFallback(B,{quota:z,refreshAfter:X+w(this.storage),checkedAt:X},Z),this.fallbackApiErrors.delete(B),this.fallbackErrorTokenFps.delete(B),z}finally{await $.release()}}catch($){throw this._handleFallbackFetchError(B,Z,$),$}finally{this.inflightFallbacks.delete(P.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(P.isAuthError(B))return;this.mainLastApiError=l({error:B,now:this.now(),previous:this.mainLastApiError}),this.onApiError?.(this.mainLastApiError)}_handleFallbackFetchError(B,Z,$){if(P.isAuthError($))return;let z=b(Z),X=this.fallbackErrorTokenFps.get(B)===z?this.fallbackApiErrors.get(B):void 0;this.fallbackApiErrors.set(B,l({error:$,now:this.now(),previous:X})),this.fallbackErrorTokenFps.set(B,z)}}function m3(B){for(let Z of Object.keys(B))return!0;return!1}function j3(B){let{primary:Z,secondary:$}=B;if(!Z||!$)return!1;return Z.usedPercent<100&&$.usedPercent<100}import{createHash as r0,randomUUID as n0}from"node:crypto";import{homedir as c0}from"node:os";import{dirname as a0,join as B3}from"node:path";import{setTimeout as o0}from"node:timers/promises";import{randomUUID as l0}from"node:crypto";import{mkdir as d0,rename as g0,rm as i0,writeFile as u0}from"node:fs/promises";import{dirname as s0}from"node:path";async function k(B,Z){await d0(s0(B),{recursive:!0});let $=`${B}.${l0()}.tmp`;await u0($,`${JSON.stringify(Z,null,2)}
|
|
91
|
-
`,{encoding:"utf8",mode:384});try{await g0($,B)}catch(z){throw await i0($,{force:!0}).catch(()=>{}),z}}import{readFile as YB}from"node:fs/promises";var y=g3("refresh"),w3=1e4,t0=50,i3="openai-auth.json",e0="openai-auth-state.json";function BB(){if(process.env.OPENCODE_CONFIG_DIR?.trim())return process.env.OPENCODE_CONFIG_DIR.trim();return B3(process.env.XDG_CONFIG_HOME||B3(c0(),".config"),"opencode")}function h(){return process.env.OPENCODE_OPENAI_AUTH_FILE?.trim()||B3(BB(),i3)}function z3(B=h()){let Z=process.env.OPENCODE_OPENAI_AUTH_STATE_FILE?.trim();if(Z)return Z;return ZB(B)}function ZB(B){return B.endsWith(i3)?B3(a0(B),e0):`${B}.state.json`}function U(B){return B.type==="oauth"}function $B(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 xZ(B){return B.costZeroing?.enabled!==!1}class Z3 extends Error{code="ACCOUNT_REMOVED_DURING_REFRESH";constructor(B){super(`Fallback account ${B} was removed before refresh`);this.name="AccountRemovedDuringRefreshError"}}var zB=[401,403,429],k3={primary:0,secondary:0},WB=!1,L3={primary:5,secondary:10};function j(B){return B!=null&&typeof B==="object"&&!Array.isArray(B)}function XB(B){return B instanceof Z3||j(B)&&B.name==="AccountRemovedDuringRefreshError"&&B.code==="ACCOUNT_REMOVED_DURING_REFRESH"}function h3(B){return{id:typeof B.id==="string"&&B.id.trim()?B.id.trim():n0(),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 v3(B){if(!j(B))return;if(typeof B.message!=="string")return;let Z=Number(B.checkedAt);if(!Number.isFinite(Z))return;let $=Number(B.nextRetryAt),z=Number(B.retryCount);return{message:B.message,checkedAt:Z,nextRetryAt:Number.isFinite($)?$:void 0,retryCount:Number.isFinite(z)?z:void 0,tokenHash:typeof B.tokenHash==="string"?B.tokenHash:void 0}}function GB(B){if(!j(B))return;let Z={};for(let $ of["primary","secondary"]){let z=B[$];if(!j(z))continue;let X=Number(z.usedPercent),W=Number(z.remainingPercent),G=Number(z.checkedAt);if(!Number.isFinite(X)||!Number.isFinite(W)||!Number.isFinite(G))continue;Z[$]={usedPercent:X,remainingPercent:W,checkedAt:G,resetsAt:typeof z.resetsAt==="string"?z.resetsAt:void 0}}return Object.keys(Z).length?Z:void 0}function KB(B){if(!j(B))return null;if(B.type==="api"){let Z=typeof B.baseURL==="string"?B.baseURL.trim():"",$=typeof B.apiKey==="string"?B.apiKey.trim():"";if(!$B(Z))return null;let z=B.authHeader==="x-api-key"?"x-api-key":"authorization-bearer";return{...h3(B),type:"api",apiKey:$||void 0,baseURL:Z,authHeader:z}}if(B.type!=="oauth")return null;if(typeof B.refresh!=="string"||!B.refresh.trim())return null;return{...h3(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:v3(B.lastRefreshError),lastQuotaRefreshError:v3(B.lastQuotaRefreshError),quota:GB(B.quota)}}function u3(B){if(!j(B)||!Array.isArray(B.accounts))return null;return{version:1,main:{type:"opencode",provider:"openai"},routing:j(B.routing)?B.routing:void 0,fallbackOn:Array.isArray(B.fallbackOn)?B.fallbackOn.filter((Z)=>Number.isInteger(Z)):void 0,refresh:j(B.refresh)?B.refresh:void 0,quota:j(B.quota)?B.quota:void 0,dump:j(B.dump)?B.dump:void 0,costZeroing:j(B.costZeroing)?B.costZeroing:void 0,killswitch:j(B.killswitch)?B.killswitch:void 0,logging:j(B.logging)?B.logging:void 0,cachekeep:j(B.cachekeep)?B.cachekeep:void 0,mainAccountId:typeof B.mainAccountId==="string"?B.mainAccountId:void 0,accounts:B.accounts.map(KB).filter((Z)=>Z!=null)}}async function A(B){try{return{exists:!0,value:JSON.parse(await YB(B,"utf8"))}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,value:null};throw Z}}function M(B){return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0))}async function JB(B){let Z;try{Z=(await A(B)).value}catch{return null}if(!j(Z)||!Array.isArray(Z.accounts))return null;let $=new Set;for(let z of Z.accounts)if(j(z)&&typeof z.id==="string")$.add(z.id);return $}function s3(B,Z){if(!j(B))return B;let $=j(Z)?Z:{},z=j($.main)?$.main:void 0,X=j($.accounts)?$.accounts:{},W=j(B.quota)?B.quota:{},G=j(B.refresh)?B.refresh:{},K=z??W,Y=z??G,H=Array.isArray(B.accounts)?B.accounts.map((V)=>{if(!j(V))return V;let F=typeof V.id==="string"&&j(X[V.id])?X[V.id]:{};return{...V,...F}}):void 0;return r3({...B,refresh:M({...G,mainLastRefreshError:Y.lastRefreshError,mainRefreshLeaseId:Y.refreshLeaseId,mainRefreshLeaseUntil:Y.refreshLeaseUntil,mainRefreshLeaseTokenHash:Y.refreshLeaseTokenHash}),quota:M({...W,mainQuota:K.quota,mainQuotaCheckedAt:K.quotaCheckedAt,mainQuotaToken:K.quotaToken,mainLastQuotaApiError:K.lastQuotaApiError}),accounts:H})}async function HB(B=h()){let Z=await A(B);if(!Z.exists)return null;let $=await A(z3(B));return u3(s3(Z.value,$.value))}function r3(B){return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0))}function jB(B){return M({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 n3(B){if(B.type==="api")return M({apiKey:B.apiKey,lastUsed:B.lastUsed});return M({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 $3(B){return Math.max(B?.primary?.checkedAt??0,B?.secondary?.checkedAt??0)}function r(B,Z,$){if($ in Z)B[$]=Z[$];else delete B[$]}function QB(B,Z){return B.access===Z.access&&B.refresh===Z.refresh&&B.expires===Z.expires&&B.lastRefreshedAt===Z.lastRefreshedAt}function VB(B,Z){if(!QB(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 NB(B,Z,$){let z=Z.lastRefreshedAt??0,X=$.lastRefreshedAt??0,W=Z.expires??0,G=$.expires??0,K=X>z?$:z>X?Z:G>W?$:W>G?Z:VB(Z,$);r(B,K,"access"),r(B,K,"refresh"),r(B,K,"expires"),r(B,K,"lastRefreshedAt"),r(B,K,"lastRefreshError")}function LB(B,Z){if(!j(B))return Z;let $=B,z=$3($.quota),X=$3(Z.quota),W=z>X,G=W?{...$,...Z,quota:$.quota,lastQuotaRefreshError:$.lastQuotaRefreshError}:{...$,...Z};if(!W&&!("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 NB(G,$,Z),G}function c3(B){let Z=B.refresh?M({enabled:B.refresh.enabled,intervalMinutes:B.refresh.intervalMinutes,refreshBeforeExpiryMinutes:B.refresh.refreshBeforeExpiryMinutes}):void 0,$=B.quota?M({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 r3({version:1,main:B.main,routing:B.routing,fallbackOn:B.fallbackOn,refresh:Z,quota:$,dump:B.dump,costZeroing:B.costZeroing,killswitch:B.killswitch,logging:B.logging,cachekeep:B.cachekeep,mainAccountId:B.mainAccountId,accounts:B.accounts.map(jB)})}async function n(B){let Z=Date.now()+w3;while(Date.now()<=Z){let $=await m({name:"save",ttlMs:w3,path:B});if($)return $;let z=Z-Date.now();if(z<=0)break;await o0(Math.min(t0,z))}throw Error(`Timed out acquiring account store lock for ${B}; refusing to overwrite newer account data`)}function a3(B){let Z=Object.fromEntries(B.accounts.map(($)=>[$.id,n3($)]));return{version:1,main:M({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 IZ(B,Z=h()){let $=z3(Z),z=await n(Z);try{let X=await n($);try{let W=await A(Z),G=await A($),K=(W.exists?u3(s3(W.value,G.value)):null)??bB(),Y=B(K)??K,H={...j(W.value)?W.value:{},...c3(Y)};return await k(Z,H),await k($,a3(Y)),Y}finally{await X.release()}}finally{await z.release()}}function bB(){return{version:1,main:{type:"opencode",provider:"openai"},accounts:[]}}function FB(B,Z){B.main=B.main??{};let $=typeof B.main.quotaCheckedAt==="number"?B.main.quotaCheckedAt:$3(B.main.quota),z=typeof Z.quota?.mainQuotaCheckedAt==="number"?Z.quota.mainQuotaCheckedAt:$3(Z.quota?.mainQuota);if($>z)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 DB(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 b3(B){if(Array.isArray(B))return B.map(b3);if(!j(B))return B;return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0).map(([Z,$])=>[Z,b3($)]))}async function OB(B,Z=h(),$={mainQuota:!0,mainRefresh:!0,accounts:!0}){let z=z3(Z),X=await n(z);try{let W=(await A(z)).value,G=j(W)?{...W,version:1}:{version:1};if($.mainQuota)FB(G,B);if($.mainRefresh)DB(G,B);if($.accounts){let K=$.accounts===!0?null:new Set($.accounts),Y=await JB(Z);G.accounts={...j(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]=LB(G.accounts[J.id],n3(J))}if(K){for(let J of K)if(!B.accounts.some((H)=>H.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 k(z,b3(G))}finally{await X.release()}}function PB(B){return B?.fallbackOn?.length?B.fallbackOn:zB}function TZ(B,Z){return PB(Z).includes(B)}function UB(B){let Z=B?.quota?.minimumRemaining||{};return{primary:Z.primary??Z["5h"]??k3.primary,secondary:Z.secondary??Z["1w"]??k3.secondary}}function F3(B){return B?.quota?.enabled!==!1}function O3(B){return B?.quota?.failClosedOnUnknownQuota??WB}function o3(B,Z,$=Date.now()){if(!F3(Z))return!0;let z=UB(Z);for(let X of["primary","secondary"]){let W=B?.[X];if(!W||Q3(W,$))return!O3(Z);if(W.remainingPercent<z[X])return!1}return!0}function MB(B){return B?.killswitch?.enabled===!0}function p3(B){return{primary:B?.primary??B?.["5h"]??L3.primary,secondary:B?.secondary??B?.["1w"]??L3.secondary}}function _B(B,Z){if(!B?.killswitch)return L3;if(Z&&B.killswitch.accounts?.[Z])return p3(B.killswitch.accounts[Z]);return p3(B.killswitch.main)}function fZ(B,Z,$,z=Date.now()){if(!MB(Z))return!0;let X=_B(Z,$),W=!1;for(let G of["primary","secondary"]){let K=B?.[G];if(!K||Q3(K,z)){W=!0;continue}if(K.remainingPercent<X[G])return!1}if(W)return!O3(Z);return!0}function mZ(B,Z,$){let z=[],X=[B,...Z.map((G)=>G.quota)];for(let G of X)for(let K of["primary","secondary"]){let Y=G?.[K]?.resetsAt;if(!Y)continue;let J=Date.parse(Y);if(Number.isFinite(J)&&J>$)z.push(J)}if(z.length===0)return 300;let W=Math.min(...z);return Math.max(1,Math.ceil((W-$)/1000))}function qB(B){return typeof B.version==="number"&&Array.isArray(B.accounts)}async function wZ(B,Z=h()){let $=z3(Z),z=await n(Z);try{let X=await n($);try{let W=await A(Z);if(W.exists&&j(W.value)){if(qB(W.value))return}if(!B)return;let G={version:1,main:{type:"opencode",provider:"openai"},accounts:[]};if(B.access){let J=t({id_token:"",access_token:B.access,refresh_token:B.refresh});if(J)G.mainAccountId=J}let Y={...W.exists&&j(W.value)?W.value:{},...c3(G)};await k(Z,Y),await k($,a3(G))}finally{await X.release()}}finally{await z.release()}}function CB(B){return B?.refresh?.enabled!==!1}function SB(B){return(B?.refresh?.refreshBeforeExpiryMinutes??240)*60000}function RB(B){return Math.floor(Math.random()*(B+1))}function x(B,Z,$){return!B.access||!B.expires||B.expires-$<=SB(Z)}function EB(B,Z){return Boolean(B.access&&typeof B.expires==="number"&&B.expires>Z)}function yB(B,Z){return Boolean(B.mainAccountId&&Z.accountId&&Z.accountId===B.mainAccountId)}function L(B,Z){let $=B.accounts.findIndex((z)=>z.id===Z.id);if($!==-1)B.accounts[$]=Z}function V3(B){return B instanceof Error?B.message:String(B)}function D3(B,Z,$){B.lastRefreshError=S3({error:Z,now:$,refreshToken:B.refresh,previous:B.lastRefreshError})}function N3(B,Z,$){if(B.lastQuotaRefreshError=l({error:Z,now:$,previous:B.lastQuotaRefreshError}),Z?.isRefreshError===!0)D3(B,Z,$)}function xB(B){return`fallback-oauth-refresh-${r0("sha256").update(B).digest("base64url").slice(0,16)}`}function l3(B,Z){if(!B)return!1;if(!B.resetsAt)return!0;let $=Date.parse(B.resetsAt);return Number.isFinite($)?$>Z:!0}function AB(B,Z){if(!B)return!1;return l3(B[T],Z)||l3(B[f],Z)}function IB(B,Z,$){if(!B)return!1;let z=Z?.quota?.checkIntervalMinutes??5,X=Math.max(1,z)*60000,W=Math.max(B[T]?.checkedAt??0,B[f]?.checkedAt??0);return $-W<X}function d3(B,Z,$){return!IB(B.quota,Z,$)}function TB(B,Z,$,z){return X3($)&&o3(B.quota,Z,z)&&AB(B.quota,z)}function fB(B){let Z=B?.quota?.checkIntervalMinutes??5;return Math.max(1,Z)*60000}var mB=60000,wB=60000,kB=600000,hB=1e4,vB=100;var kZ=globalThis.setTimeout.bind(globalThis),hZ=globalThis.clearTimeout.bind(globalThis);class pB{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??h(),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[T]?.checkedAt??0,B.quota[f]?.checkedAt??0);if($<=0)return;let z=this.quotaManager.getFallback(B.id,B.access);if(z&&z.checkedAt>=$)return;this.quotaManager.setFallback(B.id,{quota:B.quota,refreshAfter:$+fB(Z),checkedAt:$},B.access)}async load(){return HB(this.configPath)}async save(B,Z){await OB(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(()=>{})},mB+RB(wB)),"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 $=[],z=!1;for(let X of Z.accounts){if(X.enabled===!1||!U(X))continue;if(yB(Z,X))continue;let W=!1,G=X;try{if(x(G,Z,this.now())){let K=G.lastRefreshError;if(K&&q(K,G.refresh,this.now()))throw W=!0,Error(a(K,this.now()));try{G=await this.refreshAccount(G,Z),z=!0}catch(Y){if(XB(Y))continue;W=!0;let J=Z.accounts.find((H)=>H.id===X.id&&U(H));if(J&&!q(J.lastRefreshError,J.refresh,this.now()))D3(J,Y,this.now()),L(Z,J),z=!0;throw Y}}if(this.seedFallbackQuota(G,Z),this.accountPassesQuotaPolicy(this.quotaPolicyAccount(G),Z))$.push(G)}catch(K){let Y=EB(G,this.now());if(W){if(!Y)continue}else if(!Y)continue;if(TB(G,Z,K,this.now()))y.debug("fallback quota using cached quota after refresh error",{pid:process.pid,accountId:G.id,error:V3(K)}),$.push(G);else if(!O3(Z))$.push(G)}}if(z)await this.save(Z);return $}async markUsed(B){let Z=await this.load();if(!Z)return;let $=Z.accounts.find((z)=>z.id===B.id);if(!$)return;$.lastUsed=this.now(),await this.save(Z)}accountPassesQuotaPolicy(B,Z){return o3(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||!CB(B))return;let Z=!1;for(let $ of B.accounts){if($.enabled===!1||!U($))continue;if(!x($,B,this.now()))continue;if(q($.lastRefreshError,$.refresh,this.now()))continue;try{y.debug("fallback oauth background due",{pid:process.pid,accountId:$.id,expiresInMs:$.expires?$.expires-this.now():void 0}),await this.refreshAccount($,B),Z=!0}catch(z){y.warn("fallback oauth background failed",{pid:process.pid,accountId:$.id,error:V3(z)}),D3($,z,this.now()),L(B,$),Z=!0}}if(Z)await this.save(B)}async refreshQuotaForDueAccounts(){let B=await this.load();if(!B||!F3(B))return;if(!this.options.fetchQuotaFn)return;let Z=!1;for(let $ of B.accounts){if($.enabled===!1||!U($))continue;let z=$;try{if(x(z,B,this.now())){if(q(z.lastRefreshError,z.refresh,this.now()))continue;z=await this.refreshAccount(z,B),Z=!0}if(I(z.lastQuotaRefreshError,this.now()))continue;if(this.seedFallbackQuota(z,B),!(this.quotaManager?this.quotaManager.isFallbackStale(z.id,z.access):d3(z,B,this.now())))continue;await this.refreshAccountQuota(z,B),Z=!0}catch(X){N3($,X,this.now()),L(B,$),Z=!0}}if(Z)await this.save(B),this.onFallbackStorageChanged?.()}async refreshQuotaForAllAccounts(B={}){let Z=await this.load(),$=[];if(!Z||!F3(Z))return{storage:Z,errors:$};if(!this.options.fetchQuotaFn)return{storage:Z,errors:$};let z=B.force??!1,X=!1;for(let W of Z.accounts){if(W.enabled===!1||!U(W))continue;let G=W;try{if(x(G,Z,this.now())){let K=G.lastRefreshError;if(K&&q(K,G.refresh,this.now()))throw Error(a(K,this.now()));G=await this.refreshAccount(G,Z),X=!0}if(!z&&!d3(G,Z,this.now())){if(G.lastQuotaRefreshError)G.lastQuotaRefreshError=void 0,L(Z,G),X=!0;continue}await this.refreshAccountQuota(G,Z),X=!0}catch(K){N3(W,K,this.now()),L(Z,W),X=!0,$.push({accountId:W.id,message:V3(K)})}}if(X)await this.save(Z);return{storage:Z,errors:$}}async refreshAccount(B,Z,$={}){let z=this.refreshPromises.get(B.id);if(z){let G=await z;return L(Z,G),G}let X=this.refreshAccountNow(B,Z,$).finally(()=>{this.refreshPromises.delete(B.id)});this.refreshPromises.set(B.id,X);let W=await X;return L(Z,W),W}async waitForConcurrentFallbackRefresh(B,Z,$,z){let X=Date.now()+hB;while(Date.now()<X){await new Promise((J)=>setTimeout(J,vB));let W=await this.load(),G=W?.accounts.find((J)=>J.id===B.id&&U(J));if(!G)continue;if((G.access!==$.access||G.refresh!==$.refresh||(G.expires??0)>($.expires??0)+60000)&&(z.force||!x(G,W,this.now())))return L(Z,G),y.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&&q(Y,G.refresh,this.now()))throw L(Z,G),Error(a(Y,this.now()))}return null}async refreshAccountNow(B,Z,$){let z=await this.load(),X=z?.accounts.find((K)=>K.id===B.id&&U(K));if(X&&!$.force&&!x(X,z,this.now()))return L(Z,X),X;let W=X??B,G=await m({name:xB(W.id),ttlMs:kB,path:this.configPath,now:this.now,renew:!0});if(!G){y.debug("fallback oauth refresh skipped file lock",{pid:process.pid,accountId:W.id});let K=await this.waitForConcurrentFallbackRefresh(B,Z,W,$);if(K)return K;throw Error("Fallback OAuth refresh is already in progress")}try{if(z=await this.load(),X=z?.accounts.find((H)=>H.id===B.id&&U(H)),X&&!$.force&&!x(X,z,this.now()))return L(Z,X),X;if(!X)throw new Z3(B.id);W=X;let K=this.options.refreshFn??(async()=>{throw Error("No refreshFn injected into FallbackAccountManager")});y.debug("fallback oauth refresh request start",{pid:process.pid,accountId:W.id,force:$.force===!0,expiresInMs:W.expires?W.expires-this.now():void 0});let Y=await K({refreshToken:W.refresh,fetchImpl:this.fetchImpl,now:this.now});if(W.access=Y.access,W.refresh=Y.refresh,W.expires=Y.expires,W.lastRefreshedAt=Y.expires-Y.expiresIn*1000,W.lastRefreshError=void 0,L(Z,W),await this.save(Z),!(await this.load())?.accounts.some((H)=>H.id===B.id))throw new Z3(B.id);return y.debug("fallback oauth refresh succeeded",{pid:process.pid,accountId:W.id,expiresInMs:W.expires?W.expires-this.now():void 0}),W}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 z=this.options.fetchQuotaFn??(async()=>{throw Error("No fetchQuotaFn injected — wham/usage supplement is disabled")}),X=(W)=>this.quotaManager?this.quotaManager.refreshFallback($.id,W):z({accessToken:W,fetchImpl:this.fetchImpl,now:this.now});try{if(!$.access)throw Error(`Fallback account ${B.id} has no access token`);let W=await X($.access);$.quota=W,$.lastQuotaRefreshError=void 0,L(Z,$),await this.save(Z)}catch(W){throw N3(B,W,this.now()),L(Z,B),W}}}
|
|
92
|
-
export{C3 as g,S3 as h,q as i,a as j,x3 as k,I3 as l,j0 as m,E3 as n,y3 as o,t as p,K3 as q,V0 as r,E as s,F0 as t,D0 as u,O0 as v,P0 as w,aB as x,oB as y,BZ as z,ZZ as A,m as B,Q3 as C,VZ as D,P as E,h as F,U as G,xZ as H,L3 as I,HB as J,IZ as K,TZ as L,MB as M,fZ as N,mZ as O,wZ as P,pB as Q};
|
package/dist/index-qdh7pt5a.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{appendFileSync as Y,chmodSync as w,existsSync as B,renameSync as N,statSync as C}from"node:fs";import{tmpdir as F}from"node:os";import{join as x}from"node:path";var $={error:0,warn:1,info:2,debug:3,trace:4},A=!1,D=5242880;function X(){return process.env.OPENCODE_OPENAI_AUTH_LOG_FILE??x(F(),"opencode-openai-auth.log")}var G;function k(q){if(q===void 0||q in $)G=q}function I(){if(G)return G;let q=process.env.OPENCODE_OPENAI_AUTH_LOG_LEVEL;if(q&&q in $)return q;return"info"}var K=/^(authorization|x-api-key|cookie|set-cookie|refresh|access|token)$/i;function b(q){if(K.test(q))return!0;let H=q.toLowerCase().replace(/[-_]/g,"");if(H==="chatgptaccountid")return!0;if(H.includes("apikey"))return!0;if(H.endsWith("secret")||H.endsWith("password"))return!0;if(H.endsWith("token")&&!H.endsWith("tokens"))return!0;return!1}var L=/\b(Bearer\s+[\w.-]+|sk-[\w-]+|eyJ[\w.-]+)\b/g;function P(q){return M(q,new WeakSet)}function M(q,H){if(typeof q==="string")return q.replace(L,"***REDACTED***");if(Array.isArray(q)){if(H.has(q))return"[Circular]";H.add(q);let J=q.map((Q)=>M(Q,H));return H.delete(q),J}if(q&&typeof q==="object"){if(H.has(q))return"[Circular]";H.add(q);let J={};for(let[Q,j]of Object.entries(q))J[Q]=b(Q)?"***REDACTED***":M(j,H);return H.delete(q),J}return q}var Z=[],z,_=3;function U(q){try{w(q,384)}catch{}}function g(){try{let q=X();if(!(B(q)&&C(q).size>D))return;for(let J=_-1;J>=1;J--)if(B(`${q}.${J}`)){let Q=`${q}.${J+1}`;N(`${q}.${J}`,Q),U(Q)}let H=`${q}.1`;N(q,H),U(H)}catch{}}function V(){if(!Z.length)return;let q=Z.join("");Z=[];try{g();let H=X();if(B(H))U(H);Y(H,q,{encoding:"utf8",mode:384})}catch{}}function O(){if(!z)z=setTimeout(()=>{z=void 0,V()},500)}if(!A)process.on("exit",V);function p(q){try{return` ${JSON.stringify(P(q))}`}catch{return" [unserializable]"}}function W(q,H,J,Q){if($[H]>$[I()])return;let j=`[${new Date().toISOString()}] ${H.toUpperCase()} [${q}] ${J}`+(Q===void 0?"":p(Q))+`
|
|
2
|
-
`;if(Z.push(j),Z.length>=50)V();else O()}function y(q){return{error:(H,J)=>W(q,"error",H,J),warn:(H,J)=>W(q,"warn",H,J),info:(H,J)=>W(q,"info",H,J),debug:(H,J)=>W(q,"debug",H,J),trace:(H,J)=>W(q,"trace",H,J)}}
|
|
3
|
-
export{k as aa,P as ba,y as ca};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as a,d as b,e as c,f as d}from"./index-d9hq0tmc.js";import"./index-e7m7qbne.js";export{a as toResetIso,c as normalizeWsFrame,d as normalizeWham,b as normalizeQuotaHeaders};
|
package/dist/token-01dcf92a.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as U,b as V}from"./index-5s67238f.js";import{ia as R}from"./index-e7m7qbne.js";var E=R((M,Q)=>{var{defineProperty:K,getOwnPropertyDescriptor:W,getOwnPropertyNames:X}=Object,Y=Object.prototype.hasOwnProperty,Z=(q,v)=>{for(var z in v)K(q,z,{get:v[z],enumerable:!0})},$=(q,v,z,F)=>{if(v&&typeof v==="object"||typeof v==="function"){for(let G of X(v))if(!Y.call(q,G)&&G!==z)K(q,G,{get:()=>v[G],enumerable:!(F=W(v,G))||F.enumerable})}return q},A=(q)=>$(K({},"__esModule",{value:!0}),q),L={};Z(L,{refreshToken:()=>D});Q.exports=A(L);var H=U(),B=V();async function D(){let{projectId:q,teamId:v}=(0,B.findProjectInfo)(),z=(0,B.loadToken)(q);if(!z||(0,B.isExpired)((0,B.getTokenPayload)(z.token))){let F=await(0,B.getVercelCliToken)();if(!F)throw new H.VercelOidcTokenError("Failed to refresh OIDC token: Log in to Vercel CLI and link your project with `vc link`");if(!q)throw new H.VercelOidcTokenError("Failed to refresh OIDC token: Try re-linking your project with `vc link`");if(z=await(0,B.getVercelOidcToken)(F,q,v),!z)throw new H.VercelOidcTokenError("Failed to refresh OIDC token");(0,B.saveToken)(z,q)}process.env.VERCEL_OIDC_TOKEN=z.token;return}});export default E();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as a}from"./index-5s67238f.js";import"./index-e7m7qbne.js";export default a();
|