@cortexkit/opencode-openai-auth 1.1.0 → 1.3.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.
Files changed (66) hide show
  1. package/dist/bin.js +8 -8
  2. package/dist/{codex-request-BXDXToyt.d.ts → codex-request-B9D0e97Q.d.ts} +177 -28
  3. package/dist/{index-7c6sxtd6.js → index-1mbgsxsr.js} +2 -2
  4. package/dist/{index-4c8yw54k.js → index-2pgkrebq.js} +2 -2
  5. package/dist/index-4v2fs42x.js +65 -0
  6. package/dist/index-8x1aj7q3.js +2 -0
  7. package/dist/{index-f2fmb596.js → index-bc89akak.js} +1 -1
  8. package/dist/index-ex6nx3mq.js +2 -0
  9. package/dist/{index-zpm95mt5.js → index-ftkhhr6d.js} +1 -1
  10. package/dist/{index-msx2m78k.js → index-gn2b097f.js} +2 -2
  11. package/dist/{index-j8v2xwq6.js → index-m3ctrabv.js} +1 -1
  12. package/dist/index-psjyexj3.js +69 -0
  13. package/dist/{index-k6cydkgt.js → index-tddr876f.js} +2 -2
  14. package/dist/index-tn8x5tz8.js +90 -0
  15. package/dist/{index-csky2xpg.js → index-xwvze96g.js} +1 -1
  16. package/dist/index.d.ts +5 -3
  17. package/dist/index.js +1 -1
  18. package/dist/{model-YRg7Uowo.d.ts → model-BdITTmeb.d.ts} +1 -1
  19. package/dist/{port-file-CxEpgSHY.d.ts → port-file-DbHIVC9a.d.ts} +1 -1
  20. package/dist/{protocol-CDV1Pc6h.d.ts → protocol-MysYPAho.d.ts} +1 -1
  21. package/dist/rpc/port-file.d.ts +1 -1
  22. package/dist/rpc/port-file.js +1 -1
  23. package/dist/rpc/protocol.d.ts +1 -1
  24. package/dist/rpc/protocol.js +1 -1
  25. package/dist/rpc/rpc-client.d.ts +3 -3
  26. package/dist/rpc/rpc-client.js +1 -1
  27. package/dist/rpc/rpc-dir.js +1 -1
  28. package/dist/{sidebar-state-DjTWUbmf.d.ts → sidebar-state-CVSok7zv.d.ts} +114 -5
  29. package/dist/sidebar-state.d.ts +2 -2
  30. package/dist/sidebar-state.js +1 -1
  31. package/dist/token-util-cf0nyh7n.js +1 -0
  32. package/dist/{token-rz4t3ay6.js → token-z6qq7a1d.js} +1 -1
  33. package/dist/tui-preferences.js +1 -1
  34. package/dist/tui.d.ts +2 -2
  35. package/dist/v2/server.d.ts +109 -2
  36. package/dist/v2/server.js +3 -3
  37. package/package.json +4 -4
  38. package/src/tui-compiled/raw/shared/0332701351b3eeec-format.js +203 -18
  39. package/src/tui-compiled/raw/shared/0f77ebc3c914c9c6-custody.js +242 -16
  40. package/src/tui-compiled/raw/shared/169b2b4bf30909bc-consumer.js +168 -6
  41. package/src/tui-compiled/raw/shared/375d9cca2def037d-private-files.js +10 -2
  42. package/src/tui-compiled/raw/shared/94f53cfd572ba4bb-availability.js +106 -0
  43. package/src/tui-compiled/raw/shared/d0f0b6be200311af-insula.js +286 -21
  44. package/src/tui-compiled/raw/shared/d5a8f1061ee2f114-index.js +1 -1
  45. package/src/tui-compiled/raw/shared/dc9290c2a7552ba6-watch.js +253 -0
  46. package/src/tui-compiled/raw/shared/e8d3c8da776ef9cd-index.js +4 -1
  47. package/src/tui-compiled/raw/sidebar-state.js +63 -1
  48. package/src/tui-compiled/raw/tui.tsx +82 -30
  49. package/src/tui-compiled/runtime/shared/0332701351b3eeec-format.js +203 -18
  50. package/src/tui-compiled/runtime/shared/0f77ebc3c914c9c6-custody.js +242 -16
  51. package/src/tui-compiled/runtime/shared/169b2b4bf30909bc-consumer.js +168 -6
  52. package/src/tui-compiled/runtime/shared/375d9cca2def037d-private-files.js +10 -2
  53. package/src/tui-compiled/runtime/shared/94f53cfd572ba4bb-availability.js +106 -0
  54. package/src/tui-compiled/runtime/shared/d0f0b6be200311af-insula.js +286 -21
  55. package/src/tui-compiled/runtime/shared/d5a8f1061ee2f114-index.js +1 -1
  56. package/src/tui-compiled/runtime/shared/dc9290c2a7552ba6-watch.js +253 -0
  57. package/src/tui-compiled/runtime/shared/e8d3c8da776ef9cd-index.js +4 -1
  58. package/src/tui-compiled/runtime/sidebar-state.js +63 -1
  59. package/src/tui-compiled/runtime/tui.js +245 -208
  60. package/dist/index-0yh85bwb.js +0 -69
  61. package/dist/index-7eb3dw37.js +0 -90
  62. package/dist/index-8re8rprk.js +0 -2
  63. package/dist/index-edbdscy7.js +0 -65
  64. package/dist/index-m5qmvr6c.js +0 -2
  65. package/dist/map-Buq-GW7l.d.ts +0 -56
  66. package/dist/token-util-tpy2c7h6.js +0 -1
