@cortexkit/opencode-anthropic-auth 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,9 @@
1
- import{$ as T0,A as S1,B as R1,C as y1,D as S0,E as Y0,F as f1,G as i,H as R0,I as y0,J as T1,K as K0,L as Q0,M as G0,N as r,O as A1,P as P0,Q as Y1,R as K1,S as f0,T as Q1,U as G1,V as P1,W as I0,X as k1,Y as b1,Z as m1,_ as g1,a as Z1,aa as h1,b as $1,ba as d1,c as $0,ca as z0,d as V0,da as w0,e as V1,ea as l1,f as o,fa as A0,g as F1,ga as O0,h as D1,ha as k0,i as X1,ia as L0,j as W1,ja as p1,k as H0,ka as b0,l as B1,la as u1,m as q0,ma as N0,n as E0,na as i1,o as q,oa as c1,p as H1,pa as m0,q as C,r as a,ra as n1,s as q1,t as X0,ta as _0,u as W0,ua as g0,v as E1,va as o1,w as x1,wa as s1,x as x0,xa as h0,y as C1,z as C0}from"./index-4wz5npbg.js";import{Ba as a1}from"./index-nfgq84t3.js";import{randomUUID as qj}from"node:crypto";function l(j){return typeof j==="object"&&j!==null}function Kj(j){if(Array.isArray(j))return j;if(l(j)&&Array.isArray(j.data))return j.data;return[]}function Qj(j){if(!l(j)||!l(j.info))return;return typeof j.info.role==="string"?j.info.role:void 0}function c0(j){if(!l(j)||!l(j.info))return null;let J=j.info,Z=l(J.model)?J.model:void 0,V=typeof J.agent==="string"?J.agent:void 0,D=typeof Z?.providerID==="string"?Z.providerID:typeof J.providerID==="string"?J.providerID:void 0,Y=typeof Z?.modelID==="string"?Z.modelID:typeof J.modelID==="string"?J.modelID:void 0,B=typeof Z?.variant==="string"?Z.variant:typeof J.variant==="string"?J.variant:void 0;if(!V&&(!D||!Y)&&!B)return null;let k={};if(V)k.agent=V;if(D&&Y)k.model={providerID:D,modelID:Y};if(B)k.variant=B;return k}function n0(j,J){return{agent:j.agent??J.agent,model:j.model??J.model,variant:j.variant??J.variant}}function o0(j){return Boolean(j.agent&&j.model&&j.variant)}async function s0(j,J){if(!j||!J)return null;let Z=j;if(typeof Z.session?.messages!=="function")return null;let V=[];try{V=Kj(await Promise.resolve(Z.session.messages({path:{id:J},query:{limit:100}})))}catch{return null}if(V.length===0)return null;let D={};for(let Y=V.length-1;Y>=0;Y--){if(Qj(V[Y])!=="assistant")continue;let B=c0(V[Y]);if(!B)continue;if(D=n0(D,B),o0(D))return D}for(let Y=V.length-1;Y>=0;Y--){let B=c0(V[Y]);if(!B)continue;if(D=n0(D,B),o0(D))return D}if(!D.agent&&!D.model&&!D.variant)return null;return D}function a0(j){return`${Z1}${j.charAt(0).toUpperCase()}${j.slice(1)}`}function I1(j){if(j==="StructuredOutput")return j;return`${j.charAt(0).toLowerCase()}${j.slice(1)}`}var Gj=new Set(["callgraph","conflicts","delete","import","inspect","move","navigate","outline","refactor","safety","search","transform","zoom"]);function r0(j){let J=I1(j);if(J.startsWith("aft_"))return J;if(Gj.has(J))return`aft_${J}`;return null}function z1(j,J){let Z=new Headers;if(j instanceof Request)j.headers.forEach((D,Y)=>{Z.set(Y,D)});let V=J?.headers;if(V){if(V instanceof Headers)V.forEach((D,Y)=>{Z.set(Y,D)});else if(Array.isArray(V))for(let D of V){let[Y,B]=D;if(typeof B<"u")Z.set(Y,String(B))}else for(let[D,Y]of Object.entries(V))if(typeof Y<"u")Z.set(D,String(Y))}return Z}function B0(j){return j.set("anthropic-beta",$0(j.get("anthropic-beta"),[$1])),j}function s(j,J,Z={}){return G1(j,J,Z)}function Pj(j){if(j.tools&&Array.isArray(j.tools))j.tools=j.tools.map((J)=>({...J,name:J.name?a0(J.name):J.name}));if(j.messages&&Array.isArray(j.messages))j.messages=j.messages.map((J)=>{if(J.content&&Array.isArray(J.content))J.content=J.content.map((Z)=>{if(Z.type==="tool_use"&&Z.name)return{...Z,name:a0(Z.name)};return Z});return J});return JSON.stringify(P1(j))}function v0(j){return j.replace(/"name"\s*:\s*"(mcp_)?([^"]+)"/g,(J,Z,V)=>{if(Z)return`"name": "${r0(V)??I1(V)}"`;let D=r0(V);return D?`"name": "${D}"`:J})}function t0(j,J=!1){if(J)return{ready:v0(j),pending:""};let Z=j.length,V='"name"',D=Math.max(0,j.length-V.length+1);for(let B=D;B<j.length;B++)if(V.startsWith(j.slice(B))){Z=Math.min(Z,B);break}let Y=j.lastIndexOf(V);if(Y!==-1){let B=j.slice(Y);if(/^"name"\s*(?::\s*(?:"[^"]*)?)?$/.test(B))Z=Math.min(Z,Y)}if(Z<j.length)return{ready:v0(j.slice(0,Z)),pending:j.slice(Z)};return{ready:v0(j),pending:""}}function w1(){if(!process.env.ANTHROPIC_BASE_URL?.trim())return!1;let j=process.env.ANTHROPIC_INSECURE?.trim();return j==="1"||j==="true"}function Ij(){let j=process.env.ANTHROPIC_BASE_URL?.trim();if(!j)return null;try{let J=new URL(j);if(J.protocol!=="http:"&&J.protocol!=="https:"||J.username||J.password)return null;return J}catch{return null}}function O1(j){let J=null;try{if(typeof j==="string"||j instanceof URL)J=new URL(j.toString());else if(j instanceof Request)J=new URL(j.url)}catch{J=null}if(!J)return{input:j,url:null};let Z=J.href,V=Ij();if(V)J.protocol=V.protocol,J.host=V.host;if(J.pathname==="/v1/messages"&&!J.searchParams.has("beta"))J.searchParams.set("beta","true");if(J.href===Z)return{input:j,url:J};return{input:j instanceof Request?new Request(J.toString(),j):J,url:J}}function j0(j){let V=j.split(/\n\n+/).filter((D)=>{if(D.includes(V1))return!1;for(let Y of X1)if(D.includes(Y))return!1;return!0}).join(`
1
+ import{$ as v1,A as p1,B as l1,Ba as f0,C as u1,Ca as j1,D as c0,Da as Pj,E as M0,Ea as zj,F as i1,Fa as J1,G as $0,H as n0,I as c1,J as P0,K as z0,L as v0,M as n1,N as o1,O as s1,P as r1,Q as F0,R as q0,S as E0,T as Q0,U as t1,V as C0,W as B1,X as H1,Y as o0,Z as U1,_ as M1,a as I1,aa as x0,b as O1,ba as a1,c as _0,ca as e1,d as B0,da as jj,e as L1,ea as Jj,f as K0,fa as s0,g as k1,ga as Zj,h as N1,ha as $j,i as w1,ia as S0,j as _1,ja as R0,k as d0,ka as Gj,l as f1,la as r0,m as p0,ma as T0,n as l0,na as t0,o as F,oa as y0,p as m1,pa as Vj,q as R,qa as a0,r as Y0,ra as A0,s as b1,sa as Dj,t as H0,ta as Kj,u as U0,ua as k0,v as h1,va as Xj,w as g1,wa as Wj,x as u0,xa as e0,y as d1,z as i0,za as Yj}from"./index-zx0zb5c8.js";import{Ja as Qj}from"./index-q0d64q8d.js";import{randomUUID as pj}from"node:crypto";function Z0(j){return typeof j==="object"&&j!==null}function Fj(j){if(Array.isArray(j))return j;if(Z0(j)&&Array.isArray(j.data))return j.data;return[]}function qj(j){if(!Z0(j)||!Z0(j.info))return;return typeof j.info.role==="string"?j.info.role:void 0}function G1(j){if(!Z0(j)||!Z0(j.info))return null;let J=j.info,Z=Z0(J.model)?J.model:void 0,G=typeof J.agent==="string"?J.agent:void 0,V=typeof Z?.providerID==="string"?Z.providerID:typeof J.providerID==="string"?J.providerID:void 0,Y=typeof Z?.modelID==="string"?Z.modelID:typeof J.modelID==="string"?J.modelID:void 0,v=typeof Z?.variant==="string"?Z.variant:typeof J.variant==="string"?J.variant:void 0;if(!G&&(!V||!Y)&&!v)return null;let u={};if(G)u.agent=G;if(V&&Y)u.model={providerID:V,modelID:Y};if(v)u.variant=v;return u}function V1(j,J){return{agent:j.agent??J.agent,model:j.model??J.model,variant:j.variant??J.variant}}function D1(j){return Boolean(j.agent&&j.model&&j.variant)}async function K1(j,J){if(!j||!J)return null;let Z=j;if(typeof Z.session?.messages!=="function")return null;let G=[];try{G=Fj(await Promise.resolve(Z.session.messages({path:{id:J},query:{limit:100}})))}catch{return null}if(G.length===0)return null;let V={};for(let Y=G.length-1;Y>=0;Y--){if(qj(G[Y])!=="assistant")continue;let v=G1(G[Y]);if(!v)continue;if(V=V1(V,v),D1(V))return V}for(let Y=G.length-1;Y>=0;Y--){let v=G1(G[Y]);if(!v)continue;if(V=V1(V,v),D1(V))return V}if(!V.agent&&!V.model&&!V.variant)return null;return V}function X1(j){return`${I1}${j.charAt(0).toUpperCase()}${j.slice(1)}`}function F1(j){if(j==="StructuredOutput")return j;return`${j.charAt(0).toLowerCase()}${j.slice(1)}`}var Ej=new Set(["callgraph","conflicts","delete","import","inspect","move","navigate","outline","refactor","safety","search","transform","zoom"]);function W1(j){let J=F1(j);if(J.startsWith("aft_"))return J;if(Ej.has(J))return`aft_${J}`;return null}function q1(j,J){let Z=new Headers;if(j instanceof Request)j.headers.forEach((V,Y)=>{Z.set(Y,V)});let G=J?.headers;if(G){if(G instanceof Headers)G.forEach((V,Y)=>{Z.set(Y,V)});else if(Array.isArray(G))for(let V of G){let[Y,v]=V;if(typeof v<"u")Z.set(Y,String(v))}else for(let[V,Y]of Object.entries(G))if(typeof Y<"u")Z.set(V,String(Y))}return Z}function g0(j){return j.set("anthropic-beta",_0(j.get("anthropic-beta"),[O1])),j}function X0(j,J,Z={}){return M1(j,J,Z)}function Cj(j){if(j.tools&&Array.isArray(j.tools))j.tools=j.tools.map((J)=>({...J,name:J.name?X1(J.name):J.name}));if(j.messages&&Array.isArray(j.messages))j.messages=j.messages.map((J)=>{if(J.content&&Array.isArray(J.content))J.content=J.content.map((Z)=>{if(Z.type==="tool_use"&&Z.name)return{...Z,name:X1(Z.name)};return Z});return J});return JSON.stringify(v1(j))}function b0(j){return j.replace(/"name"\s*:\s*"(mcp_)?([^"]+)"/g,(J,Z,G)=>{if(Z)return`"name": "${W1(G)??F1(G)}"`;let V=W1(G);return V?`"name": "${V}"`:J})}function Y1(j,J=!1){if(J)return{ready:b0(j),pending:""};let Z=j.length,G='"name"',V=Math.max(0,j.length-G.length+1);for(let v=V;v<j.length;v++)if(G.startsWith(j.slice(v))){Z=Math.min(Z,v);break}let Y=j.lastIndexOf(G);if(Y!==-1){let v=j.slice(Y);if(/^"name"\s*(?::\s*(?:"[^"]*)?)?$/.test(v))Z=Math.min(Z,Y)}if(Z<j.length)return{ready:b0(j.slice(0,Z)),pending:j.slice(Z)};return{ready:b0(j),pending:""}}function E1(){if(!process.env.ANTHROPIC_BASE_URL?.trim())return!1;let j=process.env.ANTHROPIC_INSECURE?.trim();return j==="1"||j==="true"}function xj(){let j=process.env.ANTHROPIC_BASE_URL?.trim();if(!j)return null;try{let J=new URL(j);if(J.protocol!=="http:"&&J.protocol!=="https:"||J.username||J.password)return null;return J}catch{return null}}function C1(j){let J=null;try{if(typeof j==="string"||j instanceof URL)J=new URL(j.toString());else if(j instanceof Request)J=new URL(j.url)}catch{J=null}if(!J)return{input:j,url:null};let Z=J.href,G=xj();if(G)J.protocol=G.protocol,J.host=G.host;if(J.pathname==="/v1/messages"&&!J.searchParams.has("beta"))J.searchParams.set("beta","true");if(J.href===Z)return{input:j,url:J};return{input:j instanceof Request?new Request(J.toString(),j):J,url:J}}function L0(j){let G=j.split(/\n\n+/).filter((V)=>{if(V.includes(L1))return!1;for(let Y of w1)if(V.includes(Y))return!1;return!0}).join(`
2
2
 
3
- `);for(let D of W1)V=V.replace(D.match,D.replacement);return V.trim()}function y(j){return j!=null&&typeof j==="object"&&!Array.isArray(j)}function zj(j){let J={type:"text",text:o};if(j==null)return[J];if(typeof j==="string"){let V=j0(j);if(V===o)return[J];return[J,{type:"text",text:V}]}if(y(j)){let V=typeof j.type==="string"?j.type:"text",D=typeof j.text==="string"?j.text:"";return[J,{...j,type:V,text:j0(D)}]}if(!Array.isArray(j))return[J];let Z=j.map((V)=>{if(typeof V==="string")return{type:"text",text:j0(V)};if(y(V)&&V.type==="text"&&typeof V.text==="string")return{...V,type:"text",text:j0(V.text)};return{type:"text",text:String(V)}});if(Z[0]?.text===o)return Z;return[J,...Z]}var L1={type:"ephemeral",ttl:"1h"},wj=20;function Oj(j){if(y(j.cache_control))return j.cache_control;if(y(j.cacheControl))return j.cacheControl;return null}function F0(j,J){if(!y(j))return!1;return delete j.cacheControl,j.cache_control=J?{...L1}:{type:"ephemeral"},!0}function e0(j){if(!y(j))return;delete j.cache_control,delete j.cacheControl}function Lj(j){if(Array.isArray(j))return j;if(typeof j==="string")return[{type:"text",text:j}];return null}function J0(j,J){if(!y(j))return;let Z=Oj(j);if(Z?.type!=="ephemeral")return;if(J)Z.ttl="1h";else delete Z.ttl}function j1(j,J){if(Array.isArray(j.system))for(let Z of j.system)J0(Z,J);else J0(j.system,J);if(!Array.isArray(j.messages))return;for(let Z of j.messages)if(J0(Z,J),y(Z)&&Array.isArray(Z.content))for(let V of Z.content)J0(V,J)}function Nj(j,J){if(Array.isArray(j.system))for(let Z of j.system)J(Z);else J(j.system);if(!Array.isArray(j.messages))return;for(let Z of j.messages)if(J(Z),y(Z)&&Array.isArray(Z.content))for(let V of Z.content)J(V)}function N1(j){e0(j),Nj(j,e0)}function _j(j){N1(j),j.cache_control={...L1}}function Z0(j){if(!y(j))return!1;let J=Lj(j.content);if(!J?.length)return!1;let Z=[...J].reverse().find((V)=>y(V)&&V.type!=="thinking"&&V.type!=="redacted_thinking");if(!Z)return!1;return j.content=J,F0(Z,!0)}function Uj(j){if(!y(j))return 0;let J=j.content;if(Array.isArray(J))return J.length;if(J==null)return 0;return 1}function Mj(j){let J=[],Z=0;return j.forEach((V,D)=>{let Y=Uj(V);if(y(V)&&V.role==="user"&&Y>0)J.push({index:D,blockPosition:Z+Y-1});Z+=Y}),J}function vj(j){let J=Mj(j),Z=[...J].reverse().find((B)=>B.index>1);if(!Z)return{latest:void 0,bridge:void 0};let V=[...J].reverse().find((B)=>B.index<Z.index),D=V?Z.blockPosition-V.blockPosition+1:0,Y=V&&V.index>1&&D>wj?V:void 0;return{latest:Z,bridge:Y}}function J1(j){if(Array.isArray(j.system)){let J=j.system.findIndex((D)=>y(D)&&D.text===o),Z=j.system.slice(J>=0?J+1:0).filter(y),V=Z[Z.length-1];F0(V,!0)}else F0(j.system,!0)}function Fj(j){if(N1(j),!Array.isArray(j.messages)){J1(j);return}let{latest:J,bridge:Z}=vj(j.messages);if(!Z)J1(j);if(Z0(j.messages[0]),Z0(j.messages[1]),Z)Z0(j.messages[Z.index]);if(J)Z0(j.messages[J.index])}function Bj(j,J){if(!J.enabled){j1(j,!1),delete j.cache_control,delete j.cacheControl;return}if(J.mode==="automatic"){_j(j);return}if(J.mode==="hybrid"){Fj(j);return}j1(j,!0),delete j.cacheControl}function Hj(j){if(!Array.isArray(j.messages))return;while(j.messages.length){let J=j.messages[j.messages.length-1];if(!y(J)||J.role!=="assistant")break;j.messages.pop()}}async function _1(j,J={}){try{let Z=JSON.parse(j);Hj(Z);let V=Array.isArray(Z.messages)&&Z.messages.some((D)=>D.role==="user")?K1(Z.messages,void 0,D1):null;if(Z.system=zj(Z.system),V&&Array.isArray(Z.system))Z.system.unshift({type:"text",text:V});if(Bj(Z,{enabled:J.cache1hEnabled??!1,mode:J.cache1hMode??"explicit"}),J.fastModeEnabled&&V0(Z.model))Z.speed="fast";else if(Z.speed==="fast")delete Z.speed;if(J.identity)Q1(Z,J.identity);return await Y1(Pj(Z))}catch{return j}}function D0(j){if(!j.body)return j;let J=j.body.getReader(),Z=new TextDecoder,V=new TextEncoder,D="",Y=new ReadableStream({async pull(B){let{done:k,value:g}=await J.read();if(k){let h=t0(`${D}${Z.decode()}`,!0);if(h.ready)B.enqueue(V.encode(h.ready));B.close();return}let b=D+Z.decode(g,{stream:!0}),m=t0(b);if(D=m.pending,m.ready)B.enqueue(V.encode(m.ready))}});return new Response(Y,{status:j.status,statusText:j.statusText,headers:j.headers})}var Ej="__OPENCODE_ANTHROPIC_AUTH_COMMAND_HANDLED__",xj=60000,Cj=60000,Sj=5000,U1=200,r1=240,Rj=r1,yj=1,M1=!1;function U0(){return process.env.OPENCODE_ANTHROPIC_AUTH_PERF==="1"}function H(){return performance.now()}function R(j){return Math.round(j*10)/10}function v1(j){return Math.floor(Math.random()*Math.max(0,j))}function fj(){if(M1||!1||!U0())return;M1=!0;let j=100,J=250,Z=H()+j;setInterval(()=>{let V=H(),D=V-Z;if(Z=V+j,D<J)return;q("[perf] opencode event_loop_lag",{lagMs:R(D),thresholdMs:J})},j).unref?.()}function Tj(j){let J=H(),Z={requestId:String(yj++),start:J,last:J,mark(V,D){let Y=H();if(U0())q("[perf] opencode request stage",{requestId:Z.requestId,stage:V,deltaMs:R(Y-Z.last),totalMs:R(Y-Z.start),...D});Z.last=Y},done(V,D){let Y=H();if(U0())q("[perf] opencode request done",{requestId:Z.requestId,stage:V,deltaMs:R(Y-Z.last),totalMs:R(Y-Z.start),...D});Z.last=Y}};if(U0())q("[perf] opencode request start",{requestId:Z.requestId,...j});return Z}async function p(j,J,Z){let V=j.client.session,D=await s0(j.client,J),Y={path:{id:J},body:{noReply:!0,parts:[{type:"text",text:Z,ignored:!0}]}};if(D?.agent)Y.body.agent=D.agent;if(D?.model)Y.body.model=D.model;if(D?.variant)Y.body.variant=D.variant;if(typeof V?.promptAsync==="function"){await V.promptAsync(Y);return}if(typeof V?.prompt==="function"){await Promise.resolve(V.prompt(Y));return}throw Error("OpenCode session prompt API is unavailable for ignored replies.")}function u(){throw Error(Ej)}function Aj(j){if(j.sessionID==null)return!1;let J=j.model;return J?.providerID==="anthropic"||J?.api?.npm==="@ai-sdk/anthropic"||J?.api?.npm==="@ai-sdk/google-vertex/anthropic"}function kj(j){if(j.some((J)=>J.includes("<use_parallel_tool_calls>")))return!1;return j.push(F1),!0}var cj=async(j)=>{fj();let{client:J}=j,Z=H1(),V=await C(Z),D=new u1({storage:V,onMainQuotaFetched:async($,W,K)=>{try{let I=await C(Z)??{version:1,accounts:[]};I.quota=I.quota??{},I.quota.mainQuota=$,I.quota.mainQuotaCheckedAt=W,I.quota.mainQuotaToken=K,I.quota.mainLastQuotaApiError=void 0,await a(I,Z)}catch(I){q("[quota] failed to persist main quota",{error:I instanceof Error?I.message:String(I)})}},onApiError:async($)=>{try{let W=await C(Z)??{version:1,accounts:[]};W.quota=W.quota??{},W.quota.mainLastQuotaApiError=$,await a(W,Z)}catch(W){q("[quota] failed to persist backoff state",{error:W instanceof Error?W.message:String(W)})}}}),Y=new T1({quotaManager:D});Y.startBackgroundRefresh();let B=null,k=new d1({loadStorage:()=>C(Z),prepareHeaders:async($,W)=>{if(!b)return $;let K=await b();if(K.type!=="oauth")return $;if(!K.access||K.expires&&K.expires<Date.now()){if(!B)return $;K.access=await B()}if(!K.access)return $;try{let I=JSON.parse(W.bodyText),_=await f0(K.access,typeof I.model==="string"?I.model:void 0);if($.delete("anthropic-beta"),s($,K.access,{body:I,identity:_}),$.set("anthropic-beta",$0($.get("anthropic-beta"),[k1])),I.speed==="fast")B0($)}catch{s($,K.access)}return $},log:q});r({enabled:X0(V),mode:W0(V)}),w0(x0(V)),L0(C0(V));function g($,W){let K=D.getMain(W.mainAccessToken),I=D.getLastApiError(),_=$?.refresh?.mainLastRefreshError,f={main:{quota:K?.quota??null,quotaBackedOff:D.isBackedOff(),quotaBackoffUntil:I?.nextRetryAt,refreshBackedOff:_?i(_,W.mainRefreshToken,Date.now()):!1,refreshBackoffUntil:_?.nextRetryAt},fallbacks:($?.accounts??[]).filter((E)=>E.enabled!==!1).map((E)=>({id:E.id,label:E.label,quota:E.access?D.getFallback(E.id,E.access)?.quota??null:null,enabled:E.enabled!==!1})),activeId:W.activeId,route:W.route,relay:(()=>{let E=m0($);return E?{enabled:!0,transport:E.transport??"http"}:null})(),fastMode:k0(),cacheKeep:{enabled:T0($),window:$?.cacheKeep?.startHour!=null&&$?.cacheKeep?.endHour!=null?`${$.cacheKeep.startHour}-${$.cacheKeep.endHour}`:void 0,trackedSessions:k.trackedCount()},lastUpdated:Date.now()};a1(f).catch((E)=>q("[sidebar] state write failed",{error:E instanceof Error?E.message:String(E)}))}let b=null,m=null,h=0;function t1($){let W=$?.refresh?.refreshBeforeExpiryMinutes??Rj;return Math.max(r1,W)*60000}function e1($){return $?.refresh?.enabled!==!1}async function d0($){if(!$)return;let W=await C(Z),K=W?.refresh?.mainLastRefreshError;if(!W?.refresh||!K?.tokenHash)return;let I=Y0($);if(K.tokenHash===I)return;if(K.nextRetryAt&&K.nextRetryAt>Date.now()){q("[refresh] opencode main oauth keeping backoff despite token rotation",{nextRetryAt:K.nextRetryAt,retryCount:K.retryCount,remainingMs:K.nextRetryAt-Date.now()});return}W.refresh.mainLastRefreshError=void 0,await a(W,Z),q("[refresh] opencode main oauth cleared stale backoff after token rotation",{previousCheckedAt:K.checkedAt,previousNextRetryAt:K.nextRetryAt,previousRetryCount:K.retryCount})}async function jj(){let $=[];if(b)try{let _=await b();if(_.type==="oauth"&&_.access){let f=await D.refreshMain(_.access);$.push({name:"OpenCode anthropic",role:"main",quota:f})}else if(_.type==="oauth")$.push({name:"OpenCode anthropic",role:"main",error:"missing access token; send a request first or reconnect auth"})}catch(_){let f=_ instanceof Error?_.message:String(_);$.push({name:"OpenCode anthropic",role:"main",error:f.includes("429")?"Usage API rate limited — try again in a moment":f})}let{storage:W,errors:K}=await Y.refreshQuotaForAllAccounts({force:!0}),I=new Map(K.map((_)=>[_.accountId,_.message]));if($.push(...i1(W,I)),!b)$.unshift({name:"OpenCode anthropic",role:"main",error:"auth loader has not run yet; send a request first"});return c1({accounts:$,refreshedAt:Date.now()})}async function Jj($){let W=A1($);if(W.type==="enable"||W.type==="disable"){let f=W.type==="enable",E=await E1(f),t=W0(E);return r({enabled:f,mode:t}),P0({argumentsText:$,enabled:f,mode:t})}if(W.type==="mode"){let f=await x1(W.mode),E=X0(f);return r({enabled:E,mode:W.mode}),P0({argumentsText:$,enabled:E,mode:W.mode})}let K=await C(Z),I=X0(K),_=W0(K);return r({enabled:I,mode:_}),P0({argumentsText:$,enabled:I,mode:_})}async function Zj($){let W=b1($),K=await C(Z);if(W.type==="window")K=await R1(W.startHour,W.endHour);else if(W.type==="disable")K=await y1(!1);let I=m1(K),_=k.stats(I);return h1({argumentsText:$,enabled:g1(K),window:I,hybridActive:T0(K),trackedSessions:_.trackedSessions,nextPrewarmAt:_.nextPrewarmAt})}async function $j($){let W=l1($);if(W.type==="enable"||W.type==="disable"){let _=W.type==="enable";return await C1(_),w0(_),A0({argumentsText:$,enabled:_})}let K=await C(Z),I=x0(K);return w0(I),A0({argumentsText:$,enabled:I})}async function Vj($){let W=p1($);if(W.type==="enable"||W.type==="disable"){let _=W.type==="enable";return await S1(_),L0(_),b0({argumentsText:$,enabled:_})}let K=await C(Z),I=C0(K);return L0(I),b0({argumentsText:$,enabled:I})}async function Dj($){let W=s1($);if(W.type==="mode")return await o1(W.mode),h0({argumentsText:$,mode:W.mode});let K=await C();return h0({argumentsText:$,mode:g0(K)})}return{config:async($)=>{$.command={...$.command??{},[K0]:{template:K0,description:"Show or toggle 1-hour Anthropic ephemeral prompt cache TTL."},[I0]:{template:I0,description:"Keep hybrid Claude cache warm for recently used sessions during a local time window."},[N0]:{template:N0,description:"Show current Claude OAuth quota usage for all accounts."},[z0]:{template:z0,description:"Show or toggle Anthropic request dump capture for debugging."},[O0]:{template:O0,description:"Show or toggle Anthropic fast mode for supported Opus models."},[_0]:{template:_0,description:"Show or change Claude account routing between main-first and fallback-first."}}},"experimental.chat.system.transform":async($,W)=>{if(!Aj($))return;kj(W.system)},"command.execute.before":async($)=>{if($.command===K0)await p(j,$.sessionID,await Jj($.arguments)),u();if($.command===I0)await p(j,$.sessionID,await Zj($.arguments)),u();if($.command===N0){await p(j,$.sessionID,await jj());let W=await C(),K=b?await b().catch(()=>{return}):void 0;g(W,{activeId:"main",route:"main",mainAccessToken:K?.access,mainRefreshToken:K?.refresh}),u()}if($.command===z0)await p(j,$.sessionID,await $j($.arguments)),u();if($.command===O0)await p(j,$.sessionID,await Vj($.arguments)),u();if($.command===_0)await p(j,$.sessionID,await Dj($.arguments)),u()},auth:{provider:"anthropic",async loader($,W){b=$;let K=await $();if(K.type==="oauth"){let f=function(){if(m)clearInterval(m),m=null;let P=async()=>{try{let w=await C(Z);if(!e1(w))return;let v=await $();if(v.type!=="oauth")return;if(await d0(v.refresh),!v.expires)return;let N=v.expires-Date.now(),x=t1(w);if(N>x)return;if(q("[refresh] opencode main oauth background due",{expiresInMs:N,refreshBeforeMs:x}),v.refresh&&i(w?.refresh?.mainLastRefreshError,v.refresh,Date.now())){q("[refresh] opencode main oauth background skipped backoff",{nextRetryAt:w?.refresh?.mainLastRefreshError?.nextRetryAt,retryCount:w?.refresh?.mainLastRefreshError?.retryCount,expiresInMs:N});return}if(v.refresh&&w?.refresh?.mainRefreshLeaseUntil&&w.refresh.mainRefreshLeaseUntil>Date.now()&&w.refresh.mainRefreshLeaseTokenHash===Y0(v.refresh))return;await _();let Q=await $();q("[refresh] opencode main oauth refreshed in background",{newExpiresInMs:Q.expires?Q.expires-Date.now():void 0})}catch(w){q("[refresh] opencode main oauth refresh failed",{message:w instanceof Error?w.message:String(w)})}};if(m=setInterval(()=>{P()},xj+v1(Cj)),"unref"in m)m.unref()},E=function(P,w){if(P instanceof Request&&P.body)return!1;return w==null||typeof w==="string"},t=function(P){return P.has("x-parent-session-id")},l0=function(P){return P.includes("rate_limit_error")||/exceed your account'?s rate limit/i.test(P)},Xj=function(P){return P?.quota?.enabled===!0};for(let P of Object.values(W.models))P.cost={input:0,output:0,cache:{read:0,write:0}};let I=null;async function _(){if(!I)I=(async()=>{let v=null,N=null,x=null;async function Q(G){let U=await C(Z)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};U.refresh=U.refresh??{},G(U),await a(U,Z)}async function S(G){let U=Date.now()+Sj;while(Date.now()<U){await new Promise((M)=>setTimeout(M,U1+v1(U1)));let X=await $();if(X.type!=="oauth"||!X.access)continue;if((X.access!==G.access||X.refresh!==G.refresh||(X.expires??0)>(G.expires??0)+60000)&&(!X.expires||X.expires>Date.now()))return q("[refresh] opencode main oauth joined concurrent refresh",{expiresInMs:X.expires?X.expires-Date.now():void 0}),X.access}return null}for(let G=0;G<=2;G++){let U=null;try{if(G>0){let L=500*2**(G-1);await new Promise((A)=>setTimeout(A,L))}if(U=await $(),!U.refresh)throw Error("Token refresh failed: missing refresh token");let X=await C(Z),O=Y0(U.refresh),M=X?.refresh?.mainLastRefreshError;if(q("[refresh] opencode main oauth refresh check",{attempt:G,expiresInMs:U.expires?U.expires-Date.now():void 0,hasBackoff:Boolean(M),backoffActive:M?i(M,U.refresh,Date.now()):!1,retryCount:M?.retryCount,nextRetryAt:M?.nextRetryAt}),M&&i(M,U.refresh,Date.now()))throw q("[refresh] opencode main oauth refresh skipped backoff",{nextRetryAt:M.nextRetryAt,retryCount:M.retryCount}),Error(R0(M,Date.now()));if(X?.refresh?.mainRefreshLeaseUntil&&X.refresh.mainRefreshLeaseUntil>Date.now()&&X.refresh.mainRefreshLeaseTokenHash===O){q("[refresh] opencode main oauth refresh skipped lease",{leaseUntil:X.refresh.mainRefreshLeaseUntil});let L=await S(U);if(L)return L;throw Error("Claude OAuth refresh is already in progress")}let z=await q1({name:"opencode-main-oauth-refresh",ttlMs:120000,renew:!0});if(!z){q("[refresh] opencode main oauth refresh skipped file lock");let L=await S(U);if(L)return L;throw Error("Claude OAuth refresh is already in progress")}x=z.release,v=qj(),N=O,await Q((L)=>{L.refresh=L.refresh??{},L.refresh.mainRefreshLeaseId=v??void 0,L.refresh.mainRefreshLeaseUntil=Date.now()+120000,L.refresh.mainRefreshLeaseTokenHash=O});let T=await C(Z);if(q("[refresh] opencode main oauth refresh lease acquired",{attempt:G,leaseUntil:Date.now()+120000}),T?.refresh?.mainRefreshLeaseId!==v||T.refresh.mainRefreshLeaseTokenHash!==O)throw Error("Claude OAuth refresh is already in progress");q("[refresh] opencode main oauth refresh request start",{attempt:G});let F=await B1({refreshToken:U.refresh,maxRetries:0});return await J.auth.set({path:{id:"anthropic"},body:{type:"oauth",refresh:F.refresh,access:F.access,expires:F.expires}}),await Q((L)=>{if(!L?.refresh)return;if(L.refresh.mainLastRefreshError=void 0,L.refresh.mainRefreshLeaseId===v)L.refresh.mainRefreshLeaseId=void 0,L.refresh.mainRefreshLeaseUntil=void 0,L.refresh.mainRefreshLeaseTokenHash=void 0}),q("[refresh] opencode main oauth refresh succeeded",{attempt:G,expiresInMs:F.expires-Date.now()}),F.access}catch(X){let O=X instanceof Error&&(X.message.includes("fetch failed")||("code"in X)&&(X.code==="ECONNRESET"||X.code==="ECONNREFUSED"||X.code==="ETIMEDOUT"||X.code==="UND_ERR_CONNECT_TIMEOUT"));if(G<2&&(O||X instanceof H0&&X.status>=500))continue;q("[refresh] opencode main oauth refresh attempt failed",{attempt:G,error:X instanceof Error?X.message:String(X),transient:O});let M=U?.refresh;if(M&&X instanceof H0)await Q((z)=>{z.refresh=z.refresh??{},z.refresh.mainLastRefreshError=f1({error:X,now:Date.now(),refreshToken:M,previous:z.refresh.mainLastRefreshError})});throw X}finally{if(v)await Q((X)=>{if(!X?.refresh)return;if(X.refresh.mainRefreshLeaseId===v&&X.refresh.mainRefreshLeaseTokenHash===N)X.refresh.mainRefreshLeaseId=void 0,X.refresh.mainRefreshLeaseUntil=void 0,X.refresh.mainRefreshLeaseTokenHash=void 0}).catch(()=>{});await x?.().catch(()=>{})}}throw Error("Token refresh exhausted all retries")})().finally(()=>{I=null});return I}B=_,f(),D.seedFallbacksFromAccounts(V?.accounts??[]),g(V,{activeId:"main",route:"main",mainAccessToken:K.access,mainRefreshToken:K.refresh});async function p0(P,w){if(!P.body||P.status!==200)return w?.mark("inspect_stream_skip",{status:P.status}),{response:P,rateLimited:!1};if(P.headers.get("x-cortexkit-relay-optimistic")==="true")return w?.mark("inspect_stream_skip",{status:P.status,reason:"optimistic_relay"}),{response:P,rateLimited:!1};let v=H(),N=P.body.getReader(),x=[],Q=new TextDecoder,S="",G=0;while(!S.includes(`
3
+ `);for(let V of _1)G=G.replace(V.match,V.replacement);return G.trim()}function f(j){return j!=null&&typeof j==="object"&&!Array.isArray(j)}function Sj(j){let J={type:"text",text:K0};if(j==null)return[J];if(typeof j==="string"){let G=L0(j);if(G===K0)return[J];return[J,{type:"text",text:G}]}if(f(j)){let G=typeof j.type==="string"?j.type:"text",V=typeof j.text==="string"?j.text:"";return[J,{...j,type:G,text:L0(V)}]}if(!Array.isArray(j))return[J];let Z=j.map((G)=>{if(typeof G==="string")return{type:"text",text:L0(G)};if(f(G)&&G.type==="text"&&typeof G.text==="string")return{...G,type:"text",text:L0(G.text)};return{type:"text",text:String(G)}});if(Z[0]?.text===K0)return Z;return[J,...Z]}var x1={type:"ephemeral",ttl:"1h"},Rj=20;function Tj(j){if(f(j.cache_control))return j.cache_control;if(f(j.cacheControl))return j.cacheControl;return null}function h0(j,J){if(!f(j))return!1;return delete j.cacheControl,j.cache_control=J?{...x1}:{type:"ephemeral"},!0}function P1(j){if(!f(j))return;delete j.cache_control,delete j.cacheControl}function yj(j){if(Array.isArray(j))return j;if(typeof j==="string")return[{type:"text",text:j}];return null}function N0(j,J){if(!f(j))return;let Z=Tj(j);if(Z?.type!=="ephemeral")return;if(J)Z.ttl="1h";else delete Z.ttl}function z1(j,J){if(Array.isArray(j.system))for(let Z of j.system)N0(Z,J);else N0(j.system,J);if(!Array.isArray(j.messages))return;for(let Z of j.messages)if(N0(Z,J),f(Z)&&Array.isArray(Z.content))for(let G of Z.content)N0(G,J)}function Aj(j,J){if(Array.isArray(j.system))for(let Z of j.system)J(Z);else J(j.system);if(!Array.isArray(j.messages))return;for(let Z of j.messages)if(J(Z),f(Z)&&Array.isArray(Z.content))for(let G of Z.content)J(G)}function S1(j){P1(j),Aj(j,P1)}function kj(j){S1(j),j.cache_control={...x1}}function w0(j){if(!f(j))return!1;let J=yj(j.content);if(!J?.length)return!1;let Z=[...J].reverse().find((G)=>f(G)&&G.type!=="thinking"&&G.type!=="redacted_thinking");if(!Z)return!1;return j.content=J,h0(Z,!0)}function fj(j){if(!f(j))return 0;let J=j.content;if(Array.isArray(J))return J.length;if(J==null)return 0;return 1}function mj(j){let J=[],Z=0;return j.forEach((G,V)=>{let Y=fj(G);if(f(G)&&G.role==="user"&&Y>0)J.push({index:V,blockPosition:Z+Y-1});Z+=Y}),J}function bj(j){let J=mj(j),Z=[...J].reverse().find((v)=>v.index>1);if(!Z)return{latest:void 0,bridge:void 0};let G=[...J].reverse().find((v)=>v.index<Z.index),V=G?Z.blockPosition-G.blockPosition+1:0,Y=G&&G.index>1&&V>Rj?G:void 0;return{latest:Z,bridge:Y}}function Q1(j){if(Array.isArray(j.system)){let J=j.system.findIndex((V)=>f(V)&&V.text===K0),Z=j.system.slice(J>=0?J+1:0).filter(f),G=Z[Z.length-1];h0(G,!0)}else h0(j.system,!0)}function hj(j){if(S1(j),!Array.isArray(j.messages)){Q1(j);return}let{latest:J,bridge:Z}=bj(j.messages);if(!Z)Q1(j);if(w0(j.messages[0]),w0(j.messages[1]),Z)w0(j.messages[Z.index]);if(J)w0(j.messages[J.index])}function gj(j,J){if(!J.enabled){z1(j,!1),delete j.cache_control,delete j.cacheControl;return}if(J.mode==="automatic"){kj(j);return}if(J.mode==="hybrid"){hj(j);return}z1(j,!0),delete j.cacheControl}function dj(j){if(!Array.isArray(j.messages))return;while(j.messages.length){let J=j.messages[j.messages.length-1];if(!f(J)||J.role!=="assistant")break;j.messages.pop()}}async function R1(j,J={}){try{let Z=JSON.parse(j);dj(Z);let G=Array.isArray(Z.messages)&&Z.messages.some((V)=>V.role==="user")?H1(Z.messages,void 0,N1):null;if(Z.system=Sj(Z.system),G&&Array.isArray(Z.system))Z.system.unshift({type:"text",text:G});if(gj(Z,{enabled:J.cache1hEnabled??!1,mode:J.cache1hMode??"explicit"}),J.fastModeEnabled&&B0(Z.model))Z.speed="fast";else if(Z.speed==="fast")delete Z.speed;if(J.identity)U1(Z,J.identity);return await B1(Cj(Z))}catch{return j}}function W0(j){if(!j.body)return j;let J=j.body.getReader(),Z=new TextDecoder,G=new TextEncoder,V="",Y=new ReadableStream({async pull(v){let{done:u,value:G0}=await J.read();if(u){let d=Y1(`${V}${Z.decode()}`,!0);if(d.ready)v.enqueue(G.encode(d.ready));v.close();return}let o=V+Z.decode(G0,{stream:!0}),e=Y1(o);if(V=e.pending,e.ready)v.enqueue(G.encode(e.ready))}});return new Response(Y,{status:j.status,statusText:j.statusText,headers:j.headers})}var lj="__OPENCODE_ANTHROPIC_AUTH_COMMAND_HANDLED__",uj=60000,ij=60000,cj=5000,T1=200,Ij=240,nj=Ij,oj=1,y1=!1;function m0(){return process.env.OPENCODE_ANTHROPIC_AUTH_PERF==="1"}function q(){return performance.now()}function y(j){return Math.round(j*10)/10}function A1(j){return Math.floor(Math.random()*Math.max(0,j))}function sj(){if(y1||!1||!m0())return;y1=!0;let j=100,J=250,Z=q()+j;setInterval(()=>{let G=q(),V=G-Z;if(Z=G+j,V<J)return;F("[perf] opencode event_loop_lag",{lagMs:y(V),thresholdMs:J})},j).unref?.()}function rj(j){let J=q(),Z={requestId:String(oj++),start:J,last:J,mark(G,V){let Y=q();if(m0())F("[perf] opencode request stage",{requestId:Z.requestId,stage:G,deltaMs:y(Y-Z.last),totalMs:y(Y-Z.start),...V});Z.last=Y},done(G,V){let Y=q();if(m0())F("[perf] opencode request done",{requestId:Z.requestId,stage:G,deltaMs:y(Y-Z.last),totalMs:y(Y-Z.start),...V});Z.last=Y}};if(m0())F("[perf] opencode request start",{requestId:Z.requestId,...j});return Z}async function t(j,J,Z){let G=j.client.session,V=await K1(j.client,J),Y={path:{id:J},body:{noReply:!0,parts:[{type:"text",text:Z,ignored:!0}]}};if(V?.agent)Y.body.agent=V.agent;if(V?.model)Y.body.model=V.model;if(V?.variant)Y.body.variant=V.variant;if(typeof G?.promptAsync==="function"){await G.promptAsync(Y);return}if(typeof G?.prompt==="function"){await Promise.resolve(G.prompt(Y));return}throw Error("OpenCode session prompt API is unavailable for ignored replies.")}function a(){throw Error(lj)}function tj(j){if(j.sessionID==null)return!1;let J=j.model;return J?.providerID==="anthropic"||J?.api?.npm==="@ai-sdk/anthropic"||J?.api?.npm==="@ai-sdk/google-vertex/anthropic"}function aj(j){if(j.some((J)=>J.includes("<use_parallel_tool_calls>")))return!1;return j.push(k1),!0}var XJ=async(j)=>{sj();let{client:J}=j,Z=m1(),G=await R(Z),V=new Kj({storage:G,onMainQuotaFetched:async($,D,X)=>{try{let W=await R(Z)??{version:1,accounts:[]};W.quota=W.quota??{},W.quota.mainQuota=$,W.quota.mainQuotaCheckedAt=D,W.quota.mainQuotaToken=X,W.quota.mainLastQuotaApiError=void 0,await Y0(W,Z)}catch(W){F("[quota] failed to persist main quota",{error:W instanceof Error?W.message:String(W)})}},onApiError:async($)=>{try{let D=await R(Z)??{version:1,accounts:[]};D.quota=D.quota??{},D.quota.mainLastQuotaApiError=$,await Y0(D,Z)}catch(D){F("[quota] failed to persist backoff state",{error:D instanceof Error?D.message:String(D)})}}}),Y=new r1({quotaManager:V,onFallbackStorageChanged:()=>{e()}});Y.startBackgroundRefresh();let v=null,u=new $j({loadStorage:()=>R(Z),prepareHeaders:async($,D)=>{if(!d)return $;let X=await d();if(X.type!=="oauth")return $;if(!X.access||X.expires&&X.expires<Date.now()){if(!v)return $;X.access=await v()}if(!X.access)return $;try{let W=JSON.parse(D.bodyText),P=await o0(X.access,typeof W.model==="string"?W.model:void 0);if($.delete("anthropic-beta"),X0($,X.access,{body:W,identity:P}),$.set("anthropic-beta",_0($.get("anthropic-beta"),[a1])),W.speed==="fast")g0($)}catch{X0($,X.access)}return $},log:F});Q0({enabled:H0(G),mode:U0(G)}),R0(u0(G)),y0(i0(G));let G0={activeId:"main",route:"main"};function o($,D){G0={activeId:D.activeId,route:D.route};let X=V.getMain(D.mainAccessToken),W=V.getLastApiError(),P=$?.refresh?.mainLastRefreshError,x={main:{quota:X?.quota??null,quotaBackedOff:V.isBackedOff(),quotaBackoffUntil:W?.nextRetryAt,refreshBackedOff:P?$0(P,D.mainRefreshToken,Date.now()):!1,refreshBackoffUntil:P?.nextRetryAt},fallbacks:($?.accounts??[]).filter((E)=>E.enabled!==!1).map((E)=>({id:E.id,label:E.label,quota:E.access?V.getFallback(E.id,E.access)?.quota??null:null,enabled:E.enabled!==!1})),activeId:D.activeId,route:D.route,relay:(()=>{let E=e0($);return E?{enabled:!0,transport:E.transport??"http"}:null})(),fastMode:t0(),cacheKeep:{enabled:s0($),window:$?.cacheKeep?.startHour!=null&&$?.cacheKeep?.endHour!=null?`${$.cacheKeep.startHour}-${$.cacheKeep.endHour}`:void 0,trackedSessions:u.trackedCount()},lastUpdated:Date.now()};Qj(x).catch((E)=>F("[sidebar] state write failed",{error:E instanceof Error?E.message:String(E)}))}async function e(){let $=await R(Z),D,X;if(d)try{let W=await d();D=W.access,X=W.refresh}catch{}o($,{activeId:G0.activeId,route:G0.route,mainAccessToken:D,mainRefreshToken:X})}let d=null,j0=null,I0=0;function Oj($){let D=$?.refresh?.refreshBeforeExpiryMinutes??nj;return Math.max(Ij,D)*60000}function Lj($){return $?.refresh?.enabled!==!1}async function Z1($){if(!$)return;let D=await R(Z),X=D?.refresh?.mainLastRefreshError;if(!D?.refresh||!X?.tokenHash)return;let W=M0($);if(X.tokenHash===W)return;if(X.nextRetryAt&&X.nextRetryAt>Date.now()){F("[refresh] opencode main oauth keeping backoff despite token rotation",{nextRetryAt:X.nextRetryAt,retryCount:X.retryCount,remainingMs:X.nextRetryAt-Date.now()});return}D.refresh.mainLastRefreshError=void 0,await Y0(D,Z),F("[refresh] opencode main oauth cleared stale backoff after token rotation",{previousCheckedAt:X.checkedAt,previousNextRetryAt:X.nextRetryAt,previousRetryCount:X.retryCount})}async function Nj(){let $=[];if(d)try{let P=await d();if(P.type==="oauth"&&P.access){let x=await V.refreshMain(P.access);$.push({name:"OpenCode anthropic",role:"main",quota:x})}else if(P.type==="oauth")$.push({name:"OpenCode anthropic",role:"main",error:"missing access token; send a request first or reconnect auth"})}catch(P){let x=P instanceof Error?P.message:String(P);$.push({name:"OpenCode anthropic",role:"main",error:x.includes("429")?"Usage API rate limited — try again in a moment":x})}let{storage:D,errors:X}=await Y.refreshQuotaForAllAccounts({force:!0}),W=new Map(X.map((P)=>[P.accountId,P.message]));if($.push(...Xj(D,W)),!d)$.unshift({name:"OpenCode anthropic",role:"main",error:"auth loader has not run yet; send a request first"});return Wj({accounts:$,refreshedAt:Date.now()})}async function wj($){let D=t1($);if(D.type==="enable"||D.type==="disable"){let x=D.type==="enable",E=await h1(x),h=U0(E);return Q0({enabled:x,mode:h}),C0({argumentsText:$,enabled:x,mode:h})}if(D.type==="mode"){let x=await g1(D.mode),E=H0(x);return Q0({enabled:E,mode:D.mode}),C0({argumentsText:$,enabled:E,mode:D.mode})}let X=await R(Z),W=H0(X),P=U0(X);return Q0({enabled:W,mode:P}),C0({argumentsText:$,enabled:W,mode:P})}async function _j($){let D=e1($),X=await R(Z);if(D.type==="window")X=await l1(D.startHour,D.endHour);else if(D.type==="disable")X=await u1(!1);let W=jj(X),P=u.stats(W);return Zj({argumentsText:$,enabled:Jj(X),window:W,hybridActive:s0(X),trackedSessions:P.trackedSessions,nextPrewarmAt:P.nextPrewarmAt})}async function Bj($){let D=Gj($);if(D.type==="enable"||D.type==="disable"){let P=D.type==="enable";return await d1(P),R0(P),r0({argumentsText:$,enabled:P})}let X=await R(Z),W=u0(X);return R0(W),r0({argumentsText:$,enabled:W})}async function Hj($){let D=Vj($);if(D.type==="enable"||D.type==="disable"){let P=D.type==="enable";return await p1(P),y0(P),a0({argumentsText:$,enabled:P})}let X=await R(Z),W=i0(X);return y0(W),a0({argumentsText:$,enabled:W})}async function Uj($){let D=zj($);if(D.type==="mode")return await Pj(D.mode),J1({argumentsText:$,mode:D.mode});let X=await R();return J1({argumentsText:$,mode:j1(X)})}function Mj($,D=10){let X=Math.max(0,Math.min(Math.round($/100*D),D));return"█".repeat(X)+"░".repeat(D-X)}function O0($,D){return`${$} ${Mj(D)} ${String(Math.round(D)).padStart(3)}%`}function $1($){if(!$)return"";let D=new Date($).getTime();if(Number.isNaN(D))return"";let X=D-Date.now();if(X<=0)return"resets now";let W=Math.floor(X/60000);if(W<1)return"resets <1m";if(W<60)return`resets ${W}m`;let P=Math.floor(W/60),x=W%60;return x>0?`resets ${P}h${x}m`:`resets ${P}h`}function vj($,D,X){let W=[],P=0;if($){let{five_hour:h,seven_day:p}=$;if(h||p){let i=X==="main"?"active":"idle",s=$1(h?.resetsAt),n=[`main · ${i}${s?` (${s})`:""}`];if(h)n.push(O0("5h",h.usedPercent)),P=Math.max(P,h.usedPercent);if(p)n.push(O0("7d",p.usedPercent)),P=Math.max(P,p.usedPercent);W.push(n.join(`
4
+ `))}}if(D?.length)for(let h of D){let p=h.quota;if(!p)continue;let{five_hour:c,seven_day:i}=p;if(!c&&!i)continue;let s=h.label||"alt",V0=X===h.id?"active":"idle",r=$1(c?.resetsAt),D0=[`${s} · ${V0}${r?` (${r})`:""}`];if(c)D0.push(O0("5h",c.usedPercent)),P=Math.max(P,c.usedPercent);if(i)D0.push(O0("7d",i.usedPercent)),P=Math.max(P,i.usedPercent);W.push(D0.join(`
5
+ `))}if(!W.length)return;let x=W.join(`
4
6
 
5
- `)&&S.length<65536){let{done:X,value:O}=await N.read();if(X)break;if(x.push(O),G+=O.byteLength,S+=Q.decode(O,{stream:!0}),l0(S))break}if(l0(S))return await N.cancel().catch(()=>{}),w?.mark("inspect_stream_first_event",{ms:R(H()-v),bytes:G,rateLimited:!0}),{response:P,rateLimited:!0};let U=new ReadableStream({start(X){for(let O of x)X.enqueue(O)},async pull(X){let{done:O,value:M}=await N.read();if(O){X.close();return}X.enqueue(M)},cancel(X){return N.cancel(X)}});return w?.mark("inspect_stream_first_event",{ms:R(H()-v),bytes:G,rateLimited:!1}),{response:new Response(U,{status:P.status,statusText:P.statusText,headers:P.headers}),rateLimited:!1}}async function u0(P,w,v,N,x="unknown",Q){let S=H(),G=Q,U=async()=>{return G??=await C(Z),G},X=z1(P,w),O=X.get("x-session-affinity")||X.get("x-opencode-session"),M=t(X);X.delete("x-parent-session-id"),X.delete("x-session-affinity"),X.delete("x-opencode-session");let z=w?.body,T;if(z&&typeof z==="string")try{let d=JSON.parse(z);if(typeof d.model==="string")T=d.model}catch{}let F=await f0(v,T),L=typeof z==="string"?z.length:void 0;if(z&&typeof z==="string"){let d=H(),e=(()=>{if(!k0())return!1;try{return V0(JSON.parse(z).model)}catch{return!1}})();z=await _1(z,{cache1hEnabled:!M&&Q0(),cache1hMode:G0(),fastModeEnabled:e,identity:F});try{s(X,v,{body:JSON.parse(z),identity:F})}catch{s(X,v,{identity:F})}if(e)B0(X);N?.mark("rewrite_body",{route:x,ms:R(H()-d),originalBytes:L,rewrittenBytes:z.length,cacheEnabled:!M&&Q0(),cacheMode:G0(),fastModeEnabled:e,subagent:M})}let A=O1(P);if(x==="main"&&typeof z==="string"&&!M&&Q0()&&G0()==="hybrid"){let d=await U();if(k.track({sessionId:O,url:A.url?.toString()??A.input.toString(),headers:X,bodyText:z,storage:d,cacheMode:"hybrid"}).tracked)N?.mark("cachekeep_track",{session:O})}let c=()=>fetch(A.input,{...w,body:z,headers:X,...w1()&&{tls:{rejectUnauthorized:!1}}}),n=m0(await U()),Yj=H(),i0=await n1({config:n,input:A.input,init:w,headers:X,body:z,fallback:c,affinity:O,optimisticResponse:n?.transport==="websocket"});return N?.mark("send_headers_received",{route:x,ms:R(H()-Yj),status:i0.status,relayConfigured:n!=null,totalSendWithAccessMs:R(H()-S)}),i0}async function M0(P,w,v,N,x,Q,S){if(!v.length)return x??null;let G=S?.returnLastOnExhausted??!0;await x?.body?.cancel().catch(()=>{});let U=x??null;for(let[X,O]of v.entries()){let M=O.access;if(!M)continue;let z=await u0(P,w,M,Q,`fallback_${X}`,N);U=z;let T=S0(z.status,N);if(!T){let F=await p0(z,Q);z=F.response,U=z,T=F.rateLimited}if(!T){if(await Y.markUsed(O),S?.onSuccess?.(O),M&&D.shouldRefreshOnRequestCount(h))D.refreshFallback(O.id,M).then(()=>S?.onSuccess?.(O)).catch(()=>{});return z}if(X<v.length-1||!G)await z.body?.cancel().catch(()=>{})}return G?U:null}async function Wj(P,w,v,N,x,Q,S){if(!E(P,w?.body))return v;let G=H(),U=Q??await C(Z);x?.mark("fallback_load_storage",{ms:R(H()-G),cached:!!Q});let X=v,O=S0(X.status,U);if(!O){let z=await p0(X,x);X=z.response,O=z.rateLimited}if(!O)return X;let M=N;if(!M){let z=H();M=await Y.getUsableFallbackAccounts(),x?.mark("fallback_get_accounts",{ms:R(H()-z),accounts:M.length})}return await M0(P,w,M,U,X,x,{onSuccess:S})??X}return{apiKey:"",async fetch(P,w){let v=w?.body,N=Tj({bodyBytes:typeof v==="string"?v.length:void 0}),x=H(),Q=await $();if(N.mark("get_auth",{ms:R(H()-x),authType:Q.type,hasAccess:Boolean(Q.access)}),Q.type!=="oauth"){let F=await fetch(P,w);return N.done("non_oauth_passthrough",{status:F.status}),F}await d0(Q.refresh);let S=H(),G=await C();N.mark("load_storage",{ms:R(H()-S)}),D.updateStorage(G),D.seedFallbacksFromAccounts(G?.accounts??[]);let U=E(P,w?.body);if(U)h++;let X=(F,L)=>g(G,{activeId:F,route:L,mainAccessToken:Q.access,mainRefreshToken:Q.refresh}),O;if(U&&g0(G)==="fallback-first")try{let F=H();O=await Y.getUsableFallbackAccounts(G),N.mark("fallback_first_get_accounts",{ms:R(H()-F),accounts:O.length});let L=await M0(P,w,O,G,void 0,N,{returnLastOnExhausted:!1,onSuccess:(A)=>X(A.id,"fallback-first")});if(L)return N.done("return_fallback_first",{status:L.status}),D0(L);O=[]}catch(F){N.mark("fallback_first_error",{error:F instanceof Error?F.message:String(F)})}if(!Q.access||!Q.expires||Q.expires<Date.now()){let L=(await C())?.refresh?.mainLastRefreshError;if(Q.refresh&&L&&i(L,Q.refresh,Date.now()))throw q("[refresh] opencode main oauth request skipped backoff",{nextRetryAt:L.nextRetryAt,retryCount:L.retryCount,expiresInMs:Q.expires?Q.expires-Date.now():void 0}),Error(R0(L,Date.now()));q("[refresh] opencode main oauth refresh required for request",{hasAccess:Boolean(Q.access),expiresInMs:Q.expires?Q.expires-Date.now():void 0,expiredAgoMs:Q.expires&&Q.expires<Date.now()?Date.now()-Q.expires:void 0});let A=H();Q.access=await _(),N.mark("refresh_main_access",{ms:R(H()-A)})}if(!Q.access)throw N.done("missing_access_error"),Error("OAuth access token is missing after refresh");if(U&&Xj(G))try{let F=H(),L=D.getMain(Q.access)?.quota;if(!L)L=await D.refreshMain(Q.access);else if(D.needsRefresh(h))D.refreshMain(Q.access).then(()=>g(G,{activeId:"main",route:"main",mainAccessToken:Q.access,mainRefreshToken:Q.refresh})).catch(()=>{});if(g(G,{activeId:"main",route:"main",mainAccessToken:Q.access,mainRefreshToken:Q.refresh}),N.mark("main_quota_for_routing",{ms:R(H()-F),passes:y0(L,G)}),!y0(L,G)){let A=H();O=await Y.getUsableFallbackAccounts(G),N.mark("preselect_fallback_accounts",{ms:R(H()-A),accounts:O.length});let c=await M0(P,w,O,G,void 0,N,{onSuccess:(n)=>X(n.id,"fallback")});if(c)return N.done("return_preselected_fallback",{status:c.status}),D0(c)}}catch(F){N.mark("main_quota_for_routing_error",{error:F instanceof Error?F.message:String(F)})}let M=await u0(P,w,Q.access,N,"main",G),z=!1,T=await Wj(P,w,M,O,N,G,(F)=>{z=!0,X(F.id,"fallback")});if(!z)X("main","main");return N.done("return_response",{status:T.status}),D0(T)}}}return{}},methods:[{label:"Claude Pro/Max",type:"oauth",authorize:async()=>{let $=await q0("max");return{url:$.url,instructions:"Paste the authorization code here:",method:"code",callback:async(W)=>{return E0(W,$.verifier,$.redirectUri,$.state)}}}},{label:"Create an API Key",type:"oauth",authorize:async()=>{let $=await q0("console");return{url:$.url,instructions:"Paste the authorization code here:",method:"code",callback:async(W)=>{let K=await E0(W,$.verifier,$.redirectUri,$.state);if(K.type==="failed")return K;return{type:"success",key:(await fetch("https://api.anthropic.com/api/oauth/claude_cli/create_api_key",{method:"POST",headers:{"Content-Type":"application/json",authorization:`Bearer ${K.access}`}}).then((_)=>_.json())).raw_key}}}}},{provider:"anthropic",label:"Manually enter API Key",type:"api"}]}}};export{cj as AnthropicAuthPlugin};
7
+ `),E=P>=90?"error":P>=70?"warning":"info";J.tui?.showToast?.({body:{title:"Claude Quota",message:x,variant:E,duration:E==="error"?8000:5000}})?.catch?.(()=>{})}return{config:async($)=>{$.command={...$.command??{},[F0]:{template:F0,description:"Show or toggle 1-hour Anthropic ephemeral prompt cache TTL."},[x0]:{template:x0,description:"Keep hybrid Claude cache warm for recently used sessions during a local time window."},[k0]:{template:k0,description:"Show current Claude OAuth quota usage for all accounts."},[S0]:{template:S0,description:"Show or toggle Anthropic request dump capture for debugging."},[T0]:{template:T0,description:"Show or toggle Anthropic fast mode for supported Opus models."},[f0]:{template:f0,description:"Show or change Claude account routing between main-first and fallback-first."},[A0]:{template:A0,description:"Manage killswitch — hard-block requests when quota drops below per-account thresholds."}}},"experimental.chat.system.transform":async($,D)=>{if(!tj($))return;aj(D.system)},"command.execute.before":async($)=>{if($.command===F0)await t(j,$.sessionID,await wj($.arguments)),a();if($.command===x0)await t(j,$.sessionID,await _j($.arguments)),a();if($.command===k0){await t(j,$.sessionID,await Nj());let D=await R(),X=d?await d().catch(()=>{return}):void 0;o(D,{activeId:"main",route:"main",mainAccessToken:X?.access,mainRefreshToken:X?.refresh}),a()}if($.command===S0)await t(j,$.sessionID,await Bj($.arguments)),a();if($.command===T0)await t(j,$.sessionID,await Hj($.arguments)),a();if($.command===f0)await t(j,$.sessionID,await Uj($.arguments)),a();if($.command===A0){let D=await R(),X=o1(D),W=(D?.accounts??[]).filter((x)=>x.enabled!==!1).map((x)=>x.id),P=Dj({argumentsText:$.arguments,config:X,accountIds:W});if(P.updatedConfig)await s1(P.updatedConfig);await t(j,$.sessionID,P.text),a()}},auth:{provider:"anthropic",async loader($,D){d=$;let X=await $();if(X.type==="oauth"){let x=function(){if(j0)clearInterval(j0),j0=null;let Q=async()=>{try{let L=await R(Z);if(!Lj(L))return;let U=await $();if(U.type!=="oauth")return;if(await Z1(U.refresh),!U.expires)return;let N=U.expires-Date.now(),S=Oj(L);if(N>S)return;if(F("[refresh] opencode main oauth background due",{expiresInMs:N,refreshBeforeMs:S}),U.refresh&&$0(L?.refresh?.mainLastRefreshError,U.refresh,Date.now())){F("[refresh] opencode main oauth background skipped backoff",{nextRetryAt:L?.refresh?.mainLastRefreshError?.nextRetryAt,retryCount:L?.refresh?.mainLastRefreshError?.retryCount,expiresInMs:N});return}if(U.refresh&&L?.refresh?.mainRefreshLeaseUntil&&L.refresh.mainRefreshLeaseUntil>Date.now()&&L.refresh.mainRefreshLeaseTokenHash===M0(U.refresh))return;await P();let I=await $();F("[refresh] opencode main oauth refreshed in background",{newExpiresInMs:I.expires?I.expires-Date.now():void 0})}catch(L){F("[refresh] opencode main oauth refresh failed",{message:L instanceof Error?L.message:String(L)})}};if(j0=setInterval(()=>{Q()},uj+A1(ij)),"unref"in j0)j0.unref()},E=function(Q,L){if(Q instanceof Request&&Q.body)return!1;return L==null||typeof L==="string"},h=function(Q){return Q.has("x-parent-session-id")},p=function(Q){return Q.includes("rate_limit_error")||/exceed your account'?s rate limit/i.test(Q)},c=function(Q){return Q?.quota?.enabled===!0},n=function(Q){return V.getFallback(Q.id,Q.access)?.quota??Q.quota};for(let Q of Object.values(D.models))Q.cost={input:0,output:0,cache:{read:0,write:0}};let W=null;async function P(){if(!W)W=(async()=>{let U=null,N=null,S=null;async function I(z){let H=await R(Z)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};H.refresh=H.refresh??{},z(H),await Y0(H,Z)}async function T(z){let H=Date.now()+cj;while(Date.now()<H){await new Promise((w)=>setTimeout(w,T1+A1(T1)));let K=await $();if(K.type!=="oauth"||!K.access)continue;if((K.access!==z.access||K.refresh!==z.refresh||(K.expires??0)>(z.expires??0)+60000)&&(!K.expires||K.expires>Date.now()))return F("[refresh] opencode main oauth joined concurrent refresh",{expiresInMs:K.expires?K.expires-Date.now():void 0}),K.access}return null}for(let z=0;z<=2;z++){let H=null;try{if(z>0){let C=500*2**(z-1);await new Promise((B)=>setTimeout(B,C))}if(H=await $(),!H.refresh)throw Error("Token refresh failed: missing refresh token");let K=await R(Z),_=M0(H.refresh),w=K?.refresh?.mainLastRefreshError;if(F("[refresh] opencode main oauth refresh check",{attempt:z,expiresInMs:H.expires?H.expires-Date.now():void 0,hasBackoff:Boolean(w),backoffActive:w?$0(w,H.refresh,Date.now()):!1,retryCount:w?.retryCount,nextRetryAt:w?.nextRetryAt}),w&&$0(w,H.refresh,Date.now()))throw F("[refresh] opencode main oauth refresh skipped backoff",{nextRetryAt:w.nextRetryAt,retryCount:w.retryCount}),Error(n0(w,Date.now()));if(K?.refresh?.mainRefreshLeaseUntil&&K.refresh.mainRefreshLeaseUntil>Date.now()&&K.refresh.mainRefreshLeaseTokenHash===_){F("[refresh] opencode main oauth refresh skipped lease",{leaseUntil:K.refresh.mainRefreshLeaseUntil});let C=await T(H);if(C)return C;throw Error("Claude OAuth refresh is already in progress")}let O=await b1({name:"opencode-main-oauth-refresh",ttlMs:120000,renew:!0});if(!O){F("[refresh] opencode main oauth refresh skipped file lock");let C=await T(H);if(C)return C;throw Error("Claude OAuth refresh is already in progress")}S=O.release,U=pj(),N=_,await I((C)=>{C.refresh=C.refresh??{},C.refresh.mainRefreshLeaseId=U??void 0,C.refresh.mainRefreshLeaseUntil=Date.now()+120000,C.refresh.mainRefreshLeaseTokenHash=_});let g=await R(Z);if(F("[refresh] opencode main oauth refresh lease acquired",{attempt:z,leaseUntil:Date.now()+120000}),g?.refresh?.mainRefreshLeaseId!==U||g.refresh.mainRefreshLeaseTokenHash!==_)throw Error("Claude OAuth refresh is already in progress");F("[refresh] opencode main oauth refresh request start",{attempt:z});let m=await f1({refreshToken:H.refresh,maxRetries:0});return await J.auth.set({path:{id:"anthropic"},body:{type:"oauth",refresh:m.refresh,access:m.access,expires:m.expires}}),await I((C)=>{if(!C?.refresh)return;if(C.refresh.mainLastRefreshError=void 0,C.refresh.mainRefreshLeaseId===U)C.refresh.mainRefreshLeaseId=void 0,C.refresh.mainRefreshLeaseUntil=void 0,C.refresh.mainRefreshLeaseTokenHash=void 0}),F("[refresh] opencode main oauth refresh succeeded",{attempt:z,expiresInMs:m.expires-Date.now()}),m.access}catch(K){let _=K instanceof Error&&(K.message.includes("fetch failed")||("code"in K)&&(K.code==="ECONNRESET"||K.code==="ECONNREFUSED"||K.code==="ETIMEDOUT"||K.code==="UND_ERR_CONNECT_TIMEOUT"));if(z<2&&(_||K instanceof d0&&K.status>=500))continue;F("[refresh] opencode main oauth refresh attempt failed",{attempt:z,error:K instanceof Error?K.message:String(K),transient:_});let w=H?.refresh;if(w&&K instanceof d0)await I((O)=>{O.refresh=O.refresh??{},O.refresh.mainLastRefreshError=i1({error:K,now:Date.now(),refreshToken:w,previous:O.refresh.mainLastRefreshError})});throw K}finally{if(U)await I((K)=>{if(!K?.refresh)return;if(K.refresh.mainRefreshLeaseId===U&&K.refresh.mainRefreshLeaseTokenHash===N)K.refresh.mainRefreshLeaseId=void 0,K.refresh.mainRefreshLeaseUntil=void 0,K.refresh.mainRefreshLeaseTokenHash=void 0}).catch(()=>{});await S?.().catch(()=>{})}}throw Error("Token refresh exhausted all retries")})().finally(()=>{W=null});return W}v=P,x(),V.seedFallbacksFromAccounts(G?.accounts??[]),o(G,{activeId:"main",route:"main",mainAccessToken:X.access,mainRefreshToken:X.refresh});async function i(Q,L){if(!Q.body||Q.status!==200)return L?.mark("inspect_stream_skip",{status:Q.status}),{response:Q,rateLimited:!1};if(Q.headers.get("x-cortexkit-relay-optimistic")==="true")return L?.mark("inspect_stream_skip",{status:Q.status,reason:"optimistic_relay"}),{response:Q,rateLimited:!1};let U=q(),N=Q.body.getReader(),S=[],I=new TextDecoder,T="",z=0;while(!T.includes(`
8
+
9
+ `)&&T.length<65536){let{done:K,value:_}=await N.read();if(K)break;if(S.push(_),z+=_.byteLength,T+=I.decode(_,{stream:!0}),p(T))break}if(p(T))return await N.cancel().catch(()=>{}),L?.mark("inspect_stream_first_event",{ms:y(q()-U),bytes:z,rateLimited:!0}),{response:Q,rateLimited:!0};let H=new ReadableStream({start(K){for(let _ of S)K.enqueue(_)},async pull(K){let{done:_,value:w}=await N.read();if(_){K.close();return}K.enqueue(w)},cancel(K){return N.cancel(K)}});return L?.mark("inspect_stream_first_event",{ms:y(q()-U),bytes:z,rateLimited:!1}),{response:new Response(H,{status:Q.status,statusText:Q.statusText,headers:Q.headers}),rateLimited:!1}}async function s(Q,L,U,N,S="unknown",I){let T=q(),z=I,H=async()=>{return z??=await R(Z),z},K=q1(Q,L),_=K.get("x-session-affinity")||K.get("x-opencode-session"),w=h(K);K.delete("x-parent-session-id"),K.delete("x-session-affinity"),K.delete("x-opencode-session");let O=L?.body,g;if(O&&typeof O==="string")try{let b=JSON.parse(O);if(typeof b.model==="string")g=b.model}catch{}let m=await o0(U,g),C=typeof O==="string"?O.length:void 0;if(O&&typeof O==="string"){let b=q(),J0=(()=>{if(!t0())return!1;try{return B0(JSON.parse(O).model)}catch{return!1}})();O=await R1(O,{cache1hEnabled:!w&&q0(),cache1hMode:E0(),fastModeEnabled:J0,identity:m});try{X0(K,U,{body:JSON.parse(O),identity:m})}catch{X0(K,U,{identity:m})}if(J0)g0(K);N?.mark("rewrite_body",{route:S,ms:y(q()-b),originalBytes:C,rewrittenBytes:O.length,cacheEnabled:!w&&q0(),cacheMode:E0(),fastModeEnabled:J0,subagent:w})}let B=C1(Q);if(S==="main"&&typeof O==="string"&&!w&&q0()&&E0()==="hybrid"){let b=await H();if(u.track({sessionId:_,url:B.url?.toString()??B.input.toString(),headers:K,bodyText:O,storage:b,cacheMode:"hybrid"}).tracked)N?.mark("cachekeep_track",{session:_})}let M=()=>fetch(B.input,{...L,body:O,headers:K,...E1()&&{tls:{rejectUnauthorized:!1}}}),k=e0(await H()),l=q(),A=await Yj({config:k,input:B.input,init:L,headers:K,body:O,fallback:M,affinity:_,optimisticResponse:k?.transport==="websocket"});return N?.mark("send_headers_received",{route:S,ms:y(q()-l),status:A.status,relayConfigured:k!=null,totalSendWithAccessMs:y(q()-T)}),A}async function V0(Q){let L=await Y.getUsableFallbackAccounts(Q);if(!z0(Q))return L;return L.filter((U)=>v0(n(U),Q,U.id))}async function r(Q,L,U,N,S,I,T){if(!U.length)return S??null;let z=T?.returnLastOnExhausted??!0;await S?.body?.cancel().catch(()=>{});let H=S??null;for(let[K,_]of U.entries()){let w=_.access;if(!w)continue;let O=await s(Q,L,w,I,`fallback_${K}`,N);H=O;let g=c0(O.status,N);if(!g){let m=await i(O,I);O=m.response,H=O,g=m.rateLimited}if(!g){if(await Y.markUsed(_),T?.onSuccess?.(_),w&&V.shouldRefreshOnRequestCount(I0))V.refreshFallback(_.id,w).then(()=>T?.onSuccess?.(_)).catch(()=>{});return O}if(K<U.length-1||!z)await O.body?.cancel().catch(()=>{})}return z?H:null}async function D0(Q,L,U,N,S,I,T){if(!E(Q,L?.body))return U;let z=q(),H=I??await R(Z);S?.mark("fallback_load_storage",{ms:y(q()-z),cached:!!I});let K=U,_=c0(K.status,H);if(!_){let O=await i(K,S);K=O.response,_=O.rateLimited}if(!_)return K;let w=N;if(!w){let O=q();w=await Y.getUsableFallbackAccounts(),S?.mark("fallback_get_accounts",{ms:y(q()-O),accounts:w.length})}if(z0(H)){let O=w.length;if(w=w.filter((g)=>v0(n(g),H,g.id)),w.length<O)F("[killswitch] filtered fallbacks",{before:O,after:w.length})}return await r(Q,L,w,H,K,S,{onSuccess:T})??K}return{apiKey:"",async fetch(Q,L){let U=L?.body,N=rj({bodyBytes:typeof U==="string"?U.length:void 0}),S=q(),I=await $();if(N.mark("get_auth",{ms:y(q()-S),authType:I.type,hasAccess:Boolean(I.access)}),I.type!=="oauth"){let B=await fetch(Q,L);return N.done("non_oauth_passthrough",{status:B.status}),B}await Z1(I.refresh);let T=q(),z=await R();N.mark("load_storage",{ms:y(q()-T)}),V.updateStorage(z),V.seedFallbacksFromAccounts(z?.accounts??[]);let H=E(Q,L?.body);if(H)I0++;let K=(B,M)=>o(z,{activeId:B,route:M,mainAccessToken:I.access,mainRefreshToken:I.refresh}),_;if(H&&j1(z)==="fallback-first")try{let B=q();_=await V0(z),N.mark("fallback_first_get_accounts",{ms:y(q()-B),accounts:_.length});let M=await r(Q,L,_,z,void 0,N,{returnLastOnExhausted:!1,onSuccess:(k)=>K(k.id,"fallback-first")});if(M)return N.done("return_fallback_first",{status:M.status}),W0(M);_=[]}catch(B){N.mark("fallback_first_error",{error:B instanceof Error?B.message:String(B)})}if(!I.access||!I.expires||I.expires<Date.now()){let M=(await R())?.refresh?.mainLastRefreshError;if(I.refresh&&M&&$0(M,I.refresh,Date.now()))throw F("[refresh] opencode main oauth request skipped backoff",{nextRetryAt:M.nextRetryAt,retryCount:M.retryCount,expiresInMs:I.expires?I.expires-Date.now():void 0}),Error(n0(M,Date.now()));F("[refresh] opencode main oauth refresh required for request",{hasAccess:Boolean(I.access),expiresInMs:I.expires?I.expires-Date.now():void 0,expiredAgoMs:I.expires&&I.expires<Date.now()?Date.now()-I.expires:void 0});let k=q();I.access=await P(),N.mark("refresh_main_access",{ms:y(q()-k)})}if(!I.access)throw N.done("missing_access_error"),Error("OAuth access token is missing after refresh");function w(){if(z?.quota?.showToasts!==!0)return;let B=V.getMain();if(!B)return;let M=(z?.accounts??[]).filter((A)=>A.enabled!==!1).map((A)=>({...A,quota:V.getFallback(A.id,A.access)?.quota??A.quota})),k=P0(B.quota,z),l;if(k)l="main";else l=M.find((A)=>P0(A.quota,z))?.id??"main";vj(B.quota,M,l)}if(H&&c(z))try{let B=q(),M=V.getMain(I.access)?.quota;if(!M)M=await V.refreshMain(I.access),w();else if(V.needsRefresh(I0))V.refreshMain(I.access).then(()=>{e(),w()}).catch(()=>{});if(o(z,{activeId:"main",route:"main",mainAccessToken:I.access,mainRefreshToken:I.refresh}),N.mark("main_quota_for_routing",{ms:y(q()-B),passes:P0(M,z)}),!P0(M,z)){let k=q();_=await V0(z),N.mark("preselect_fallback_accounts",{ms:y(q()-k),accounts:_.length});let l=await r(Q,L,_,z,void 0,N,{onSuccess:(A)=>K(A.id,"fallback")});if(l)return N.done("return_preselected_fallback",{status:l.status}),W0(l)}}catch(B){N.mark("main_quota_for_routing_error",{error:B instanceof Error?B.message:String(B)})}let O=V.getMain(I.access)?.quota;if(z?.quota?.failClosedOnUnknownQuota&&!O&&V.isBackedOff()){let B=V.getLastApiError(),M=B?c1(B,Date.now()):"Quota API unavailable";return F("[quota] blocked: quota API backed off (failClosed)",{nextRetryAt:B?.nextRetryAt,retryCount:B?.retryCount}),new Response(JSON.stringify({type:"error",error:{type:"rate_limit_error",message:M}}),{status:429,headers:{"content-type":"application/json","retry-after":String(B?.nextRetryAt?Math.max(1,Math.ceil((B.nextRetryAt-Date.now())/1000)):60)}})}if(z0(z)){if(V.needsRefresh(I0))try{let M=(z?.accounts??[]).filter((k)=>k.enabled!==!1&&k.access);await Promise.all([V.refreshMain(I.access),V.refreshAllFallbacks(M)])}catch(M){F("[quota] killswitch refresh failed",{error:M instanceof Error?M.message:String(M),backedOff:V.isBackedOff()})}O=V.getMain(I.access)?.quota}if(z0(z)&&!v0(O,z)){let M=E(Q,L?.body)?await V0(z):[];if(M.length>0){F("[route] skipping main (killswitch), trying fallbacks");let b=await r(Q,L,M,z,void 0,N,{onSuccess:(J0)=>K(J0.id,"fallback")});if(b)return N.done("return_killswitch_fallback",{status:b.status}),W0(b)}let k=Date.now(),l=(z?.accounts??[]).filter((b)=>b.enabled!==!1).map((b)=>({...b,quota:n(b)})),A=n1(O,l,k);return new Response(JSON.stringify({type:"error",error:{type:"rate_limit_error",message:`Killswitch: no routable accounts. Retry in ${Math.floor(A/60)}m ${A%60}s.`}}),{status:429,headers:{"content-type":"application/json","retry-after":String(A)}})}let g=await s(Q,L,I.access,N,"main",z),m=!1,C=await D0(Q,L,g,_,N,z,(B)=>{m=!0,K(B.id,"fallback")});if(!m)K("main","main");return N.done("return_response",{status:C.status}),W0(C)}}}return{}},methods:[{label:"Claude Pro/Max",type:"oauth",authorize:async()=>{let $=await p0("max");return{url:$.url,instructions:"Paste the authorization code here:",method:"code",callback:async(D)=>{return l0(D,$.verifier,$.redirectUri,$.state)}}}},{label:"Create an API Key",type:"oauth",authorize:async()=>{let $=await p0("console");return{url:$.url,instructions:"Paste the authorization code here:",method:"code",callback:async(D)=>{let X=await l0(D,$.verifier,$.redirectUri,$.state);if(X.type==="failed")return X;return{type:"success",key:(await fetch("https://api.anthropic.com/api/oauth/claude_cli/create_api_key",{method:"POST",headers:{"Content-Type":"application/json",authorization:`Bearer ${X.access}`}}).then((P)=>P.json())).raw_key}}}}},{provider:"anthropic",label:"Manually enter API Key",type:"api"}]}}};export{XJ as AnthropicAuthPlugin};
@@ -40,3 +40,8 @@ export declare function getSidebarStateFile(): string;
40
40
  export declare const DEFAULT_SIDEBAR_STATE: SidebarState;
41
41
  export declare function getSidebarState(): Promise<SidebarState>;
42
42
  export declare function setSidebarState(state: SidebarState): Promise<void>;
43
+ export declare function resolveActiveAccount(state: SidebarState): {
44
+ id: string;
45
+ name: string;
46
+ quota: AccountQuota | null;
47
+ };
@@ -1 +1 @@
1
- import{Aa as c,Ba as d,ya as a,za as b}from"./index-nfgq84t3.js";export{d as setSidebarState,a as getSidebarStateFile,c as getSidebarState,b as DEFAULT_SIDEBAR_STATE};
1
+ import{Ga as a,Ha as b,Ia as c,Ja as d,Ka as e}from"./index-q0d64q8d.js";export{d as setSidebarState,e as resolveActiveAccount,a as getSidebarStateFile,c as getSidebarState,b as DEFAULT_SIDEBAR_STATE};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-anthropic-auth",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -51,9 +51,9 @@
51
51
  "@opencode-ai/plugin": "*"
52
52
  },
53
53
  "dependencies": {
54
- "@cortexkit/anthropic-auth-core": "1.5.0",
55
- "@opentui/core": ">=0.1.92",
56
- "@opentui/solid": ">=0.1.92",
54
+ "@cortexkit/anthropic-auth-core": "1.6.0",
55
+ "@opentui/core": ">=0.3.1",
56
+ "@opentui/solid": ">=0.3.1",
57
57
  "solid-js": "^1.9.10"
58
58
  }
59
59
  }
@@ -77,3 +77,31 @@ export async function setSidebarState(state: SidebarState): Promise<void> {
77
77
  // Best-effort — sidebar is non-critical
78
78
  }
79
79
  }
80
+
81
+ // Resolve the currently-active account from activeId for the collapsed sidebar
82
+ // view. activeId === 'main' (or undefined/unmatched/disabled) → the main
83
+ // account; otherwise the enabled fallback whose id matches.
84
+ export function resolveActiveAccount(state: SidebarState): {
85
+ id: string
86
+ name: string
87
+ quota: AccountQuota | null
88
+ } {
89
+ const activeId = state.activeId
90
+ if (activeId && activeId !== 'main') {
91
+ // `account.enabled` is defensive: writeSidebarState already filters disabled
92
+ // accounts out of state.fallbacks, so in normal operation every entry is
93
+ // enabled. Kept so this pure helper stays correct for any caller and is
94
+ // exercised directly by the unit tests.
95
+ const fallback = state.fallbacks.find(
96
+ (account) => account.enabled && account.id === activeId,
97
+ )
98
+ if (fallback) {
99
+ return {
100
+ id: fallback.id,
101
+ name: fallback.label ?? fallback.id,
102
+ quota: fallback.quota,
103
+ }
104
+ }
105
+ }
106
+ return { id: 'main', name: 'main', quota: state.main.quota }
107
+ }
package/src/tui.tsx CHANGED
@@ -1,17 +1,21 @@
1
1
  /** @jsxImportSource @opentui/solid */
2
2
 
3
+ import { readFileSync } from 'node:fs'
4
+ import { dirname, join } from 'node:path'
5
+ import { fileURLToPath } from 'node:url'
3
6
  import type {
4
7
  TuiPlugin,
5
8
  TuiPluginApi,
6
9
  TuiPluginModule,
7
10
  } from '@opencode-ai/plugin/tui'
8
- import { For, Show, createSignal, onCleanup } from 'solid-js'
11
+ import { For, type JSX, Show, createSignal, onCleanup } from 'solid-js'
9
12
 
10
13
  import {
11
14
  type AccountQuota,
12
15
  DEFAULT_SIDEBAR_STATE,
13
16
  type SidebarState,
14
17
  getSidebarState,
18
+ resolveActiveAccount,
15
19
  } from './sidebar-state.js'
16
20
 
17
21
  const POLL_MS = 1500
@@ -22,6 +26,23 @@ const BAR_WIDTH = 10
22
26
  const BAR_FILLED = '\u2588'
23
27
  const BAR_EMPTY = '\u2591'
24
28
 
29
+ // Plugin version for the header (mirrors the Magic Context / AFT convention).
30
+ // Read at runtime from package.json relative to this module — NOT a TS JSON
31
+ // import, which would break the declaration build (package.json is outside
32
+ // rootDir). tui.tsx ships as source (package.json exports["./tui"] →
33
+ // "./src/tui.tsx") and is never compiled into a deeper dist tree, so `..` from
34
+ // src/ is always the package root. Empty string on any failure → header shows
35
+ // the badge with no version.
36
+ const PLUGIN_VERSION: string = (() => {
37
+ try {
38
+ const here = dirname(fileURLToPath(import.meta.url))
39
+ const raw = readFileSync(join(here, '..', 'package.json'), 'utf8')
40
+ return (JSON.parse(raw) as { version?: string }).version ?? ''
41
+ } catch {
42
+ return ''
43
+ }
44
+ })()
45
+
25
46
  // biome-ignore lint/suspicious/noExplicitAny: opentui border prop not typed in plugin tui surface
26
47
  const SINGLE_BORDER = { type: 'single' } as any
27
48
 
@@ -116,6 +137,21 @@ function StatRow(props: {
116
137
  )
117
138
  }
118
139
 
140
+ // Compact row for the collapsed view: muted label left, caller-provided value
141
+ // right. Mirrors StatRow's layout so columns line up.
142
+ function CollapsedRow(props: {
143
+ theme: ThemeCurrent
144
+ label: string
145
+ children: JSX.Element
146
+ }) {
147
+ return (
148
+ <box width='100%' flexDirection='row' justifyContent='space-between'>
149
+ <text fg={props.theme.textMuted}>{props.label}</text>
150
+ {props.children}
151
+ </box>
152
+ )
153
+ }
154
+
119
155
  // Quota window row: muted label left, tone-colored bar + percentage right,
120
156
  // with an optional muted reset suffix.
121
157
  function QuotaRow(props: {
@@ -203,6 +239,7 @@ async function readStateFromFile(): Promise<SidebarState> {
203
239
 
204
240
  function QuotaSidebar(props: { api: TuiPluginApi }) {
205
241
  const [state, setState] = createSignal<SidebarState>(DEFAULT_SIDEBAR_STATE)
242
+ const [collapsed, setCollapsed] = createSignal(false)
206
243
  let lastUpdated = 0
207
244
  let debounce: ReturnType<typeof setTimeout> | null = null
208
245
 
@@ -241,6 +278,12 @@ function QuotaSidebar(props: { api: TuiPluginApi }) {
241
278
  const hasData = () =>
242
279
  state().main.quota != null || enabledFallbacks().length > 0
243
280
 
281
+ const headerLabel = () =>
282
+ !hasData() ? 'CLAUDE' : collapsed() ? '\u25b6 CLAUDE' : '\u25bc CLAUDE'
283
+ const activeAccount = () => resolveActiveAccount(state())
284
+ const activeFiveHourPct = () =>
285
+ activeAccount().quota?.five_hour?.usedPercent ?? null
286
+
244
287
  const quotaBackedOff = () => state().main.quotaBackedOff === true
245
288
  const refreshBackedOff = () => state().main.refreshBackedOff === true
246
289
  const degraded = () => quotaBackedOff() || refreshBackedOff()
@@ -264,19 +307,30 @@ function QuotaSidebar(props: { api: TuiPluginApi }) {
264
307
  paddingLeft={1}
265
308
  paddingRight={1}
266
309
  >
267
- {/* Header: CLAUDE badge + optional LIMITED degraded badge */}
310
+ {/* Header: ▼/▶ CLAUDE badge (click to collapse) + version, or LIMITED badge */}
311
+ {/* biome-ignore lint/a11y/noStaticElementInteractions: opentui renders to a terminal, not the DOM — ARIA roles do not apply */}
268
312
  <box
269
313
  width='100%'
270
314
  flexDirection='row'
271
315
  justifyContent='space-between'
272
316
  alignItems='center'
317
+ onMouseDown={() => {
318
+ if (hasData()) setCollapsed((value) => !value)
319
+ }}
273
320
  >
274
321
  <box paddingLeft={1} paddingRight={1} backgroundColor={theme().accent}>
275
322
  <text fg={theme().background}>
276
- <b>{'CLAUDE'}</b>
323
+ <b>{headerLabel()}</b>
277
324
  </text>
278
325
  </box>
279
- <Show when={degraded()}>
326
+ <Show
327
+ when={degraded()}
328
+ fallback={
329
+ <Show when={PLUGIN_VERSION !== ''}>
330
+ <text fg={theme().textMuted}>{`v${PLUGIN_VERSION}`}</text>
331
+ </Show>
332
+ }
333
+ >
280
334
  <box
281
335
  paddingLeft={1}
282
336
  paddingRight={1}
@@ -289,93 +343,135 @@ function QuotaSidebar(props: { api: TuiPluginApi }) {
289
343
  </Show>
290
344
  </box>
291
345
 
292
- <Show
293
- when={hasData()}
294
- fallback={
295
- <box marginTop={1} width='100%'>
296
- <text fg={theme().textMuted}>{'Waiting for quota\u2026'}</text>
297
- </box>
298
- }
299
- >
300
- {/* Quota */}
301
- <SectionHeader theme={theme()} title='Quota' />
302
- <AccountBlock
303
- theme={theme()}
304
- name='main'
305
- quota={state().main.quota}
306
- active={state().activeId === 'main'}
307
- />
308
- <For each={enabledFallbacks()}>
309
- {(fb) => (
310
- <AccountBlock
311
- theme={theme()}
312
- name={fb.label ?? fb.id}
313
- quota={fb.quota}
314
- active={state().activeId === fb.id}
315
- marginTop={1}
316
- />
317
- )}
318
- </For>
346
+ {/* Collapsed: active account 5h quota + dot, plus fast-mode when on */}
347
+ <Show when={collapsed() && hasData()}>
348
+ <CollapsedRow theme={theme()} label={activeAccount().name}>
349
+ <Show
350
+ when={activeFiveHourPct() != null}
351
+ fallback={<text fg={theme().textMuted}>{'\u2014'}</text>}
352
+ >
353
+ <box flexDirection='row'>
354
+ <text
355
+ fg={toneColor(
356
+ theme(),
357
+ usageTone(activeFiveHourPct() as number),
358
+ )}
359
+ >
360
+ <b>
361
+ {`${String(Math.round(activeFiveHourPct() as number)).padStart(3)}%`}
362
+ </b>
363
+ </text>
364
+ <text
365
+ fg={toneColor(
366
+ theme(),
367
+ usageTone(activeFiveHourPct() as number),
368
+ )}
369
+ >
370
+ {' \u25cf'}
371
+ </text>
372
+ </box>
373
+ </Show>
374
+ </CollapsedRow>
375
+ <Show when={state().fastMode}>
376
+ <CollapsedRow theme={theme()} label='Mode'>
377
+ <text fg={toneColor(theme(), 'accent')}>
378
+ <b>{'fast'}</b>
379
+ </text>
380
+ </CollapsedRow>
381
+ </Show>
319
382
  </Show>
320
383
 
321
- {/* Routing */}
322
- <SectionHeader theme={theme()} title='Routing' />
323
- <StatRow
324
- theme={theme()}
325
- label='Route'
326
- value={state().route}
327
- tone='accent'
328
- />
329
- <StatRow
330
- theme={theme()}
331
- label='Mode'
332
- value={state().fastMode ? 'fast' : 'std'}
333
- tone={state().fastMode ? 'accent' : 'muted'}
334
- />
335
- <StatRow
336
- theme={theme()}
337
- label='Relay'
338
- value={relayValue()}
339
- tone={state().relay?.enabled ? 'ok' : 'muted'}
340
- />
341
-
342
- {/* Cache */}
343
- <Show when={showCache()}>
344
- <SectionHeader theme={theme()} title='Cache' />
345
- <StatRow
346
- theme={theme()}
347
- label='1h cache'
348
- value={`${cacheKeep()?.window} \u00b7 ${cacheKeep()?.enabled ? 'on' : 'off'}`}
349
- tone={cacheKeep()?.enabled ? 'ok' : 'muted'}
350
- />
351
- <Show when={(cacheKeep()?.trackedSessions ?? 0) > 0}>
352
- <StatRow
384
+ {/* Expanded: full sections. Also render when there's no data so the
385
+ sidebar can never go blank if data clears while collapsed. */}
386
+ <Show when={!collapsed() || !hasData()}>
387
+ <Show
388
+ when={hasData()}
389
+ fallback={
390
+ <box marginTop={1} width='100%'>
391
+ <text fg={theme().textMuted}>{'Waiting for quota\u2026'}</text>
392
+ </box>
393
+ }
394
+ >
395
+ {/* Quota */}
396
+ <SectionHeader theme={theme()} title='Quota' />
397
+ <AccountBlock
353
398
  theme={theme()}
354
- label='Tracked'
355
- value={String(cacheKeep()?.trackedSessions)}
356
- tone='text'
399
+ name='main'
400
+ quota={state().main.quota}
401
+ active={state().activeId === 'main'}
357
402
  />
403
+ <For each={enabledFallbacks()}>
404
+ {(fb) => (
405
+ <AccountBlock
406
+ theme={theme()}
407
+ name={fb.label ?? fb.id}
408
+ quota={fb.quota}
409
+ active={state().activeId === fb.id}
410
+ marginTop={1}
411
+ />
412
+ )}
413
+ </For>
358
414
  </Show>
359
- </Show>
360
415
 
361
- {/* Health — only when something is wrong */}
362
- <Show when={degraded()}>
363
- <SectionHeader theme={theme()} title='Health' />
364
- <Show when={quotaBackedOff()}>
416
+ {/* Routing */}
417
+ <SectionHeader theme={theme()} title='Routing' />
418
+ <StatRow
419
+ theme={theme()}
420
+ label='Route'
421
+ value={state().route}
422
+ tone='accent'
423
+ />
424
+ <StatRow
425
+ theme={theme()}
426
+ label='Mode'
427
+ value={state().fastMode ? 'fast' : 'std'}
428
+ tone={state().fastMode ? 'accent' : 'muted'}
429
+ />
430
+ <StatRow
431
+ theme={theme()}
432
+ label='Relay'
433
+ value={relayValue()}
434
+ tone={state().relay?.enabled ? 'ok' : 'muted'}
435
+ />
436
+
437
+ {/* Cache */}
438
+ <Show when={showCache()}>
439
+ <SectionHeader theme={theme()} title='Cache' />
365
440
  <StatRow
366
441
  theme={theme()}
367
- label='Quota API'
368
- value={`backoff ${formatUntil(state().main.quotaBackoffUntil)}`}
369
- tone='warn'
442
+ label='1h cache'
443
+ value={`${cacheKeep()?.window} \u00b7 ${cacheKeep()?.enabled ? 'on' : 'off'}`}
444
+ tone={cacheKeep()?.enabled ? 'ok' : 'muted'}
370
445
  />
446
+ <Show when={(cacheKeep()?.trackedSessions ?? 0) > 0}>
447
+ <StatRow
448
+ theme={theme()}
449
+ label='Tracked'
450
+ value={String(cacheKeep()?.trackedSessions)}
451
+ tone='text'
452
+ />
453
+ </Show>
371
454
  </Show>
372
- <Show when={refreshBackedOff()}>
373
- <StatRow
374
- theme={theme()}
375
- label='Token refresh'
376
- value={`backoff ${formatUntil(state().main.refreshBackoffUntil)}`}
377
- tone='warn'
378
- />
455
+
456
+ {/* Health — only when something is wrong */}
457
+ <Show when={degraded()}>
458
+ <SectionHeader theme={theme()} title='Health' />
459
+ <Show when={quotaBackedOff()}>
460
+ <StatRow
461
+ theme={theme()}
462
+ label='Quota API'
463
+ value={`backoff ${formatUntil(state().main.quotaBackoffUntil)}`}
464
+ tone='warn'
465
+ />
466
+ </Show>
467
+ <Show when={refreshBackedOff()}>
468
+ <StatRow
469
+ theme={theme()}
470
+ label='Token refresh'
471
+ value={`backoff ${formatUntil(state().main.refreshBackoffUntil)}`}
472
+ tone='warn'
473
+ />
474
+ </Show>
379
475
  </Show>
380
476
  </Show>
381
477
  </box>