package/dist/v2/server.js CHANGED
@@ -1,3 +1,3 @@
1
- import{c as BZ}from"../index-j8v2xwq6.js";import{A as o2,B as XZ,C as GZ,D as I1,E as y$,F as w$,G as YZ,H as jZ,I as e1,J as $$,K as E2,L as f1,O as H$,P as K$,X as C$,Y as T$,aa as QZ,d as m1,e as s$,f as P2,g as B2,ga as V1,h as A2,ha as W1,i as $Z,j as ZZ,k as S2,ka as VZ,l as H2,n as j1,o as Q1,p as B1,q as g1,r as l1,s as u1,t as o1,u as r1,v as t1,w as V$,x as W$,y as JZ,z as zZ}from"../index-edbdscy7.js";import{$a as D2,Ka as X$,Ra as L$,ab as i$,bb as n$,cb as a$,eb as o$,fb as G$,ob as r$,pb as t$,qb as e$,ra as d$,rb as Y$,sa as R1,ta as O1}from"../index-0yh85bwb.js";import{$b as k$,Fb as S$,Ub as D$,Vb as q$,Xb as b$}from"../index-8re8rprk.js";import{$c as J$,Ad as E1,Gd as x2,Ic as R2,Jc as O2,Kc as p$,Nd as P$,Od as N2,Pd as A1,Qd as x1,Rc as s2,Rd as S1,Sc as C1,Tc as T1,Td as D1,Uc as M1,Ud as q1,Vd as b1,Wd as k1,Xd as y1,Yd as w1,fd as z$,hd as c$,id as F$,jd as _1,mc as P1,sd as z2,xd as L1}from"../index-7eb3dw37.js";import{ce as v1}from"../index-msx2m78k.js";import{le as a1}from"../index-4c8yw54k.js";import"../index-k6cydkgt.js";import{ve as u$,xe as j2}from"../index-7c6sxtd6.js";import"../index-m5qmvr6c.js";import{Te as s1}from"../index-f2fmb596.js";import{Xe as a2,Ye as l$}from"../index-csky2xpg.js";import{AsyncLocalStorage as tZ}from"node:async_hooks";import{randomUUID as eZ}from"node:crypto";class a extends Error{kind;providerID;sessionID;requestKind;constructor($){super($.message??`${$.providerID} ${$.requestKind} request refused (${$.kind})`);this.name="OpenCode2AuthError",this.kind=$.kind,this.providerID=$.providerID,this.sessionID=$.sessionID,this.requestKind=$.requestKind}}function e($){return`common-auth-placeholder.${$}`}function z1($){let Z=e($.integrationID);return{type:"oauth",methodID:$.methodID,access:Z,refresh:Z,expires:$.now+31536000000,metadata:{["commonAuthPlaceholder"]:!0}}}function U2($,Z){if($?.type!=="oauth")return!1;let z=Z===void 0?void 0:e(Z),X=(G)=>z===void 0?G.startsWith("common-auth-placeholder."):G===z;return X($.access)&&X($.refresh)}var X1="No browser sign-in: this connects the plugin to the accounts in its vault.";async function k2($,Z){let z=Z.now??Date.now,{integrationID:X}=Z,G=(K)=>z1({integrationID:X,methodID:K,now:z()}),Q=async(K,L)=>{return await Z.onLogin(K,{integrationID:X,methodID:L}),G(L)},F=(K)=>async(L)=>{let N=K.method.id,H=await K.authorize(L),A={url:H.url,instructions:H.instructions,...H.expiresAt===void 0?{}:{expiresAt:H.expiresAt}};if(H.mode==="auto")return{...A,mode:"auto",callback:H.callback.then((W)=>Q(W,N))};let P=H.callback;return{...A,mode:"code",callback:async(W)=>Q(await P(W),N)}};return $.integration.transform((K)=>{let L=Z.label===void 0?{}:{label:()=>Z.label};for(let A of Z.methods)K.method.update({integrationID:X,method:A.method,authorize:F(A),refresh:async(P)=>{if(!U2(P,X))throw Error("This login method refreshes only its pool placeholder; sign in again with the plugin's login method.");return G(P.methodID)},...L});let N=Z.vault;if(N===void 0)return;let H=N.method.id;K.method.update({integrationID:X,method:N.method,authorize:async()=>({url:"",instructions:N.instructions??X1,mode:"auto",callback:Promise.resolve().then(()=>N.activate({integrationID:X,methodID:H})).then(()=>G(H))}),refresh:async(A)=>{if(!U2(A,X)||A.methodID!==H)throw Error("This login method refreshes only its vault placeholder; choose the plugin's vault login method again.");return G(H)},...L})})}function UZ($){let Z=[],z;for(let X of $.split(/\r?\n/))if(X.startsWith("data:"))Z.push(X.slice(5).replace(/^ /,""));else if(X.startsWith("event:"))z=X.slice(6).trim();if(Z.length===0)return;return z===void 0?{data:Z.join(`
2
- `)}:{event:z,data:Z.join(`
3
- `)}}function y2($,Z){let z=new TextDecoder,X="",G=(F)=>{let K=UZ(F);if(!K)return;try{$(K)}catch(L){Z(L)}},Q=()=>{for(;;){let F=/\r?\n\r?\n/.exec(X);if(!F)return;let K=X.slice(0,F.index);X=X.slice(F.index+F[0].length),G(K)}};return new TransformStream({transform(F,K){K.enqueue(F),X+=z.decode(F,{stream:!0}),Q()},flush(){if(X+=z.decode(),Q(),X.trim()!=="")G(X);X=""}})}var G1=512,Q2="x-common-auth-attempt",Y2=($,Z)=>JSON.stringify([$,Z]),$2=($)=>({providerID:$.model.providerID,modelID:$.model.id,sessionID:$.sessionID,agent:$.agent,kind:$.kind});function HZ($){let Z=$.headers;return typeof Z==="object"&&Z!==null}function KZ($,Z){let z=$.getReader();return new ReadableStream({async pull(X){let G;try{G=await z.read()}catch(Q){Z({reason:"failed",message:Q instanceof Error?Q.message:String(Q)}),X.error(Q);return}if(G.done)Z(),X.close();else X.enqueue(G.value)},async cancel(X){Z({reason:"cancelled",...X===void 0?{}:{message:String(X)}}),await z.cancel(X)}})}function w2($,Z){for(let[z,X]of Object.entries(Z)){let G=z.toLowerCase();for(let Q of Object.keys($))if(Q.toLowerCase()===G)delete $[Q];if(X!==null)$[z]=X}}function NZ($,Z){for(let[z,X]of Object.entries(Z))if(X===null)$.delete(z);else $.set(z,X)}async function I2($,Z,z={}){let{providerID:X}=Z,G=z.gateOnPlaceholder,Q=(J)=>G===void 0||G.credential(J)===e(X),F=z.logger,K=Math.max(1,z.maxRecords??G1),L=[...z.hostCredentials??[e(X)],...G?[e(X)]:[]].filter((J)=>J!==""),N=new Map,H=new WeakMap,A=new Map,P=new Set,W=new Map,g=!1,p=!1,l=new Map,m=0,r=!1,k=new Map,f=(J,j)=>{try{F?.warn(J,j)}catch{}},Y=(J)=>J instanceof Error?J.message:String(J),U=async(J,j)=>{let B=l.get(J);if(!B||B.size===0)return;await Promise.all([...B].map(async(V)=>{try{await V(j)}catch(R){f("opencode2 auth listener threw; the request is unaffected",{event:J,error:Y(R)})}}))},M=async(J,j)=>{try{await Z.onAttemptEnd?.(J,j)}catch(B){f("opencode2 auth onAttemptEnd threw; the request is unaffected",{attemptId:J.attemptId,error:Y(B)})}},C=(J,j)=>{if(J.ended||!J.attempt)return;let B={...J.status===void 0?{}:{status:J.status},outputStarted:J.outputStarted,...J.limit?{limit:J.limit.signal}:{},...j?{error:j}:{}};if(j)J.endError=j;J.ended=M(J.attempt,B)},q=(J,j)=>C(J,{reason:"abandoned",message:j}),T=(J)=>[...N.values()].filter((j)=>j.key===J),x=(J)=>T(J).at(-1),y=(J)=>{if(N.delete(J.id),!T(J.key).length)A.delete(J.key)},b=(J)=>{N.set(J.id,J);while(N.size>K){let j=N.values().next().value;if(j===void 0)break;q(j,"dropped to keep the record bound"),y(j)}},h=(J)=>J.accountId===void 0?void 0:{...J.scope,accountId:J.accountId},i=(J,j)=>new a({kind:"no-account",providerID:X,sessionID:J.sessionID,requestKind:J.kind,...j===void 0?{}:{message:j}}),n=(J)=>{k.get(J)?.clear(),k.delete(J)},c=async(J,j)=>{let B=()=>i(J,`${X} ${J.kind} request has no account: its auth selection was revoked by session forgetting or installation disposal`);if(r)throw B();let V=k.get(J.sessionID);if(!V)V=new Set,k.set(J.sessionID,V);let R={};V.add(R);let S=()=>{if(!V.has(R))throw B()};try{return await j(S)}finally{if(V.delete(R),V.size===0&&k.get(J.sessionID)===V)k.delete(J.sessionID)}},d=(J,j)=>{for(let[B,V]of j)if(L.some((R)=>V.includes(R)))throw new a({kind:"host-credential-on-wire",providerID:X,sessionID:J.sessionID,requestKind:J.kind,message:`${X} ${J.kind} request still carries the host's placeholder credential in ${B}; the adapter's account headers must replace it`})},D=(J)=>{for(let j of T(J))if(j.ended||!j.attempt)y(j);else if(j.transport==="ws"||j.judged)q(j,"a newer attempt of its session and kind began"),y(j)},v=async(J,j,B,V)=>{let R=Y2(J.sessionID,J.kind),S=A.get(R);A.delete(R);let _=S?.accountId??x(R)?.accountId;D(R);let O={...J,..._===void 0?{}:{previousAccountId:_},...S?.rerouteFrom===void 0?{}:{rerouteFrom:S.rerouteFrom}},w=await Z.chooseAccount(O);B();let t={},Z1;if(w!==void 0){let _2=await Z.accountHeaders({...J,accountId:w});if(B(),HZ(_2))t=_2.headers,Z1=_2.attempt;else t=_2}let J1=`attempt-${++m}`,W2={id:J1,key:R,scope:J,accountId:w,headers:t,attempt:w===void 0?void 0:{...J,accountId:w,attemptId:J1,transport:V,data:Z1},...V===void 0?{}:{transport:V},outputStarted:!1};if(b(W2),W2.attempt)U("select",{...J,accountId:W2.attempt.accountId,hook:j,...O.previousAccountId===void 0?{}:{previousAccountId:O.previousAccountId},...O.rerouteFrom===void 0?{}:{rerouteFrom:O.rerouteFrom},handle:W2.attempt});return W2},I=async(J,j,B,V,R)=>{let S=Y2(J.sessionID,J.kind),_=V===void 0?void 0:N.get(V);if(_?.key!==S)_=void 0;if(!_){if(_=x(S),T(S).filter((w)=>w.transport===void 0&&!w.ended).length>1&&!p)p=!0,f("opencode2 auth tied a send without its attempt mark to the newest of several waiting attempts",{sessionID:J.sessionID,kind:J.kind})}if(!_||_.transport!==void 0||_.ended)_=await v(J,j,R,B);else if(_.transport=B,_.attempt)_.attempt.transport=B;if(B==="ws"){for(let O of T(S))if(O!==_&&O.transport==="ws")q(O,"a newer attempt of its session and kind went out over WebSocket")}return _},o=async(J,j)=>{try{return await j()}catch(B){throw C(J,{reason:"failed",message:Y(B)}),B}},T2=(J,j)=>{let B=T(Y2(J,j)).filter((V)=>V.transport==="ws").at(-1);return B?.attempt!==void 0&&!B.ended?B:void 0},V2=(J,j,B)=>{let V=h(J);if(!V||!J.attempt||J.limit)return;J.limit={signal:j,delivered:U("limit",{...V,via:B,limit:j,outputStarted:J.outputStarted,handle:J.attempt})}},M2=(J,j,B,V)=>{let R=h(J);if(!R||!J.attempt)return;U("quota",{...R,transport:j,...V===void 0?{}:{status:V},quota:B,handle:J.attempt})},E=(J,j,B,V)=>{let R=J.attempt;if(!R)return;let S=Z.inspectEvent?.(V===void 0?{transport:j,data:B,attempt:R}:{transport:j,data:B,event:V,attempt:R});if(!S)return;if(S.quota!==void 0)M2(J,j,S.quota);if(S.outputStarted)J.outputStarted=!0;if(S.limit)V2(J,S.limit,j);if(S.error!==void 0)C(J,{reason:"failed",message:S.error});else if(S.done)C(J)},u=(J,j)=>{let B=J.attempt;if(!B||j.accountId===J.accountId)return;if(B.reboundFrom??=B.accountId,B.accountId=j.accountId,"data"in j)B.data=j.data;J.accountId=j.accountId},X2=(J)=>!J.attempt||J.endError!==void 0||J.status!==void 0&&J.status>=400,WZ=(J)=>{let j=[...N.values()].filter((O)=>O.scope.sessionID===J),B=j.filter((O)=>O.limit&&!O.rerouted).at(-1);if(B)return B;let V=j.filter((O)=>O.scope.kind==="primary"),R=V.length>0?V:j;if(R.length<=1)return R[0];let S=R.filter((O)=>!O.judged&&X2(O)).at(-1);if(S)return S;let _=R.filter((O)=>O.attempt&&!O.ended);if(_.length>1)return"ambiguous";return _[0]??R.at(-1)},G2={providerID:X},J2=[];J2.push(await $.session.hook("model.request",(J)=>{if(G)return;return c($2(J),async(j)=>{let B=await v($2(J),"model.request",j);if(j(),B.accountId===void 0)throw i(B.scope);w2(J.headers,{...B.headers,[Q2]:B.id})})},G2)),J2.push(await $.session.hook("http.request",(J)=>{if(G){let j=Q(J.request.headers);if(W.set(J.sessionID,j),!j)return}return c($2(J),async(j)=>{let B=J.request.headers.get(Q2)??void 0,V=G?await v($2(J),"http.request",j,"http"):await I($2(J),"http.request","http",B,j);j();let R=h(V),S=V.attempt;if(!R||!S)throw i(V.scope);await o(V,async()=>{let _=J.request;if(Z.rewriteRequest){if(B!==void 0){let t=new Headers(_.headers);t.delete(Q2),_=new Request(_,{headers:t})}_=await Z.rewriteRequest({...R,request:_,attempt:S})??_,j()}let O=new Headers(_.headers);O.delete(Q2),NZ(O,V.headers),d(V.scope,O.entries());let w=new Request(_,{headers:O});H.set(w,V),J.request=w})})},G2)),J2.push(await $.session.hook("http.response",async(J)=>{let j=H.get(J.request);if(!j){if(G)return;if(!g)g=!0,f("opencode2 auth dropped an http.response whose request it did not produce",{sessionID:J.sessionID,kind:J.kind});return}let B=J.response;if(Z.answeredBy&&j.attempt){let O=j.attempt,w=await o(j,async()=>Z.answeredBy?.({request:J.request,response:B,attempt:O}));if(w)u(j,w)}let V=h(j),R=j.attempt;if(!V||!R)return;j.status=B.status;let S=Z.quotaFromHeaders?.(B.headers,B.status,R);if(S!==void 0)M2(j,"http",S,B.status);if(!B.ok&&Z.limitFromResponse){let O=await Z.limitFromResponse({status:B.status,headers:B.headers,body:()=>B.clone().text(),attempt:R});if(O)V2(j,O,"http")}if(!B.ok||!B.body)C(j);let _=B;if(B.body&&(Z.inspectEvent||Z.onAttemptEnd)){let O=B.body;if(Z.inspectEvent)O=O.pipeThrough(y2((w)=>E(j,"http",w.data,w.event),(w)=>f("opencode2 auth event inspection threw",{error:Y(w)})));_=new Response(KZ(O,(w)=>C(j,w)),{status:B.status,statusText:B.statusText,headers:B.headers})}if(Z.rewriteResponse)_=await Z.rewriteResponse({...V,request:J.request,response:_,attempt:R})??_;if(_!==B)J.response=_},G2)),J2.push(await $.session.hook("experimental.ws.handshake",(J)=>{if(G){let j=Q(new Headers(J.headers)),B=Y2(J.sessionID,J.kind);if(W.set(J.sessionID,j),P.delete(B),!j)return}return c($2(J),async(j)=>{let B;for(let _ of Object.keys(J.headers)){if(_.toLowerCase()!==Q2)continue;B??=J.headers[_],delete J.headers[_]}let V=G?await v($2(J),"experimental.ws.handshake",j,"ws"):await I($2(J),"experimental.ws.handshake","ws",B,j);j();let R=h(V),S=V.attempt;if(!R||!S)throw i(V.scope);await o(V,async()=>{w2(J.headers,V.headers);let _=Z.rewriteHandshakeURL?.({...R,url:J.url,attempt:S});if(_!==void 0)J.url=_;if(d(V.scope,Object.entries(J.headers)),G)P.add(V.key)})})},G2));let t2=Z.rewriteWebSocketFrame?.bind(Z);if(t2)J2.push(await $.session.hook("experimental.ws.send",async(J)=>{let j=$2(J);if(G&&!P.has(Y2(j.sessionID,j.kind)))return;let B=T2(j.sessionID,j.kind),V=await t2({...j,attempt:B?.attempt,frame:J.frame});if(V!==void 0)J.frame=V},G2));J2.push(await $.session.hook("experimental.ws.receive",(J)=>{if(G&&!P.has(Y2(J.sessionID,J.kind)))return;let j=T2(J.sessionID,J.kind);if(!j)return;try{E(j,"ws",J.frame)}catch(B){f("opencode2 auth frame inspection threw",{error:Y(B)})}},G2)),J2.push(await $.session.hook("retry",async(J)=>{if(G&&W.get(J.sessionID)!==!0)return;let j=WZ(J.sessionID);if(!j)return;let B=J.decision;if(j==="ambiguous"){await U("retry",{sessionID:J.sessionID,attempt:J.attempt,reason:"host-decides",hostDecision:B,decision:B});return}let V=j;await c(V.scope,async(R)=>{V.judged=!0;let S=B,_,O,w=V.attempt;if(V.accountId===void 0||!w)S={retry:!1},_="no-account";else if(V.outputStarted)S={retry:!1},_="output-started";else{if(!V.limit){let t=Z.limitFromError?.(J.error,w);if(t)V2(V,t,"error")}if(V.ended)await V.ended,R();if(V.limit)await V.limit.delivered,R(),V.rerouted=!0,O={accountId:V.accountId,limit:V.limit.signal},S={retry:!0,delay:0},_="reroute";else _="host-decides"}if(J.decision=S,S.retry&&V.accountId!==void 0)A.set(V.key,{sessionID:V.scope.sessionID,accountId:V.accountId,...O===void 0?{}:{rerouteFrom:O}});await U("retry",{sessionID:J.sessionID,...V.accountId===void 0?{}:{accountId:V.accountId},kind:V.scope.kind,attempt:J.attempt,reason:_,hostDecision:B,decision:S,...w===void 0?{}:{handle:w}})})},G2));let e2=(J)=>{n(J),W.delete(J);for(let j of P)if(JSON.parse(j)[0]===J)P.delete(j);for(let j of[...N.values()]){if(j.scope.sessionID!==J)continue;q(j,"its session was forgotten"),N.delete(j.id)}for(let[j,B]of A)if(B.sessionID===J)A.delete(j)},b2=new AbortController,$1=$.event;if($1)(async()=>{try{for await(let J of $1.subscribe({signal:b2.signal}))if(J.type==="session.deleted")e2(J.data.sessionID)}catch(J){if(!b2.signal.aborted)f("opencode2 auth stopped listening for session deletion",{error:Y(J)})}})();return{on(J,j){let B=l.get(J);if(!B)B=new Set,l.set(J,B);let V=j;return B.add(V),()=>{B.delete(V)}},accountFor(J,j){return x(Y2(J,j))?.accountId},forgetSession:e2,get size(){return N.size},async dispose(){if(r)return;r=!0;for(let J of k.keys())n(J);b2.abort();for(let J of N.values())q(J,"the installation was disposed");N.clear(),A.clear(),P.clear(),W.clear(),l.clear(),await Promise.all(J2.map(async(J)=>{try{await J.dispose()}catch(j){f("opencode2 auth hook did not dispose cleanly",{error:Y(j)})}}))}}}var Y1=Symbol.for("@cortexkit/openai-auth/opencode2/codex-installation");function FZ(){let $=globalThis;return $[Y1]??=crypto.randomUUID(),$[Y1]}class K2{runtime;store;sessions;installationID;constructor($,Z,z){this.runtime=$;this.store=z;this.installationID=Z??FZ(),this.sessions=z?.sessions??new Map}get($){let Z=this.runtime?.uuid??H2;if(this.store)return this.store.get($,Z);let z=this.sessions.get($);if(!z){let X=Z();z={threadID:X,turnID:Z(),windowID:`${X}:0`},this.sessions.set($,z)}return z}forget($){if(this.store)this.store.delete($);else this.sessions.delete($)}}var f2={version:j1,"user-agent":Q1,originator:"codex_exec"};var PZ=1024,CZ=/(?:^|\/)gpt-6-(?:astra|sol|luna)$/i,L2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($),TZ=($)=>L2($)&&($.type==="message"||("role"in $))&&$.role==="user",MZ=($)=>L2($)&&$.type==="configuration_update";class h2{http;#$=new Map;constructor($=new K2){this.http=$}apply($,Z,z){if(Z.kind!=="primary")return!1;let X=typeof $.model==="string"?$.model:"";if(!V1.has(X))return!1;if(CZ.test(X))return!1;let G=L2($.reasoning)?$.reasoning:void 0,Q=typeof G?.effort==="string"?G.effort:void 0;if(!Q)return!1;let F=this.#$.get(Z.sessionID);if(F===void 0)return this.#Z(Z.sessionID,Q),!1;if(Q===F)return!1;let K=Array.isArray($.input)?$.input:void 0;if(!K||K.length===0)return!1;let L=K.findLastIndex(TZ);if(L<0){if(z==="http")return!1;return $.reasoning={...G,effort:F},!0}if($.reasoning={...G,effort:F},!MZ(K[L-1]))K.splice(L,0,{type:"configuration_update",reasoning:{effort:Q}});return!0}forget($){this.#$.delete($),this.http.forget($)}#Z($,Z){this.#$.set($,Z);while(this.#$.size>PZ){let z=this.#$.keys().next().value;if(z===void 0)break;this.#$.delete(z)}}}function U1($){try{let Z=JSON.parse($);return L2(Z)?Z:void 0}catch{return}}async function H1($,Z,z,X,G=z.http){if($.method.toUpperCase()!=="POST")return;if(!/\/responses\/?$/.test(new URL($.url).pathname))return;let Q=await $.clone().text(),F=U1(Q);if(F)delete F.max_output_tokens;let K=new Headers($.headers),L=B1({rewriteLite:W1,init:{body:F?JSON.stringify(F):$.body===null?void 0:Q},headers:K,metadata:G.get(Z.sessionID),installationID:G.installationID,runtime:G.runtime,websocket:!1,responsesLite:X,applyEffort:(N)=>{z.apply(N,Z,"http")}});return new Request($,{headers:K,body:L.init?.body})}function K1($,Z,z){let X=U1($);if(X?.type!=="response.create")return;let G="max_output_tokens"in X;delete X.max_output_tokens;let Q=z.http.get(Z.sessionID).threadID,F=X.prompt_cache_key!==Q;X.prompt_cache_key=Q;let K=z.apply(X,Z,"ws");return G||F||K?JSON.stringify(X):void 0}function _Z($){return $.replace(/\/responses\/?$/,"").replace(/\/$/,"")}function v2($,Z){let z=new URL($);if(z.origin!=="https://api.openai.com"&&z.origin!=="wss://api.openai.com"||!/\/responses\/?$/.test(z.pathname))return $;let X=new URL(`${_Z(Z)}/responses`);if(X.search=z.search,z.protocol==="ws:"||z.protocol==="wss:")X.protocol=X.protocol==="https:"?"wss:":"ws:";return X.href}var s="openai",LZ=60000,N1=1,EZ="request refused: no account with a usable credential",RZ=1024,Z2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($);function OZ($){let Z=Z2($)?$.counters:void 0,z=Z2(Z)?Z.resetCredits:void 0,X=Z2(z)?z.value:void 0;return typeof X==="number"&&Number.isFinite(X)?X:void 0}function m2($){try{return JSON.parse($)}catch{return}}function F1($){let Z=R2($);return Z?O2(Z):void 0}var AZ=new Set(["usage_limit_reached","rate_limit_exceeded"]);function g2($,Z,z){return{reason:$.window,...z!==void 0?{status:z}:{},...$.resetAt!==void 0?{retryAfterMs:Math.max(0,$.resetAt-Z)}:{}}}function xZ($,Z){let z=E2($);if(z){let Q=typeof $.status==="number"?$.status:void 0;return g2(z,Z,Q)}if($.type!=="response.failed"||!Z2($.response))return;let X=$.response.failed;if(Z2(X)&&typeof X.rate_limit_reached_type==="string")return{reason:X.rate_limit_reached_type};let G=$.response.error;if(Z2(G)){let Q=typeof G.code==="string"?G.code:typeof G.type==="string"?G.type:void 0;if(Q&&AZ.has(Q))return{reason:Q}}return}function SZ($,Z){let z=m2($);if(!Z2(z))return;let X=typeof z.type==="string"?z.type:void 0;if(X==="codex.rate_limits")return{quota:{snapshot:M1(z),complete:!0}};let G=xZ(z,Z);if(G)return{limit:G};if(X===void 0||X==="error")return;return f1(X)?void 0:{outputStarted:!0}}function DZ($){let Z=!1;for(let z of $.keys())if(z.toLowerCase().startsWith("x-codex-")){Z=!0;break}if(!Z)return;return{snapshot:C1($),complete:T1($)}}function qZ($){let Z=$.get("retry-after");if(Z===null)return;let z=Number(Z);return Number.isFinite(z)&&z>=0?z*1000:void 0}function h1($){let{source:Z,pins:z}=$,X=$.now??Date.now,G=$.log,Q=$.vault,F=new h2($.codex),K=new Map,L=(Y)=>`${Y.sessionID}\x00${Y.kind}\x00${Y.accountId}`,N=new Map,H=new Map,A=(Y,U)=>{H.delete(Y),H.set(Y,U);while(H.size>RZ){let M=H.keys().next().value;if(M===void 0)break;H.delete(M)}},P=(Y,U,M)=>{let C=M?[]:I1(Z.peek().rows,Y,U,Q?.identities()??new Set),q=(Q?.routes()??[]).filter((T)=>T.kind==="oauth"&&L1(N2(T.quota),Y,U));return[...C.map((T)=>({id:T.id,...T.identity!==void 0?{identity:T.identity}:{},quota:T.quota,row:T})),...q.map((T)=>({id:T.id,...T.identity!==void 0?{identity:T.identity}:{},quota:T.quota}))]},W=(Y,U,M)=>{let C=S1(Y,U,M),q=Y.map((b)=>({id:b.id,kind:"oauth",...P1(b.quota)?{quota:b.quota}:{}})),T=Y.flatMap((b)=>b.row?[b.row]:[]),x=new Set(Y.filter((b)=>!b.row).map((b)=>b.id)),y=Z.rateLimitMarks(T);for(let b of x){let h=N.get(b);if(h===void 0)continue;if(h<=M)N.delete(b);else y.set(b,h)}return{rows:q,now:M,rateLimitMarks:y,refreshBackoff:Z.refreshBackoffFor(T),killswitch:C,requestPull:(b)=>x.has(b)?Q?.requestReading(b):Z.requestReading(b)}},g=(Y,U,M,C,q)=>{let T=b1({...Y,placement:D1(U),mainId:q});if(T.kind==="block"){G?.debug("pool admission refused the request",{reason:T.block.reason});return}let x=T.order.filter((y)=>!M.has(y));if(C!==void 0&&x.includes(C))return C;return x[0]},p=(Y,U,M,C,q,T)=>{let x=new Map(U.map((D)=>[D.id,D.quota])),y={requestBytes:N1,reservePercent:(D)=>E1(M,D===A1?void 0:D),resetCredits:(D)=>OZ(x.get(D))},b=k1(Y),h=(D,v)=>z.place({sessionId:C,requestBytes:N1,validPinnedAccountIds:Y.rows.map((I)=>I.id).filter((I)=>!b.excluded.has(I)),excludeAccountIds:D,quotaCheckedAtByAccount:Object.fromEntries(Y.rows.map((I)=>[I.id,b.projections.get(I.id)?.checkedAt])),wireAccountIdByAccount:Object.fromEntries(U.map((I)=>[I.id,I.identity])),select:(I)=>y1(Y,y,new Set(D),I),persist:v}),i=[...q],n=h(i,T);if(!n)return;let c=n.accountId,d=w1(Y,y,c);if(d.kind==="none")return;if(d.kind==="move"){let D=h([...i,c],T);if(D)return D.accountId;return d.reason==="killswitch"?void 0:c}if(d.kind==="detour")return h([...i,c],!1)?.accountId;return c},r={providerID:s,chooseAccount:async(Y)=>{let U=await Q?.authority(),M=await $.storage(),C=U!==void 0&&U!=="local",q=()=>{throw new a({kind:"no-account",providerID:s,sessionID:Y.sessionID,requestKind:Y.kind,message:A2})};if(C)await $.awaitVaultRoster?.();else{if(!(await Z.current()).active){if(await $.slotPlaceholderWithoutMain?.())q();G?.warn("the account pool does not serve requests yet; refusing the request",{kind:Y.kind});return}await Z.prepareTokens(Z.peek().rows,M)}let T=X(),x=P(M,T,C),y=q1(W(x.filter((v)=>v.id!==Y.rerouteFrom?.accountId),M,T));if(y)await y,T=X(),x=P(M,T,C);let b=new Map(x.map((v)=>[v.id,v])),h=W(x,M,T),i=new Set(Y.rerouteFrom?[Y.rerouteFrom.accountId]:[]),n=M?.routing?.mode??"main-first",c=Y.kind==="primary",d=new Set,D;for(;;){let v=new Set([...i,...d]);if(D=void 0,n==="sticky-balanced")D=p(h,x,M,Y.sessionID,v,c&&d.size===0);if(D??=g(h,n,v,c?void 0:H.get(Y.sessionID),C?n==="sticky-balanced"?null:x1(Q?.routes()??[]):void 0),D===void 0||d.has(D)){D=void 0;break}let I=b.get(D)?.row;if(I){if(Z.usableToken(I)!==void 0)break;G?.debug("pool row holds no usable token; choosing again",{accountId:D})}else{if(!Q)break;let o=await Q.authorize(D);if(o){K.set(L({...Y,accountId:D}),o);break}G?.debug("the vault refused to serve an account; choosing again",{accountId:D})}d.add(D)}if(D===void 0&&!C&&x.length===0&&await $.slotPlaceholderWithoutMain?.())q();if(D===void 0&&C&&Q&&(x.length===0||d.size>0)){let v=d.size>0?"vault-refused":O1(Q);throw G?.warn("vault mode: no vault account can serve; refusing the request",{cause:v}),new a({kind:"no-account",providerID:s,sessionID:Y.sessionID,requestKind:Y.kind,message:R1[v]})}if(D!==void 0&&c)A(Y.sessionID,D),$.onRoute?.(Y.sessionID,D,n);return G?.debug("pool account chosen",{kind:Y.kind,accountId:D,mode:n,...Y.rerouteFrom?{rerouteFrom:Y.rerouteFrom.accountId}:{}}),D},accountHeaders:async(Y)=>{let{accountId:U}=Y,M=()=>new a({kind:"no-account",providerID:s,sessionID:Y.sessionID,requestKind:Y.kind,message:EZ}),C=Q&&await Q.authority()!=="local"?void 0:Z.peek().rows.find((x)=>x.id===U);if(!C&&Q){let x=L(Y),y=K.get(x)??await Q.authorize(U);if(K.delete(x),!y)throw G?.warn("the vault refused to serve an account; refusing the request",{accountId:U}),M();return{headers:{...f2,"session-id":Y.sessionID,authorization:`Bearer ${y.accessToken}`,"chatgpt-account-id":y.accountIdentity??F1(y.accessToken)??null},attempt:{kind:"vault",routeId:U,receipt:y}}}let q=C?Z.usableToken(C):void 0;if(!C||!q)throw G?.warn("pool row holds no usable token; refusing the request",{accountId:U}),M();let T=C.identity??F1(q);return{headers:{...f2,"session-id":Y.sessionID,authorization:`Bearer ${q}`,"chatgpt-account-id":T??null},attempt:{kind:"pool",token:q,credentialEpoch:C.credentialEpoch}}},async rewriteRequest({request:Y,sessionID:U,kind:M}){let C=$.codexEndpoint?v2(Y.url,$.codexEndpoint()):Y.url,q=C===Y.url?Y:new Request(C,Y);return await H1(q,{sessionID:U,kind:M},F,$.responsesLite?.()??!1)??q},rewriteHandshakeURL:({url:Y})=>$.codexEndpoint?v2(Y,$.codexEndpoint()):void 0,rewriteWebSocketFrame:({frame:Y,sessionID:U,kind:M})=>K1(Y,{sessionID:U,kind:M},F),quotaFromHeaders:(Y)=>DZ(Y),async limitFromResponse({status:Y,headers:U,body:M}){if(Y<400)return;let C=m2(await M().catch(()=>"")),q=E2({...Z2(C)?C:{},status:Y});if(!q)return;let T=X(),x=g2(q,T,Y);if(x.retryAfterMs!==void 0)return x;let y=qZ(U);return y===void 0?x:{...x,retryAfterMs:y}},inspectEvent:({data:Y})=>SZ(Y,X()),limitFromError(Y){let U=m2(Y.message),M=E2({...Z2(U)?U:{},...Y.status!==void 0?{status:Y.status}:{}})??(Y.message.includes("usage_limit_reached")?{window:"usage_limit_reached"}:void 0);return M?g2(M,X(),Y.status):void 0},async onAttemptEnd(Y,U){let M=Y.data;if(M?.kind!=="vault"||U.status!==401)return;G?.warn("a vault account answered 401; reporting it to the vault",{accountId:Y.accountId}),await Q?.reportFailure(M.receipt,401)}},k=(Y,U,M)=>{let C=M.data;if(C?.kind==="vault"){Q?.recordSnapshot(Y,U.snapshot,U.complete,C.receipt);return}if(C?.kind!=="pool")return;if(Z.peek().rows.find((T)=>T.id===Y)?.credentialEpoch!==C.credentialEpoch){G?.debug("quota reading dropped: the row holds another credential",{accountId:Y});return}Z.recordSnapshot(Y,U.snapshot,C.token,U.complete)},f=(Y,U,M)=>{let C=X(),q=M.data?.kind==="vault",T=q?Q?.routes().find((b)=>b.id===Y)?.quota:Z.peek().rows.find((b)=>b.id===Y)?.quota,x=_1(N2(T),U.reason,C,LZ,U.retryAfterMs!==void 0?C+U.retryAfterMs:void 0);if(!q){Z.markRateLimited(Y,x);return}let y=N.get(Y);if(y===void 0||y<x)N.set(Y,x)};return{adapter:r,attach(Y){Y.on("quota",(U)=>k(U.accountId,U.quota,U.handle)),Y.on("limit",(U)=>{f(U.accountId,U.limit,U.handle),G?.debug("pool row refused the request",{accountId:U.accountId,via:U.via,reason:U.limit.reason,outputStarted:U.outputStarted})})},forgetSession(Y){z.forget(Y),H.delete(Y),F.forget(Y)}}}import{mkdirSync as bZ}from"node:fs";import{dirname as kZ,join as yZ,resolve as wZ}from"node:path";var IZ="openai-auth-sessions-opencode2.json";function fZ(){return yZ(m1(),IZ)}var hZ="sessions",vZ=1e4,mZ=5000,gZ=25;class p1{path;options;sessions;#$=new Set;#Z=new Set;#J=Promise.resolve();#z=!1;constructor($,Z={}){this.path=$;this.options=Z;this.sessions=l1($,Z.uuid??H2)}get($,Z=H2){let z=this.sessions.get($);if(!z){let X=Z();z={threadID:X,turnID:Z(),windowID:`${X}:0`},this.sessions.set($,z),this.#Z.delete($),this.#$.add($),this.save()}return z}delete($){this.sessions.delete($),this.#$.delete($),this.#Z.add($),this.save()}save(){if(!this.#z)this.#z=!0,this.#J=this.#J.then(()=>{return this.#z=!1,this.#X()});return this.#J}settled(){return this.#J}async#X(){if(this.#$.size===0&&this.#Z.size===0)return;let $=[...this.#$].flatMap((X)=>{let G=this.sessions.get(X);return G?[[X,G]]:[]}),Z=[...this.#Z],z=null;try{if(bZ(kZ(this.path),{recursive:!0}),z=await this.#G(),!z)return;let X;try{X=g1(this.path)}catch{X=new Map}await this.options.afterRead?.();for(let G of Z)X.delete(G);for(let[G,Q]of $)X.set(G,Q.threadID);u1(this.path,X)}catch{return}finally{await z?.release().catch(()=>{})}for(let[X,G]of $)if(this.sessions.get(X)===G)this.#$.delete(X);for(let X of Z)if(!this.sessions.has(X))this.#Z.delete(X)}async#G(){let $=performance.now()+(this.options.lockWaitMs??mZ);for(;;){let Z=await v1({name:hZ,path:this.path,ttlMs:vZ});if(Z||performance.now()>=$)return Z;await new Promise((z)=>setTimeout(z,gZ))}}}var c1=Symbol.for("@cortexkit/openai-auth/opencode2-codex-sessions"),d1=globalThis,l2=d1[c1]??new Map;d1[c1]=l2;function i1($=fZ()){let Z=wZ($),z=l2.get(Z);if(!z)z=new p1(Z),l2.set(Z,z);return z}var n1=Symbol.for("cortexkit.openai-auth.v2.commands");function lZ(){let $=globalThis;return $[n1]??={locations:new Map},$[n1]}async function Z$($,Z){let z=lZ(),X=$.location.directory,G={menu:Z,session:$.session},Q=await s1(X),F=await a1(e1,Q.dir,()=>$$({...Q,drain:r1,apply:(H)=>{let A=z.locations.get(X);if(!A)throw Error("The OpenAI menu location was closed");return A.menu.apply(H)}})),K=z.locations.get(X);z.locations.set(X,G),await K?.registration?.dispose(),z.command??={name:"openai",description:"OpenAI account menu",async execute(H){let A=z.locations.values().next().value?.session;if(!A)return;let P=await A.get({sessionID:H.sessionID}),W=z.locations.get(P.location.directory);if(!W||!t1(H.sessionID))return;let g=await W.menu.open(H.sessionID);o1(g,H.sessionID)}};let L=z.command;try{G.registration=await $.command.transform((H)=>{H.add(L)})}catch(H){if(z.locations.get(X)===G)z.locations.delete(X);throw await F.release(),H}let N=!1;return async()=>{if(N)return;if(N=!0,z.locations.get(X)===G)z.locations.delete(X);await F.release(),await G.registration?.dispose()}}var uZ="openai-auth-pool-browser",pZ="openai-auth-pool-headless",cZ="openai-auth-vault",dZ="Vault login requires this OpenCode host to be enrolled in the Claustrum vault. Connect to the vault or disconnect this host before trying again.";async function F2($){if(await $.authority()!=="local")throw Error("This host is connected to the credential vault or its enrollment is unreadable; the login was not stored. Disconnect this host from the vault to add a local login.")}function j$($){return{method:{id:cZ,type:"oauth",label:"ChatGPT accounts in the vault"},async activate(){if(await J$($.paths,$.name)!=="vault")throw Error(dZ)}}}function Q$($){let Z=(z,X,G)=>({method:{id:z,type:"oauth",label:X},async authorize(){if($.vault)await F2($.vault);let Q=await $.beginLogin({version:$.version,headless:G});return{url:Q.url,instructions:Q.instructions,mode:"auto",callback:Q.completion}}});return[Z(uZ,"ChatGPT (openai-auth pool, browser)",!1),Z(pZ,"ChatGPT (openai-auth pool, headless)",!0)]}function u2($){let Z=(z)=>typeof z==="string"?z:"";return U2({type:"oauth",access:Z($.access),refresh:Z($.refresh)})||$.refresh===G$||z$($)}function iZ($){if($.accountId)return $.accountId;let Z=$.access?R2($.access):void 0;return Z?O2(Z):void 0}async function B$($,Z,z,X={}){if(X.vault)await F2(X.vault);if(u2(z))throw Error("the credential is not a ChatGPT login (a placeholder or a tombstone); it was not stored");let G=X$($,{rowLocks:(W)=>Y$(Z,W)}),Q=await G.read();if(Q.status!=="ready")throw Error(`the account pool cannot be read (${Q.status}); the login was not stored`);let F={type:"oauth",refresh:z.refresh,...z.access!==void 0?{access:z.access}:{},...z.expires!==void 0?{expires:z.expires}:{}},K=iZ(z);if(X.vault)await F2(X.vault);let L=K!==void 0?{identity:K}:{};if(X.origin==="import"){let W=Q.rows.find((g)=>K!==void 0&&g.identity===K||g.credential?.type==="oauth"&&g.credential.refresh===z.refresh);if(W)return{id:W.id,operation:"kept"}}let N=Q.rows.filter((W)=>W.type==="oauth"&&!W.invalid),H=K?N.find((W)=>W.identity===K):void 0,A=Q.rows.find((W)=>W.id===x2);if(H)return{id:(await G.replace(H.id,F,L)).id,operation:"replaced"};if(!A){let W=await G.add({id:x2,credential:F,...L,...z.label!==void 0?{label:z.label}:{}});return{id:W.id,operation:W.outcome==="added-disabled"?"added-disabled":"added"}}if(!A.invalid&&!A.credential)return{id:(await G.replace(x2,F,L)).id,operation:"replaced"};let P=await G.add({id:z.id,credential:F,...L,...z.label!==void 0?{label:z.label}:{}});return{id:P.id,operation:P.outcome==="added-disabled"?"added-disabled":P.outcome==="rotated"?"replaced":"added"}}function nZ($){let Z=$.itemId!==void 0;switch($.sectionId){case"accounts":return Z?["enable","disable","remove","move"].includes($.actionId):$.actionId==="add";case"routing":return!Z&&["order","mode"].includes($.actionId);case"quota":return $.actionId==="check";case"limits":return Z?$.actionId==="floors":$.actionId==="killswitch";case"session":return!Z&&$.actionId==="clear-pin";case"diagnostics":return!Z&&["logging","dump"].includes($.actionId);case"reset":return Z&&["preview","spend","retry"].includes($.actionId);default:return!1}}function U$($){let Z={...$,allowAction:nZ,unavailableSections:["cache"]};return{open:(z)=>V$(Z,z),apply:(z)=>{let X=z!==null&&typeof z==="object"?z:{},G=X.values&&typeof X.values==="object"&&!Array.isArray(X.values)?Object.fromEntries(Object.entries(X.values).filter(([,Q])=>Q===null||["string","number","boolean"].includes(typeof Q))):void 0;return W$(Z,{command:"openai",sectionId:typeof X.sectionId==="string"?X.sectionId:"",actionId:typeof X.actionId==="string"?X.actionId:"",...G?{values:G}:{},...X.confirmed===!0?{confirmed:!0}:{},...typeof X.itemId==="string"?{itemId:X.itemId}:{},...typeof X.sessionId==="string"?{sessionId:X.sessionId}:{}})}}}function aZ($){if(!H$($.modelID??$.id)){$.enabled=!1;return}let Z=K$($.id);if(Z)$.limit={...Z}}function N$($){return $.model.transform((Z)=>{for(let z of Z.list(s))Z.update(s,String(z.id),(X)=>aZ(X))})}class p2{log;pending=new Map;requests=new Map;writing=new Set;constructor($){this.log=$}async safely($){let Z=(async()=>{try{await $()}catch{this.log.warn("request dump failed")}})();this.writing.add(Z);try{await Z}finally{this.writing.delete(Z)}}async captureHttp($,Z){await this.safely(async()=>{if(!P2().dump)return;let z={sessionID:Z.sessionID,accountId:Z.accountId,transport:"http",phase:"http",url:$.url,method:$.method,headers:new Headers($.headers),bodyText:await $.clone().text()};if(this.pending.set($,{attemptId:Z.attemptId,input:z}),this.requests.set(Z.attemptId,$),this.pending.size>512){let X=this.pending.keys().next().value;if(X)this.take(X)}})}take($){let Z=this.pending.get($);if(Z)this.pending.delete($),this.requests.delete(Z.attemptId);return Z?.input}async response($,Z){let z=this.take($);if(z)await this.safely(()=>S2({...z,status:Z}))}async end($,Z){if(Z.status!==void 0||!Z.error)return;let z=this.requests.get($.attemptId),X=z&&this.take(z);if(!X)return;let{reason:G,message:Q}=Z.error,F=Q?`${G}: ${Q}`:G;await this.safely(()=>S2({...X,error:D2(F,z?.headers.get("authorization")?.replace(/^Bearer /,""))}))}async frame($,Z){await this.safely(()=>S2({sessionID:Z.sessionID,accountId:Z.accountId,transport:"websocket",phase:"observed",bodyText:$}))}clear(){this.pending.clear(),this.requests.clear()}async settle(){await Promise.all(this.writing)}}class c2{counts=new Map;record($,Z){let z=Z.resetCreditsApplicable;this.counts.set($.id,{credentialEpoch:$.credentialEpoch,identity:$.identity,applicable:typeof z==="number"&&Number.isFinite(z)?z:void 0})}applicable($){let Z=this.counts.get($.id);if(!Z||Z.credentialEpoch!==$.credentialEpoch||Z.identity!==$.identity)return;return Z.applicable}}function M$($){return async(Z)=>{let z=Z.credential;if(z.type!=="oauth"||!z.access)throw Error("the row holds no access token to poll with");let X=await F$({accessToken:z.access,fetchImpl:$.fetchImpl,now:$.now,...Z.identity?{accountId:Z.identity}:{},accountKey:Z.id,...$.logger?{logger:$.logger}:{}});return $.counts.record(Z,X),P$(X,$.now(),!0)}}function _$($){let{source:Z,counts:z,now:X}=$,G=async(N)=>{let H=await Z.rowAccess(N,await $.storage());if(!H?.row)throw new C$("unknown_account",`${N==="main"?"Main":"Fallback"} account ${N} was not found.`);return T$(N,H)},Q=async(N)=>{if($.authority&&await $.authority()!=="local")return{account:N,ok:!1,error:"local accounts are not polled while this host is connected to the vault"};let[H]=await Z.pollRows(await $.storage(),{ids:[N]});if(!H)return{account:N,ok:!1,error:"targeted quota refresh returned no result"};return{account:H.id,ok:H.ok,...H.error!==void 0?{error:H.error}:{}}},F=(N)=>Z.peek().rows.find((H)=>H.id===N),K=(N)=>{let H=F(N);if(!H)return null;let A=N2(H.quota)??{},P=z.applicable(H),W=Math.max(0,...[A.primary?.checkedAt,A.secondary?.checkedAt].filter((g)=>typeof g==="number"));return{quota:{...A,...P!==void 0?{resetCreditsApplicable:P}:{}},checkedAt:W,refreshAfter:W,...H.identity!==void 0?{accountId:H.identity}:{}}};return{resolveResetTarget:G,refreshResetTargetQuota:Q,quotaManager:{isRateLimited:(N)=>{let H=F(N);if(!H)return!1;let A=Z.rateLimitMarks([H]).get(H.id);return A!==void 0&&A>X()},getMain:()=>K("main"),getFallback:(N)=>K(N)}}}import{resolve as E$}from"node:path";var sZ=1024;class d2{pins=new Map;listeners=new Set;limit;constructor($=sZ){this.limit=Math.max(1,$)}get($){return this.pins.get($)?.accountId}forget($){this.pins.delete($);for(let Z of this.listeners)Z($)}subscribe($){return this.listeners.add($),()=>{this.listeners.delete($)}}snapshot(){return new Map(this.pins)}get size(){return this.pins.size}set($,Z){this.pins.delete($),this.pins.set($,Z);for(let z of this.listeners)z($,Z);while(this.pins.size>this.limit){let z=this.pins.keys().next().value;if(z===void 0)break;this.forget(z)}}place($){return L$(this.pins,$,(Z,z)=>this.set(Z,z))}}var R$=Symbol.for("@cortexkit/openai-auth/opencode2-pins"),O$=globalThis,i2=O$[R$]??new Map;O$[R$]=i2;function A$($){let Z=JSON.stringify([E$($.configPath),E$($.statePath)]),z=i2.get(Z);if(!z)z=new d2,i2.set(Z,z);return z}import{statSync as oZ}from"node:fs";import{resolve as rZ}from"node:path";function I$($){return $.map((Z)=>{try{let z=oZ(Z);return`${z.ino}:${z.size}:${z.mtimeMs}:${z.ctimeMs}`}catch{return"?"}}).join("|")}function n2($){return I$([$.vault.paths.tokenPath,$.vault.paths.statePath])}function x$($){return I$([$.paths.configPath,$.paths.statePath,$.vault.paths.rosterPath])+n2($)}class f${file;observationIntervalMs;producers=new Set;subscriptions=new Map;observations=new Map;chain=Promise.resolve();timer;constructor($,Z){this.file=$;this.observationIntervalMs=Z}add($){this.producers.add($),this.observations.set($,{stamp:x$($),roster:$.vault.snapshot()});let Z=$.source.subscribe(()=>{this.publish($)}),z=this.subscriptions.get($.pins);if(!z){let X=new Set;z={producers:X,stop:$.pins.subscribe((G,Q)=>{let F=X.values().next().value;if(F)this.publish(F,{sessionId:G,pin:Q,accountId:Q?.accountId,route:"sticky-balanced"})})},this.subscriptions.set($.pins,z)}return z.producers.add($),this.timer??=setInterval(()=>{for(let X of this.producers){let G={stamp:x$(X),roster:X.vault.snapshot()},Q=this.observations.get(X);if(G.stamp!==Q?.stamp||G.roster!==Q?.roster)this.observations.set(X,G),this.publish(X)}},this.observationIntervalMs),this.timer.unref?.(),()=>{if(Z(),this.producers.delete($),this.observations.delete($),z.producers.delete($),!z.producers.size)z.stop(),this.subscriptions.delete($.pins);if(!this.producers.size)clearInterval(this.timer),this.timer=void 0}}publish($,Z){return this.chain=this.chain.then(async()=>{if(!this.producers.has($))return;let X=await $.vault.authority()!=="local",G=n2($),Q=()=>this.producers.has($)&&$.vault.enrolled()===X&&n2($)===G,F=await z2($.paths),K=X?y$($.vault.snapshot()?.rows??[],new Set($.vault.routes().map((N)=>N.id)),F,Date.now()):w$((await $.source.sidebarView()).rows,F,Date.now());if(await D$(K,this.file,{canWrite:Q}),!Q()||!Z)return;let L=K.vaultAccounts??K.fallbacks;if(Z.accountId===void 0){await b$(Z.sessionId,L,this.file,{canWrite:Q});return}if(Z.pin){let N=Date.now();await k$({sessionId:Z.sessionId,assignment:{accountId:Z.pin.accountId,wireAccountId:Z.pin.wireIdentity,inputBytes:Z.pin.inputBytes??0,quotaCheckedAt:Z.pin.quotaCheckedAt,assignedAt:N,lastSeenAt:N},validPinnedAccountIds:[...X?[]:["main"],...L.filter((H)=>H.enabled).map((H)=>H.id)]},this.file)}await q$({sessionId:Z.sessionId,activeId:Z.accountId,route:Z.route??K.route,updatedAt:Date.now()},L,this.file,{canWrite:Q})}).catch(()=>{j2("opencode2").warn("sidebar publication failed")}),this.chain}settled(){return this.chain}get empty(){return this.producers.size===0}}var h$=Symbol.for("@cortexkit/openai-auth/opencode2-sidebar-publishers"),v$=globalThis,C2=v$[h$]??new Map;v$[h$]=C2;function m$($,Z=S$(),z=2000){let X=rZ(Z),G=C2.get(X);if(!G)G=new f$(X,z),C2.set(X,G);let Q=G,F=Q.add($),K=!1;for(let[L,N]of $.pins.snapshot())Q.publish($,{sessionId:L,pin:N,accountId:N.accountId,route:"sticky-balanced"});return{publish:()=>Q.publish($),route:(L,N,H)=>{Q.publish($,{sessionId:L,accountId:N,route:H})},async release(){if(K)return;if(K=!0,F(),await Q.settled(),Q.empty&&C2.get(X)===Q)C2.delete(X)}}}var q2="cortexkit-openai-auth",$0=5000;async function g$($,Z,z,X=new K2){let G=new p2(z),Q=new tZ,F=new Map,K=new Map,L=(P)=>{K.delete(P);for(let W of F.keys())if(W.startsWith(`${P}:`))F.delete(W)},H=await I2({session:{hook:(P,W,g)=>$.session.hook(P,async(p)=>{let l=P==="http.request"?p:void 0,m=P==="experimental.ws.handshake"?p:void 0,k=(l?l.request.headers:m?new Headers(m.headers):void 0)?.get("authorization")===`Bearer ${e(Z.providerID)}`,f={};if(m)F.delete(`${m.sessionID}:${m.kind}`);try{await Q.run(f,()=>W(p))}catch(Y){if(k&&!(Y instanceof a))throw i$(Y);throw Y}if(l&&k&&f.attempt){let Y=l.request.headers.get("thread-id");if(Y)l.request.headers.set("session-id",Y)}if(l&&k&&f.attempt)await G.captureHttp(l.request,f.attempt);if(m&&k&&f.attempt)m.headers["session-id"]=X.get(m.sessionID).threadID;if(P==="experimental.ws.send"){let Y=p,U=F.get(`${Y.sessionID}:${Y.kind}`);if(U)await G.frame(Y.frame,U.attempt)}if(l||m){let Y=l??m;if(!Y)return;let M=(l?l.request.headers:new Headers(Y.headers)).get("authorization")?.replace(/^Bearer /,"");if(k&&M)K.set(Y.sessionID,M);else K.delete(Y.sessionID);if(m){let C=`${m.sessionID}:${m.kind}`;if(k&&M&&f.attempt)F.set(C,{bearer:M,attempt:f.attempt});else F.delete(C)}if(K.size>512){let C=K.keys().next().value;if(C)K.delete(C)}if(F.size>512){let C=F.keys().next().value;if(C)F.delete(C)}}else if(P==="experimental.ws.receive"){let Y=p,U=F.get(`${Y.sessionID}:${Y.kind}`);if(U)Y.frame=n$(Y.frame,U.bearer)}else if(P==="retry"){let Y=p,U=K.get(Y.sessionID);if(U)Object.assign(Y.error,{message:D2(Y.error.message,U)})}},g)},event:{subscribe:(P)=>async function*(){for await(let W of $.event.subscribe(P)){if(W.type==="session.deleted")L(W.data.sessionID);yield W}}()}},{...Z,rewriteRequest:async(P)=>{let W=Q.getStore();if(W)W.attempt=P.attempt;return Z.rewriteRequest?.(P)},rewriteHandshakeURL:(P)=>{let W=Q.getStore();if(W)W.attempt=P.attempt;return Z.rewriteHandshakeURL?.(P)},onAttemptEnd:async(P,W)=>{await G.end(P,W),await Z.onAttemptEnd?.(P,W)},rewriteResponse:async(P)=>{await G.response(P.request,P.response.status);let W=await Z.rewriteResponse?.(P)??P.response;return a$(W,P.request.headers.get("authorization")?.replace(/^Bearer /,""),"event-stream")}},{gateOnPlaceholder:{credential:(P)=>{let W=P.get("authorization");return W?.startsWith("Bearer ")?W.slice(7):void 0}},logger:{warn:(P,W)=>z.warn(P,{data:W})}}),A=H.dispose;return{...H,dispose:async()=>{K.clear(),F.clear(),await A(),await G.settle(),G.clear()}}}function r2($={}){return{id:q2,setup:(Z)=>Z0(Z,$)}}async function Z0($,Z={}){let o=[];try{let z=j2("opencode2");let X=j2("quota");let G=Z.paths??(()=>o$(s$()));let Q=await z2(G());let F=Q?.logging?.level;if(F&&typeof F==="string")u$(F);let K=Z.fetch??fetch;let L=Z.now??Date.now;let N=Z.version??ZZ;let H=Z.poolMigration??QZ;if(!H&&!B2(G().configPath)){z.info("openai-auth stands aside on OpenCode 2: this install has not moved into the account pool and the migration is switched off, so OpenCode 2 serves its own ChatGPT login");let E=(X2)=>{throw new a({kind:"no-account",providerID:s,sessionID:X2.sessionID,requestKind:X2.kind,message:A2})},u=await g$($,{providerID:s,chooseAccount:E,accountHeaders:E},z);return()=>u.dispose()}let A=Z.vault?.firstRosterWaitMs??zZ;let P=jZ({host:"opencode",stateDir:Z.vault?.stateDir??d$(G().statePath),reservedRouteIds:()=>k.peek().rows.map((E)=>E.id),...Z.vault?.connectionFile?{connectionFile:Z.vault.connectionFile}:{},...Z.vault?.connectScoped?{connectScoped:Z.vault.connectScoped}:{},...Z.vault?.connectEnrollment?{connectEnrollment:Z.vault.connectEnrollment}:{},...Z.vault?.pollIntervalMs!==void 0?{pollIntervalMs:Z.vault.pollIntervalMs}:{},fetchImpl:()=>K},G());let W=P.vault;let g=!1;let p=!1;const l=a2(o,{[Symbol.dispose](){if(!g)P.release()}},0);await W.authority();let m=P.firstRoster;let r=new c2;let k=new XZ({paths:G,refreshProvider:async(E)=>{let u=await c$({refreshToken:E.refresh,fetchImpl:K,now:L}),X2=p$({id_token:"",access_token:u.access,refresh_token:u.refresh});return{...u,...X2?{identity:X2}:{}}},pullQuota:M$({fetchImpl:K,now:L,counts:r,logger:X}),now:L,vaultIdentities:()=>W.identities(),vaultMode:()=>W.enrolled(),vaultAuthority:()=>W.authority(),vaultFirstRoster:m,vaultFirstRosterBackgroundWaitMs:A,log:j2("pool")});await k.load();let f=Z.heartbeat===!1?void 0:await YZ({version:N,logger:j2("heartbeat")});let Y=Z.fence??(()=>$Z({currentVersion:N}));let U=Z.slot??BZ();let M=async()=>r$(G(),await U.get({path:{id:"openai"}}));let C=!1;let q=H?GZ({paths:G,slot:U,version:N,fence:Y,runDeps:{vaultServes:()=>W.serves()},paused:async()=>await W.authority()!=="local",migrate:async(E)=>{let u=await t$(E);if(C=u.status==="refused",!p)await k.load();return u},adopt:async(E)=>{if(p)return{status:"retry",reason:"unsettled"};if(!await o2(m,A))return{status:"retry",reason:"vault-roster-pending"};if(p)return{status:"retry",reason:"unsettled"};let u=await e$(E);if(!p)await k.load();return u}}):void 0;q?.start();P.start();let T=A$(G());let x=m$({paths:G(),source:k,pins:T,vault:W},Z.sidebarStateFile,Z.sidebarObservationIntervalMs);const y=a2(o,{[Symbol.dispose](){if(!g)x.release()}},0);x.publish();let b=Z.codex??new K2(void 0,void 0,i1());let h=h1({codex:b,onRoute:x.route,source:k,slotPlaceholderWithoutMain:M,storage:()=>z2(G()),pins:T,vault:W,awaitVaultRoster:async()=>{await o2(W.awaitRequestRoster(),JZ)},responsesLite:()=>P2().responsesLite,codexEndpoint:()=>P2().codexApiEndpoint,now:L,log:z});let i=await g$($,h.adapter,z,b);h.attach(i);let n=async(E)=>{if(await F2(W),B2(G().configPath))return;if(await q?.idle(),B2(G().configPath))return;if(C&&!u2(E)&&(await Y()).open){await k.poolStore().initialize();return}throw Error("OpenAI accounts move to the shared account pool once every OpenCode process on this machine runs this version of openai-auth; the login was not stored. Update or close the older processes and sign in again.")};let c=async(E)=>{await n(E);let u=await B$(k.poolStore(),G(),E,{vault:W});if(!B2(G().configPath))await q?.requestAdoption();await k.load(),z.info("ChatGPT login stored in the account pool",u)};let d=await k2($,{integrationID:s,methods:Q$({beginLogin:Z.beginLogin??s2,version:N,vault:W}),onLogin:(E)=>c(E),label:"ChatGPT (openai-auth account pool)",vault:j$(W)});let D=await N$($);if(Z.controlPlane&&(!$.command||!$.location))throw Error("OpenCode 2 control plane requires command and location APIs");let v=$.command&&$.location?await Z$({session:$.session,command:$.command,location:$.location},Z.controlPlane??U$({..._$({source:k,storage:()=>z2(G()),counts:r,now:L,authority:()=>W.authority()}),fetchImpl:K,now:L,randomUUID:eZ,accountStoragePath:G().configPath,accountStatePath:G().statePath,packageVersion:N,loadAccounts:z2,store:()=>k.poolStore(),migration:async()=>{if(B2(G().configPath))return{migrated:!0};let E=await Y();return{migrated:!1,blockers:E.open?[]:E.blockers}},beginAccountLogin:Z.beginLogin??s2,refreshAllQuota:async()=>(await k.pollRows(await z2(G()))).map((E)=>({...E,account:E.id})),getStickyRouting:async(E)=>T.get(E),afterWrite:()=>k.load(),refreshSidebar:()=>x.publish(),clearStickyRouting:async(E)=>{let u=T.get(E)!==void 0;return T.forget(E),u},vault:W})):void 0;let I=new AbortController;(async()=>{try{for await(let E of $.event.subscribe({signal:I.signal}))if(E.type==="session.deleted")h.forgetSession(E.data.sessionID)}catch(E){if(!I.signal.aborted)z.warn("stopped listening for session deletion",{error:E instanceof Error?E.message:String(E)})}})();g=!0;return async()=>{p=!0,I.abort(),await v?.(),q?.dispose(),k.dispose(),await x.release(),await Promise.allSettled([i.dispose(),d.dispose(),D.dispose()]);let E;try{await Promise.race([Promise.all([q?.idle(),k.settled(),b.store?.settled()]),new Promise((u)=>{E=setTimeout(u,$0),E.unref?.()})])}finally{clearTimeout(E),P.release(),await f?.release()}}}catch(T2){var V2=T2,M2=1}finally{l$(o,V2,M2)}}var J0=r2(),z5={id:q2,setup:J0.setup,server:VZ.server};export{z5 as default,r2 as createOpenAIAuthPlugin,q2 as OPENAI_AUTH_PLUGIN_ID};
1
+ import{c as uZ}from"../index-m3ctrabv.js";import{$ as s$,A as W$,B as U$,C as IZ,D as fZ,E as W1,F as vZ,G as hZ,H as Z$,I as UZ,J as HZ,K as mZ,L as gZ,M as D$,N as w$,O as S2,P as J$,S as i$,T as a$,aa as t$,d as L$,e as SZ,ea as lZ,f as V2,g as B2,h as b2,i as wZ,j as yZ,k as I2,ka as R1,l as Y2,la as A1,n as E1,o as O1,oa as pZ,p as _1,q as R2,r as C$,s as T$,t as _$,u as q$,v as k$,w as b$,x as p$,y as c$,z as D2}from"../index-4v2fs42x.js";import{Qa as v$,Xa as ZZ,fb as f2,gb as RZ,hb as AZ,ib as xZ,kb as qZ,lb as h$,ub as kZ,va as OZ,vb as bZ,wb as DZ,xb as m$,ya as c1,za as d1}from"../index-psjyexj3.js";import{$b as VZ,Lb as QZ,_b as jZ,bc as BZ,fc as WZ}from"../index-ex6nx3mq.js";import{$c as B1,$d as n1,Cd as Z2,Hd as u1,Jd as B$,Kd as p1,Qd as y2,Sc as q2,Tc as k2,Uc as MZ,Xd as r$,Yd as K2,Zd as i1,_d as a1,ad as h1,bd as m1,be as o1,cd as g1,ce as r1,de as s1,ee as t1,fe as e1,ge as $$,jd as I$,pd as f$,rd as EZ,sd as o$,td as l1,vc as v1}from"../index-tn8x5tz8.js";import{me as K$}from"../index-gn2b097f.js";import{ve as x$}from"../index-2pgkrebq.js";import"../index-tddr876f.js";import{Fe as _Z,He as J2}from"../index-1mbgsxsr.js";import"../index-8x1aj7q3.js";import{bf as S$}from"../index-bc89akak.js";import{ff as v2,gf as TZ}from"../index-xwvze96g.js";import{AsyncLocalStorage as p0}from"node:async_hooks";import{randomUUID as c0}from"node:crypto";class n extends Error{kind;providerID;sessionID;requestKind;constructor($){super($.message??`${$.providerID} ${$.requestKind} request refused (${$.kind})`);this.name="OpenCode2AuthError",this.kind=$.kind,this.providerID=$.providerID,this.sessionID=$.sessionID,this.requestKind=$.requestKind}}function t($){return`common-auth-placeholder.${$}`}function K1($){let Z=t($.integrationID);return{type:"oauth",methodID:$.methodID,access:Z,refresh:Z,expires:$.now+31536000000,metadata:{["commonAuthPlaceholder"]:!0}}}function N2($,Z){if($?.type!=="oauth")return!1;let J=Z===void 0?void 0:t(Z),z=(X)=>J===void 0?X.startsWith("common-auth-placeholder."):X===J;return z($.access)&&z($.refresh)}var L1="No browser sign-in: this connects the plugin to the accounts in its vault.";async function p2($,Z){let J=Z.now??Date.now,{integrationID:z}=Z,X=(H)=>K1({integrationID:z,methodID:H,now:J()}),Y=async(H,W)=>{return await Z.onLogin(H,{integrationID:z,methodID:W}),X(W)},F=(H)=>async(W)=>{let B=H.method.id,V=await H.authorize(W),L={url:V.url,instructions:V.instructions,...V.expiresAt===void 0?{}:{expiresAt:V.expiresAt}};if(V.mode==="auto")return{...L,mode:"auto",callback:V.callback.then((T)=>Y(T,B))};let x=V.callback;return{...L,mode:"code",callback:async(T)=>Y(await x(T),B)}};return $.integration.transform((H)=>{let W=Z.label===void 0?{}:{label:()=>Z.label};for(let L of Z.methods)H.method.update({integrationID:z,method:L.method,authorize:F(L),refresh:async(x)=>{if(!N2(x,z))throw Error("This login method refreshes only its pool placeholder; sign in again with the plugin's login method.");return X(x.methodID)},...W});let B=Z.vault;if(B===void 0)return;let V=B.method.id;H.method.update({integrationID:z,method:B.method,authorize:async()=>({url:"",instructions:B.instructions??L1,mode:"auto",callback:Promise.resolve().then(()=>B.activate({integrationID:z,methodID:V})).then(()=>X(V))}),refresh:async(L)=>{if(!N2(L,z)||L.methodID!==V)throw Error("This login method refreshes only its vault placeholder; choose the plugin's vault login method again.");return X(V)},...W})})}function cZ($){let Z=[],J;for(let z of $.split(/\r?\n/))if(z.startsWith("data:"))Z.push(z.slice(5).replace(/^ /,""));else if(z.startsWith("event:"))J=z.slice(6).trim();if(Z.length===0)return;return J===void 0?{data:Z.join(`
2
+ `)}:{event:J,data:Z.join(`
3
+ `)}}function c2($,Z){let J=new TextDecoder,z="",X=(F)=>{let H=cZ(F);if(!H)return;try{$(H)}catch(W){Z(W)}},Y=()=>{for(;;){let F=/\r?\n\r?\n/.exec(z);if(!F)return;let H=z.slice(0,F.index);z=z.slice(F.index+F[0].length),X(H)}};return new TransformStream({transform(F,H){H.enqueue(F),z+=J.decode(F,{stream:!0}),Y()},flush(){if(z+=J.decode(),Y(),z.trim()!=="")X(z);z=""}})}var C1=512,j2="x-common-auth-attempt",X2=($,Z)=>JSON.stringify([$,Z]),e=($)=>({providerID:$.model.providerID,modelID:$.model.id,sessionID:$.sessionID,agent:$.agent,kind:$.kind});function dZ($){let Z=$.headers;return typeof Z==="object"&&Z!==null}function iZ($,Z){let J=$.getReader();return new ReadableStream({async pull(z){let X;try{X=await J.read()}catch(Y){Z({reason:"failed",message:Y instanceof Error?Y.message:String(Y)}),z.error(Y);return}if(X.done)Z(),z.close();else z.enqueue(X.value)},async cancel(z){Z({reason:"cancelled",...z===void 0?{}:{message:String(z)}}),await J.cancel(z)}})}function d2($,Z){for(let[J,z]of Object.entries(Z)){let X=J.toLowerCase();for(let Y of Object.keys($))if(Y.toLowerCase()===X)delete $[Y];if(z!==null)$[J]=z}}function aZ($,Z){for(let[J,z]of Object.entries(Z))if(z===null)$.delete(J);else $.set(J,z)}async function i2($,Z,J={}){let{providerID:z}=Z,X=J.gateOnPlaceholder,Y=(G)=>X===void 0||X.credential(G)===t(z),F=J.logger,H=Math.max(1,J.maxRecords??C1),W=[...J.hostCredentials??[t(z)],...X?[t(z)]:[]].filter((G)=>G!==""),B=new Map,V=new WeakMap,L=new Map,x=new Set,T=new Map,v=!1,d=!1,S=new Map,y=0,a=!1,I=new Map,j=(G,Q)=>{try{F?.warn(G,Q)}catch{}},K=(G)=>G instanceof Error?G.message:String(G),R=async(G,Q)=>{let U=S.get(G);if(!U||U.size===0)return;await Promise.all([...U].map(async(P)=>{try{await P(Q)}catch(q){j("opencode2 auth listener threw; the request is unaffected",{event:G,error:K(q)})}}))},M=async(G,Q)=>{try{await Z.onAttemptEnd?.(G,Q)}catch(U){j("opencode2 auth onAttemptEnd threw; the request is unaffected",{attemptId:G.attemptId,error:K(U)})}},A=(G,Q)=>{if(G.ended||!G.attempt)return;let U={...G.status===void 0?{}:{status:G.status},outputStarted:G.outputStarted,...G.limit?{limit:G.limit.signal}:{},...Q?{error:Q}:{}};if(Q)G.endError=Q;G.ended=M(G.attempt,U)},N=(G,Q)=>A(G,{reason:"abandoned",message:Q}),_=(G)=>[...B.values()].filter((Q)=>Q.key===G),k=(G)=>_(G).at(-1),E=(G)=>{if(B.delete(G.id),!_(G.key).length)L.delete(G.key)},l=(G)=>{B.set(G.id,G);while(B.size>H){let Q=B.values().next().value;if(Q===void 0)break;N(Q,"dropped to keep the record bound"),E(Q)}},i=(G)=>G.accountId===void 0?void 0:{...G.scope,accountId:G.accountId},c=(G,Q)=>new n({kind:"no-account",providerID:z,sessionID:G.sessionID,requestKind:G.kind,...Q===void 0?{}:{message:Q}}),m=(G)=>{I.get(G)?.clear(),I.delete(G)},p=async(G,Q)=>{let U=()=>c(G,`${z} ${G.kind} request has no account: its auth selection was revoked by session forgetting or installation disposal`);if(a)throw U();let P=I.get(G.sessionID);if(!P)P=new Set,I.set(G.sessionID,P);let q={};P.add(q);let w=()=>{if(!P.has(q))throw U()};try{return await Q(w)}finally{if(P.delete(q),P.size===0&&I.get(G.sessionID)===P)I.delete(G.sessionID)}},b=(G,Q)=>{for(let[U,P]of Q)if(W.some((q)=>P.includes(q)))throw new n({kind:"host-credential-on-wire",providerID:z,sessionID:G.sessionID,requestKind:G.kind,message:`${z} ${G.kind} request still carries the host's placeholder credential in ${U}; the adapter's account headers must replace it`})},u=(G)=>{for(let Q of _(G))if(Q.ended||!Q.attempt)E(Q);else if(Q.transport==="ws"||Q.judged)N(Q,"a newer attempt of its session and kind began"),E(Q)},g=async(G,Q,U,P)=>{let q=X2(G.sessionID,G.kind),w=L.get(q);L.delete(q);let O=w?.accountId??k(q)?.accountId;u(q);let D={...G,...O===void 0?{}:{previousAccountId:O},...w?.rerouteFrom===void 0?{}:{rerouteFrom:w.rerouteFrom}},h=await Z.chooseAccount(D);U();let s={},F1;if(h!==void 0){let E2=await Z.accountHeaders({...G,accountId:h});if(U(),dZ(E2))s=E2.headers,F1=E2.attempt;else s=E2}let P1=`attempt-${++y}`,H2={id:P1,key:q,scope:G,accountId:h,headers:s,attempt:h===void 0?void 0:{...G,accountId:h,attemptId:P1,transport:P,data:F1},...P===void 0?{}:{transport:P},outputStarted:!1};if(l(H2),H2.attempt)R("select",{...G,accountId:H2.attempt.accountId,hook:Q,...D.previousAccountId===void 0?{}:{previousAccountId:D.previousAccountId},...D.rerouteFrom===void 0?{}:{rerouteFrom:D.rerouteFrom},handle:H2.attempt});return H2},z2=async(G,Q,U,P,q)=>{let w=X2(G.sessionID,G.kind),O=P===void 0?void 0:B.get(P);if(O?.key!==w)O=void 0;if(!O){if(O=k(w),_(w).filter((h)=>h.transport===void 0&&!h.ended).length>1&&!d)d=!0,j("opencode2 auth tied a send without its attempt mark to the newest of several waiting attempts",{sessionID:G.sessionID,kind:G.kind})}if(!O||O.transport!==void 0||O.ended)O=await g(G,Q,q,U);else if(O.transport=U,O.attempt)O.attempt.transport=U;if(U==="ws"){for(let D of _(w))if(D!==O&&D.transport==="ws")N(D,"a newer attempt of its session and kind went out over WebSocket")}return O},W2=async(G,Q)=>{try{return await Q()}catch(U){throw A(G,{reason:"failed",message:K(U)}),U}},M2=(G,Q)=>{let U=_(X2(G,Q)).filter((P)=>P.transport==="ws").at(-1);return U?.attempt!==void 0&&!U.ended?U:void 0},U2=(G,Q,U)=>{let P=i(G);if(!P||!G.attempt||G.limit)return;G.limit={signal:Q,delivered:R("limit",{...P,via:U,limit:Q,outputStarted:G.outputStarted,handle:G.attempt})}},Q2=(G,Q,U,P)=>{let q=i(G);if(!q||!G.attempt)return;R("quota",{...q,transport:Q,...P===void 0?{}:{status:P},quota:U,handle:G.attempt})},G2=(G,Q,U,P)=>{let q=G.attempt;if(!q)return;let w=Z.inspectEvent?.(P===void 0?{transport:Q,data:U,attempt:q}:{transport:Q,data:U,event:P,attempt:q});if(!w)return;if(w.quota!==void 0)Q2(G,Q,w.quota);if(w.outputStarted)G.outputStarted=!0;if(w.limit)U2(G,w.limit,Q);if(w.error!==void 0)A(G,{reason:"failed",message:w.error});else if(w.done)A(G)},m2=(G,Q)=>{let U=G.attempt;if(!U||Q.accountId===G.accountId)return;if(U.reboundFrom??=U.accountId,U.accountId=Q.accountId,"data"in Q)U.data=Q.data;G.accountId=Q.accountId},g2=(G)=>!G.attempt||G.endError!==void 0||G.status!==void 0&&G.status>=400,l2=(G)=>{let Q=[...B.values()].filter((D)=>D.scope.sessionID===G),U=Q.filter((D)=>D.limit&&!D.rerouted).at(-1);if(U)return U;let P=Q.filter((D)=>D.scope.kind==="primary"),q=P.length>0?P:Q;if(q.length<=1)return q[0];let w=q.filter((D)=>!D.judged&&g2(D)).at(-1);if(w)return w;let O=q.filter((D)=>D.attempt&&!D.ended);if(O.length>1)return"ambiguous";return O[0]??q.at(-1)},C={providerID:z},f=[];f.push(await $.session.hook("model.request",(G)=>{if(X)return;return p(e(G),async(Q)=>{let U=await g(e(G),"model.request",Q);if(Q(),U.accountId===void 0)throw c(U.scope);d2(G.headers,{...U.headers,[j2]:U.id})})},C)),f.push(await $.session.hook("http.request",(G)=>{if(X){let Q=Y(G.request.headers);if(T.set(G.sessionID,Q),!Q)return}return p(e(G),async(Q)=>{let U=G.request.headers.get(j2)??void 0,P=X?await g(e(G),"http.request",Q,"http"):await z2(e(G),"http.request","http",U,Q);Q();let q=i(P),w=P.attempt;if(!q||!w)throw c(P.scope);await W2(P,async()=>{let O=G.request;if(Z.rewriteRequest){if(U!==void 0){let s=new Headers(O.headers);s.delete(j2),O=new Request(O,{headers:s})}O=await Z.rewriteRequest({...q,request:O,attempt:w})??O,Q()}let D=new Headers(O.headers);D.delete(j2),aZ(D,P.headers),b(P.scope,D.entries());let h=new Request(O,{headers:D});V.set(h,P),G.request=h})})},C)),f.push(await $.session.hook("http.response",async(G)=>{let Q=V.get(G.request);if(!Q){if(X)return;if(!v)v=!0,j("opencode2 auth dropped an http.response whose request it did not produce",{sessionID:G.sessionID,kind:G.kind});return}let U=G.response;if(Z.answeredBy&&Q.attempt){let D=Q.attempt,h=await W2(Q,async()=>Z.answeredBy?.({request:G.request,response:U,attempt:D}));if(h)m2(Q,h)}let P=i(Q),q=Q.attempt;if(!P||!q)return;Q.status=U.status;let w=Z.quotaFromHeaders?.(U.headers,U.status,q);if(w!==void 0)Q2(Q,"http",w,U.status);if(!U.ok&&Z.limitFromResponse){let D=await Z.limitFromResponse({status:U.status,headers:U.headers,body:()=>U.clone().text(),attempt:q});if(D)U2(Q,D,"http")}if(!U.ok||!U.body)A(Q);let O=U;if(U.body&&(Z.inspectEvent||Z.onAttemptEnd)){let D=U.body;if(Z.inspectEvent)D=D.pipeThrough(c2((h)=>G2(Q,"http",h.data,h.event),(h)=>j("opencode2 auth event inspection threw",{error:K(h)})));O=new Response(iZ(D,(h)=>A(Q,h)),{status:U.status,statusText:U.statusText,headers:U.headers})}if(Z.rewriteResponse)O=await Z.rewriteResponse({...P,request:G.request,response:O,attempt:q})??O;if(O!==U)G.response=O},C)),f.push(await $.session.hook("experimental.ws.handshake",(G)=>{if(X){let Q=Y(new Headers(G.headers)),U=X2(G.sessionID,G.kind);if(T.set(G.sessionID,Q),x.delete(U),!Q)return}return p(e(G),async(Q)=>{let U;for(let O of Object.keys(G.headers)){if(O.toLowerCase()!==j2)continue;U??=G.headers[O],delete G.headers[O]}let P=X?await g(e(G),"experimental.ws.handshake",Q,"ws"):await z2(e(G),"experimental.ws.handshake","ws",U,Q);Q();let q=i(P),w=P.attempt;if(!q||!w)throw c(P.scope);await W2(P,async()=>{d2(G.headers,P.headers);let O=Z.rewriteHandshakeURL?.({...q,url:G.url,attempt:w});if(O!==void 0)G.url=O;if(b(P.scope,Object.entries(G.headers)),X)x.add(P.key)})})},C));let r=Z.rewriteWebSocketFrame?.bind(Z);if(r)f.push(await $.session.hook("experimental.ws.send",async(G)=>{let Q=e(G);if(X&&!x.has(X2(Q.sessionID,Q.kind)))return;let U=M2(Q.sessionID,Q.kind),P=await r({...Q,attempt:U?.attempt,frame:G.frame});if(P!==void 0)G.frame=P},C));f.push(await $.session.hook("experimental.ws.receive",(G)=>{if(X&&!x.has(X2(G.sessionID,G.kind)))return;let Q=M2(G.sessionID,G.kind);if(!Q)return;try{G2(Q,"ws",G.frame)}catch(U){j("opencode2 auth frame inspection threw",{error:K(U)})}},C)),f.push(await $.session.hook("retry",async(G)=>{if(X&&T.get(G.sessionID)!==!0)return;let Q=l2(G.sessionID);if(!Q)return;let U=G.decision;if(Q==="ambiguous"){await R("retry",{sessionID:G.sessionID,attempt:G.attempt,reason:"host-decides",hostDecision:U,decision:U});return}let P=Q;await p(P.scope,async(q)=>{P.judged=!0;let w=U,O,D,h=P.attempt;if(P.accountId===void 0||!h)w={retry:!1},O="no-account";else if(P.outputStarted)w={retry:!1},O="output-started";else{if(!P.limit){let s=Z.limitFromError?.(G.error,h);if(s)U2(P,s,"error")}if(P.ended)await P.ended,q();if(P.limit)await P.limit.delivered,q(),P.rerouted=!0,D={accountId:P.accountId,limit:P.limit.signal},w={retry:!0,delay:0},O="reroute";else O="host-decides"}if(G.decision=w,w.retry&&P.accountId!==void 0)L.set(P.key,{sessionID:P.scope.sessionID,accountId:P.accountId,...D===void 0?{}:{rerouteFrom:D}});await R("retry",{sessionID:G.sessionID,...P.accountId===void 0?{}:{accountId:P.accountId},kind:P.scope.kind,attempt:G.attempt,reason:O,hostDecision:U,decision:w,...h===void 0?{}:{handle:h}})})},C));let H1=(G)=>{m(G),T.delete(G);for(let Q of x)if(JSON.parse(Q)[0]===G)x.delete(Q);for(let Q of[...B.values()]){if(Q.scope.sessionID!==G)continue;N(Q,"its session was forgotten"),B.delete(Q.id)}for(let[Q,U]of L)if(U.sessionID===G)L.delete(Q)},u2=new AbortController,N1=$.event;if(N1)(async()=>{try{for await(let G of N1.subscribe({signal:u2.signal}))if(G.type==="session.deleted")H1(G.data.sessionID)}catch(G){if(!u2.signal.aborted)j("opencode2 auth stopped listening for session deletion",{error:K(G)})}})();return{on(G,Q){let U=S.get(G);if(!U)U=new Set,S.set(G,U);let P=Q;return U.add(P),()=>{U.delete(P)}},accountFor(G,Q){return k(X2(G,Q))?.accountId},forgetSession:H1,get size(){return B.size},async dispose(){if(a)return;a=!0;for(let G of I.keys())m(G);u2.abort();for(let G of B.values())N(G,"the installation was disposed");B.clear(),L.clear(),x.clear(),T.clear(),S.clear(),await Promise.all(f.map(async(G)=>{try{await G.dispose()}catch(Q){j("opencode2 auth hook did not dispose cleanly",{error:K(Q)})}}))}}}import{createHash as nZ}from"node:crypto";var oZ=1024,rZ=($)=>typeof $==="object"&&$!==null&&!Array.isArray($),T1=($)=>_1($,"user"),sZ=($)=>rZ($)&&($.role==="assistant"||typeof $.type==="string"&&$.type!=="message"&&$.type!=="configuration_update");function tZ($){return nZ("sha256").update(JSON.stringify($)).digest("hex")}class F2{runtime;maxSessions;#$=new Map;constructor($,Z=oZ){this.runtime=$;this.maxSessions=Z}advance($,Z,J=this.runtime){let z=this.#$.get($),X=Array.isArray(Z.input)?Z.input:[],Y=X.filter(T1),F=X.findLastIndex(T1),H=F<0?void 0:tZ(X[F]),W=typeof Z.previous_response_id==="string"&&Z.previous_response_id.length>0,B,V,L;if(W)B=Y.length>0,V=H??z?.fingerprint,L=z?.userCount===void 0?void 0:z.userCount+Y.length;else{V=H,L=Y.length;let T=F>=0&&F>X.findLastIndex(sZ),v=z!==void 0&&!z.completed&&z.fingerprint===V&&z.userCount===L;B=T&&!v}let x=B||!z?{turnID:(J?.uuid??Y2)(),turnStartedAt:(J?.now??Date.now)()}:{turnID:z.turnID,turnStartedAt:z.turnStartedAt};return this.#Z($,{...x,completed:!1,fingerprint:V,userCount:L}),x}completed($){let Z=this.#$.get($);if(Z)this.#Z($,{...Z,completed:!0})}get($){return this.#$.get($)}forget($){this.#$.delete($)}#Z($,Z){this.#$.delete($),this.#$.set($,Z);while(this.#$.size>this.maxSessions){let J=this.#$.keys().next().value;if(J===void 0)break;this.#$.delete(J)}}}function a2($,Z){return{threadID:$.threadID,windowID:$.windowID,turnID:Z.turnID,turnStartedAt:Z.turnStartedAt}}var M1=Symbol.for("@cortexkit/openai-auth/opencode2/codex-installation");function eZ(){let $=globalThis;return $[M1]??=crypto.randomUUID(),$[M1]}class P2{runtime;store;sessions;frameTurns;installationID;constructor($,Z,J){this.runtime=$;this.store=J;this.installationID=Z??eZ(),this.sessions=J?.sessions??new Map,this.frameTurns=J?.frameTurns??new F2}get($){let Z=this.runtime?.uuid??Y2;if(this.store)return this.store.get($,Z);let J=this.sessions.get($);if(!J){let z=Z();J={threadID:z,turnID:Z(),windowID:`${z}:0`},this.sessions.set($,J)}return J}advanceFrame($,Z){return this.frameTurns.advance($,Z,this.runtime)}frameReceived($,Z){if(!Z.includes("response.completed"))return;if(O2(Z)?.type==="response.completed")this.frameTurns.completed($)}forget($){if(this.store)this.store.delete($);else this.sessions.delete($),this.frameTurns.forget($)}}var n2={version:E1,"user-agent":O1,originator:"codex_exec"};var $0=1024,Z0=/(?:^|\/)gpt-6-(?:astra|sol|luna)$/i,A2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($),x1=($)=>A2($)&&($.type==="message"||("role"in $))&&$.role==="user",S1=($)=>A2($)&&$.type==="configuration_update";class o2{http;#$=new Map;constructor($=new P2){this.http=$}apply($,Z,J){if(Z.kind!=="primary")return!1;let z=typeof $.model==="string"?$.model:"";if(!R1.has(z))return!1;if(Z0.test(z))return!1;let X=A2($.reasoning)?$.reasoning:void 0,Y=typeof X?.effort==="string"?X.effort:void 0;if(!Y)return!1;let F=this.#$.get(Z.sessionID);if(F===void 0)return this.#Z(Z.sessionID,Y),!1;if(Y===F)return!1;let H=Array.isArray($.input)?$.input:void 0;if(!H||H.length===0)return!1;let W=H.findLastIndex(x1);if(W<0){if(J==="http")return!1;return $.reasoning={...X,effort:F},!0}if($.reasoning={...X,effort:F},!S1(H[W-1]))H.splice(W,0,{type:"configuration_update",reasoning:{effort:Y}});return!0}forget($){this.#$.delete($),this.http.forget($)}#Z($,Z){this.#$.set($,Z);while(this.#$.size>$0){let J=this.#$.keys().next().value;if(J===void 0)break;this.#$.delete(J)}}}function O2($){try{let Z=JSON.parse($);return A2(Z)?Z:void 0}catch{return}}async function q1($,Z,J,z,X=J.http){if($.method.toUpperCase()!=="POST")return;if(!/\/responses\/?$/.test(new URL($.url).pathname))return;let Y=await $.clone().text(),F=O2(Y);if(F)delete F.max_output_tokens;let H=new Headers($.headers),W=R2({rewriteLite:A1,init:{body:F?JSON.stringify(F):$.body===null?void 0:Y},headers:H,metadata:X.get(Z.sessionID),installationID:X.installationID,runtime:X.runtime,websocket:!1,responsesLite:z,applyEffort:(B)=>{J.apply(B,Z,"http")}});return new Request($,{headers:H,body:W.init?.body})}function k1($,Z,J,z){let X=z.sessions.get($.sessionID),Y=z.frameTurns.get($.sessionID);if(!X||!Y)return;let F=a2(X,Y),H=new Headers({"content-type":"application/json"});for(let B of["chatgpt-account-id","x-opencode-parent-session-id","x-parent-session-id"]){let V=J.get(B);if(V!==null)H.set(B,V)}R2({init:{body:$.bodyText},headers:H,metadata:F,installationID:z.installationID,runtime:z.runtime,websocket:!1,skipTurnUpdate:!0,responsesLite:!1,rewriteLite:()=>{}});let W=new URL(Z);if(W.protocol==="wss:")W.protocol="https:";if(W.protocol==="ws:")W.protocol="http:";return new Request(W,{method:"POST",headers:H,body:$.bodyText})}function J0($,Z){if(JSON.stringify($)===JSON.stringify(Z))return!0;if(!Array.isArray($)||!Array.isArray(Z)||Z.length!==$.length+1)return!1;let J=Z.findIndex((z,X)=>JSON.stringify(z)!==JSON.stringify($[X]));return J>=0&&S1(Z[J])&&x1(Z[J+1])&&JSON.stringify(Z.slice(J+1))===JSON.stringify($.slice(J))}function b1($,Z,J){let z=O2($);if(z?.type!=="response.create")return;let X=J.http.advanceFrame(Z.sessionID,z),Y=J.http.get(Z.sessionID);delete z.max_output_tokens;let F=R2({rewriteLite:()=>{},init:{body:JSON.stringify(z)},headers:new Headers,metadata:a2(Y,X),installationID:J.http.installationID,runtime:J.http.runtime,websocket:!0,responsesLite:!1,applyEffort:(W)=>{J.apply(W,Z,"ws")}}),H=O2(String(F.init?.body));if(!H)return;if(!J0(z.input,H.input)){if("input"in z)H.input=z.input;else delete H.input;return JSON.stringify(H)}return String(F.init?.body)}function z0($){return $.replace(/\/responses\/?$/,"").replace(/\/$/,"")}function r2($,Z){let J=new URL($);if(J.origin!=="https://api.openai.com"&&J.origin!=="wss://api.openai.com"||!/\/responses\/?$/.test(J.pathname))return $;let z=new URL(`${z0(Z)}/responses`);if(z.search=J.search,J.protocol==="ws:"||J.protocol==="wss:")z.protocol=z.protocol==="https:"?"wss:":"ws:";return z.href}import{resolve as D1}from"node:path";var G0=1024;class x2{accounts=new Map;limit;constructor($=G0){this.limit=Math.max(1,$)}record($,Z){this.accounts.delete($),this.accounts.set($,Z);while(this.accounts.size>this.limit){let J=this.accounts.keys().next().value;if(J===void 0)break;this.accounts.delete(J)}}activeAccount($){return this.accounts.get($)}forget($){this.accounts.delete($)}get size(){return this.accounts.size}}var w1=Symbol.for("@cortexkit/openai-auth/opencode2-session-accounts"),y1=globalThis,s2=y1[w1]??new Map;y1[w1]=s2;function t2($){let Z=JSON.stringify([D1($.configPath),D1($.statePath)]),J=s2.get(Z);if(!J)J=new x2,s2.set(Z,J);return J}var o="openai",X0=60000,I1=1,Y0="request refused: no account with a usable credential",$2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($);function Q0($){let Z=$2($)?$.counters:void 0,J=$2(Z)?Z.resetCredits:void 0,z=$2(J)?J.value:void 0;return typeof z==="number"&&Number.isFinite(z)?z:void 0}function e2($){try{return JSON.parse($)}catch{return}}function f1($){let Z=q2($);return Z?k2(Z):void 0}var j0=new Set(["usage_limit_reached","rate_limit_exceeded"]);function $1($,Z,J){return{reason:$.window,...J!==void 0?{status:J}:{},...$.resetAt!==void 0?{retryAfterMs:Math.max(0,$.resetAt-Z)}:{}}}function V0($,Z){let J=S2($);if(J){let Y=typeof $.status==="number"?$.status:void 0;return $1(J,Z,Y)}if($.type!=="response.failed"||!$2($.response))return;let z=$.response.failed;if($2(z)&&typeof z.rate_limit_reached_type==="string")return{reason:z.rate_limit_reached_type};let X=$.response.error;if($2(X)){let Y=typeof X.code==="string"?X.code:typeof X.type==="string"?X.type:void 0;if(Y&&j0.has(Y))return{reason:Y}}return}function B0($,Z){let J=e2($);if(!$2(J))return;let z=typeof J.type==="string"?J.type:void 0;if(z==="codex.rate_limits")return{quota:{snapshot:g1(J),complete:!0}};let X=V0(J,Z);if(X)return{limit:X};if(z===void 0||z==="error")return;return J$(z)?void 0:{outputStarted:!0}}function W0($){let Z=!1;for(let J of $.keys())if(J.toLowerCase().startsWith("x-codex-")){Z=!0;break}if(!Z)return;return{snapshot:h1($),complete:m1($)}}function U0($){let Z=$.get("retry-after");if(Z===null)return;let J=Number(Z);return Number.isFinite(J)&&J>=0?J*1000:void 0}function z$($){let{source:Z,pins:J}=$,z=$.now??Date.now,X=$.log,Y=$.vault,F=new o2($.codex),H=new Map,W=(j)=>`${j.sessionID}\x00${j.kind}\x00${j.accountId}`,B=new Map,V=$.sessionAccounts??new x2,L=(j,K,R)=>{let M=R?[]:Z$(Z.peek().rows,j,K,Y?.identities()??new Set),A=(Y?.routes()??[]).filter((N)=>N.kind==="oauth"&&u1(K2(N.quota),j,K));return[...M.map((N)=>({id:N.id,...N.identity!==void 0?{identity:N.identity}:{},quota:N.quota,row:N})),...A.map((N)=>({id:N.id,...N.identity!==void 0?{identity:N.identity}:{},quota:N.quota}))]},x=(j,K,R)=>{let M=n1(j,K,R),A=j.map((E)=>({id:E.id,kind:"oauth",...v1(E.quota)?{quota:E.quota}:{}})),N=j.flatMap((E)=>E.row?[E.row]:[]),_=new Set(j.filter((E)=>!E.row).map((E)=>E.id)),k=Z.rateLimitMarks(N);for(let E of _){let l=B.get(E);if(l===void 0)continue;if(l<=R)B.delete(E);else k.set(E,l)}return{rows:A,now:R,rateLimitMarks:k,refreshBackoff:Z.refreshBackoffFor(N),killswitch:M,requestPull:(E)=>_.has(E)?Y?.requestReading(E):Z.requestReading(E)}},T=(j,K,R,M,A)=>{let N=s1({...j,placement:o1(K),mainId:A});if(N.kind==="block"){X?.debug("pool admission refused the request",{reason:N.block.reason});return}let _=N.order.filter((k)=>!R.has(k));if(M!==void 0&&_.includes(M))return M;return _[0]},v=(j,K,R,M,A,N)=>{let _=new Map(K.map((b)=>[b.id,b.quota])),k={requestBytes:I1,reservePercent:(b)=>p1(R,b===i1?void 0:b),resetCredits:(b)=>Q0(_.get(b))},E=t1(j),l=(b,u)=>J.place({sessionId:M,requestBytes:I1,validPinnedAccountIds:j.rows.map((g)=>g.id).filter((g)=>!E.excluded.has(g)),excludeAccountIds:b,quotaCheckedAtByAccount:Object.fromEntries(j.rows.map((g)=>[g.id,E.projections.get(g.id)?.checkedAt])),wireAccountIdByAccount:Object.fromEntries(K.map((g)=>[g.id,g.identity])),select:(g)=>e1(j,k,new Set(b),g),persist:u}),i=[...A],c=l(i,N);if(!c)return;let m=c.accountId,p=$$(j,k,m);if(p.kind==="none")return;if(p.kind==="move"){let b=l([...i,m],N);if(b)return b.accountId;return p.reason==="killswitch"?void 0:m}if(p.kind==="detour")return l([...i,m],!1)?.accountId;return m},y={providerID:o,chooseAccount:async(j)=>{let K=await Y?.authority(),R=await $.storage(),M=K!==void 0&&K!=="local",A=()=>{throw new n({kind:"no-account",providerID:o,sessionID:j.sessionID,requestKind:j.kind,message:b2})};if(M)await $.awaitVaultRoster?.();else{if(!(await Z.current()).active){if(await $.slotPlaceholderWithoutMain?.())A();X?.warn("the account pool does not serve requests yet; refusing the request",{kind:j.kind});return}await Z.prepareTokens(Z.peek().rows,R)}let N=z(),_=L(R,N,M),k=r1(x(_.filter((u)=>u.id!==j.rerouteFrom?.accountId),R,N));if(k)await k,N=z(),_=L(R,N,M);let E=new Map(_.map((u)=>[u.id,u])),l=x(_,R,N),i=new Set(j.rerouteFrom?[j.rerouteFrom.accountId]:[]),c=R?.routing?.mode??"main-first",m=j.kind==="primary",p=new Set,b;for(;;){let u=new Set([...i,...p]);if(b=void 0,c==="sticky-balanced")b=v(l,_,R,j.sessionID,u,m&&p.size===0);if(b??=T(l,c,u,m?void 0:V.activeAccount(j.sessionID),M?c==="sticky-balanced"?null:a1(Y?.routes()??[]):void 0),b===void 0||p.has(b)){b=void 0;break}let g=E.get(b)?.row;if(g){if(Z.usableToken(g)!==void 0)break;X?.debug("pool row holds no usable token; choosing again",{accountId:b})}else{if(!Y)break;let z2=await Y.authorize(b);if(z2){H.set(W({...j,accountId:b}),z2);break}X?.debug("the vault refused to serve an account; choosing again",{accountId:b})}p.add(b)}if(b===void 0&&!M&&_.length===0&&await $.slotPlaceholderWithoutMain?.())A();if(b===void 0&&M&&Y&&(_.length===0||p.size>0)){let u=p.size>0?"vault-refused":d1(Y);throw X?.warn("vault mode: no vault account can serve; refusing the request",{cause:u}),new n({kind:"no-account",providerID:o,sessionID:j.sessionID,requestKind:j.kind,message:c1(u,Y.name)})}if(b!==void 0&&m)V.record(j.sessionID,b),$.onRoute?.(j.sessionID,b,c);return X?.debug("pool account chosen",{kind:j.kind,accountId:b,mode:c,...j.rerouteFrom?{rerouteFrom:j.rerouteFrom.accountId}:{}}),b},accountHeaders:async(j)=>{let{accountId:K}=j,R=()=>new n({kind:"no-account",providerID:o,sessionID:j.sessionID,requestKind:j.kind,message:Y0}),M=Y&&await Y.authority()!=="local"?void 0:Z.peek().rows.find((_)=>_.id===K);if(!M&&Y){let _=W(j),k=H.get(_)??await Y.authorize(K);if(H.delete(_),!k)throw X?.warn("the vault refused to serve an account; refusing the request",{accountId:K}),R();return{headers:{...n2,"session-id":j.sessionID,authorization:`Bearer ${k.accessToken}`,"chatgpt-account-id":k.accountIdentity??f1(k.accessToken)??null},attempt:{kind:"vault",routeId:K,receipt:k}}}let A=M?Z.usableToken(M):void 0;if(!M||!A)throw X?.warn("pool row holds no usable token; refusing the request",{accountId:K}),R();let N=M.identity??f1(A);return{headers:{...n2,"session-id":j.sessionID,authorization:`Bearer ${A}`,"chatgpt-account-id":N??null},attempt:{kind:"pool",token:A,credentialEpoch:M.credentialEpoch}}},async rewriteRequest({request:j,sessionID:K,kind:R}){let M=$.codexEndpoint?r2(j.url,$.codexEndpoint()):j.url,A=M===j.url?j:new Request(M,j);return await q1(A,{sessionID:K,kind:R},F,$.responsesLite?.()??!1)??A},rewriteHandshakeURL:({url:j})=>$.codexEndpoint?r2(j,$.codexEndpoint()):void 0,rewriteWebSocketFrame:({frame:j,sessionID:K,kind:R})=>b1(j,{sessionID:K,kind:R},F),quotaFromHeaders:(j)=>W0(j),async limitFromResponse({status:j,headers:K,body:R}){if(j<400)return;let M=e2(await R().catch(()=>"")),A=S2({...$2(M)?M:{},status:j});if(!A)return;let N=z(),_=$1(A,N,j);if(_.retryAfterMs!==void 0)return _;let k=U0(K);return k===void 0?_:{..._,retryAfterMs:k}},inspectEvent:({data:j})=>B0(j,z()),limitFromError(j){let K=e2(j.message),R=S2({...$2(K)?K:{},...j.status!==void 0?{status:j.status}:{}})??(j.message.includes("usage_limit_reached")?{window:"usage_limit_reached"}:void 0);return R?$1(R,z(),j.status):void 0},async onAttemptEnd(j,K){let R=j.data;if(R?.kind!=="vault"||K.status!==401)return;X?.warn("a vault account answered 401; reporting it to the vault",{accountId:j.accountId}),await Y?.reportFailure(R.receipt,401)}},a=(j,K,R)=>{let M=R.data;if(M?.kind==="vault"){Y?.recordSnapshot(j,K.snapshot,K.complete,M.receipt);return}if(M?.kind!=="pool")return;if(Z.peek().rows.find((N)=>N.id===j)?.credentialEpoch!==M.credentialEpoch){X?.debug("quota reading dropped: the row holds another credential",{accountId:j});return}Z.recordSnapshot(j,K.snapshot,M.token,K.complete)},I=(j,K,R)=>{let M=z(),A=R.data?.kind==="vault",N=A?Y?.routes().find((E)=>E.id===j)?.quota:Z.peek().rows.find((E)=>E.id===j)?.quota,_=l1(K2(N),K.reason,M,X0,K.retryAfterMs!==void 0?M+K.retryAfterMs:void 0);if(!A){Z.markRateLimited(j,_);return}let k=B.get(j);if(k===void 0||k<_)B.set(j,_)};return{adapter:y,attach(j){j.on("quota",(K)=>a(K.accountId,K.quota,K.handle)),j.on("limit",(K)=>{I(K.accountId,K.limit,K.handle),X?.debug("pool row refused the request",{accountId:K.accountId,via:K.via,reason:K.limit.reason,outputStarted:K.outputStarted})})},forgetSession(j){J.forget(j),V.forget(j),F.forget(j)},activeAccount:(j)=>V.activeAccount(j)}}import{resolve as V$}from"node:path";import{Buffer as H0}from"node:buffer";import{resolve as G$}from"node:path";function L2($){return H0.byteLength(JSON.stringify($))}function N0($){return $.reduce((Z,J)=>Z+L2(J),0)}function Z1($,Z){return 2+$+Math.max(0,Z-1)}function F0($){let{head:Z,pending:J}=$;return 10+$.fieldsBytes+1+(Z?22+Z.responseIDBytes+9+Z1(Z.inputBytes,Z.input.length)+1:0)+(J?20+Z1(J.inputBytes,J.input.length)+10+Z1(J.outputBytes,J.output.length)+(J.responseID===void 0?0:14+J.responseIDBytes)+1:0)}function X$($){try{let Z=JSON.parse($);if(Z&&typeof Z==="object"&&!Array.isArray(Z))return Z}catch{}return}class Y${enabled;caps=D2;entries=new Map;bytes=0;constructor($=!1){this.enabled=$}setEnabled($){if(this.enabled=$,!$)this.entries.clear(),this.bytes=0}send($,Z){if(!this.enabled)return;let J=X$(Z);if(J?.type!=="response.create")return;if(!Array.isArray(J.input)){this.forget($);return}let z=J.previous_response_id,X=this.entries.get($),Y=X?.head;if(z&&z!==Y?.responseID){this.forget($);return}let{type:F,previous_response_id:H,input:W,...B}=J;this.keep($,{fields:z&&X?X.fields:B,fieldsBytes:z&&X?X.fieldsBytes:L2(B),...z&&Y?{head:Y}:{},pending:{input:W,inputBytes:N0(W),output:[],outputBytes:0,responseIDBytes:0},bytes:0})}receive($,Z,J){if(!this.enabled||!Z.includes("response.created")&&!Z.includes("response.output_item.done")&&!Z.includes("response.completed"))return;let z=this.entries.get($);if(!z?.pending)return;let X=X$(Z);if(!X)return;let Y=z.pending,F=X.response;if(X.type==="response.created"&&typeof F?.id==="string")Y.responseID=F.id,Y.responseIDBytes=L2(F.id),this.keep($,z);else if(X.type==="response.output_item.done"&&X.item){if(typeof X.response_id==="string"&&Y.responseID!==void 0&&X.response_id!==Y.responseID)return;Y.output.push(X.item),Y.outputBytes+=L2(X.item),this.keep($,z)}else if(X.type==="response.completed"&&typeof F?.id==="string"){if(F.id===z.head?.responseID||Y.responseID!==void 0&&F.id!==Y.responseID)return;let H={responseID:F.id,responseIDBytes:Y.responseID===F.id?Y.responseIDBytes:L2(F.id),input:[...z.head?.input??[],...Y.input,...Y.output],inputBytes:(z.head?.inputBytes??0)+Y.inputBytes+Y.outputBytes},W={...z,head:H,pending:void 0};if(!this.keep($,W))return;J?.({sessionID:$,responseID:H.responseID,bodyText:this.body(z.fields,H)})}}replay($){let Z=this.entries.get($);if(!Z?.head)return;return this.entries.delete($),this.entries.set($,Z),this.body(Z.fields,Z.head)}forget($){let Z=this.entries.get($);if(Z)this.bytes-=Z.bytes;this.entries.delete($)}status(){return{bytes:this.bytes,sessions:[...this.entries].map(([$,Z])=>({sessionID:$,bytes:Z.bytes,responseID:Z.head?.responseID,pending:Z.pending!==void 0}))}}body($,Z){return JSON.stringify({...$,input:Z.input,stream:!0})}keep($,Z){let J=F0(Z);if(this.forget($),J>this.caps.maxBytes)return!1;Z.bytes=J,this.entries.set($,Z),this.bytes+=J;while(this.entries.size>this.caps.maxTargets||this.bytes>this.caps.maxBytes){let z=this.entries.keys().next().value;if(z===void 0)break;this.forget(z)}return this.entries.has($)}}var Q$=Symbol.for("@cortexkit/openai-auth/opencode2-frame-mirror"),j$=globalThis,J1=j$[Q$]??new Map;j$[Q$]=J1;function w2($){let Z=JSON.stringify([G$($.configPath),G$($.statePath)]),J=J1.get(Z);if(!J)J=new Y$,J1.set(Z,J);return J}var P0=5000,K0=["accept","originator","session-id","thread-id","user-agent","version","x-client-request-id","x-codex-beta-features","x-codex-turn-metadata","x-codex-window-id","x-openai-internal-codex-responses-lite","x-opencode-parent-session-id","x-parent-session-id"],L0=["x-opencode-parent-session-id","x-parent-session-id"];function H$($){let Z=B$($);return{enabled:Z?.enabled===!0,subagents:Z?.subagents===!0,sustain:Z?.sustain===!0,window:W$($?{...$,cachekeep:Z}:$)}}var N$=Symbol.for("@cortexkit/openai-auth/opencode2-cache-keep"),F$=globalThis,C2=F$[N$]??new Map;F$[N$]=C2;function C0($,Z){let J=[],z=()=>J.at(-1)?.location,X=()=>{let W=z();if(!W)throw Error("no location holds keep-warm");return W},Y=(W,B)=>{H.remove(W),z()?.log?.debug(`cachekeep dropped target (${B})`,{sessionKey:W})},F=async(W)=>{if(W.meta.credentialMode!=="local")throw Error("a target captured in vault mode is not warmed with a local credential");let B=W.accountId??"main",V=X(),L=await V.source.accessFor(B,await V.storage());if(!L)throw Error(`pool row ${B} has no usable token`);return{token:L.token,identity:L.row.identity}},H=U$({...D2,now:$.now,...$.setIntervalImpl?{setIntervalImpl:$.setIntervalImpl}:{},...$.clearIntervalImpl?{clearIntervalImpl:$.clearIntervalImpl}:{},codexResponsesUrl:$.codexResponsesUrl,fetchImpl:(W,B)=>X().fetch(W,B),logger:{debug:(W,B)=>z()?.log?.debug(W,B),warn:(W,B)=>z()?.log?.warn(W,B)},getWindow:()=>z()?.settings().window,getSustain:()=>z()?.settings().sustain===!0,resolveLocal:F,vault:{owns:(W)=>z()?.vault.owns(W)===!0,authority:()=>X().vault.authority(),send:async(W,B,V)=>{let L=X();if(await L.vault.authority()!=="vault")return;return L.vault.send(W,B,V)}},activeAccount:(W)=>{if(W===void 0)throw Error("target has no session");let B=z(),V=B?.settings();if(!B||!V?.enabled){Y(W,"keep-warm is off");return}if(!V.subagents&&H.status().targets.some((x)=>x.sessionKey===W&&x.isSubagent)){Y(W,"subagent warming is off");return}let L=B.accounts.activeAccount(W);if(L===void 0){Y(W,"no account recorded for the session");return}return L},verifyCredential:({target:W,mode:B,identity:V})=>{if(W.meta.credentialMode!==B)throw Error(`a target captured in ${W.meta.credentialMode??"an unknown"} mode is not warmed with a ${B} credential`);if(V!==W.meta.chatgptAccountId)throw Y(W.sessionKey,"the account signs in as another login now"),Error("the account signs in as another login now")}});return{manager:H,settings:Z,holders:J,joinTimeoutMs:$.joinTimeoutMs??P0}}function T0($){try{let Z=JSON.parse($),J=Array.isArray(Z.input)?Z.input.at(-1):void 0;if(J?.role!=="user")return!1;return(typeof J.content==="string"?J.content:Array.isArray(J.content)?J.content.map((X)=>typeof X?.text==="string"?X.text:"").join(""):"").startsWith("This is a keep-alive request.")}catch{return!1}}function _0($){let Z={};for(let J of K0){let z=$.get(J);if(z)Z[J]=z}return Z}function P$($,Z,J){let z=JSON.stringify([V$($.configPath),V$($.statePath)]),X=C2.get(z);if(!X)X=C0(J,Z.settings()),C2.set(z,X);let Y=X,F=w2($);F.setEnabled(Y.settings.enabled);let H={location:{...Z,settings:()=>Y.settings}};Y.holders.push(H);let W=!1,B=async(V)=>{try{let L=H.location.settings();if(W||!L.enabled)return;if(V.kind!=="primary"){if(V.kind==="generate"&&T0(await V.request.clone().text())){if(W)return;Y.manager.remove(V.sessionID)}return}let x=V.attempt.data,T=x?.kind==="pool"?"local":x?.kind==="vault"?"vault":void 0;if(!T)return;let v=V.request.headers,d=L0.some((a)=>v.has(a))||Z.parentOf!==void 0&&await Z.parentOf(V.sessionID)!==void 0;if(d&&!L.subagents)return;let S=await V.request.clone().text();if(W)return;let y=v.get("chatgpt-account-id")??void 0;Y.manager.track({sessionKey:V.sessionID,bodyText:S,accountId:V.attempt.accountId,isSubagent:d,meta:{replayHeaders:_0(v),...y?{chatgptAccountId:y}:{},routingSessionId:V.sessionID,url:V.request.url,credentialMode:T}})}catch(L){Z.log?.warn("cachekeep capture failed",{error:L instanceof Error?L.message:String(L)})}};return{manager:Y.manager,configure:(V)=>{Object.assign(Y.settings,V),F.setEnabled(Y.settings.enabled)},capture:B,forget:(V)=>Y.manager.remove(V),async release(){if(W)return;W=!0;let V=Y.holders.indexOf(H);if(V>=0)Y.holders.splice(V,1);if(Y.holders.length>0)return;if(C2.get(z)===Y)C2.delete(z);Y.manager.stop();let L;try{await Promise.race([Y.manager.tick().catch(()=>{}),new Promise((x)=>{L=setTimeout(x,Y.joinTimeoutMs),L.unref?.()})])}finally{clearTimeout(L)}}}}import{mkdirSync as M0}from"node:fs";import{dirname as E0,join as O0,resolve as R0}from"node:path";var A0="openai-auth-sessions-opencode2.json";function x0(){return O0(L$(),A0)}var S0="sessions",q0=1e4,k0=5000,b0=25;class M${path;options;sessions;frameTurns=new F2;#$=new Set;#Z=new Set;#J=Promise.resolve();#z=!1;constructor($,Z={}){this.path=$;this.options=Z;this.sessions=T$($,Z.uuid??Y2)}get($,Z=Y2){let J=this.sessions.get($);if(!J){let z=Z();J={threadID:z,turnID:Z(),windowID:`${z}:0`},this.sessions.set($,J),this.#Z.delete($),this.#$.add($),this.save()}return J}delete($){this.sessions.delete($),this.frameTurns.forget($),this.#$.delete($),this.#Z.add($),this.save()}save(){if(!this.#z)this.#z=!0,this.#J=this.#J.then(()=>{return this.#z=!1,this.#G()});return this.#J}settled(){return this.#J}async#G(){if(this.#$.size===0&&this.#Z.size===0)return;let $=[...this.#$].flatMap((z)=>{let X=this.sessions.get(z);return X?[[z,X]]:[]}),Z=[...this.#Z],J=null;try{if(M0(E0(this.path),{recursive:!0}),J=await this.#X(),!J)return;let z;try{z=C$(this.path)}catch{z=new Map}await this.options.afterRead?.();for(let X of Z)z.delete(X);for(let[X,Y]of $)z.set(X,Y.threadID);_$(this.path,z)}catch{return}finally{await J?.release().catch(()=>{})}for(let[z,X]of $)if(this.sessions.get(z)===X)this.#$.delete(z);for(let z of Z)if(!this.sessions.has(z))this.#Z.delete(z)}async#X(){let $=performance.now()+(this.options.lockWaitMs??k0);for(;;){let Z=await K$({name:S0,path:this.path,ttlMs:q0});if(Z||performance.now()>=$)return Z;await new Promise((J)=>setTimeout(J,b0))}}}var E$=Symbol.for("@cortexkit/openai-auth/opencode2-codex-sessions"),O$=globalThis,z1=O$[E$]??new Map;O$[E$]=z1;function R$($=x0()){let Z=R0($),J=z1.get(Z);if(!J)J=new M$(Z),z1.set(Z,J);return J}var A$=Symbol.for("cortexkit.openai-auth.v2.commands");function D0(){let $=globalThis;return $[A$]??={locations:new Map},$[A$]}async function y$($,Z){let J=D0(),z=$.location.directory,X={menu:Z,session:$.session},Y=await S$(z),F=await x$(D$,Y.dir,()=>w$({...Y,drain:k$,apply:(V)=>{let L=J.locations.get(z);if(!L)throw Error("The OpenAI menu location was closed");return L.menu.apply(V)}})),H=J.locations.get(z);J.locations.set(z,X),await H?.registration?.dispose(),J.command??={name:"openai",description:"OpenAI account menu",async execute(V){let L=J.locations.values().next().value?.session;if(!L)return;let x=await L.get({sessionID:V.sessionID}),T=J.locations.get(x.location.directory);if(!T||!b$(V.sessionID))return;let v=await T.menu.open(V.sessionID);q$(v,V.sessionID)}};let W=J.command;try{X.registration=await $.command.transform((V)=>{V.add(W)})}catch(V){if(J.locations.get(z)===X)J.locations.delete(z);throw await F.release(),V}let B=!1;return async()=>{if(B)return;if(B=!0,J.locations.get(z)===X)J.locations.delete(z);await F.release(),await X.registration?.dispose()}}var w0="openai-auth-pool-browser",y0="openai-auth-pool-headless",I0="openai-auth-vault",f0="Vault login requires this OpenCode host to be enrolled in the Claustrum vault. Connect to the vault or disconnect this host before trying again.";async function T2($){if(await $.authority()!=="local")throw Error("This host is connected to the credential vault or its enrollment is unreadable; the login was not stored. Disconnect this host from the vault to add a local login.")}function g$($){return{method:{id:I0,type:"oauth",label:"ChatGPT accounts in the vault"},async activate(){if(await I$($.paths,$.name)!=="vault")throw Error(f0)}}}function l$($){let Z=(J,z,X)=>({method:{id:J,type:"oauth",label:z},async authorize(){if($.vault)await T2($.vault);let Y=await $.beginLogin({version:$.version,headless:X});return{url:Y.url,instructions:Y.instructions,mode:"auto",callback:Y.completion}}});return[Z(w0,"ChatGPT (openai-auth pool, browser)",!1),Z(y0,"ChatGPT (openai-auth pool, headless)",!0)]}function G1($){let Z=(J)=>typeof J==="string"?J:"";return N2({type:"oauth",access:Z($.access),refresh:Z($.refresh)})||$.refresh===h$||f$($)}function v0($){if($.accountId)return $.accountId;let Z=$.access?q2($.access):void 0;return Z?k2(Z):void 0}async function u$($,Z,J,z={}){if(z.vault)await T2(z.vault);if(G1(J))throw Error("the credential is not a ChatGPT login (a placeholder or a tombstone); it was not stored");let X=v$($,{rowLocks:(T)=>m$(Z,T)}),Y=await X.read();if(Y.status!=="ready")throw Error(`the account pool cannot be read (${Y.status}); the login was not stored`);let F={type:"oauth",refresh:J.refresh,...J.access!==void 0?{access:J.access}:{},...J.expires!==void 0?{expires:J.expires}:{}},H=v0(J);if(z.vault)await T2(z.vault);let W=H!==void 0?{identity:H}:{};if(z.origin==="import"){let T=Y.rows.find((v)=>H!==void 0&&v.identity===H||v.credential?.type==="oauth"&&v.credential.refresh===J.refresh);if(T)return{id:T.id,operation:"kept"}}let B=Y.rows.filter((T)=>T.type==="oauth"&&!T.invalid),V=H?B.find((T)=>T.identity===H):void 0,L=Y.rows.find((T)=>T.id===y2);if(V)return{id:(await X.replace(V.id,F,W)).id,operation:"replaced"};if(!L){let T=await X.add({id:y2,credential:F,...W,...J.label!==void 0?{label:J.label}:{}});return{id:T.id,operation:T.outcome==="added-disabled"?"added-disabled":"added"}}if(!L.invalid&&!L.credential)return{id:(await X.replace(y2,F,W)).id,operation:"replaced"};let x=await X.add({id:J.id,credential:F,...W,...J.label!==void 0?{label:J.label}:{}});return{id:x.id,operation:x.outcome==="added-disabled"?"added-disabled":x.outcome==="rotated"?"replaced":"added"}}function h0($){let Z=$.itemId!==void 0;switch($.sectionId){case"accounts":return Z?["enable","disable","remove","move"].includes($.actionId):$.actionId==="add";case"routing":return!Z&&["order","mode"].includes($.actionId);case"quota":return $.actionId==="check";case"limits":return Z?$.actionId==="floors":$.actionId==="killswitch";case"session":return!Z&&$.actionId==="clear-pin";case"diagnostics":return!Z&&["logging","dump"].includes($.actionId);case"cache":return!Z&&["enabled","subagents","sustain","window"].includes($.actionId);case"reset":return Z&&["preview","spend","retry"].includes($.actionId);default:return!1}}function d$($){let Z={...$,allowAction:h0,unavailableSections:[]};return{open:(J)=>p$(Z,J),apply:(J)=>{let z=J!==null&&typeof J==="object"?J:{},X=z.values&&typeof z.values==="object"&&!Array.isArray(z.values)?Object.fromEntries(Object.entries(z.values).filter(([,Y])=>Y===null||["string","number","boolean"].includes(typeof Y))):void 0;return c$(Z,{command:"openai",sectionId:typeof z.sectionId==="string"?z.sectionId:"",actionId:typeof z.actionId==="string"?z.actionId:"",...X?{values:X}:{},...z.confirmed===!0?{confirmed:!0}:{},...typeof z.itemId==="string"?{itemId:z.itemId}:{},...typeof z.sessionId==="string"?{sessionId:z.sessionId}:{}})}}}function m0($){if(!i$($.modelID??$.id)){$.enabled=!1;return}let Z=a$($.id);if(Z)$.limit={...Z}}function n$($){return $.model.transform((Z)=>{for(let J of Z.list(o))Z.update(o,String(J.id),(z)=>m0(z))})}class X1{log;pending=new Map;requests=new Map;writing=new Set;constructor($){this.log=$}async safely($){let Z=(async()=>{try{await $()}catch{this.log.warn("request dump failed")}})();this.writing.add(Z);try{await Z}finally{this.writing.delete(Z)}}async captureHttp($,Z){await this.safely(async()=>{if(!V2().dump)return;let J={sessionID:Z.sessionID,accountId:Z.accountId,transport:"http",phase:"http",url:$.url,method:$.method,headers:new Headers($.headers),bodyText:await $.clone().text()};if(this.pending.set($,{attemptId:Z.attemptId,input:J}),this.requests.set(Z.attemptId,$),this.pending.size>512){let z=this.pending.keys().next().value;if(z)this.take(z)}})}take($){let Z=this.pending.get($);if(Z)this.pending.delete($),this.requests.delete(Z.attemptId);return Z?.input}async response($,Z){let J=this.take($);if(J)await this.safely(()=>I2({...J,status:Z}))}async end($,Z){if(Z.status!==void 0||!Z.error)return;let J=this.requests.get($.attemptId),z=J&&this.take(J);if(!z)return;let{reason:X,message:Y}=Z.error,F=Y?`${X}: ${Y}`:X;await this.safely(()=>I2({...z,error:f2(F,J?.headers.get("authorization")?.replace(/^Bearer /,""))}))}async frame($,Z){await this.safely(()=>I2({sessionID:Z.sessionID,accountId:Z.accountId,transport:"websocket",phase:"observed",bodyText:$}))}clear(){this.pending.clear(),this.requests.clear()}async settle(){await Promise.all(this.writing)}}class Y1{counts=new Map;record($,Z){let J=Z.resetCreditsApplicable;this.counts.set($.id,{credentialEpoch:$.credentialEpoch,identity:$.identity,applicable:typeof J==="number"&&Number.isFinite(J)?J:void 0})}applicable($){let Z=this.counts.get($.id);if(!Z||Z.credentialEpoch!==$.credentialEpoch||Z.identity!==$.identity)return;return Z.applicable}}function e$($){return async(Z)=>{let J=Z.credential;if(J.type!=="oauth"||!J.access)throw Error("the row holds no access token to poll with");let z=await o$({accessToken:J.access,fetchImpl:$.fetchImpl,now:$.now,...Z.identity?{accountId:Z.identity}:{},accountKey:Z.id,...$.logger?{logger:$.logger}:{}});return $.counts.record(Z,z),r$(z,$.now(),!0)}}function $Z($){let{source:Z,counts:J,now:z}=$,X=async(B)=>{let V=await Z.rowAccess(B,await $.storage());if(!V?.row)throw new s$("unknown_account",`${B==="main"?"Main":"Fallback"} account ${B} was not found.`);return t$(B,V)},Y=async(B)=>{if($.authority&&await $.authority()!=="local")return{account:B,ok:!1,error:"local accounts are not polled while this host is connected to the vault"};let[V]=await Z.pollRows(await $.storage(),{ids:[B]});if(!V)return{account:B,ok:!1,error:"targeted quota refresh returned no result"};return{account:V.id,ok:V.ok,...V.error!==void 0?{error:V.error}:{}}},F=(B)=>Z.peek().rows.find((V)=>V.id===B),H=(B)=>{let V=F(B);if(!V)return null;let L=K2(V.quota)??{},x=J.applicable(V),T=Math.max(0,...[L.primary?.checkedAt,L.secondary?.checkedAt].filter((v)=>typeof v==="number"));return{quota:{...L,...x!==void 0?{resetCreditsApplicable:x}:{}},checkedAt:T,refreshAfter:T,...V.identity!==void 0?{accountId:V.identity}:{}}};return{resolveResetTarget:X,refreshResetTargetQuota:Y,quotaManager:{isRateLimited:(B)=>{let V=F(B);if(!V)return!1;let L=Z.rateLimitMarks([V]).get(V.id);return L!==void 0&&L>z()},getMain:()=>H("main"),getFallback:(B)=>H(B)}}}import{resolve as JZ}from"node:path";var g0=1024;class Q1{pins=new Map;listeners=new Set;limit;constructor($=g0){this.limit=Math.max(1,$)}get($){return this.pins.get($)?.accountId}forget($){this.pins.delete($);for(let Z of this.listeners)Z($)}subscribe($){return this.listeners.add($),()=>{this.listeners.delete($)}}snapshot(){return new Map(this.pins)}get size(){return this.pins.size}set($,Z){this.pins.delete($),this.pins.set($,Z);for(let J of this.listeners)J($,Z);while(this.pins.size>this.limit){let J=this.pins.keys().next().value;if(J===void 0)break;this.forget(J)}}place($){return ZZ(this.pins,$,(Z,J)=>this.set(Z,J))}}var zZ=Symbol.for("@cortexkit/openai-auth/opencode2-pins"),GZ=globalThis,j1=GZ[zZ]??new Map;GZ[zZ]=j1;function XZ($){let Z=JSON.stringify([JZ($.configPath),JZ($.statePath)]),J=j1.get(Z);if(!J)J=new Q1,j1.set(Z,J);return J}import{statSync as l0}from"node:fs";import{resolve as u0}from"node:path";function NZ($){return $.map((Z)=>{try{let J=l0(Z);return`${J.ino}:${J.size}:${J.mtimeMs}:${J.ctimeMs}`}catch{return"?"}}).join("|")}function V1($){return NZ([$.vault.paths.tokenPath,$.vault.paths.statePath])}function YZ($){return NZ([$.paths.configPath,$.paths.statePath,$.vault.paths.rosterPath])+V1($)}class FZ{file;observationIntervalMs;producers=new Set;subscriptions=new Map;observations=new Map;chain=Promise.resolve();timer;constructor($,Z){this.file=$;this.observationIntervalMs=Z}add($){this.producers.add($),this.observations.set($,{stamp:YZ($),roster:$.vault.snapshot()});let Z=$.source.subscribe(()=>{this.publish($)}),J=this.subscriptions.get($.pins);if(!J){let z=new Set;J={producers:z,stop:$.pins.subscribe((X,Y)=>{let F=z.values().next().value;if(F)this.publish(F,{sessionId:X,pin:Y,accountId:Y?.accountId,route:"sticky-balanced"})})},this.subscriptions.set($.pins,J)}return J.producers.add($),this.timer??=setInterval(()=>{for(let z of this.producers){let X={stamp:YZ(z),roster:z.vault.snapshot()},Y=this.observations.get(z);if(X.stamp!==Y?.stamp||X.roster!==Y?.roster)this.observations.set(z,X),this.publish(z)}},this.observationIntervalMs),this.timer.unref?.(),()=>{if(Z(),this.producers.delete($),this.observations.delete($),J.producers.delete($),!J.producers.size)J.stop(),this.subscriptions.delete($.pins);if(!this.producers.size)clearInterval(this.timer),this.timer=void 0}}publish($,Z){return this.chain=this.chain.then(async()=>{if(!this.producers.has($))return;let z=await $.vault.authority()!=="local",X=V1($),Y=()=>this.producers.has($)&&$.vault.enrolled()===z&&V1($)===X,F=await Z2($.paths),H=z?UZ($.vault.snapshot()?.rows??[],new Set($.vault.routes().map((B)=>B.id)),F,Date.now()):HZ((await $.source.sidebarView()).rows,F,Date.now());if(await jZ(H,this.file,{canWrite:Y}),!Y()||!Z)return;let W=H.vaultAccounts??H.fallbacks;if(Z.accountId===void 0){await BZ(Z.sessionId,W,this.file,{canWrite:Y});return}if(Z.pin){let B=Date.now();await WZ({sessionId:Z.sessionId,assignment:{accountId:Z.pin.accountId,wireAccountId:Z.pin.wireIdentity,inputBytes:Z.pin.inputBytes??0,quotaCheckedAt:Z.pin.quotaCheckedAt,assignedAt:B,lastSeenAt:B},validPinnedAccountIds:[...z?[]:["main"],...W.filter((V)=>V.enabled).map((V)=>V.id)]},this.file)}await VZ({sessionId:Z.sessionId,activeId:Z.accountId,route:Z.route??H.route,updatedAt:Date.now()},W,this.file,{canWrite:Y})}).catch(()=>{J2("opencode2").warn("sidebar publication failed")}),this.chain}settled(){return this.chain}get empty(){return this.producers.size===0}}var PZ=Symbol.for("@cortexkit/openai-auth/opencode2-sidebar-publishers"),KZ=globalThis,_2=KZ[PZ]??new Map;KZ[PZ]=_2;function LZ($,Z=QZ(),J=2000){let z=u0(Z),X=_2.get(z);if(!X)X=new FZ(z,J),_2.set(z,X);let Y=X,F=Y.add($),H=!1;for(let[W,B]of $.pins.snapshot())Y.publish($,{sessionId:W,pin:B,accountId:B.accountId,route:"sticky-balanced"});return{publish:()=>Y.publish($),route:(W,B,V)=>{Y.publish($,{sessionId:W,accountId:B,route:V})},async release(){if(H)return;if(H=!0,F(),await Y.settled(),Y.empty&&_2.get(z)===Y)_2.delete(z)}}}var h2="cortexkit-openai-auth",d0=5000;async function CZ($,Z,J,z=new P2,X,Y,F){let H=new X1(J),W=new p0,B=new Map,V=new Map,L=(S)=>{V.delete(S);for(let y of B.keys())if(y.startsWith(`${S}:`))B.delete(y)},x=(S)=>{F?.(S.sessionID),Y?.send(S.sessionID,S.frame)},v=await i2({session:{hook:(S,y,a)=>$.session.hook(S,async(I)=>{let j=S==="http.request"?I:void 0,K=S==="experimental.ws.handshake"?I:void 0,M=(j?j.request.headers:K?new Headers(K.headers):void 0)?.get("authorization")===`Bearer ${t(Z.providerID)}`,A={};if(K)B.delete(`${K.sessionID}:${K.kind}`);try{await W.run(A,()=>y(I))}catch(N){if(M&&!(N instanceof n))throw RZ(N);throw N}if(j&&M&&A.attempt){let N=j.request.headers.get("thread-id");if(N)j.request.headers.set("session-id",N)}if(j&&M&&A.attempt)await H.captureHttp(j.request,A.attempt);if(j&&M&&A.attempt)await X?.({sessionID:j.sessionID,kind:j.kind,request:j.request,attempt:A.attempt});if(K&&M&&A.attempt)K.headers["session-id"]=z.get(K.sessionID).threadID;if(S==="experimental.ws.send"){let N=I,_=B.get(`${N.sessionID}:${N.kind}`);if(_)await H.frame(N.frame,_.attempt);if(_&&N.kind==="primary")x(N)}if(j||K){let N=j??K;if(!N)return;let k=(j?j.request.headers:new Headers(N.headers)).get("authorization")?.replace(/^Bearer /,"");if(M&&k)V.set(N.sessionID,k);else V.delete(N.sessionID);if(K){let E=`${K.sessionID}:${K.kind}`;if(M&&k&&A.attempt)B.set(E,{bearer:k,attempt:A.attempt,url:K.url,headers:new Headers(Object.entries(K.headers).filter(([l])=>["chatgpt-account-id","x-opencode-parent-session-id","x-parent-session-id"].includes(l.toLowerCase())))});else B.delete(E)}if(V.size>512){let E=V.keys().next().value;if(E)V.delete(E)}if(B.size>512){let E=B.keys().next().value;if(E)B.delete(E)}}else if(S==="experimental.ws.receive"){let N=I,_=B.get(`${N.sessionID}:${N.kind}`);if(_){if(z.frameReceived(N.sessionID,N.frame),N.kind==="primary"){let k;if(Y?.receive(N.sessionID,N.frame,(E)=>{k=E}),k)try{let E=k1(k,_.url,_.headers,z);if(E)await X?.({sessionID:N.sessionID,kind:"primary",request:E,attempt:_.attempt})}catch(E){J.warn("cachekeep WebSocket capture failed",{error:E instanceof Error?E.message:String(E)})}}N.frame=AZ(N.frame,_.bearer)}}else if(S==="retry"){let N=I,_=V.get(N.sessionID);if(_)Object.assign(N.error,{message:f2(N.error.message,_)})}},a)},event:{subscribe:(S)=>async function*(){for await(let y of $.event.subscribe(S)){if(y.type==="session.deleted")L(y.data.sessionID);yield y}}()}},{...Z,rewriteRequest:async(S)=>{let y=W.getStore();if(y)y.attempt=S.attempt;return Z.rewriteRequest?.(S)},rewriteHandshakeURL:(S)=>{let y=W.getStore();if(y)y.attempt=S.attempt;return Z.rewriteHandshakeURL?.(S)},onAttemptEnd:async(S,y)=>{await H.end(S,y),await Z.onAttemptEnd?.(S,y)},rewriteResponse:async(S)=>{await H.response(S.request,S.response.status);let y=await Z.rewriteResponse?.(S)??S.response;return xZ(y,S.request.headers.get("authorization")?.replace(/^Bearer /,""),"event-stream")}},{gateOnPlaceholder:{credential:(S)=>{let y=S.get("authorization");return y?.startsWith("Bearer ")?y.slice(7):void 0}},logger:{warn:(S,y)=>J.warn(S,{data:y})}}),d=v.dispose;return{...v,dispose:async()=>{V.clear(),B.clear(),await d(),await H.settle(),H.clear()}}}function U1($={}){return{id:h2,setup:(Z)=>i0(Z,$)}}async function i0($,Z={}){let G2=[];try{let J=J2("opencode2");let z=J2("quota");let X=Z.paths??(()=>qZ(SZ()));let Y=await Z2(X());let F=Y?.logging?.level;if(F&&typeof F==="string")_Z(F);let H=Z.fetch??fetch;let W=Z.now??Date.now;let B=Z.version??yZ;let V=Z.poolMigration??lZ;if(!V&&!B2(X().configPath)){J.info("openai-auth stands aside on OpenCode 2: this install has not moved into the account pool and the migration is switched off, so OpenCode 2 serves its own ChatGPT login");let C=(r)=>{throw new n({kind:"no-account",providerID:o,sessionID:r.sessionID,requestKind:r.kind,message:b2})},f=await CZ($,{providerID:o,chooseAccount:C,accountHeaders:C},J);return()=>f.dispose()}let L=Z.vault?.firstRosterWaitMs??fZ;let x=gZ({host:"opencode",stateDir:Z.vault?.stateDir??OZ(X().statePath),reservedRouteIds:()=>I.peek().rows.map((C)=>C.id),...Z.vault?.connectionFile?{connectionFile:Z.vault.connectionFile}:{},...Z.vault?.connectScoped?{connectScoped:Z.vault.connectScoped}:{},...Z.vault?.connectEnrollment?{connectEnrollment:Z.vault.connectEnrollment}:{},...Z.vault?.pollIntervalMs!==void 0?{pollIntervalMs:Z.vault.pollIntervalMs}:{},fetchImpl:()=>H},X());let T=x.vault;let v=!1;let d=!1;const S=v2(G2,{[Symbol.dispose](){if(!v)x.release()}},0);await T.authority();let y=x.firstRoster;let a=new Y1;let I=new vZ({paths:X,refreshProvider:async(C)=>{let f=await EZ({refreshToken:C.refresh,fetchImpl:H,now:W}),r=MZ({id_token:"",access_token:f.access,refresh_token:f.refresh});return{...f,...r?{identity:r}:{}}},pullQuota:e$({fetchImpl:H,now:W,counts:a,logger:z}),now:W,vaultIdentities:()=>T.identities(),vaultMode:()=>T.enrolled(),vaultAuthority:()=>T.authority(),vaultFirstRoster:y,vaultFirstRosterBackgroundWaitMs:L,log:J2("pool")});await I.load();let j=Z.heartbeat===!1?void 0:await mZ({version:B,logger:J2("heartbeat")});let K=Z.fence??(()=>wZ({currentVersion:B}));let R=Z.slot??uZ();let M=async()=>kZ(X(),await R.get({path:{id:"openai"}}));let A=!1;let N=V?hZ({paths:X,slot:R,version:B,fence:K,runDeps:{vaultServes:()=>T.serves()},paused:async()=>await T.authority()!=="local",migrate:async(C)=>{let f=await bZ(C);if(A=f.status==="refused",!d)await I.load();return f},adopt:async(C)=>{if(d)return{status:"retry",reason:"unsettled"};if(!await W1(y,L))return{status:"retry",reason:"vault-roster-pending"};if(d)return{status:"retry",reason:"unsettled"};let f=await DZ(C);if(!d)await I.load();return f}}):void 0;N?.start();x.start();let _=XZ(X());let k=LZ({paths:X(),source:I,pins:_,vault:T},Z.sidebarStateFile,Z.sidebarObservationIntervalMs);const E=v2(G2,{[Symbol.dispose](){if(!v)k.release()}},0);k.publish();let l=Z.codex??new P2(void 0,void 0,R$());let i=H$(Y);let c=w2(X());let m=P$(X(),{source:I,storage:()=>Z2(X()),vault:T,accounts:t2(X()),settings:()=>i,parentOf:async(C)=>(await $.session.get({sessionID:C}))?.parentID??void 0,fetch:H,log:J2("cachekeep")},{now:W,codexResponsesUrl:V2().codexApiEndpoint,...Z.cacheKeep});const p=v2(G2,{[Symbol.dispose](){if(!v)m.release()}},0);let b=z$({codex:l,onRoute:k.route,source:I,slotPlaceholderWithoutMain:M,storage:()=>Z2(X()),pins:_,sessionAccounts:t2(X()),vault:T,awaitVaultRoster:async()=>{await W1(T.awaitRequestRoster(),IZ)},responsesLite:()=>V2().responsesLite,codexEndpoint:()=>V2().codexApiEndpoint,now:W,log:J});let u=await CZ($,b.adapter,J,l,(C)=>m.capture(C),c,(C)=>m.forget(C));b.attach(u);let g=async(C)=>{if(await T2(T),B2(X().configPath))return;if(await N?.idle(),B2(X().configPath))return;if(A&&!G1(C)&&(await K()).open){await I.poolStore().initialize();return}throw Error("OpenAI accounts move to the shared account pool once every OpenCode process on this machine runs this version of openai-auth; the login was not stored. Update or close the older processes and sign in again.")};let z2=async(C)=>{await g(C);let f=await u$(I.poolStore(),X(),C,{vault:T});if(!B2(X().configPath))await N?.requestAdoption();await I.load(),J.info("ChatGPT login stored in the account pool",f)};let W2=await p2($,{integrationID:o,methods:l$({beginLogin:Z.beginLogin??B1,version:B,vault:T}),onLogin:(C)=>z2(C),label:"ChatGPT (openai-auth account pool)",vault:g$(T)});let M2=await n$($);if(Z.controlPlane&&(!$.command||!$.location))throw Error("OpenCode 2 control plane requires command and location APIs");let U2=$.command&&$.location?await y$({session:$.session,command:$.command,location:$.location},Z.controlPlane??d$({...$Z({source:I,storage:()=>Z2(X()),counts:a,now:W,authority:()=>T.authority()}),fetchImpl:H,now:W,randomUUID:c0,accountStoragePath:X().configPath,accountStatePath:X().statePath,packageVersion:B,loadAccounts:Z2,store:()=>I.poolStore(),migration:async()=>{if(B2(X().configPath))return{migrated:!0};let C=await K();return{migrated:!1,blockers:C.open?[]:C.blockers}},beginAccountLogin:Z.beginLogin??B1,refreshAllQuota:async()=>(await I.pollRows(await Z2(X()))).map((C)=>({...C,account:C.id})),getStickyRouting:async(C)=>_.get(C),cacheKeepManager:m.manager,setCacheKeepEnabled:(C)=>m.configure({enabled:C}),setCacheKeepSubagents:(C)=>m.configure({subagents:C}),setCacheKeepSustain:(C)=>m.configure({sustain:C}),setCacheKeepWindow:(C)=>m.configure({window:C}),afterWrite:()=>I.load(),refreshSidebar:()=>k.publish(),clearStickyRouting:async(C)=>{let f=_.get(C)!==void 0;return _.forget(C),f},vault:T})):void 0;let Q2=new AbortController;(async()=>{try{for await(let C of $.event.subscribe({signal:Q2.signal}))if(C.type==="session.deleted")b.forgetSession(C.data.sessionID),m.forget(C.data.sessionID),c.forget(C.data.sessionID)}catch(C){if(!Q2.signal.aborted)J.warn("stopped listening for session deletion",{error:C instanceof Error?C.message:String(C)})}})();v=!0;return async()=>{d=!0,Q2.abort();let C=m.release();await U2?.(),N?.dispose(),I.dispose(),await k.release(),await Promise.allSettled([u.dispose(),W2.dispose(),M2.dispose()]);let f;try{await Promise.race([Promise.all([N?.idle(),I.settled(),l.store?.settled(),C]),new Promise((r)=>{f=setTimeout(r,d0),f.unref?.()})])}finally{clearTimeout(f),x.release(),await j?.release()}}}catch(m2){var g2=m2,l2=1}finally{TZ(G2,g2,l2)}}var a0=U1(),F6={id:h2,setup:a0.setup,server:pZ.server};export{F6 as default,U1 as createOpenAIAuthPlugin,h2 as OPENAI_AUTH_PLUGIN_ID};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-openai-auth",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -66,14 +66,14 @@
66
66
  },
67
67
  "devDependencies": {
68
68
  "@ai-sdk/openai": "3.0.88",
69
- "@cortexkit/common-auth": "^0.18.0",
69
+ "@cortexkit/common-auth": "^0.21.0",
70
70
  "@cortexkit/openai-auth-core": "workspace:*",
71
71
  "@opencode/plugin": "2.0.27"
72
72
  },
73
73
  "dependencies": {
74
- "@cortexkit/claustrum-client": "^0.9.0",
74
+ "@cortexkit/claustrum-client": "^0.12.0",
75
75
  "@cortexkit/private-files": "^0.2.1",
76
- "@cortexkit/subc-client": "^0.16.0",
76
+ "@cortexkit/subc-client": "^0.22.0",
77
77
  "@opentui/core": ">=0.6.1",
78
78
  "@opentui/solid": ">=0.6.1",
79
79
  "ai": "^7.0.137",
@@ -63,8 +63,12 @@ export function quotaWindowName(limit) {
63
63
  function clampPercent(remaining) {
64
64
  return Math.min(100, Math.max(0, remaining));
65
65
  }
66
+ /** A remaining percentage as the whole number every form shows. */
67
+ function wholePercent(remaining) {
68
+ return Math.round(clampPercent(remaining));
69
+ }
66
70
  function percentLeft(remaining) {
67
- return `${Math.round(clampPercent(remaining))}% left`;
71
+ return `${wholePercent(remaining)}% left`;
68
72
  }
69
73
  function resetDetails(resetsAt, checkedAt, now) {
70
74
  const at = resetsAt === undefined ? Number.NaN : Date.parse(resetsAt);
@@ -98,6 +102,16 @@ function displayOrder(left, right) {
98
102
  * and the optional age keep the shared formatter's wording.
99
103
  */
100
104
  export function quotaWindowParts(quota, options) {
105
+ const { windows, age } = scopedWindowParts(quota, options);
106
+ const parts = windows.map(({ part }) => part);
107
+ return age === undefined ? { windows: parts } : { windows: parts, age };
108
+ }
109
+ /**
110
+ * `quotaWindowParts` with each window's scope kept beside it. The narrow form
111
+ * needs the scope to name and pick model-scoped windows; the public parts do
112
+ * not carry it, so their shape stays as it was.
113
+ */
114
+ function scopedWindowParts(quota, options) {
101
115
  if (!quota)
102
116
  return { windows: [] };
103
117
  const { now } = options;
@@ -107,12 +121,18 @@ export function quotaWindowParts(quota, options) {
107
121
  const windows = readings.map((limit) => {
108
122
  const remainingPercent = clampPercent(limit.remainingPercent ?? 0);
109
123
  return {
110
- kind: 'window',
111
- name: quotaWindowName(limit),
112
- figure: percentLeft(limit.remainingPercent ?? 0),
113
- remainingPercent,
114
- checkedAt: limit.checkedAt,
115
- ...resetDetails(limit.resetsAt, limit.checkedAt, now),
124
+ scope: limit.scope,
125
+ ...(limit.windowMinutes === undefined
126
+ ? {}
127
+ : { windowMinutes: limit.windowMinutes }),
128
+ part: {
129
+ kind: 'window',
130
+ name: quotaWindowName(limit),
131
+ figure: percentLeft(limit.remainingPercent ?? 0),
132
+ remainingPercent,
133
+ checkedAt: limit.checkedAt,
134
+ ...resetDetails(limit.resetsAt, limit.checkedAt, now),
135
+ },
116
136
  };
117
137
  });
118
138
  const budget = quota.budget;
@@ -124,32 +144,196 @@ export function quotaWindowParts(quota, options) {
124
144
  ? `credits ${percentLeft(remainingPercent)}`
125
145
  : 'credits available';
126
146
  windows.push({
127
- kind: 'budget',
128
- name: 'credits',
129
- figure,
130
- ...(remainingPercent === undefined
131
- ? {}
132
- : { remainingPercent: clampPercent(remainingPercent) }),
133
- checkedAt: budget.checkedAt,
134
- ...resetDetails(budget.resetsAt, budget.checkedAt, now),
147
+ scope: ALL_SCOPE,
148
+ spent: budget.reached,
149
+ part: {
150
+ kind: 'budget',
151
+ name: 'credits',
152
+ figure,
153
+ ...(remainingPercent === undefined
154
+ ? {}
155
+ : { remainingPercent: clampPercent(remainingPercent) }),
156
+ checkedAt: budget.checkedAt,
157
+ ...resetDetails(budget.resetsAt, budget.checkedAt, now),
158
+ },
135
159
  });
136
160
  }
137
161
  if (windows.length > 0) {
138
- const age = now - Math.min(...windows.map((part) => part.checkedAt));
162
+ const age = now - Math.min(...windows.map(({ part }) => part.checkedAt));
139
163
  if (age > (options.staleAfterMs ?? QUOTA_STALE_AFTER_MS)) {
140
164
  return { windows, age: `checked ${shortSpan(age)} ago` };
141
165
  }
142
166
  }
143
167
  return { windows };
144
168
  }
169
+ /**
170
+ * Whether the reading is stale: true exactly when the compact and full forms
171
+ * would end with `checked … ago`. The narrow form leaves that age out to stay
172
+ * short, so a caller drawing a narrow line uses this to dim it instead.
173
+ */
174
+ export function isQuotaStale(quota, options) {
175
+ return scopedWindowParts(quota, options).age !== undefined;
176
+ }
177
+ /**
178
+ * The model a scope names, as a display name: any namespace before a colon
179
+ * is dropped (`model:claude-opus-4` → `claude-opus-4`) and the first letter is
180
+ * capitalized (`fable` → `Fable`); the rest stays as written.
181
+ */
182
+ function scopeDisplayName(scope) {
183
+ const model = scope.slice(scope.indexOf(':') + 1);
184
+ return model.charAt(0).toUpperCase() + model.slice(1);
185
+ }
186
+ /**
187
+ * Short names for the model scopes in one row: the first two letters of each
188
+ * display name. Names that would read the same for different models are each
189
+ * extended one letter at a time until they differ (`Fable` and `Fabric` read
190
+ * `Fabl` and `Fabr`); a name that runs out of letters stays whole.
191
+ */
192
+ function scopeAbbreviations(scopes) {
193
+ const names = [...new Set(scopes.map(scopeDisplayName))];
194
+ const lengths = new Map(names.map((name) => [name, 2]));
195
+ const short = (name) => name.slice(0, lengths.get(name));
196
+ for (;;) {
197
+ const byShort = new Map();
198
+ for (const name of names) {
199
+ byShort.set(short(name), [...(byShort.get(short(name)) ?? []), name]);
200
+ }
201
+ let extended = false;
202
+ for (const group of byShort.values()) {
203
+ if (group.length < 2)
204
+ continue;
205
+ for (const name of group) {
206
+ const length = lengths.get(name) ?? 2;
207
+ if (length < name.length) {
208
+ lengths.set(name, length + 1);
209
+ extended = true;
210
+ }
211
+ }
212
+ }
213
+ if (!extended)
214
+ break;
215
+ }
216
+ return new Map(scopes.map((scope) => [scope, short(scopeDisplayName(scope))]));
217
+ }
218
+ /** The most groups a grouped narrow line shows. */
219
+ const NARROW_GROUP_LIMIT = 2;
220
+ /**
221
+ * The names the groups read under in the narrow line, one per listed group:
222
+ * each label's short name, derived exactly as a model window's is (`Gemini`
223
+ * → `Ge`, `Other models` → `Ot`, colliding names extended until they
224
+ * differ), computed over every listed group so a group keeps its name
225
+ * whichever groups show. A blank label falls back to the group's scope.
226
+ */
227
+ function groupShortNames(groups) {
228
+ const labels = groups.map((group) => group.label.trim() || group.scope);
229
+ const short = scopeAbbreviations(labels);
230
+ return labels.map((label) => short.get(label) ?? label);
231
+ }
232
+ /**
233
+ * The narrow line of a reading whose windows belong to named groups and that
234
+ * has no account-wide window: for each group, its tightest window as
235
+ * `Ge 7d 62%`, with ` left` once at the end. The tightest window is the
236
+ * one with least left, compared before rounding; on a tie the first in
237
+ * display order (the shorter window) wins. At most two groups show: the two
238
+ * with least left, earlier-listed first on a tie, and always in the order
239
+ * the reading lists them, so the line does not reorder as the figures move.
240
+ * A group with no reported window is skipped. Windows outside the listed
241
+ * groups and the credit budget are left out. Undefined when the rule does
242
+ * not apply, so the caller uses the ordinary narrow rule.
243
+ */
244
+ function groupedNarrowPieces(groups, windows) {
245
+ if (!groups || groups.length === 0)
246
+ return undefined;
247
+ const reported = windows.filter(({ part }) => part.kind === 'window');
248
+ if (reported.some(({ scope }) => scope === ALL_SCOPE))
249
+ return undefined;
250
+ const candidates = groups.flatMap((group, listed) => {
251
+ const inGroup = reported.filter(({ scope }) => scope === group.scope);
252
+ // `windows` is already in display order, and strictly lower wins, so on
253
+ // a tie the shorter window keeps the place.
254
+ const groupTightest = inGroup.reduce((least, window) => least === undefined ||
255
+ (window.part.remainingPercent ?? 0) < (least.part.remainingPercent ?? 0)
256
+ ? window
257
+ : least, undefined);
258
+ return groupTightest ? [{ group, listed, window: groupTightest }] : [];
259
+ });
260
+ if (candidates.length === 0)
261
+ return undefined;
262
+ const names = groupShortNames(groups);
263
+ const left = (candidate) => candidate.window.part.remainingPercent ?? 0;
264
+ const shown = [...candidates]
265
+ .sort((a, b) => left(a) - left(b) || a.listed - b.listed)
266
+ .slice(0, NARROW_GROUP_LIMIT)
267
+ .sort((a, b) => a.listed - b.listed);
268
+ return shown.map((candidate, index) => {
269
+ const { windowMinutes } = candidate.window;
270
+ const piece = [
271
+ names[candidate.listed] ?? candidate.group.scope,
272
+ ...(windowMinutes === undefined ? [] : [lengthName(windowMinutes)]),
273
+ `${wholePercent(left(candidate))}%`,
274
+ ].join(' ');
275
+ return index === shown.length - 1 ? `${piece} left` : piece;
276
+ });
277
+ }
278
+ /**
279
+ * The narrow form's pieces: every account-wide window as `5h 92%`, then at
280
+ * most one more item, with ` left` added once to the last piece. That item is
281
+ * the tightest (least remaining) of the model-scoped windows and the credit
282
+ * budget, so the line stays bounded whatever the account carries: a scoped
283
+ * window reads under its short model name (`Fa 98%`), the budget as `cr 75%`
284
+ * (`cr 0%` when spent). On a tie a scoped window wins over the budget, and
285
+ * among scoped windows the first in display order wins. The choice depends
286
+ * only on the reading, never on a width. A budget without a percentage cannot
287
+ * be chosen; when nothing at all is shown it keeps its compact wording
288
+ * (`credits available`). No age is added; `isQuotaStale` says whether the
289
+ * reading is stale. A window whose reset arrived after the reading keeps its
290
+ * figure, as in the other forms. A reading that lists named groups and has no
291
+ * account-wide window reads one item per group instead (see
292
+ * `groupedNarrowPieces`).
293
+ */
294
+ function narrowTextParts(quota, options) {
295
+ const { windows } = scopedWindowParts(quota, options);
296
+ const grouped = groupedNarrowPieces(quota?.groups, windows);
297
+ if (grouped)
298
+ return grouped;
299
+ const general = windows.filter(({ part, scope }) => part.kind === 'window' && scope === ALL_SCOPE);
300
+ const scoped = windows.filter(({ part, scope }) => part.kind === 'window' && scope !== ALL_SCOPE);
301
+ const abbreviations = scopeAbbreviations(scoped.map(({ scope }) => scope));
302
+ // The items competing for the one slot after the account-wide windows, in
303
+ // tie-break order: scoped windows in display order, then the budget. A
304
+ // spent budget counts as 0% left; one without a percentage cannot compete.
305
+ const budget = windows.find(({ part }) => part.kind === 'budget');
306
+ const budgetLeft = budget?.spent ? 0 : budget?.part.remainingPercent;
307
+ const extras = [
308
+ ...scoped.map(({ scope, part }) => ({
309
+ label: abbreviations.get(scope) ?? scope,
310
+ remaining: part.remainingPercent ?? 0,
311
+ })),
312
+ ...(budgetLeft === undefined
313
+ ? []
314
+ : [{ label: 'cr', remaining: budgetLeft }]),
315
+ ];
316
+ // Strictly lower wins, so on a tie the earlier item keeps the slot.
317
+ const tightest = extras.reduce((best, item) => best === undefined || item.remaining < best.remaining ? item : best, undefined);
318
+ const pieces = general.map(({ part }) => `${part.name} ${wholePercent(part.remainingPercent ?? 0)}%`);
319
+ if (tightest) {
320
+ pieces.push(`${tightest.label} ${wholePercent(tightest.remaining)}%`);
321
+ }
322
+ if (pieces.length === 0)
323
+ return windows.map(({ part }) => part.figure);
324
+ return pieces.map((piece, index) => index === pieces.length - 1 ? `${piece} left` : piece);
325
+ }
145
326
  /**
146
327
  * The pieces of a quota text, in order: one per reported window
147
328
  * (`5h 58% left, resets 2h`), then the credit budget when there is one, then
148
329
  * `checked 3h ago` when the oldest piece shown is stale. Empty when nothing
149
330
  * was reported; `formatQuota` turns that into a sentence. A caller printing
150
- * one line per window (the terminal auth menu) uses these directly.
331
+ * one line per window (the terminal auth menu) uses these directly. In the
332
+ * narrow form the pieces are the narrow line's (`5h 92%`, `7d 66% left`).
151
333
  */
152
334
  export function quotaTextParts(quota, options) {
335
+ if (options.form === 'narrow')
336
+ return narrowTextParts(quota, options);
153
337
  const parts = quotaWindowParts(quota, options);
154
338
  const full = (options.form ?? 'full') === 'full';
155
339
  const text = parts.windows.map((part) => {
@@ -160,7 +344,8 @@ export function quotaTextParts(quota, options) {
160
344
  }
161
345
  /**
162
346
  * A row's quota as one line: `5h 58% left · 7d 90% left` in the compact
163
- * form, with `, resets 2h` after each window in the full form. With nothing
347
+ * form, with `, resets 2h` after each window in the full form, and
348
+ * `5h 58% · 7d 90% left` in the narrow form. With nothing
164
349
  * reported it is `NO_QUOTA_READING`, or `NO_LIMITS_REPORTED` when the
165
350
  * provider answered without a limit for any window.
166
351
  */