@cortexkit/opencode-anthropic-auth 1.9.4 → 1.10.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/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{Oa as I,Qa as $,m as w,n as k,p as A,r as R,t as d,u as l,v as p}from"./index-fvzta6xw.js";import"./index-agh52sak.js";import{stdin as E,stdout as U}from"node:process";import{createInterface as _}from"node:readline/promises";function g(){return{version:1,main:{type:"opencode",provider:"anthropic"},fallbackOn:[401,403,429],refresh:{enabled:!0,intervalMinutes:10,refreshBeforeExpiryMinutes:240},quota:{enabled:!0,checkIntervalMinutes:5,minimumRemaining:{five_hour:10,seven_day:20},failClosedOnUnknownQuota:!0},accounts:[]}}function y(){console.log(`Usage:
2
+ import{Oa as I,Qa as $,m as w,n as k,p as A,r as R,t as d,u as l,v as p}from"./index-fvzta6xw.js";import"./index-p8j7mmfc.js";import{stdin as E,stdout as U}from"node:process";import{createInterface as _}from"node:readline/promises";function g(){return{version:1,main:{type:"opencode",provider:"anthropic"},fallbackOn:[401,403,429],refresh:{enabled:!0,intervalMinutes:10,refreshBeforeExpiryMinutes:240},quota:{enabled:!0,checkIntervalMinutes:5,minimumRemaining:{five_hour:10,seven_day:20},failClosedOnUnknownQuota:!0},accounts:[]}}function y(){console.log(`Usage:
3
3
  opencode-anthropic-auth login [label]
4
4
  opencode-anthropic-auth api add [label]
5
5
  opencode-anthropic-auth list
@@ -0,0 +1 @@
1
+ import{createHash as z}from"node:crypto";import{homedir as F,tmpdir as L}from"node:os";import{join as k}from"node:path";var G="OPENCODE_ANTHROPIC_AUTH_RPC_DIR";function Q(q){let g=process.env[G]?.trim();if(g)return g;let w=z("sha256").update(q).digest("hex").slice(0,16),x=process.env.XDG_STATE_HOME||k(F(),".local","state");return k(x,"cortexkit","anthropic-auth","rpc",w)}export{L as fb,Q as gb};
@@ -0,0 +1,2 @@
1
+ import{mkdir as s,readdir as a,readFile as u,rename as c,unlink as l,writeFile as p}from"node:fs/promises";import{join as o}from"node:path";function m(r){try{return process.kill(r,0),!0}catch(n){return n.code==="EPERM"}}async function g(r,n){await s(r,{recursive:!0});let i={...n,startedAt:Date.now()},t=o(r,`port-${n.pid}.json`),e=`${t}.${process.pid}.tmp`;return await p(e,JSON.stringify(i),{encoding:"utf8",mode:384}),await c(e,t),t}async function y(r){let n;try{n=await a(r)}catch{return null}let i=[];for(let t of n){if(!t.startsWith("port-")||!t.endsWith(".json"))continue;try{let e=JSON.parse(await u(o(r,t),"utf8"));if(Number.isFinite(e.port))if(m(e.pid))i.push(e);else l(o(r,t)).catch(()=>{})}catch{}}if(i.length===0)return null;return i.sort((t,e)=>e.startedAt-t.startedAt)[0]??null}
2
+ export{g as db,y as eb};
@@ -1,2 +1,2 @@
1
1
  import{createRequire as q}from"node:module";var j=Object.create;var{getPrototypeOf:k,defineProperty:i,getOwnPropertyNames:l}=Object;var m=Object.prototype.hasOwnProperty;function n(a){return this[a]}var o,p,r=(a,b,d)=>{var f=a!=null&&typeof a==="object";if(f){var g=b?o??=new WeakMap:p??=new WeakMap,h=g.get(a);if(h)return h}d=a!=null?j(k(a)):{};let c=b||!a||!a.__esModule?i(d,"default",{value:a,enumerable:!0}):d;for(let e of l(a))if(!m.call(c,e))i(c,e,{get:n.bind(a,e),enumerable:!0});if(f)g.set(a,c);return c};var s=(a,b)=>()=>(b||a((b={exports:{}}).exports,b),b.exports);var u=q(import.meta.url);
2
- export{r as db,s as eb,u as fb};
2
+ export{r as hb,s as ib,u as jb};
package/dist/index.js CHANGED
@@ -1,14 +1,15 @@
1
- import{$ as mj,A as xj,Aa as rj,B as Tj,Ba as Pj,C as q1,Ca as p0,D as qj,Da as sj,E as E1,Ea as aj,F as Ej,Fa as tj,G as Rj,Ga as ej,H as vj,Ha as Oj,I as R1,Ia as zj,J as W1,Ja as jJ,K as Sj,Ka as N1,L as U0,La as JJ,M as v1,Ma as $J,N as Aj,Na as y1,O as fj,P as b0,Pa as VJ,Q as h0,R as X1,Ra as _1,S as kj,Sa as b1,T as yj,Ta as WJ,U as bj,Ua as XJ,V as hj,Va as h1,W as gj,X as G1,Y as B0,Z as F0,_ as g0,a as e1,aa as Z1,b as jj,ba as Xj,c as v0,ca as Gj,d as S0,da as S1,e as Jj,ea as Zj,f as E0,fa as Kj,g as Uj,ga as Yj,h as $j,ha as K1,i as Vj,ia as pj,j as Wj,ja as lj,k as C1,ka as dj,l as Bj,la as ij,m as H1,ma as A1,n as x1,na as uj,o as q,oa as cj,p as e,pa as Y1,q as k0,qa as P1,r as T1,ra as nj,s as Fj,sa as f1,t as Cj,ta as m0,u as h,ua as O1,va as z1,w as y0,wa as D1,x as Hj,xa as oj,y as $1,ya as k1,z as V1,za as I1}from"./index-fvzta6xw.js";import{Za as GJ}from"./index-9yjbmhf1.js";import"./index-agh52sak.js";import{randomUUID as uJ}from"node:crypto";function M0(j){return typeof j==="object"&&j!==null}function zJ(j){if(Array.isArray(j))return j;if(M0(j)&&Array.isArray(j.data))return j.data;return[]}function DJ(j){if(!M0(j)||!M0(j.info))return;return typeof j.info.role==="string"?j.info.role:void 0}function m1(j){if(!M0(j)||!M0(j.info))return null;let J=j.info,$=M0(J.model)?J.model:void 0,W=typeof J.agent==="string"?J.agent:void 0,V=typeof $?.providerID==="string"?$.providerID:typeof J.providerID==="string"?J.providerID:void 0,z=typeof $?.modelID==="string"?$.modelID:typeof J.modelID==="string"?J.modelID:void 0,M=typeof $?.variant==="string"?$.variant:typeof J.variant==="string"?J.variant:void 0;if(!W&&(!V||!z)&&!M)return null;let S={};if(W)S.agent=W;if(V&&z)S.model={providerID:V,modelID:z};if(M)S.variant=M;return S}function p1(j,J){return{agent:j.agent??J.agent,model:j.model??J.model,variant:j.variant??J.variant}}function l1(j){return Boolean(j.agent&&j.model&&j.variant)}async function d1(j,J){if(!j||!J)return null;let $=j;if(typeof $.session?.messages!=="function")return null;let W=[];try{W=zJ(await Promise.resolve($.session.messages({path:{id:J},query:{limit:100}})))}catch{return null}if(W.length===0)return null;let V={};for(let z=W.length-1;z>=0;z--){if(DJ(W[z])!=="assistant")continue;let M=m1(W[z]);if(!M)continue;if(V=p1(V,M),l1(V))return V}for(let z=W.length-1;z>=0;z--){let M=m1(W[z]);if(!M)continue;if(V=p1(V,M),l1(V))return V}if(!V.agent&&!V.model&&!V.variant)return null;return V}function i1(j,J){let $=new Map,W=0,V=0,z=0,M=0,S=0,r=(y)=>{let f=performance.now(),n=j(y);return S+=performance.now()-f,z++,n};return{call:(y)=>{if(!J.enabled())return r(y);let f=$.get(y);if(f!==void 0)return V++,$.delete(y),$.set(y,f),f;let n=r(y),a=y.length+n.length;if(a>J.maxBytes)return n;$.set(y,n),W+=a;while(W>J.maxBytes&&$.size>1){let d=$.keys().next().value,W0=$.get(d)??"";$.delete(d),W-=d.length+W0.length,M++}return n},stats:()=>({hits:V,misses:z,evictions:M,entries:$.size,cacheBytes:W,computeMsTotal:S})}}function u1(j){return`${e1}${j.charAt(0).toUpperCase()}${j.slice(1)}`}function Dj(j){if(j==="StructuredOutput")return j;return`${j.charAt(0).toLowerCase()}${j.slice(1)}`}var IJ=new Set(["callgraph","conflicts","delete","import","inspect","move","navigate","outline","refactor","safety","search","transform","zoom"]);function c1(j){let J=Dj(j);if(J.startsWith("aft_"))return J;if(IJ.has(J))return`aft_${J}`;return null}function w1(j,J){let $=new Headers;if(j instanceof Request)j.headers.forEach((V,z)=>{$.set(z,V)});let W=J?.headers;if(W){if(W instanceof Headers)W.forEach((V,z)=>{$.set(z,V)});else if(Array.isArray(W))for(let V of W){let[z,M]=V;if(typeof M<"u")$.set(z,String(M))}else for(let[V,z]of Object.entries(W))if(typeof z<"u")$.set(V,String(z))}return $}function t0(j){return j.set("anthropic-beta",v0(j.get("anthropic-beta"),[jj])),j}function A0(j,J,$={}){return Kj(j,J,$)}function NJ(j){if(j.tools&&Array.isArray(j.tools))j.tools=j.tools.map((J)=>({...J,name:J.name?u1(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(($)=>{if($.type==="tool_use"&&$.name)return{...$,name:u1($.name)};return $});return J});return JSON.stringify(Yj(j))}function M1(j){return j.replace(/"name"\s*:\s*"(mcp_)?([^"]+)"/g,(J,$,W)=>{if($)return`"name": "${c1(W)??Dj(W)}"`;let V=c1(W);return V?`"name": "${V}"`:J})}function n1(j,J=!1){if(J)return{ready:M1(j),pending:""};let $=j.length,W='"name"',V=Math.max(0,j.length-W.length+1);for(let M=V;M<j.length;M++)if(W.startsWith(j.slice(M))){$=Math.min($,M);break}let z=j.lastIndexOf(W);if(z!==-1){let M=j.slice(z);if(/^"name"\s*(?::\s*(?:"[^"]*)?)?$/.test(M))$=Math.min($,z)}if($<j.length)return{ready:M1(j.slice(0,$)),pending:j.slice($)};return{ready:M1(j),pending:""}}function U1(){if(!process.env.ANTHROPIC_BASE_URL?.trim())return!1;let j=process.env.ANTHROPIC_INSECURE?.trim();return j==="1"||j==="true"}function Ij(j){let J=j?.trim();if(!J)return null;try{let $=new URL(J);if($.protocol!=="http:"&&$.protocol!=="https:"||$.username||$.password)return null;return $}catch{return null}}function _J(){return Ij(process.env.ANTHROPIC_BASE_URL)}function B1(j,J={}){let $=null;try{if(typeof j==="string"||j instanceof URL)$=new URL(j.toString());else if(j instanceof Request)$=new URL(j.url)}catch{$=null}if(!$)return{input:j,url:null};let W=$.href,V=J.baseURL?Ij(J.baseURL):_J();if(V){if($.protocol=V.protocol,$.host=V.host,J.baseURL)$.pathname=`${V.pathname.replace(/\/$/,"")}${$.pathname}`}if($.pathname.endsWith("/v1/messages")&&!$.searchParams.has("beta"))$.searchParams.set("beta","true");if($.href===W)return{input:j,url:$};return{input:j instanceof Request?new Request($.toString(),j):$,url:$}}function LJ(j){let W=j.split(/\n\n+/).filter((V)=>{if(V.includes(Jj))return!1;for(let z of Vj)if(V.includes(z))return!1;return!0}).join(`
1
+ import{$ as aW,A as gW,Aa as N4,B as mW,Ba as BW,C as O1,Ca as n0,D as pW,Da as G4,E as $1,Ea as V4,F as iW,Fa as X4,G as lW,Ga as Z4,H as dW,Ha as CW,I as x1,Ia as FW,J as N1,Ja as D4,K as nW,Ka as m1,L as f0,La as K4,M as q1,Ma as _4,N as uW,Na as p1,O as cW,P as p0,Pa as Y4,Q as i0,R as G1,Ra as i1,S as oW,Sa as K1,T as T1,Ta as I4,U as rW,Ua as z4,V as tW,Va as l1,W as sW,X as R1,Y as x0,Z as q0,_ as l0,a as DW,aa as V1,b as KW,ba as wW,c as v0,ca as QW,d as A0,da as S1,e as _W,ea as LW,f as S0,fa as UW,g as AW,ga as MW,h as YW,ha as E1,i as IW,ia as eW,j as zW,ja as W4,k as C1,ka as v1,l as kW,la as j4,m as F1,ma as A1,n as H1,na as J4,o as S,oa as P4,p as W0,pa as k1,q as h0,qa as X1,r as f1,ra as O4,s as yW,sa as y1,t as hW,ta as d0,u as A,ua as h1,va as Z1,w as b0,wa as D1,x as bW,xa as $4,y as g0,ya as b1,z as m0,za as g1}from"./index-fvzta6xw.js";import{Za as Q4}from"./index-9yjbmhf1.js";import{db as e1}from"./index-jb14nj5c.js";import{gb as w4}from"./index-3ynbghx3.js";import"./index-p8j7mmfc.js";import{randomUUID as Yj}from"node:crypto";function H0(W){return typeof W==="object"&&W!==null}function F4(W){if(Array.isArray(W))return W;if(H0(W)&&Array.isArray(W.data))return W.data;return[]}function H4(W){if(!H0(W)||!H0(W.info))return;return typeof W.info.role==="string"?W.info.role:void 0}function n1(W){if(!H0(W)||!H0(W.info))return null;let J=W.info,j=H0(J.model)?J.model:void 0,O=typeof J.agent==="string"?J.agent:void 0,P=typeof j?.providerID==="string"?j.providerID:typeof J.providerID==="string"?J.providerID:void 0,G=typeof j?.modelID==="string"?j.modelID:typeof J.modelID==="string"?J.modelID:void 0,I=typeof j?.variant==="string"?j.variant:typeof J.variant==="string"?J.variant:void 0;if(!O&&(!P||!G)&&!I)return null;let H={};if(O)H.agent=O;if(P&&G)H.model={providerID:P,modelID:G};if(I)H.variant=I;return H}function u1(W,J){return{agent:W.agent??J.agent,model:W.model??J.model,variant:W.variant??J.variant}}function c1(W){return Boolean(W.agent&&W.model&&W.variant)}async function o1(W,J){if(!W||!J)return null;let j=W;if(typeof j.session?.messages!=="function")return null;let O=[];try{O=F4(await Promise.resolve(j.session.messages({path:{id:J},query:{limit:100}})))}catch{return null}if(O.length===0)return null;let P={};for(let G=O.length-1;G>=0;G--){if(H4(O[G])!=="assistant")continue;let I=n1(O[G]);if(!I)continue;if(P=u1(P,I),c1(P))return P}for(let G=O.length-1;G>=0;G--){let I=n1(O[G]);if(!I)continue;if(P=u1(P,I),c1(P))return P}if(!P.agent&&!P.model&&!P.variant)return null;return P}var D0=[],f4=1,w1=0,r1=new Map;function t1(W,J){if(D0.push({id:f4++,type:"open-dialog",payload:W,sessionId:J}),D0.length>100)D0=D0.slice(D0.length-100)}function s1(W=0,J){let j=Date.now();if(w1=j,J!==void 0)r1.set(J,j);let O=(P)=>J===void 0||P.sessionId===void 0||P.sessionId===J;if(W>0)D0=D0.filter((P)=>{if(P.id>W)return!0;if(J===void 0)return!1;return P.sessionId!==J});return D0.filter((P)=>P.id>W&&O(P))}function a1(W){let J=Date.now();if(W!==void 0){let j=r1.get(W)??0;return j>0&&J-j<3000}return w1>0&&J-w1<3000}import{randomBytes as x4,timingSafeEqual as q4}from"node:crypto";import{unlink as T4}from"node:fs/promises";import{createServer as R4}from"node:http";import{join as S4}from"node:path";function E4(W){return new Promise((J,j)=>{let O=[],P=0;W.on("data",(G)=>{if(P+=G.length,P>1e6){W.destroy(),j(Error("body too large"));return}O.push(G)}),W.on("end",()=>J(Buffer.concat(O).toString("utf8"))),W.on("error",j)})}function v4(W,J){if(!W?.startsWith("Bearer "))return!1;let j=Buffer.from(W.slice(7)),O=Buffer.from(J);return j.length===O.length&&q4(j,O)}async function WW(W){let J=x4(32).toString("hex"),j=R4((G,I)=>{O(G,I)});async function O(G,I){let H=(k,b)=>{I.writeHead(k,{"content-type":"application/json"}),I.end(JSON.stringify(b))};try{let k=G.url??"";if(G.method==="GET"&&k==="/health")return H(200,{ok:!0});if(G.method!=="POST"||!k.startsWith("/rpc/"))return H(404,{error:"not found"});if(!v4(G.headers.authorization,J))return H(401,{error:"unauthorized"});let b=k.slice(5),m=JSON.parse(await E4(G)||"{}");if(b==="pending-notifications"){let E=W.drain(Number(m.lastReceivedId??0),typeof m.sessionId==="string"?m.sessionId:void 0);return H(200,{messages:E})}if(b==="apply"){let E=await W.apply(m);return H(200,E)}return H(404,{error:"unknown method"})}catch(k){H(500,{error:k instanceof Error?k.message:String(k)})}}let P=await new Promise((G,I)=>{j.on("error",I),j.listen(0,"127.0.0.1",()=>{let H=j.address();if(H&&typeof H==="object")G(H.port);else I(Error("no port"))})});j.unref();try{await e1(W.dir,{port:P,token:J,pid:process.pid})}catch(G){throw await new Promise((I)=>j.close(()=>I())),G}return{port:P,token:J,async stop(){await new Promise((G)=>j.close(()=>G())),await T4(S4(W.dir,`port-${process.pid}.json`)).catch(()=>{})}}}function jW(W,J){let j=new Map,O=0,P=0,G=0,I=0,H=0,k=(E)=>{let r=performance.now(),i=W(E);return H+=performance.now()-r,G++,i};return{call:(E)=>{if(!J.enabled())return k(E);let r=j.get(E);if(r!==void 0)return P++,j.delete(E),j.set(E,r),r;let i=k(E),$0=E.length+i.length;if($0>J.maxBytes)return i;j.set(E,i),O+=$0;while(O>J.maxBytes&&j.size>1){let d=j.keys().next().value,j0=j.get(d)??"";j.delete(d),O-=d.length+j0.length,I++}return i},stats:()=>({hits:P,misses:G,evictions:I,entries:j.size,cacheBytes:O,computeMsTotal:H})}}function JW(W){return`${DW}${W.charAt(0).toUpperCase()}${W.slice(1)}`}function HW(W){if(W==="StructuredOutput")return W;return`${W.charAt(0).toLowerCase()}${W.slice(1)}`}var A4=new Set(["callgraph","conflicts","delete","import","inspect","move","navigate","outline","refactor","safety","search","transform","zoom"]);function PW(W){let J=HW(W);if(J.startsWith("aft_"))return J;if(A4.has(J))return`aft_${J}`;return null}function L1(W,J){let j=new Headers;if(W instanceof Request)W.headers.forEach((P,G)=>{j.set(G,P)});let O=J?.headers;if(O){if(O instanceof Headers)O.forEach((P,G)=>{j.set(G,P)});else if(Array.isArray(O))for(let P of O){let[G,I]=P;if(typeof I<"u")j.set(G,String(I))}else for(let[P,G]of Object.entries(O))if(typeof G<"u")j.set(P,String(G))}return j}function W1(W){return W.set("anthropic-beta",v0(W.get("anthropic-beta"),[KW])),W}function k0(W,J,j={}){return UW(W,J,j)}function k4(W){if(W.tools&&Array.isArray(W.tools))W.tools=W.tools.map((J)=>({...J,name:J.name?JW(J.name):J.name}));if(W.messages&&Array.isArray(W.messages))W.messages=W.messages.map((J)=>{if(J.content&&Array.isArray(J.content))J.content=J.content.map((j)=>{if(j.type==="tool_use"&&j.name)return{...j,name:JW(j.name)};return j});return J});return JSON.stringify(MW(W))}function Q1(W){return W.replace(/"name"\s*:\s*"(mcp_)?([^"]+)"/g,(J,j,O)=>{if(j)return`"name": "${PW(O)??HW(O)}"`;let P=PW(O);return P?`"name": "${P}"`:J})}function OW(W,J=!1){if(J)return{ready:Q1(W),pending:""};let j=W.length,O='"name"',P=Math.max(0,W.length-O.length+1);for(let I=P;I<W.length;I++)if(O.startsWith(W.slice(I))){j=Math.min(j,I);break}let G=W.lastIndexOf(O);if(G!==-1){let I=W.slice(G);if(/^"name"\s*(?::\s*(?:"[^"]*)?)?$/.test(I))j=Math.min(j,G)}if(j<W.length)return{ready:Q1(W.slice(0,j)),pending:W.slice(j)};return{ready:Q1(W),pending:""}}function U1(){if(!process.env.ANTHROPIC_BASE_URL?.trim())return!1;let W=process.env.ANTHROPIC_INSECURE?.trim();return W==="1"||W==="true"}function fW(W){let J=W?.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 y4(){return fW(process.env.ANTHROPIC_BASE_URL)}function M1(W,J={}){let j=null;try{if(typeof W==="string"||W instanceof URL)j=new URL(W.toString());else if(W instanceof Request)j=new URL(W.url)}catch{j=null}if(!j)return{input:W,url:null};let O=j.href,P=J.baseURL?fW(J.baseURL):y4();if(P){if(j.protocol=P.protocol,j.host=P.host,J.baseURL)j.pathname=`${P.pathname.replace(/\/$/,"")}${j.pathname}`}if(j.pathname.endsWith("/v1/messages")&&!j.searchParams.has("beta"))j.searchParams.set("beta","true");if(j.href===O)return{input:W,url:j};return{input:W instanceof Request?new Request(j.toString(),W):j,url:j}}function h4(W){let O=W.split(/\n\n+/).filter((P)=>{if(P.includes(_W))return!1;for(let G of IW)if(P.includes(G))return!1;return!0}).join(`
2
2
 
3
- `);for(let V of Wj)W=W.replace(V.match,V.replacement);return W.trim()}var QJ=8388608;function MJ(){return process.env.OPENCODE_ANTHROPIC_AUTH_MEMO!=="0"}var wJ=i1(LJ,{maxBytes:QJ,enabled:MJ});function o0(j){return wJ.call(j)}function g(j){return j!=null&&typeof j==="object"&&!Array.isArray(j)}function UJ(j){let J={type:"text",text:E0};if(j==null)return[J];if(typeof j==="string"){let W=o0(j);if(W===E0)return[J];return[J,{type:"text",text:W}]}if(g(j)){let W=typeof j.type==="string"?j.type:"text",V=typeof j.text==="string"?j.text:"";return[J,{...j,type:W,text:o0(V)}]}if(!Array.isArray(j))return[J];let $=j.map((W)=>{if(typeof W==="string")return{type:"text",text:o0(W)};if(g(W)&&W.type==="text"&&typeof W.text==="string")return{...W,type:"text",text:o0(W.text)};return{type:"text",text:String(W)}});if($[0]?.text===E0)return $;return[J,...$]}var Nj={type:"ephemeral",ttl:"1h"},BJ=20;function FJ(j){if(g(j.cache_control))return j.cache_control;if(g(j.cacheControl))return j.cacheControl;return null}function R0(j,J){if(!g(j))return!1;return delete j.cacheControl,j.cache_control=J?{...Nj}:{type:"ephemeral"},!0}function o1(j){if(!g(j))return;delete j.cache_control,delete j.cacheControl}function CJ(j){if(Array.isArray(j))return j;if(typeof j==="string")return[{type:"text",text:j}];return null}function r0(j,J){if(!g(j))return;let $=FJ(j);if($?.type!=="ephemeral")return;if(J)$.ttl="1h";else delete $.ttl}function r1(j,J){if(Array.isArray(j.system))for(let $ of j.system)r0($,J);else r0(j.system,J);if(!Array.isArray(j.messages))return;for(let $ of j.messages)if(r0($,J),g($)&&Array.isArray($.content))for(let W of $.content)r0(W,J)}function HJ(j,J){if(Array.isArray(j.system))for(let $ of j.system)J($);else J(j.system);if(!Array.isArray(j.messages))return;for(let $ of j.messages)if(J($),g($)&&Array.isArray($.content))for(let W of $.content)J(W)}function _j(j){o1(j),HJ(j,o1)}function xJ(j){_j(j),j.cache_control={...Nj}}function TJ(j){return g(j)&&j.type!=="thinking"&&j.type!=="redacted_thinking"}function e0(j){let J=CJ(j.content);if(!J?.length)return;let $=J.filter(TJ);if(!$.length)return;return{content:J,cacheableBlocks:$}}function qJ(j){if(!g(j))return!1;let J=e0(j);if(!J)return!1;return j.content=J.content,R0(J.cacheableBlocks[0],!0)}function EJ(j){if(!g(j))return!1;let J=e0(j);if(!J||J.cacheableBlocks.length<2)return!1;return j.content=J.content,R0(J.cacheableBlocks[1],!0)}function s0(j){if(!g(j))return!1;let J=e0(j);if(!J)return!1;let $=J.cacheableBlocks[J.cacheableBlocks.length-1];return j.content=J.content,R0($,!0)}function RJ(j){if(!g(j))return!1;return(e0(j)?.cacheableBlocks.length??0)>1}function vJ(j){if(!g(j))return 0;let J=j.content;if(Array.isArray(J))return J.length;if(J==null)return 0;return 1}function SJ(j){let J=[],$=0;return j.forEach((W,V)=>{let z=vJ(W);if(g(W)&&W.role==="user"&&z>0)J.push({index:V,blockPosition:$+z-1});$+=z}),J}function AJ(j){let J=SJ(j),$=[...J].reverse().find((M)=>M.index>1);if(!$)return{latest:void 0,bridge:void 0};let W=[...J].reverse().find((M)=>M.index<$.index),V=W?$.blockPosition-W.blockPosition+1:0,z=W&&W.index>1&&V>BJ?W:void 0;return{latest:$,bridge:z}}function s1(j){if(Array.isArray(j.system)){let J=j.system.findIndex((V)=>g(V)&&V.text===E0),$=j.system.slice(J>=0?J+1:0).filter(g),W=$[$.length-1];R0(W,!0)}else R0(j.system,!0)}function fJ(j){if(_j(j),!Array.isArray(j.messages)){s1(j);return}let{latest:J,bridge:$}=AJ(j.messages);if(!$)s1(j);if(RJ(j.messages[0]))qJ(j.messages[0]),EJ(j.messages[0]);else s0(j.messages[0]),s0(j.messages[1]);if($)s0(j.messages[$.index]);if(J)s0(j.messages[J.index])}function kJ(j){if(!Array.isArray(j.messages))return 0;let J=0;return j.messages=j.messages.filter(($)=>{if(!g($)||!Array.isArray($.content))return!0;if($.role!=="assistant")return!0;let W=$.content.filter((V)=>{if(!g(V)||V.type!=="thinking")return!0;if(!zj(V.signature))return!0;return J+=1,!1});if(W.length===$.content.length)return!0;return $.content=W,W.length>0}),J}function yJ(j){if(!Oj(j.model))return null;let J=Object.hasOwn(j,"thinking");return j.thinking={...Pj},{replacedExisting:J}}function bJ(j,J){if(!J.enabled){r1(j,!1),delete j.cache_control,delete j.cacheControl;return}if(J.mode==="automatic"){xJ(j);return}if(J.mode==="hybrid"){fJ(j);return}r1(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(!g(J)||J.role!=="assistant")break;j.messages.pop()}}function v(){return performance.now()}function J0(j){return Math.round(j*10)/10}function a1(j){let J=0,$=0,W=0,V=Array.isArray(j.messages)?j.messages:[];J=V.length;for(let z of V){if(!z||typeof z!=="object")continue;let M=z.content;if(!Array.isArray(M))continue;$+=M.length;for(let S of M)if(S&&typeof S==="object"&&S.type==="tool_use")W++}return{messageCount:J,contentBlockCount:$,toolDefinitionCount:Array.isArray(j.tools)?j.tools.length:0,toolUseCount:W,systemBlockCount:Array.isArray(j.system)?j.system.length:0}}async function F1(j,J={}){try{let $=v(),W=JSON.parse(j);J.perf?.("parse",{ms:J0(v()-$),inputBytes:j.length,...a1(W)});let V=v(),z=Array.isArray(W.messages)?W.messages.length:void 0;hJ(W);let M=Array.isArray(W.messages)?W.messages.length:void 0;J.perf?.("strip_trailing_assistant",{ms:J0(v()-V),removedMessages:typeof z==="number"&&typeof M==="number"?z-M:void 0});let S=v(),r=kJ(W),u=yJ(W);J.perf?.("model_normalize",{ms:J0(v()-S),model:typeof W.model==="string"?W.model:void 0,fableMythosThinkingDisplay:u?"summarized":void 0,replacedFableMythosThinking:u?.replacedExisting??!1,removedNonAnthropicThinking:r,hasOutputConfig:Object.hasOwn(W,"output_config")});let j0=v(),y=Array.isArray(W.messages)&&W.messages.some((H0)=>H0.role==="user")?Gj(W.messages,void 0,$j):null;J.perf?.("billing_header",{ms:J0(v()-j0),hasBillingHeader:Boolean(y)});let f=v();if(W.system=UJ(W.system),J.perf?.("system_identity",{ms:J0(v()-f),systemBlockCount:Array.isArray(W.system)?W.system.length:0}),y&&Array.isArray(W.system))W.system.unshift({type:"text",text:y});let n=v();if(bJ(W,{enabled:J.cache1hEnabled??!1,mode:J.cache1hMode??"explicit"}),J.perf?.("cache_strategy",{ms:J0(v()-n),enabled:J.cache1hEnabled??!1,mode:J.cache1hMode??"explicit"}),J.fastModeEnabled&&S0(W.model))W.speed="fast";else if(W.speed==="fast")delete W.speed;let a=v();if(J.identity)Zj(W,J.identity);J.perf?.("metadata",{ms:J0(v()-a),hasAccountUuid:Boolean(J.identity?.accountUuid)});let d=v(),W0=NJ(W);J.perf?.("prefix_tools_stringify",{ms:J0(v()-d),outputBytesBeforeSign:W0.length,...a1(W)});let C0=v(),$0=await Xj(W0);return J.perf?.("cch_sign",{ms:J0(v()-C0),outputBytes:$0.length}),$0}catch{return j}}var gJ=new TextEncoder;function mJ(){return{pending:"",events:0,parseErrors:0,eventCounts:{},typeCounts:{},deltaTypeCounts:{},contentBlockTypeCounts:{},textDeltaBytes:0,thinkingDeltaBytes:0,inputJsonDeltaBytes:0,signatureDeltaBytes:0,redactedThinkingBytes:0}}function a0(j,J){if(!J)return;j[J]=(j[J]??0)+1}function z0(j){return gJ.encode(j).byteLength}function w0(j){return j&&typeof j==="object"&&!Array.isArray(j)?j:void 0}function G0(j,J){let $=j?.[J];return typeof $==="string"?$:void 0}function pJ(j,J){let $=j?.[J];return typeof $==="number"?$:void 0}function lJ(j){if(!j.trim())return null;let J,$=[];for(let y of j.split(/\r?\n/)){if(y.startsWith("event:")){J=y.slice(6).trim();continue}if(y.startsWith("data:")){let f=y.slice(5);$.push(f.startsWith(" ")?f.slice(1):f)}}let W=$.join(`
4
- `),V={event:J,rawBytes:z0(j),dataBytes:z0(W)};if(!W||W==="[DONE]")return V.type=W==="[DONE]"?"done":void 0,V.event??=V.type,V;let z;try{z=JSON.parse(W)}catch{return V}let M=w0(z),S=w0(M?.delta),r=w0(M?.content_block),u=w0(M?.message),j0=w0(M?.usage)??w0(u?.usage);if(V.type=G0(M,"type"),V.event??=V.type,V.index=pJ(M,"index"),V.contentBlockType=G0(r,"type"),V.deltaType=G0(S,"type"),V.stopReason=G0(M,"stop_reason"),V.deltaType==="text_delta")V.textDeltaBytes=z0(G0(S,"text")??"");if(V.deltaType==="thinking_delta")V.thinkingDeltaBytes=z0(G0(S,"thinking")??"");if(V.deltaType==="input_json_delta")V.inputJsonDeltaBytes=z0(G0(S,"partial_json")??"");if(V.deltaType==="signature_delta")V.signatureDeltaBytes=z0(G0(S,"signature")??"");if(V.contentBlockType==="redacted_thinking")V.redactedThinkingBytes=z0(G0(r,"data")??"");if(j0)V.stopReason??=G0(u,"stop_reason");return V}function dJ(j){let J=j.indexOf(`
3
+ `);for(let P of zW)O=O.replace(P.match,P.replacement);return O.trim()}var b4=8388608;function g4(){return process.env.OPENCODE_ANTHROPIC_AUTH_MEMO!=="0"}var m4=jW(h4,{maxBytes:b4,enabled:g4});function t0(W){return m4.call(W)}function l(W){return W!=null&&typeof W==="object"&&!Array.isArray(W)}function p4(W){let J={type:"text",text:S0};if(W==null)return[J];if(typeof W==="string"){let O=t0(W);if(O===S0)return[J];return[J,{type:"text",text:O}]}if(l(W)){let O=typeof W.type==="string"?W.type:"text",P=typeof W.text==="string"?W.text:"";return[J,{...W,type:O,text:t0(P)}]}if(!Array.isArray(W))return[J];let j=W.map((O)=>{if(typeof O==="string")return{type:"text",text:t0(O)};if(l(O)&&O.type==="text"&&typeof O.text==="string")return{...O,type:"text",text:t0(O.text)};return{type:"text",text:String(O)}});if(j[0]?.text===S0)return j;return[J,...j]}var xW={type:"ephemeral",ttl:"1h"},i4=20;function l4(W){if(l(W.cache_control))return W.cache_control;if(l(W.cacheControl))return W.cacheControl;return null}function E0(W,J){if(!l(W))return!1;return delete W.cacheControl,W.cache_control=J?{...xW}:{type:"ephemeral"},!0}function $W(W){if(!l(W))return;delete W.cache_control,delete W.cacheControl}function d4(W){if(Array.isArray(W))return W;if(typeof W==="string")return[{type:"text",text:W}];return null}function s0(W,J){if(!l(W))return;let j=l4(W);if(j?.type!=="ephemeral")return;if(J)j.ttl="1h";else delete j.ttl}function NW(W,J){if(Array.isArray(W.system))for(let j of W.system)s0(j,J);else s0(W.system,J);if(!Array.isArray(W.messages))return;for(let j of W.messages)if(s0(j,J),l(j)&&Array.isArray(j.content))for(let O of j.content)s0(O,J)}function n4(W,J){if(Array.isArray(W.system))for(let j of W.system)J(j);else J(W.system);if(!Array.isArray(W.messages))return;for(let j of W.messages)if(J(j),l(j)&&Array.isArray(j.content))for(let O of j.content)J(O)}function qW(W){$W(W),n4(W,$W)}function u4(W){qW(W),W.cache_control={...xW}}function c4(W){return l(W)&&W.type!=="thinking"&&W.type!=="redacted_thinking"}function j1(W){let J=d4(W.content);if(!J?.length)return;let j=J.filter(c4);if(!j.length)return;return{content:J,cacheableBlocks:j}}function o4(W){if(!l(W))return!1;let J=j1(W);if(!J)return!1;return W.content=J.content,E0(J.cacheableBlocks[0],!0)}function r4(W){if(!l(W))return!1;let J=j1(W);if(!J||J.cacheableBlocks.length<2)return!1;return W.content=J.content,E0(J.cacheableBlocks[1],!0)}function a0(W){if(!l(W))return!1;let J=j1(W);if(!J)return!1;let j=J.cacheableBlocks[J.cacheableBlocks.length-1];return W.content=J.content,E0(j,!0)}function t4(W){if(!l(W))return!1;return(j1(W)?.cacheableBlocks.length??0)>1}function s4(W){if(!l(W))return 0;let J=W.content;if(Array.isArray(J))return J.length;if(J==null)return 0;return 1}function a4(W){let J=[],j=0;return W.forEach((O,P)=>{let G=s4(O);if(l(O)&&O.role==="user"&&G>0)J.push({index:P,blockPosition:j+G-1});j+=G}),J}function e4(W){let J=a4(W),j=[...J].reverse().find((I)=>I.index>1);if(!j)return{latest:void 0,bridge:void 0};let O=[...J].reverse().find((I)=>I.index<j.index),P=O?j.blockPosition-O.blockPosition+1:0,G=O&&O.index>1&&P>i4?O:void 0;return{latest:j,bridge:G}}function GW(W){if(Array.isArray(W.system)){let J=W.system.findIndex((P)=>l(P)&&P.text===S0),j=W.system.slice(J>=0?J+1:0).filter(l),O=j[j.length-1];E0(O,!0)}else E0(W.system,!0)}function Wj(W){if(qW(W),!Array.isArray(W.messages)){GW(W);return}let{latest:J,bridge:j}=e4(W.messages);if(!j)GW(W);if(t4(W.messages[0]))o4(W.messages[0]),r4(W.messages[0]);else a0(W.messages[0]),a0(W.messages[1]);if(j)a0(W.messages[j.index]);if(J)a0(W.messages[J.index])}function jj(W){if(!Array.isArray(W.messages))return 0;let J=0;return W.messages=W.messages.filter((j)=>{if(!l(j)||!Array.isArray(j.content))return!0;if(j.role!=="assistant")return!0;let O=j.content.filter((P)=>{if(!l(P)||P.type!=="thinking")return!0;if(!FW(P.signature))return!0;return J+=1,!1});if(O.length===j.content.length)return!0;return j.content=O,O.length>0}),J}function Jj(W){if(!CW(W.model))return null;let J=Object.hasOwn(W,"thinking");return W.thinking={...BW},{replacedExisting:J}}function Pj(W,J){if(!J.enabled){NW(W,!1),delete W.cache_control,delete W.cacheControl;return}if(J.mode==="automatic"){u4(W);return}if(J.mode==="hybrid"){Wj(W);return}NW(W,!0),delete W.cacheControl}function Oj(W){if(!Array.isArray(W.messages))return;while(W.messages.length){let J=W.messages[W.messages.length-1];if(!l(J)||J.role!=="assistant")break;W.messages.pop()}}function v(){return performance.now()}function P0(W){return Math.round(W*10)/10}function VW(W){let J=0,j=0,O=0,P=Array.isArray(W.messages)?W.messages:[];J=P.length;for(let G of P){if(!G||typeof G!=="object")continue;let I=G.content;if(!Array.isArray(I))continue;j+=I.length;for(let H of I)if(H&&typeof H==="object"&&H.type==="tool_use")O++}return{messageCount:J,contentBlockCount:j,toolDefinitionCount:Array.isArray(W.tools)?W.tools.length:0,toolUseCount:O,systemBlockCount:Array.isArray(W.system)?W.system.length:0}}async function B1(W,J={}){try{let j=v(),O=JSON.parse(W);J.perf?.("parse",{ms:P0(v()-j),inputBytes:W.length,...VW(O)});let P=v(),G=Array.isArray(O.messages)?O.messages.length:void 0;Oj(O);let I=Array.isArray(O.messages)?O.messages.length:void 0;J.perf?.("strip_trailing_assistant",{ms:P0(v()-P),removedMessages:typeof G==="number"&&typeof I==="number"?G-I:void 0});let H=v(),k=jj(O),b=Jj(O);J.perf?.("model_normalize",{ms:P0(v()-H),model:typeof O.model==="string"?O.model:void 0,fableMythosThinkingDisplay:b?"summarized":void 0,replacedFableMythosThinking:b?.replacedExisting??!1,removedNonAnthropicThinking:k,hasOutputConfig:Object.hasOwn(O,"output_config")});let m=v(),E=Array.isArray(O.messages)&&O.messages.some((J0)=>J0.role==="user")?QW(O.messages,void 0,YW):null;J.perf?.("billing_header",{ms:P0(v()-m),hasBillingHeader:Boolean(E)});let r=v();if(O.system=p4(O.system),J.perf?.("system_identity",{ms:P0(v()-r),systemBlockCount:Array.isArray(O.system)?O.system.length:0}),E&&Array.isArray(O.system))O.system.unshift({type:"text",text:E});let i=v();if(Pj(O,{enabled:J.cache1hEnabled??!1,mode:J.cache1hMode??"explicit"}),J.perf?.("cache_strategy",{ms:P0(v()-i),enabled:J.cache1hEnabled??!1,mode:J.cache1hMode??"explicit"}),J.fastModeEnabled&&A0(O.model))O.speed="fast";else if(O.speed==="fast")delete O.speed;let $0=v();if(J.identity)LW(O,J.identity);J.perf?.("metadata",{ms:P0(v()-$0),hasAccountUuid:Boolean(J.identity?.accountUuid)});let d=v(),j0=k4(O);J.perf?.("prefix_tools_stringify",{ms:P0(v()-d),outputBytesBeforeSign:j0.length,...VW(O)});let G0=v(),z0=await wW(j0);return J.perf?.("cch_sign",{ms:P0(v()-G0),outputBytes:z0.length}),z0}catch{return W}}var $j=new TextEncoder;function Nj(){return{pending:"",events:0,parseErrors:0,eventCounts:{},typeCounts:{},deltaTypeCounts:{},contentBlockTypeCounts:{},textDeltaBytes:0,thinkingDeltaBytes:0,inputJsonDeltaBytes:0,signatureDeltaBytes:0,redactedThinkingBytes:0}}function e0(W,J){if(!J)return;W[J]=(W[J]??0)+1}function I0(W){return $j.encode(W).byteLength}function K0(W){return W&&typeof W==="object"&&!Array.isArray(W)?W:void 0}function s(W,J){let j=W?.[J];return typeof j==="string"?j:void 0}function Gj(W,J){let j=W?.[J];return typeof j==="number"?j:void 0}function Vj(W){if(!W.trim())return null;let J,j=[];for(let E of W.split(/\r?\n/)){if(E.startsWith("event:")){J=E.slice(6).trim();continue}if(E.startsWith("data:")){let r=E.slice(5);j.push(r.startsWith(" ")?r.slice(1):r)}}let O=j.join(`
4
+ `),P={event:J,rawBytes:I0(W),dataBytes:I0(O)};if(!O||O==="[DONE]")return P.type=O==="[DONE]"?"done":void 0,P.event??=P.type,P;let G;try{G=JSON.parse(O)}catch{return P}let I=K0(G),H=K0(I?.delta),k=K0(I?.content_block),b=K0(I?.message),m=K0(I?.usage)??K0(b?.usage);if(P.type=s(I,"type"),P.event??=P.type,P.index=Gj(I,"index"),P.contentBlockType=s(k,"type"),P.deltaType=s(H,"type"),P.stopReason=s(I,"stop_reason"),P.deltaType==="text_delta")P.textDeltaBytes=I0(s(H,"text")??"");if(P.deltaType==="thinking_delta")P.thinkingDeltaBytes=I0(s(H,"thinking")??"");if(P.deltaType==="input_json_delta")P.inputJsonDeltaBytes=I0(s(H,"partial_json")??"");if(P.deltaType==="signature_delta")P.signatureDeltaBytes=I0(s(H,"signature")??"");if(P.contentBlockType==="redacted_thinking")P.redactedThinkingBytes=I0(s(k,"data")??"");if(m)P.stopReason??=s(b,"stop_reason");return P}function TW(W){let J=W.indexOf(`
5
5
 
6
- `),$=j.indexOf(`\r
6
+ `),j=W.indexOf(`\r
7
7
  \r
8
- `);if(J===-1)return $===-1?null:{index:$,length:4};if($===-1||J<$)return{index:J,length:2};return{index:$,length:4}}function t1(j,J){if(!J)return;j.pending+=J;while(!0){let $=dJ(j.pending);if(!$)break;let W=j.pending.slice(0,$.index);j.pending=j.pending.slice($.index+$.length);let V=lJ(W);if(!V)continue;if(j.events++,a0(j.eventCounts,V.event??"unknown"),a0(j.typeCounts,V.type),a0(j.deltaTypeCounts,V.deltaType),a0(j.contentBlockTypeCounts,V.contentBlockType),j.textDeltaBytes+=V.textDeltaBytes??0,j.thinkingDeltaBytes+=V.thinkingDeltaBytes??0,j.inputJsonDeltaBytes+=V.inputJsonDeltaBytes??0,j.signatureDeltaBytes+=V.signatureDeltaBytes??0,j.redactedThinkingBytes+=V.redactedThinkingBytes??0,j.last=V,V.dataBytes>0&&!V.type&&!V.event)j.parseErrors++}}function iJ(j){return{sseEvents:j.events,ssePendingChars:j.pending.length,sseParseErrors:j.parseErrors,sseEventCounts:{...j.eventCounts},sseTypeCounts:{...j.typeCounts},sseDeltaTypeCounts:{...j.deltaTypeCounts},sseContentBlockTypeCounts:{...j.contentBlockTypeCounts},sseTextDeltaBytes:j.textDeltaBytes,sseThinkingDeltaBytes:j.thinkingDeltaBytes,sseInputJsonDeltaBytes:j.inputJsonDeltaBytes,sseSignatureDeltaBytes:j.signatureDeltaBytes,sseRedactedThinkingBytes:j.redactedThinkingBytes,sseLastEvent:j.last?{...j.last}:void 0}}function f0(j,J={}){if(!j.body)return j;let $=j.body.getReader(),W=new TextDecoder,V=new TextEncoder,z="",M=0,S=0,r=0,u=0,j0=0,y=!1,f=!1,n=v(),a=v(),d=J.perf?mJ():void 0,W0=()=>{if(f)return;f=!0,$.releaseLock()},C0=(s={})=>({chunks:M,pulls:S,inputBytes:r,outputBytes:u,pendingChars:z.length,rewriteMs:J0(j0),totalMs:J0(v()-a),...d?iJ(d):{},...s}),$0=(s,x0={})=>{J.perf?.(s,C0(x0))};J.perf?.("stream_tool_prefix_wrapper_created",{status:j.status,hasBody:!0});let H0=new ReadableStream({async pull(s){if(S++,!y)y=!0,$0("stream_tool_prefix_first_pull");let x0=v();try{let{done:K0,value:T0}=await $.read(),l0=J0(v()-x0);if(K0){let G=W.decode();if(d)t1(d,G);let D=v(),w=n1(`${z}${G}`,!0);if(j0+=v()-D,w.ready){let P=V.encode(w.ready);u+=P.byteLength,s.enqueue(P)}$0("stream_tool_prefix_rewrite",{readMs:l0}),W0(),s.close();return}M++,r+=T0.byteLength;let d0=W.decode(T0,{stream:!0});if(d)t1(d,d0);let N0=z+d0,i0=v(),q0=n1(N0);if(j0+=v()-i0,z=q0.pending,q0.ready){let G=V.encode(q0.ready);u+=G.byteLength,s.enqueue(G)}let X=v();if(M===1||M%25===0||X-n>5000)n=X,$0("stream_tool_prefix_progress",{readMs:l0,lastChunkBytes:T0.byteLength})}catch(K0){throw $0("stream_tool_prefix_error",{error:K0 instanceof Error?K0.message:String(K0)}),W0(),K0}},async cancel(s){$0("stream_tool_prefix_cancel",{reason:s instanceof Error?s.message:String(s)});try{await $.cancel(s)}finally{W0()}}});return new Response(H0,{status:j.status,statusText:j.statusText,headers:j.headers})}var cJ="__OPENCODE_ANTHROPIC_AUTH_COMMAND_HANDLED__",nJ=60000,oJ=60000,rJ=5000,Lj=200,ZJ=240,sJ=ZJ,aJ=1,Qj=!1;function L1(){return process.env.OPENCODE_ANTHROPIC_AUTH_PERF==="1"}function F(){return performance.now()}function A(j){return Math.round(j*10)/10}function Mj(j){return Math.floor(Math.random()*Math.max(0,j))}function j1(j){if(typeof j==="string")return j;if(j instanceof URL)return j.toString();return j.url}function J1(j,J){return J?.method??(j instanceof Request?j.method:void 0)}function wj(j){return j instanceof Error?j.message:String(j)}function tJ(){if(Qj||!1||!L1())return;Qj=!0;let j=100,J=250,$=F()+j;setInterval(()=>{let W=F(),V=W-$;if($=W+j,V<J)return;q("[perf] opencode event_loop_lag",{lagMs:A(V),thresholdMs:J})},j).unref?.()}function eJ(j){let J=F(),$={requestId:String(aJ++),start:J,last:J,mark(W,V){let z=F();if(L1())q("[perf] opencode request stage",{requestId:$.requestId,stage:W,deltaMs:A(z-$.last),totalMs:A(z-$.start),...V});$.last=z},done(W,V){let z=F();if(L1())q("[perf] opencode request done",{requestId:$.requestId,stage:W,deltaMs:A(z-$.last),totalMs:A(z-$.start),...V});$.last=z}};if(L1())q("[perf] opencode request start",{requestId:$.requestId,...j});return $}async function D0(j,J,$){let W=j.client.session,V=await d1(j.client,J),z={path:{id:J},body:{noReply:!0,parts:[{type:"text",text:$,ignored:!0}]}};if(V?.agent)z.body.agent=V.agent;if(V?.model)z.body.model=V.model;if(V?.variant)z.body.variant=V.variant;if(typeof W?.promptAsync==="function"){await W.promptAsync(z);return}if(typeof W?.prompt==="function"){await Promise.resolve(W.prompt(z));return}throw Error("OpenCode session prompt API is unavailable for ignored replies.")}function I0(){throw Error(cJ)}function j3(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 J3(j){if(j.some((J)=>J.includes("<use_parallel_tool_calls>")))return!1;return j.push(Uj),!0}var $3={input:0,output:0,cache:{read:0,write:0}};function V3(j){let J=j["claude-opus-4-8"]??j["claude-opus-4-5"]??Object.values(j)[0];if(!J)return j;return{...j,...Object.fromEntries(Object.values(ej).map(($)=>[$.id,{...J,id:$.id,name:$.name,api:J.api?{...J.api,id:$.id}:void 0,cost:{input:p0.input,output:p0.output,cache:{read:p0.cacheRead,write:p0.cacheWrite5m}},limit:{...J.limit??{},context:sj,output:aj},capabilities:{...J.capabilities??{},reasoning:!0,attachment:!0,toolcall:!0},release_date:tj}]))}}function W3(j){return Object.fromEntries(Object.entries(j).map(([J,$])=>[J,{...$,cost:$3}]))}var _3=async(j)=>{tJ();let{client:J}=j,$=Cj(),W=await h($),V=new jJ({storage:W,onMainQuotaFetched:async(X,G,D,w)=>{try{let P=await h($)??{version:1,accounts:[]},E=fj(P);if(E&&E.checkedAt>=w&&hj(E.quota,P,E.checkedAt)>Date.now()){V.seedMainFromStorage(P);return}P.quota=P.quota??{},P.quota.mainQuota=X,P.quota.mainQuotaCheckedAt=G,P.quota.mainQuotaToken=D,P.quota.mainLastQuotaApiError=void 0,await y0(P,$,{mainQuota:!0})}catch(P){q("[quota] failed to persist main quota",{error:P instanceof Error?P.message:String(P)})}},onApiError:async(X)=>{try{let G=await h($)??{version:1,accounts:[]};G.quota=G.quota??{},G.quota.mainLastQuotaApiError=X,await y0(G,$,{mainQuota:!0})}catch(G){q("[quota] failed to persist backoff state",{error:G instanceof Error?G.message:String(G)})}}}),z=new gj({quotaManager:V,onFallbackStorageChanged:()=>{j0()}});z.startBackgroundRefresh();let M=null,S=new cj({loadStorage:()=>h($),prepareHeaders:async(X,G)=>{if(!f)return X;let D=await f();if(D.type!=="oauth")return X;if(!D.access||D.expires&&D.expires<Date.now()){if(!M)return X;D.access=await M()}if(!D.access)return X;try{let w=JSON.parse(G.bodyText),P=await S1(D.access,typeof w.model==="string"?w.model:void 0);if(X.delete("anthropic-beta"),A0(X,D.access,{body:w,identity:P}),X.set("anthropic-beta",v0(X.get("anthropic-beta"),[pj])),w.speed==="fast")t0(X)}catch{A0(X,D.access)}return X},log:q});g0({enabled:$1(W),mode:V1(W)}),P1(q1(W)),D1(E1(W));let r={activeId:"main",route:"main"};function u(X,G){r={activeId:G.activeId,route:G.route},V.updateStorage(X),V.seedMainFromStorage(X,G.mainAccessToken),V.seedFallbacksFromAccounts((X?.accounts??[]).filter(e));let D=V.getMain(G.mainAccessToken),w=V.getLastApiError(),P=X?.refresh?.mainLastRefreshError,E={main:{quota:D?.quota??null,quotaBackedOff:V.isBackedOff(),quotaBackoffUntil:w?.nextRetryAt,refreshBackedOff:P?U0(P,G.mainRefreshToken,Date.now()):!1,refreshBackoffUntil:P?.nextRetryAt},fallbacks:(X?.accounts??[]).filter((R)=>R.enabled!==!1&&e(R)).map((R)=>({id:R.id,label:R.label,quota:R.access?V.getFallback(R.id,R.access)?.quota??null:null,enabled:R.enabled!==!1})),activeId:G.activeId,route:G.route,relay:(()=>{let R=y1(X);return R?{enabled:!0,transport:R.transport??"http"}:null})(),fastMode:z1(),cacheKeep:{enabled:A1(X),window:X?.cacheKeep?.startHour!=null&&X?.cacheKeep?.endHour!=null?`${X.cacheKeep.startHour}-${X.cacheKeep.endHour}`:void 0,trackedSessions:S.trackedCount()},lastUpdated:Date.now()};GJ(E).catch((R)=>q("[sidebar] state write failed",{error:R instanceof Error?R.message:String(R)}))}async function j0(){let X=await h($),G,D;if(f)try{let w=await f();G=w.access,D=w.refresh}catch{}u(X,{activeId:r.activeId,route:r.route,mainAccessToken:G,mainRefreshToken:D})}function y(X,G){if(!G)return;if(X?.quota?.enabled!==!0)return;if(V.getMain(G))return;if(n)return;n=!0,V.refreshMain(G).then(()=>j0()).catch(()=>{}).finally(()=>{n=!1})}let f=null,n=!1,a=null,d=0;function W0(X){let G=X?.refresh?.refreshBeforeExpiryMinutes??sJ;return Math.max(ZJ,G)*60000}function C0(X){return X?.refresh?.enabled!==!1}async function $0(X){if(!X)return;let G=await h($),D=G?.refresh?.mainLastRefreshError;if(!G?.refresh||!D?.tokenHash)return;let w=W1(X);if(D.tokenHash===w)return;if(D.nextRetryAt&&D.nextRetryAt>Date.now()){q("[refresh] opencode main oauth keeping backoff despite token rotation",{nextRetryAt:D.nextRetryAt,retryCount:D.retryCount,remainingMs:D.nextRetryAt-Date.now()});return}G.refresh.mainLastRefreshError=void 0,await y0(G,$,{mainRefresh:!0}),q("[refresh] opencode main oauth cleared stale backoff after token rotation",{previousCheckedAt:D.checkedAt,previousNextRetryAt:D.nextRetryAt,previousRetryCount:D.retryCount})}async function H0(){let X=[];if(f)try{let P=await f();if(P.type==="oauth"&&P.access){let E=await V.refreshMain(P.access);X.push({name:"OpenCode anthropic",role:"main",quota:E})}else if(P.type==="oauth")X.push({name:"OpenCode anthropic",role:"main",error:"missing access token; send a request first or reconnect auth"})}catch(P){let E=P instanceof Error?P.message:String(P);X.push({name:"OpenCode anthropic",role:"main",error:E.includes("429")?"Usage API rate limited — try again in a moment":E})}let{storage:G,errors:D}=await z.refreshQuotaForAllAccounts({force:!0}),w=new Map(D.map((P)=>[P.accountId,P.message]));if(X.push(...JJ(G,w)),!f)X.unshift({name:"OpenCode anthropic",role:"main",error:"auth loader has not run yet; send a request first"});return $J({accounts:X,refreshedAt:Date.now()})}async function s(X){let G=mj(X);if(G.type==="enable"||G.type==="disable"){let E=G.type==="enable",R=await xj(E),o=V1(R);return g0({enabled:E,mode:o}),Z1({argumentsText:X,enabled:E,mode:o})}if(G.type==="mode"){let E=await Tj(G.mode),R=$1(E);return g0({enabled:R,mode:G.mode}),Z1({argumentsText:X,enabled:R,mode:G.mode})}let D=await h($),w=$1(D),P=V1(D);return g0({enabled:w,mode:P}),Z1({argumentsText:X,enabled:w,mode:P})}async function x0(X){let G=lj(X),D=await h($);if(G.type==="window")D=await Rj(G.startHour,G.endHour);else if(G.type==="disable")D=await vj(!1);let w=dj(D),P=S.stats(w);return uj({argumentsText:X,enabled:ij(D),window:w,hybridActive:A1(D),trackedSessions:P.trackedSessions,nextPrewarmAt:P.nextPrewarmAt})}async function K0(X){let G=nj(X);if(G.type==="enable"||G.type==="disable"){let P=G.type==="enable";return await qj(P),P1(P),f1({argumentsText:X,enabled:P})}let D=await h($),w=q1(D);return P1(w),f1({argumentsText:X,enabled:w})}async function T0(X){let G=oj(X);if(G.type==="enable"||G.type==="disable"){let P=G.type==="enable";return await Ej(P),D1(P),k1({argumentsText:X,enabled:P})}let D=await h($),w=E1(D);return D1(w),k1({argumentsText:X,enabled:w})}async function l0(X){let G=XJ(X);if(G.type==="mode")return await WJ(G.mode),h1({argumentsText:X,mode:G.mode});let D=await h();return h1({argumentsText:X,mode:b1(D)})}function d0(X,G=10){let D=Math.max(0,Math.min(Math.round(X/100*G),G));return"█".repeat(D)+"░".repeat(G-D)}function N0(X,G){return`${X} ${d0(G)} ${String(Math.round(G)).padStart(3)}%`}function i0(X){if(!X)return"";let G=new Date(X).getTime();if(Number.isNaN(G))return"";let D=G-Date.now();if(D<=0)return"resets now";let w=Math.floor(D/60000);if(w<1)return"resets <1m";if(w<60)return`resets ${w}m`;let P=Math.floor(w/60),E=w%60;return E>0?`resets ${P}h${E}m`:`resets ${P}h`}function q0(X,G,D){let w=[],P=0;if(X){let{five_hour:o,seven_day:V0}=X;if(o||V0){let Z0=D==="main"?"active":"idle",P0=i0(o?.resetsAt),_0=[`main · ${Z0}${P0?` (${P0})`:""}`];if(o)_0.push(N0("5h",o.usedPercent)),P=Math.max(P,o.usedPercent);if(V0)_0.push(N0("7d",V0.usedPercent)),P=Math.max(P,V0.usedPercent);w.push(_0.join(`
9
- `))}}if(G?.length)for(let o of G){let V0=o.quota;if(!V0)continue;let{five_hour:Y0,seven_day:Z0}=V0;if(!Y0&&!Z0)continue;let P0=o.label||"alt",u0=D===o.id?"active":"idle",L0=i0(Y0?.resetsAt),O0=[`${P0} · ${u0}${L0?` (${L0})`:""}`];if(Y0)O0.push(N0("5h",Y0.usedPercent)),P=Math.max(P,Y0.usedPercent);if(Z0)O0.push(N0("7d",Z0.usedPercent)),P=Math.max(P,Z0.usedPercent);w.push(O0.join(`
10
- `))}if(!w.length)return;let E=w.join(`
8
+ `);if(J===-1)return j===-1?null:{index:j,length:4};if(j===-1||J<j)return{index:J,length:2};return{index:j,length:4}}function XW(W,J){if(!J)return;W.pending+=J;while(!0){let j=TW(W.pending);if(!j)break;let O=W.pending.slice(0,j.index);W.pending=W.pending.slice(j.index+j.length);let P=Vj(O);if(!P)continue;if(W.events++,e0(W.eventCounts,P.event??"unknown"),e0(W.typeCounts,P.type),e0(W.deltaTypeCounts,P.deltaType),e0(W.contentBlockTypeCounts,P.contentBlockType),W.textDeltaBytes+=P.textDeltaBytes??0,W.thinkingDeltaBytes+=P.thinkingDeltaBytes??0,W.inputJsonDeltaBytes+=P.inputJsonDeltaBytes??0,W.signatureDeltaBytes+=P.signatureDeltaBytes??0,W.redactedThinkingBytes+=P.redactedThinkingBytes??0,W.last=P,P.dataBytes>0&&!P.type&&!P.event)W.parseErrors++}}function Xj(){return{pending:""}}function Zj(W,J){let j=W?.toLowerCase(),O=J.toLowerCase();return j==="api_error"||j==="overloaded_error"||j==="server_error"||j==="internal_server_error"||O.includes("internal server error")||O.includes("server overloaded")}function Dj(W,J){let j=W?`${W}: ${J}`:J,O=Error(`Anthropic stream error: ${j}`);if(O.code="ECONNRESET",O.syscall="anthropic-sse",W)O.providerErrorType=W;return O}function Kj(W){if(!W.includes("error"))return null;let J,j=[];for(let b of W.split(/\r?\n/)){if(b.startsWith("event:")){J=b.slice(6).trim();continue}if(b.startsWith("data:")){let m=b.slice(5);j.push(m.startsWith(" ")?m.slice(1):m)}}let O=j.join(`
9
+ `);if(!O||O==="[DONE]")return null;let P;try{P=JSON.parse(O)}catch{return null}let G=K0(P);if(J!=="error"&&s(G,"type")!=="error")return null;let I=K0(G?.error),H=s(I,"type")??s(I,"code")??void 0,k=s(I,"message")??s(G,"message")??H??"Anthropic stream error";if(!Zj(H,k))return null;return Dj(H,k)}function ZW(W,J){if(!J)return null;W.pending+=J;while(!0){let j=TW(W.pending);if(!j)break;let O=W.pending.slice(0,j.index);W.pending=W.pending.slice(j.index+j.length);let P=Kj(O);if(P)return P}return null}function _j(W){return{sseEvents:W.events,ssePendingChars:W.pending.length,sseParseErrors:W.parseErrors,sseEventCounts:{...W.eventCounts},sseTypeCounts:{...W.typeCounts},sseDeltaTypeCounts:{...W.deltaTypeCounts},sseContentBlockTypeCounts:{...W.contentBlockTypeCounts},sseTextDeltaBytes:W.textDeltaBytes,sseThinkingDeltaBytes:W.thinkingDeltaBytes,sseInputJsonDeltaBytes:W.inputJsonDeltaBytes,sseSignatureDeltaBytes:W.signatureDeltaBytes,sseRedactedThinkingBytes:W.redactedThinkingBytes,sseLastEvent:W.last?{...W.last}:void 0}}function y0(W,J={}){if(!W.body)return W;let j=W.body.getReader(),O=new TextDecoder,P=new TextEncoder,G="",I=0,H=0,k=0,b=0,m=0,E=!1,r=!1,i=v(),$0=v(),d=J.perf?Nj():void 0,j0=Xj(),G0=()=>{if(r)return;r=!0,j.releaseLock()},z0=(a={})=>({chunks:I,pulls:H,inputBytes:k,outputBytes:b,pendingChars:G.length,rewriteMs:P0(m),totalMs:P0(v()-$0),...d?_j(d):{},...a}),J0=(a,T0={})=>{J.perf?.(a,z0(T0))};J.perf?.("stream_tool_prefix_wrapper_created",{status:W.status,hasBody:!0});let Y1=new ReadableStream({async pull(a){if(H++,!E)E=!0,J0("stream_tool_prefix_first_pull");let T0=v();try{let{done:X0,value:w0}=await j.read(),R0=P0(v()-T0);if(X0){let $=O.decode();if(d)XW(d,$);let N=ZW(j0,$);if(N)throw J0("stream_tool_prefix_retryable_error",{error:N.message,providerErrorType:N.providerErrorType}),G0(),N;let K=v(),L=OW(`${G}${$}`,!0);if(m+=v()-K,L.ready){let D=P.encode(L.ready);b+=D.byteLength,a.enqueue(D)}J0("stream_tool_prefix_rewrite",{readMs:R0}),G0(),a.close();return}I++,k+=w0.byteLength;let Q0=O.decode(w0,{stream:!0});if(d)XW(d,Q0);let L0=ZW(j0,Q0);if(L0)throw J0("stream_tool_prefix_retryable_error",{error:L0.message,providerErrorType:L0.providerErrorType,readMs:R0,lastChunkBytes:w0.byteLength}),G0(),L0;let I1=G+Q0,U0=v(),M0=OW(I1);if(m+=v()-U0,G=M0.pending,M0.ready){let $=P.encode(M0.ready);b+=$.byteLength,a.enqueue($)}let u0=v();if(I===1||I%25===0||u0-i>5000)i=u0,J0("stream_tool_prefix_progress",{readMs:R0,lastChunkBytes:w0.byteLength})}catch(X0){throw J0("stream_tool_prefix_error",{error:X0 instanceof Error?X0.message:String(X0)}),G0(),X0}},async cancel(a){J0("stream_tool_prefix_cancel",{reason:a instanceof Error?a.message:String(a)});try{await j.cancel(a)}finally{G0()}}});return new Response(Y1,{status:W.status,statusText:W.statusText,headers:W.headers})}var Ij="__OPENCODE_ANTHROPIC_AUTH_COMMAND_HANDLED__",zj=60000,wj=60000,Qj=5000,RW=200,L4=240,Lj=L4,Uj=1,SW=!1;function _1(){return process.env.OPENCODE_ANTHROPIC_AUTH_PERF==="1"}function C(){return performance.now()}function h(W){return Math.round(W*10)/10}function EW(W){return Math.floor(Math.random()*Math.max(0,W))}function J1(W){if(typeof W==="string")return W;if(W instanceof URL)return W.toString();return W.url}function P1(W,J){return J?.method??(W instanceof Request?W.method:void 0)}function vW(W){return W instanceof Error?W.message:String(W)}function Mj(){if(SW||!1||!_1())return;SW=!0;let W=100,J=250,j=C()+W;setInterval(()=>{let O=C(),P=O-j;if(j=O+W,P<J)return;S("[perf] opencode event_loop_lag",{lagMs:h(P),thresholdMs:J})},W).unref?.()}function Bj(W){let J=C(),j={requestId:String(Uj++),start:J,last:J,mark(O,P){let G=C();if(_1())S("[perf] opencode request stage",{requestId:j.requestId,stage:O,deltaMs:h(G-j.last),totalMs:h(G-j.start),...P});j.last=G},done(O,P){let G=C();if(_1())S("[perf] opencode request done",{requestId:j.requestId,stage:O,deltaMs:h(G-j.last),totalMs:h(G-j.start),...P});j.last=G}};if(_1())S("[perf] opencode request start",{requestId:j.requestId,...W});return j}async function Cj(W,J,j){let O=W.client.session,P=await o1(W.client,J),G={path:{id:J},body:{noReply:!0,parts:[{type:"text",text:j,ignored:!0}]}};if(P?.agent)G.body.agent=P.agent;if(P?.model)G.body.model=P.model;if(P?.variant)G.body.variant=P.variant;if(typeof O?.promptAsync==="function"){await O.promptAsync(G);return}if(typeof O?.prompt==="function"){await Promise.resolve(O.prompt(G));return}throw Error("OpenCode session prompt API is unavailable for ignored replies.")}function Fj(){throw Error(Ij)}function Hj(W){if(W.sessionID==null)return!1;let J=W.model;return J?.providerID==="anthropic"||J?.api?.npm==="@ai-sdk/anthropic"||J?.api?.npm==="@ai-sdk/google-vertex/anthropic"}function fj(W){if(W.some((J)=>J.includes("<use_parallel_tool_calls>")))return!1;return W.push(AW),!0}var xj={input:0,output:0,cache:{read:0,write:0}};function qj(W){let J=W["claude-opus-4-8"]??W["claude-opus-4-5"]??Object.values(W)[0];if(!J)return W;return{...W,...Object.fromEntries(Object.values(Z4).map((j)=>[j.id,{...J,id:j.id,name:j.name,api:J.api?{...J.api,id:j.id}:void 0,cost:{input:n0.input,output:n0.output,cache:{read:n0.cacheRead,write:n0.cacheWrite5m}},limit:{...J.limit??{},context:G4,output:V4},capabilities:{...J.capabilities??{},reasoning:!0,attachment:!0,toolcall:!0},release_date:X4}]))}}function Tj(W){return Object.fromEntries(Object.entries(W).map(([J,j])=>[J,{...j,cost:xj}]))}var sj=async(W)=>{Mj();let{client:J}=W,j=hW(),O=await A(j),P=new D4({storage:O,onMainQuotaFetched:async($,N,K,L)=>{try{let D=await A(j)??{version:1,accounts:[]},R=cW(D);if(R&&R.checkedAt>=L&&tW(R.quota,D,R.checkedAt)>Date.now()){P.seedMainFromStorage(D);return}D.quota=D.quota??{},D.quota.mainQuota=$,D.quota.mainQuotaCheckedAt=N,D.quota.mainQuotaToken=K,D.quota.mainLastQuotaApiError=void 0,await b0(D,j,{mainQuota:!0})}catch(D){S("[quota] failed to persist main quota",{error:D instanceof Error?D.message:String(D)})}},onApiError:async($)=>{try{let N=await A(j)??{version:1,accounts:[]};N.quota=N.quota??{},N.quota.mainLastQuotaApiError=$,await b0(N,j,{mainQuota:!0})}catch(N){S("[quota] failed to persist backoff state",{error:N instanceof Error?N.message:String(N)})}}}),G=new sW({quotaManager:P,onFallbackStorageChanged:()=>{E()}});G.startBackgroundRefresh();let I=null,H=new P4({loadStorage:()=>A(j),prepareHeaders:async($,N)=>{if(!i)return $;let K=await i();if(K.type!=="oauth")return $;if(!K.access||K.expires&&K.expires<Date.now()){if(!I)return $;K.access=await I()}if(!K.access)return $;try{let L=JSON.parse(N.bodyText),D=await S1(K.access,typeof L.model==="string"?L.model:void 0);if($.delete("anthropic-beta"),k0($,K.access,{body:L,identity:D}),$.set("anthropic-beta",v0($.get("anthropic-beta"),[eW])),L.speed==="fast")W1($)}catch{k0($,K.access)}return $},log:S});l0({enabled:g0(O),mode:m0(O)}),X1(O1(O)),D1($1(O));let k=null;if(W.directory){let $=globalThis;if($.__anthropicAuthRpcServer)await $.__anthropicAuthRpcServer.stop().catch(()=>{}),$.__anthropicAuthRpcServer=void 0;try{k=await WW({dir:w4(W.directory),drain:s1,apply:L0}),$.__anthropicAuthRpcServer=k}catch(N){S("[rpc] failed to start",{error:N instanceof Error?N.message:String(N)})}}let b={activeId:"main",route:"main"};function m($,N){b={activeId:N.activeId,route:N.route},P.updateStorage($),P.seedMainFromStorage($,N.mainAccessToken),P.seedFallbacksFromAccounts(($?.accounts??[]).filter(W0));let K=P.getMain(N.mainAccessToken),L=P.getLastApiError(),D=$?.refresh?.mainLastRefreshError,R={main:{quota:K?.quota??null,quotaBackedOff:P.isBackedOff(),quotaBackoffUntil:L?.nextRetryAt,refreshBackedOff:D?f0(D,N.mainRefreshToken,Date.now()):!1,refreshBackoffUntil:D?.nextRetryAt},fallbacks:($?.accounts??[]).filter((f)=>f.enabled!==!1&&W0(f)).map((f)=>({id:f.id,label:f.label,quota:f.access?P.getFallback(f.id,f.access)?.quota??null:null,enabled:f.enabled!==!1})),activeId:N.activeId,route:N.route,relay:(()=>{let f=p1($);return f?{enabled:!0,transport:f.transport??"http"}:null})(),fastMode:Z1(),cacheKeep:{enabled:A1($),window:$?.cacheKeep?.startHour!=null&&$?.cacheKeep?.endHour!=null?`${$.cacheKeep.startHour}-${$.cacheKeep.endHour}`:void 0,trackedSessions:H.trackedCount()},lastUpdated:Date.now()};Q4(R).catch((f)=>S("[sidebar] state write failed",{error:f instanceof Error?f.message:String(f)}))}async function E(){let $=await A(j),N,K;if(i)try{let L=await i();N=L.access,K=L.refresh}catch{}m($,{activeId:b.activeId,route:b.route,mainAccessToken:N,mainRefreshToken:K})}function r($,N){if(!N)return;if($?.quota?.enabled!==!0)return;if(P.getMain(N))return;if($0)return;$0=!0,P.refreshMain(N).then(()=>E()).catch(()=>{}).finally(()=>{$0=!1})}let i=null,$0=!1,d=null,j0=0;function G0($){let N=$?.refresh?.refreshBeforeExpiryMinutes??Lj;return Math.max(L4,N)*60000}function z0($){return $?.refresh?.enabled!==!1}async function J0($){if(!$)return;let N=await A(j),K=N?.refresh?.mainLastRefreshError;if(!N?.refresh||!K?.tokenHash)return;let L=N1($);if(K.tokenHash===L)return;if(K.nextRetryAt&&K.nextRetryAt>Date.now()){S("[refresh] opencode main oauth keeping backoff despite token rotation",{nextRetryAt:K.nextRetryAt,retryCount:K.retryCount,remainingMs:K.nextRetryAt-Date.now()});return}N.refresh.mainLastRefreshError=void 0,await b0(N,j,{mainRefresh:!0}),S("[refresh] opencode main oauth cleared stale backoff after token rotation",{previousCheckedAt:K.checkedAt,previousNextRetryAt:K.nextRetryAt,previousRetryCount:K.retryCount})}async function Y1(){let $=[];if(i)try{let D=await i();if(D.type==="oauth"&&D.access){let R=await P.refreshMain(D.access);$.push({name:"OpenCode anthropic",role:"main",quota:R})}else if(D.type==="oauth")$.push({name:"OpenCode anthropic",role:"main",error:"missing access token; send a request first or reconnect auth"})}catch(D){let R=D instanceof Error?D.message:String(D);$.push({name:"OpenCode anthropic",role:"main",error:R.includes("429")?"Usage API rate limited — try again in a moment":R})}let{storage:N,errors:K}=await G.refreshQuotaForAllAccounts({force:!0}),L=new Map(K.map((D)=>[D.accountId,D.message]));if($.push(...K4(N,L)),!i)$.unshift({name:"OpenCode anthropic",role:"main",error:"auth loader has not run yet; send a request first"});return _4({accounts:$,refreshedAt:Date.now()})}async function a($){let N=aW($);if(N.type==="enable"||N.type==="disable"){let R=N.type==="enable",f=await gW(R),y=m0(f);return l0({enabled:R,mode:y}),V1({argumentsText:$,enabled:R,mode:y})}if(N.type==="mode"){let R=await mW(N.mode),f=g0(R);return l0({enabled:f,mode:N.mode}),V1({argumentsText:$,enabled:f,mode:N.mode})}let K=await A(j),L=g0(K),D=m0(K);return l0({enabled:L,mode:D}),V1({argumentsText:$,enabled:L,mode:D})}async function T0($){let N=W4($),K=await A(j);if(N.type==="window")K=await lW(N.startHour,N.endHour);else if(N.type==="disable")K=await dW(!1);let L=v1(K),D=H.stats(L);return J4({argumentsText:$,enabled:j4(K),window:L,hybridActive:A1(K),trackedSessions:D.trackedSessions,nextPrewarmAt:D.nextPrewarmAt})}async function X0($){let N=O4($);if(N.type==="enable"||N.type==="disable"){let D=N.type==="enable";return await pW(D),X1(D),y1({argumentsText:$,enabled:D})}let K=await A(j),L=O1(K);return X1(L),y1({argumentsText:$,enabled:L})}async function w0($){let N=$4($);if(N.type==="enable"||N.type==="disable"){let D=N.type==="enable";return await iW(D),D1(D),b1({argumentsText:$,enabled:D})}let K=await A(j),L=$1(K);return D1(L),b1({argumentsText:$,enabled:L})}async function R0($){let N=z4($);if(N.type==="mode")return await I4(N.mode),l1({argumentsText:$,mode:N.mode});let K=await A();return l1({argumentsText:$,mode:K1(K)})}async function Q0($,N){if($==="claude-quota")return{command:$,text:await Y1(),knobs:{}};if($==="claude-routing"){let f=await R0(N),y=await A(j);return{command:$,text:f,knobs:{mode:K1(y)}}}if($==="claude-fast"){let f=await w0(N),y=await A(j);return{command:$,text:f,knobs:{enabled:$1(y)}}}if($==="claude-dump"){let f=await X0(N),y=await A(j);return{command:$,text:f,knobs:{enabled:O1(y)}}}if($==="claude-cache"){let f=await a(N),y=await A(j);return{command:$,text:f,knobs:{enabled:g0(y),mode:m0(y)}}}if($==="claude-cachekeep"){let f=await T0(N),y=await A(j);return{command:$,text:f,knobs:{window:v1(y)}}}let K=await A(),L=T1(K),D=(K?.accounts??[]).filter((f)=>f.enabled!==!1).map((f)=>f.id),R=N4({argumentsText:N,config:L,accountIds:D});if(R.updatedConfig)await rW(R.updatedConfig);return{command:$,text:R.text,knobs:{config:T1(await A()),accountIds:D}}}async function L0($){let N=await Q0($.command,$.arguments);return{text:N.text,knobs:N.knobs}}function I1($,N=10){let K=Math.max(0,Math.min(Math.round($/100*N),N));return"█".repeat(K)+"░".repeat(N-K)}function U0($,N){return`${$} ${I1(N)} ${String(Math.round(N)).padStart(3)}%`}function M0($){if(!$)return"";let N=new Date($).getTime();if(Number.isNaN(N))return"";let K=N-Date.now();if(K<=0)return"resets now";let L=Math.floor(K/60000);if(L<1)return"resets <1m";if(L<60)return`resets ${L}m`;let D=Math.floor(L/60),R=L%60;return R>0?`resets ${D}h${R}m`:`resets ${D}h`}function u0($,N,K){let L=[],D=0;if($){let{five_hour:y,seven_day:O0}=$;if(y||O0){let V0=K==="main"?"active":"idle",_0=M0(y?.resetsAt),B0=[`main · ${V0}${_0?` (${_0})`:""}`];if(y)B0.push(U0("5h",y.usedPercent)),D=Math.max(D,y.usedPercent);if(O0)B0.push(U0("7d",O0.usedPercent)),D=Math.max(D,O0.usedPercent);L.push(B0.join(`
10
+ `))}}if(N?.length)for(let y of N){let O0=y.quota;if(!O0)continue;let{five_hour:Z0,seven_day:V0}=O0;if(!Z0&&!V0)continue;let _0=y.label||"alt",c0=K===y.id?"active":"idle",C0=M0(Z0?.resetsAt),Y0=[`${_0} · ${c0}${C0?` (${C0})`:""}`];if(Z0)Y0.push(U0("5h",Z0.usedPercent)),D=Math.max(D,Z0.usedPercent);if(V0)Y0.push(U0("7d",V0.usedPercent)),D=Math.max(D,V0.usedPercent);L.push(Y0.join(`
11
+ `))}if(!L.length)return;let R=L.join(`
11
12
 
12
- `),R=P>=90?"error":P>=70?"warning":"info";J.tui?.showToast?.({body:{title:"Claude Quota",message:E,variant:R,duration:R==="error"?8000:5000}})?.catch?.(()=>{})}return{config:async(X)=>{X.command={...X.command??{},[G1]:{template:G1,description:"Show or toggle 1-hour Anthropic ephemeral prompt cache TTL."},[K1]:{template:K1,description:"Keep hybrid Claude cache warm for recently used sessions during a local time window."},[N1]:{template:N1,description:"Show current Claude OAuth quota usage for all accounts."},[Y1]:{template:Y1,description:"Show or toggle Anthropic request dump capture for debugging."},[O1]:{template:O1,description:"Show or toggle Anthropic fast mode for supported Opus models."},[_1]:{template:_1,description:"Show or change Claude account routing between main-first and fallback-first."},[I1]:{template:I1,description:"Manage killswitch — hard-block requests when quota drops below per-account thresholds."}}},"experimental.chat.system.transform":async(X,G)=>{if(!j3(X))return;J3(G.system)},provider:{id:"anthropic",async models(X,G){let D=V3(X.models);if(G.auth?.type!=="oauth"||!Fj(W??{}))return D;return W3(D)}},"command.execute.before":async(X)=>{if(X.command===G1)await D0(j,X.sessionID,await s(X.arguments)),I0();if(X.command===K1)await D0(j,X.sessionID,await x0(X.arguments)),I0();if(X.command===N1){await D0(j,X.sessionID,await H0());let G=await h(),D=f?await f().catch(()=>{return}):void 0;u(G,{activeId:"main",route:"main",mainAccessToken:D?.access,mainRefreshToken:D?.refresh}),I0()}if(X.command===Y1)await D0(j,X.sessionID,await K0(X.arguments)),I0();if(X.command===O1)await D0(j,X.sessionID,await T0(X.arguments)),I0();if(X.command===_1)await D0(j,X.sessionID,await l0(X.arguments)),I0();if(X.command===I1){let G=await h(),D=yj(G),w=(G?.accounts??[]).filter((E)=>E.enabled!==!1).map((E)=>E.id),P=rj({argumentsText:X.arguments,config:D,accountIds:w});if(P.updatedConfig)await bj(P.updatedConfig);await D0(j,X.sessionID,P.text),I0()}},auth:{provider:"anthropic",async loader(X,G){f=X;let D=await X();if(D.type==="oauth"){let E=function(){if(a)clearInterval(a),a=null;let Y=async()=>{try{let I=await h($);if(!C0(I))return;let x=await X();if(x.type!=="oauth")return;if(await $0(x.refresh),!x.expires)return;let N=x.expires-Date.now(),H=W0(I);if(N>H)return;if(q("[refresh] opencode main oauth background due",{expiresInMs:N,refreshBeforeMs:H}),x.refresh&&U0(I?.refresh?.mainLastRefreshError,x.refresh,Date.now())){q("[refresh] opencode main oauth background skipped backoff",{nextRetryAt:I?.refresh?.mainLastRefreshError?.nextRetryAt,retryCount:I?.refresh?.mainLastRefreshError?.retryCount,expiresInMs:N});return}if(x.refresh&&I?.refresh?.mainRefreshLeaseUntil&&I.refresh.mainRefreshLeaseUntil>Date.now()&&I.refresh.mainRefreshLeaseTokenHash===W1(x.refresh))return;await P();let K=await X();q("[refresh] opencode main oauth refreshed in background",{newExpiresInMs:K.expires?K.expires-Date.now():void 0})}catch(I){q("[refresh] opencode main oauth refresh failed",{message:I instanceof Error?I.message:String(I)})}};if(a=setInterval(()=>{Y()},nJ+Mj(oJ)),"unref"in a)a.unref()},R=function(Y,I){if(Y instanceof Request&&Y.body)return!1;return I==null||typeof I==="string"},o=function(Y){return Y.has("x-parent-session-id")},V0=function(Y){return Y.includes("rate_limit_error")||/exceed your account'?s rate limit/i.test(Y)},Y0=function(Y){return Y?.quota?.enabled===!0},P0=function(Y,I){if(Y.delete("authorization"),Y.delete("x-api-key"),I.authHeader==="x-api-key")Y.set("x-api-key",I.apiKey??"");else Y.set("Authorization",`Bearer ${I.apiKey??""}`);Y.set("Content-Type","application/json")},L0=function(Y){return V.getFallback(Y.id,Y.access)?.quota??Y.quota},O0=function(Y){return Object.values(Y??{}).some((I)=>I&&I.remainingPercent<=0)},g1=function(Y,I){return Y.status===429||I},Q1=function(Y){if(!Y)return!1;let I=V.getMain(Y);return Boolean(I&&I.refreshAfter>Date.now()&&O0(I.quota))},w=null;async function P(){if(!w)w=(async()=>{let x=null,N=null,H=null;async function K(O){let T=await h($)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};T.refresh=T.refresh??{},O(T),await y0(T,$,{mainRefresh:!0})}async function b(O){let T=Date.now()+rJ;while(Date.now()<T){await new Promise((B)=>setTimeout(B,Lj+Mj(Lj)));let Z=await X();if(Z.type!=="oauth"||!Z.access)continue;if((Z.access!==O.access||Z.refresh!==O.refresh||(Z.expires??0)>(O.expires??0)+60000)&&(!Z.expires||Z.expires>Date.now()))return q("[refresh] opencode main oauth joined concurrent refresh",{expiresInMs:Z.expires?Z.expires-Date.now():void 0}),Z.access}return null}for(let O=0;O<=2;O++){let T=null;try{if(O>0){let C=500*2**(O-1);await new Promise((L)=>setTimeout(L,C))}if(T=await X(),!T.refresh)throw Error("Token refresh failed: missing refresh token");let Z=await h($),_=W1(T.refresh),B=Z?.refresh?.mainLastRefreshError;if(q("[refresh] opencode main oauth refresh check",{attempt:O,expiresInMs:T.expires?T.expires-Date.now():void 0,hasBackoff:Boolean(B),backoffActive:B?U0(B,T.refresh,Date.now()):!1,retryCount:B?.retryCount,nextRetryAt:B?.nextRetryAt}),B&&U0(B,T.refresh,Date.now()))throw q("[refresh] opencode main oauth refresh skipped backoff",{nextRetryAt:B.nextRetryAt,retryCount:B.retryCount}),Error(v1(B,Date.now()));if(Z?.refresh?.mainRefreshLeaseUntil&&Z.refresh.mainRefreshLeaseUntil>Date.now()&&Z.refresh.mainRefreshLeaseTokenHash===_){q("[refresh] opencode main oauth refresh skipped lease",{leaseUntil:Z.refresh.mainRefreshLeaseUntil});let C=await b(T);if(C)return C;throw Error("Claude OAuth refresh is already in progress")}let Q=await Hj({name:"opencode-main-oauth-refresh",ttlMs:120000,renew:!0});if(!Q){q("[refresh] opencode main oauth refresh skipped file lock");let C=await b(T);if(C)return C;throw Error("Claude OAuth refresh is already in progress")}H=Q.release,x=uJ(),N=_,await K((C)=>{C.refresh=C.refresh??{},C.refresh.mainRefreshLeaseId=x??void 0,C.refresh.mainRefreshLeaseUntil=Date.now()+120000,C.refresh.mainRefreshLeaseTokenHash=_});let l=await h($);if(q("[refresh] opencode main oauth refresh lease acquired",{attempt:O,leaseUntil:Date.now()+120000}),l?.refresh?.mainRefreshLeaseId!==x||l.refresh.mainRefreshLeaseTokenHash!==_)throw Error("Claude OAuth refresh is already in progress");q("[refresh] opencode main oauth refresh request start",{attempt:O});let m=await Bj({refreshToken:T.refresh,maxRetries:0});return await J.auth.set({path:{id:"anthropic"},body:{type:"oauth",refresh:m.refresh,access:m.access,expires:m.expires}}),await K((C)=>{if(!C?.refresh)return;if(C.refresh.mainLastRefreshError=void 0,C.refresh.mainRefreshLeaseId===x)C.refresh.mainRefreshLeaseId=void 0,C.refresh.mainRefreshLeaseUntil=void 0,C.refresh.mainRefreshLeaseTokenHash=void 0}),q("[refresh] opencode main oauth refresh succeeded",{attempt:O,expiresInMs:m.expires-Date.now()}),m.access}catch(Z){let _=Z instanceof Error&&(Z.message.includes("fetch failed")||("code"in Z)&&(Z.code==="ECONNRESET"||Z.code==="ECONNREFUSED"||Z.code==="ETIMEDOUT"||Z.code==="UND_ERR_CONNECT_TIMEOUT"));if(O<2&&(_||Z instanceof C1&&Z.status>=500))continue;q("[refresh] opencode main oauth refresh attempt failed",{attempt:O,error:Z instanceof Error?Z.message:String(Z),transient:_});let B=T?.refresh;if(B&&Z instanceof C1)await K((Q)=>{Q.refresh=Q.refresh??{},Q.refresh.mainLastRefreshError=Sj({error:Z,now:Date.now(),refreshToken:B,previous:Q.refresh.mainLastRefreshError})});throw Z}finally{if(x)await K((Z)=>{if(!Z?.refresh)return;if(Z.refresh.mainRefreshLeaseId===x&&Z.refresh.mainRefreshLeaseTokenHash===N)Z.refresh.mainRefreshLeaseId=void 0,Z.refresh.mainRefreshLeaseUntil=void 0,Z.refresh.mainRefreshLeaseTokenHash=void 0}).catch(()=>{});await H?.().catch(()=>{})}}throw Error("Token refresh exhausted all retries")})().finally(()=>{w=null});return w}M=P,E(),V.seedFallbacksFromAccounts((W?.accounts??[]).filter(e)),u(W,{activeId:"main",route:"main",mainAccessToken:D.access,mainRefreshToken:D.refresh});async function Z0(Y,I){if(!Y.body||Y.status!==200)return I?.mark("inspect_stream_skip",{status:Y.status}),{response:Y,rateLimited:!1};if(Y.headers.get("x-cortexkit-relay-optimistic")==="true")return I?.mark("inspect_stream_skip",{status:Y.status,reason:"optimistic_relay"}),{response:Y,rateLimited:!1};let x=F(),N=Y.body.getReader(),H=[],K=new TextDecoder,b="",O=0;while(!b.includes(`
13
+ `),f=D>=90?"error":D>=70?"warning":"info";J.tui?.showToast?.({body:{title:"Claude Quota",message:R,variant:f,duration:f==="error"?8000:5000}})?.catch?.(()=>{})}return{config:async($)=>{$.command={...$.command??{},[R1]:{template:R1,description:"Show or toggle 1-hour Anthropic ephemeral prompt cache TTL."},[E1]:{template:E1,description:"Keep hybrid Claude cache warm for recently used sessions during a local time window."},[m1]:{template:m1,description:"Show current Claude OAuth quota usage for all accounts."},[k1]:{template:k1,description:"Show or toggle Anthropic request dump capture for debugging."},[h1]:{template:h1,description:"Show or toggle Anthropic fast mode for supported Opus models."},[i1]:{template:i1,description:"Show or change Claude account routing between main-first and fallback-first."},[g1]:{template:g1,description:"Manage killswitch — hard-block requests when quota drops below per-account thresholds."}}},"experimental.chat.system.transform":async($,N)=>{if(!Hj($))return;fj(N.system)},provider:{id:"anthropic",async models($,N){let K=qj($.models);if(N.auth?.type!=="oauth"||!yW(O??{}))return K;return Tj(K)}},"command.execute.before":async($)=>{if(!["claude-cache","claude-cachekeep","claude-quota","claude-dump","claude-fast","claude-routing","claude-killswitch"].includes($.command))return;let K=$.command,L=await Q0(K,$.arguments);if(K==="claude-quota"){let D=await A(),R=i?await i().catch(()=>{return}):void 0;m(D,{activeId:"main",route:"main",mainAccessToken:R?.access,mainRefreshToken:R?.refresh})}if(a1($.sessionID))t1(L,$.sessionID);else await Cj(W,$.sessionID,L.text);Fj()},auth:{provider:"anthropic",async loader($,N){i=$;let K=await $();if(K.type==="oauth"){let R=function(){if(d)clearInterval(d),d=null;let Z=async()=>{try{let Y=await A(j);if(!z0(Y))return;let q=await $();if(q.type!=="oauth")return;if(await J0(q.refresh),!q.expires)return;let z=q.expires-Date.now(),x=G0(Y);if(z>x)return;if(S("[refresh] opencode main oauth background due",{expiresInMs:z,refreshBeforeMs:x}),q.refresh&&f0(Y?.refresh?.mainLastRefreshError,q.refresh,Date.now())){S("[refresh] opencode main oauth background skipped backoff",{nextRetryAt:Y?.refresh?.mainLastRefreshError?.nextRetryAt,retryCount:Y?.refresh?.mainLastRefreshError?.retryCount,expiresInMs:z});return}if(q.refresh&&Y?.refresh?.mainRefreshLeaseUntil&&Y.refresh.mainRefreshLeaseUntil>Date.now()&&Y.refresh.mainRefreshLeaseTokenHash===N1(q.refresh))return;await D();let X=await $();S("[refresh] opencode main oauth refreshed in background",{newExpiresInMs:X.expires?X.expires-Date.now():void 0})}catch(Y){S("[refresh] opencode main oauth refresh failed",{message:Y instanceof Error?Y.message:String(Y)})}};if(d=setInterval(()=>{Z()},zj+EW(wj)),"unref"in d)d.unref()},f=function(Z,Y){if(Z instanceof Request&&Z.body)return!1;return Y==null||typeof Y==="string"},y=function(Z){return Z.has("x-parent-session-id")},O0=function(Z){return Z.includes("rate_limit_error")||/exceed your account'?s rate limit/i.test(Z)},Z0=function(Z){return Z?.quota?.enabled===!0},_0=function(Z,Y){if(Z.delete("authorization"),Z.delete("x-api-key"),Y.authHeader==="x-api-key")Z.set("x-api-key",Y.apiKey??"");else Z.set("Authorization",`Bearer ${Y.apiKey??""}`);Z.set("Content-Type","application/json")},C0=function(Z){return P.getFallback(Z.id,Z.access)?.quota??Z.quota},Y0=function(Z){return Object.values(Z??{}).some((Y)=>Y&&Y.remainingPercent<=0)},d1=function(Z,Y){return Z.status===429||Y},z1=function(Z){if(!Z)return!1;let Y=P.getMain(Z);return Boolean(Y&&Y.refreshAfter>Date.now()&&Y0(Y.quota))},L=null;async function D(){if(!L)L=(async()=>{let q=null,z=null,x=null;async function X(_){let T=await A(j)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};T.refresh=T.refresh??{},_(T),await b0(T,j,{mainRefresh:!0})}async function p(_){let T=Date.now()+Qj;while(Date.now()<T){await new Promise((B)=>setTimeout(B,RW+EW(RW)));let V=await $();if(V.type!=="oauth"||!V.access)continue;if((V.access!==_.access||V.refresh!==_.refresh||(V.expires??0)>(_.expires??0)+60000)&&(!V.expires||V.expires>Date.now()))return S("[refresh] opencode main oauth joined concurrent refresh",{expiresInMs:V.expires?V.expires-Date.now():void 0}),V.access}return null}for(let _=0;_<=2;_++){let T=null;try{if(_>0){let F=500*2**(_-1);await new Promise((Q)=>setTimeout(Q,F))}if(T=await $(),!T.refresh)throw Error("Token refresh failed: missing refresh token");let V=await A(j),w=N1(T.refresh),B=V?.refresh?.mainLastRefreshError;if(S("[refresh] opencode main oauth refresh check",{attempt:_,expiresInMs:T.expires?T.expires-Date.now():void 0,hasBackoff:Boolean(B),backoffActive:B?f0(B,T.refresh,Date.now()):!1,retryCount:B?.retryCount,nextRetryAt:B?.nextRetryAt}),B&&f0(B,T.refresh,Date.now()))throw S("[refresh] opencode main oauth refresh skipped backoff",{nextRetryAt:B.nextRetryAt,retryCount:B.retryCount}),Error(q1(B,Date.now()));if(V?.refresh?.mainRefreshLeaseUntil&&V.refresh.mainRefreshLeaseUntil>Date.now()&&V.refresh.mainRefreshLeaseTokenHash===w){S("[refresh] opencode main oauth refresh skipped lease",{leaseUntil:V.refresh.mainRefreshLeaseUntil});let F=await p(T);if(F)return F;throw Error("Claude OAuth refresh is already in progress")}let U=await bW({name:"opencode-main-oauth-refresh",ttlMs:120000,renew:!0});if(!U){S("[refresh] opencode main oauth refresh skipped file lock");let F=await p(T);if(F)return F;throw Error("Claude OAuth refresh is already in progress")}x=U.release,q=Yj(),z=w,await X((F)=>{F.refresh=F.refresh??{},F.refresh.mainRefreshLeaseId=q??void 0,F.refresh.mainRefreshLeaseUntil=Date.now()+120000,F.refresh.mainRefreshLeaseTokenHash=w});let c=await A(j);if(S("[refresh] opencode main oauth refresh lease acquired",{attempt:_,leaseUntil:Date.now()+120000}),c?.refresh?.mainRefreshLeaseId!==q||c.refresh.mainRefreshLeaseTokenHash!==w)throw Error("Claude OAuth refresh is already in progress");S("[refresh] opencode main oauth refresh request start",{attempt:_});let n=await kW({refreshToken:T.refresh,maxRetries:0});return await J.auth.set({path:{id:"anthropic"},body:{type:"oauth",refresh:n.refresh,access:n.access,expires:n.expires}}),await X((F)=>{if(!F?.refresh)return;if(F.refresh.mainLastRefreshError=void 0,F.refresh.mainRefreshLeaseId===q)F.refresh.mainRefreshLeaseId=void 0,F.refresh.mainRefreshLeaseUntil=void 0,F.refresh.mainRefreshLeaseTokenHash=void 0}),S("[refresh] opencode main oauth refresh succeeded",{attempt:_,expiresInMs:n.expires-Date.now()}),n.access}catch(V){let w=V instanceof Error&&(V.message.includes("fetch failed")||("code"in V)&&(V.code==="ECONNRESET"||V.code==="ECONNREFUSED"||V.code==="ETIMEDOUT"||V.code==="UND_ERR_CONNECT_TIMEOUT"));if(_<2&&(w||V instanceof C1&&V.status>=500))continue;S("[refresh] opencode main oauth refresh attempt failed",{attempt:_,error:V instanceof Error?V.message:String(V),transient:w});let B=T?.refresh;if(B&&V instanceof C1)await X((U)=>{U.refresh=U.refresh??{},U.refresh.mainLastRefreshError=nW({error:V,now:Date.now(),refreshToken:B,previous:U.refresh.mainLastRefreshError})});throw V}finally{if(q)await X((V)=>{if(!V?.refresh)return;if(V.refresh.mainRefreshLeaseId===q&&V.refresh.mainRefreshLeaseTokenHash===z)V.refresh.mainRefreshLeaseId=void 0,V.refresh.mainRefreshLeaseUntil=void 0,V.refresh.mainRefreshLeaseTokenHash=void 0}).catch(()=>{});await x?.().catch(()=>{})}}throw Error("Token refresh exhausted all retries")})().finally(()=>{L=null});return L}I=D,R(),P.seedFallbacksFromAccounts((O?.accounts??[]).filter(W0)),m(O,{activeId:"main",route:"main",mainAccessToken:K.access,mainRefreshToken:K.refresh});async function V0(Z,Y){if(!Z.body||Z.status!==200)return Y?.mark("inspect_stream_skip",{status:Z.status}),{response:Z,rateLimited:!1};if(Z.headers.get("x-cortexkit-relay-optimistic")==="true")return Y?.mark("inspect_stream_skip",{status:Z.status,reason:"optimistic_relay"}),{response:Z,rateLimited:!1};let q=C(),z=Z.body.getReader(),x=[],X=new TextDecoder,p="",_=0;while(!p.includes(`
13
14
 
14
- `)&&b.length<65536){let{done:Z,value:_}=await N.read();if(Z)break;if(H.push(_),O+=_.byteLength,b+=K.decode(_,{stream:!0}),V0(b))break}if(V0(b))return await N.cancel().catch(()=>{}),I?.mark("inspect_stream_first_event",{ms:A(F()-x),bytes:O,rateLimited:!0}),{response:Y,rateLimited:!0};let T=new ReadableStream({start(Z){for(let _ of H)Z.enqueue(_)},async pull(Z){let{done:_,value:B}=await N.read();if(_){Z.close();return}Z.enqueue(B)},cancel(Z){return N.cancel(Z)}});return I?.mark("inspect_stream_first_event",{ms:A(F()-x),bytes:O,rateLimited:!1}),{response:new Response(T,{status:Y.status,statusText:Y.statusText,headers:Y.headers}),rateLimited:!1}}async function _0(Y,I,x,N,H="api_fallback",K){let b=F(),O=w1(Y,I),T=O.get("x-session-affinity")||O.get("x-opencode-session"),Z=o(O);O.delete("x-parent-session-id"),O.delete("x-session-affinity"),O.delete("x-opencode-session");let _=I?.body,B=typeof _==="string"?_.length:void 0;if(_&&typeof _==="string"){let C=F(),L=(()=>{if(!z1())return!1;try{return S0(JSON.parse(_).model)}catch{return!1}})();if(_=await F1(_,{cache1hEnabled:!Z&&B0(),cache1hMode:F0(),fastModeEnabled:L,perf:(U,k)=>N?.mark(`rewrite_body_${U}`,{route:H,...k})}),P0(O,x),O.set("anthropic-beta",v0(O.get("anthropic-beta"),[])),L)t0(O);N?.mark("rewrite_body",{route:H,ms:A(F()-C),originalBytes:B,rewrittenBytes:_.length,cacheEnabled:!Z&&B0(),cacheMode:F0(),fastModeEnabled:L,subagent:Z})}else P0(O,x);let Q=B1(Y,{baseURL:x.baseURL}),l=F(),m;try{m=await fetch(Q.input,{...I,body:_,headers:O,...U1()&&{tls:{rejectUnauthorized:!1}}})}catch(C){if(typeof _==="string")await m0({affinity:T,route:H,error:wj(C),bodyText:_,url:Q.url?.toString()??j1(Q.input),method:J1(Y,I),headers:O});throw C}if(typeof _==="string")await m0({affinity:T,route:H,status:m.status,bodyText:_,url:Q.url?.toString()??j1(Q.input),method:J1(Y,I),headers:O});return N?.mark("send_headers_received",{route:H,ms:A(F()-l),status:m.status,relayConfigured:!1,totalSendWithAccessMs:A(F()-b),baseURL:x.baseURL}),m}async function u0(Y,I,x,N,H="unknown",K){let b=F(),O=K,T=async()=>{return O??=await h($),O},Z=w1(Y,I),_=Z.get("x-session-affinity")||Z.get("x-opencode-session"),B=o(Z);Z.delete("x-parent-session-id"),Z.delete("x-session-affinity"),Z.delete("x-opencode-session");let Q=I?.body,l;if(Q&&typeof Q==="string"){let i=F();try{let X0=JSON.parse(Q);if(typeof X0.model==="string")l=X0.model}catch{}N?.mark("model_parse_for_identity",{route:H,ms:A(F()-i),bodyBytes:Q.length})}let m=F(),C=await S1(x,l);N?.mark("resolve_claude_code_identity",{route:H,ms:A(F()-m),hasAccountUuid:Boolean(C.accountUuid)});let L=typeof Q==="string"?Q.length:void 0;if(Q&&typeof Q==="string"){let i=F(),X0=(()=>{if(!z1())return!1;try{return S0(JSON.parse(Q).model)}catch{return!1}})();Q=await F1(Q,{cache1hEnabled:!B&&B0(),cache1hMode:F0(),fastModeEnabled:X0,identity:C,perf:(PJ,OJ)=>N?.mark(`rewrite_body_${PJ}`,{route:H,...OJ})});let Q0=F();try{A0(Z,x,{body:JSON.parse(Q),identity:C}),N?.mark("set_oauth_headers_body_parse",{route:H,ms:A(F()-Q0),bodyBytes:Q.length,parsed:!0})}catch{A0(Z,x,{identity:C}),N?.mark("set_oauth_headers_body_parse",{route:H,ms:A(F()-Q0),bodyBytes:Q.length,parsed:!1})}if(X0)t0(Z);N?.mark("rewrite_body",{route:H,ms:A(F()-i),originalBytes:L,rewrittenBytes:Q.length,cacheEnabled:!B&&B0(),cacheMode:F0(),fastModeEnabled:X0,subagent:B})}let U=B1(Y);if(H==="main"&&typeof Q==="string"&&!B&&B0()&&F0()==="hybrid"){let i=await T(),X0=F(),Q0=S.track({sessionId:_,url:U.url?.toString()??U.input.toString(),headers:Z,bodyText:Q,storage:i,cacheMode:"hybrid"});N?.mark("cachekeep_track",{session:_,ms:A(F()-X0),tracked:Q0.tracked,reason:Q0.tracked?void 0:Q0.reason,bodyBytes:Q.length})}let k=async()=>{try{let i=await fetch(U.input,{...I,body:Q,headers:Z,...U1()&&{tls:{rejectUnauthorized:!1}}});if(typeof Q==="string")await m0({affinity:_,route:H,status:i.status,bodyText:Q,url:U.url?.toString()??j1(U.input),method:J1(Y,I),headers:Z});return i}catch(i){if(typeof Q==="string")await m0({affinity:_,route:H,error:wj(i),bodyText:Q,url:U.url?.toString()??j1(U.input),method:J1(Y,I),headers:Z});throw i}},t=y1(await T()),p=F(),c=await VJ({config:t,input:U.input,init:I,headers:Z,body:Q,fallback:k,affinity:_,optimisticResponse:t?.transport==="websocket"});return N?.mark("send_headers_received",{route:H,ms:A(F()-p),status:c.status,relayConfigured:t!=null,totalSendWithAccessMs:A(F()-b)}),c}async function KJ(Y){if(!Y)return!1;try{return await V.refreshMain(Y),Q1(Y)}catch{return!1}}async function c0(Y,I={}){let x=await z.getUsableFallbackAccounts(Y),N=new Map(x.map((K)=>[K.id,K])),H=[];for(let K of Y?.accounts??[]){if(e(K)){let b=N.get(K.id);if(b)H.push(b);continue}if(I.includeApiRoutes===!0&&k0(K)&&K.enabled!==!1&&K.apiKey&&T1(K.baseURL))H.push(K)}if(!h0(Y))return H;return H.filter((K)=>e(K)?X1(L0(K),Y,K.id):!0)}async function n0(Y,I,x,N,H,K,b){if(!x.length)return H??null;let O=b?.returnLastOnExhausted??!0;await H?.body?.cancel().catch(()=>{});let T=H??null;for(let[Z,_]of x.entries()){let B;if(k0(_)){if(!_.apiKey)continue;B=await _0(Y,I,_,K,`api_fallback_${Z}`,N)}else{let l=_.access;if(!l)continue;B=await u0(Y,I,l,K,`fallback_${Z}`,N)}T=B;let Q=R1(B.status,N);if(!Q){let l=await Z0(B,K);B=l.response,T=B,Q=l.rateLimited}if(!Q){if(await z.markUsed(_),b?.onSuccess?.(_),e(_)&&_.access&&V.shouldRefreshOnRequestCount(d))V.refreshFallback(_.id,_.access).then(()=>b?.onSuccess?.(_)).catch(()=>{});return B}if(Z<x.length-1||!O)await B.body?.cancel().catch(()=>{})}return O?T:null}async function YJ(Y,I,x,N,H,K,b,O){if(!R(Y,I?.body))return x;let T=F(),Z=K??await h($);if(H?.mark("fallback_load_storage",{ms:A(F()-T),cached:!!K}),!(Z?.accounts??[]).some((L)=>L.enabled!==!1&&(e(L)||k0(L)&&Boolean(L.apiKey)&&T1(L.baseURL))))return x;let B=x,Q=R1(B.status,Z),l=g1(B,!1);if(!Q){let L=await Z0(B,H);B=L.response,Q=L.rateLimited,l=g1(B,L.rateLimited)}if(!Q)return B;let m=!1;if(N)m=N.some(k0);else if(l)m=await KJ(b);let C=N;if(!C){let L=F();C=await c0(Z,{includeApiRoutes:m}),H?.mark("fallback_get_accounts",{ms:A(F()-L),accounts:C.length})}if(h0(Z)){let L=C.length;if(C=C.filter((U)=>e(U)?X1(L0(U),Z,U.id):!0),C.length<L)q("[killswitch] filtered fallbacks",{before:L,after:C.length})}return await n0(Y,I,C,Z,B,H,{onSuccess:O})??B}return{apiKey:"",async fetch(Y,I){let x=I?.body,N=eJ({bodyBytes:typeof x==="string"?x.length:void 0}),H=F(),K=await X();if(N.mark("get_auth",{ms:A(F()-H),authType:K.type,hasAccess:Boolean(K.access)}),K.type!=="oauth"){let L=await fetch(Y,I);return N.done("non_oauth_passthrough",{status:L.status}),L}await $0(K.refresh);let b=F(),O=await h();N.mark("load_storage",{ms:A(F()-b)}),V.updateStorage(O),V.seedMainFromStorage(O,K.access),V.seedFallbacksFromAccounts((O?.accounts??[]).filter(e));let T=R(Y,I?.body);if(T)d++;if(T&&K.access&&(!K.expires||K.expires>Date.now()))y(O,K.access);let Z=(L,U)=>u(O,{activeId:L,route:U,mainAccessToken:K.access,mainRefreshToken:K.refresh}),_;if(T&&b1(O)==="fallback-first")try{let L=F();_=await c0(O,{includeApiRoutes:Q1(K.access)}),N.mark("fallback_first_get_accounts",{ms:A(F()-L),accounts:_.length});let U=await n0(Y,I,_,O,void 0,N,{returnLastOnExhausted:!1,onSuccess:(k)=>Z(k.id,"fallback-first")});if(U)return N.done("return_fallback_first",{status:U.status}),f0(U,{perf:(k,t)=>N.mark(k,t)});_=void 0}catch(L){N.mark("fallback_first_error",{error:L instanceof Error?L.message:String(L)})}if(!K.access||!K.expires||K.expires<Date.now()){let U=(await h())?.refresh?.mainLastRefreshError;if(K.refresh&&U&&U0(U,K.refresh,Date.now()))throw q("[refresh] opencode main oauth request skipped backoff",{nextRetryAt:U.nextRetryAt,retryCount:U.retryCount,expiresInMs:K.expires?K.expires-Date.now():void 0}),Error(v1(U,Date.now()));q("[refresh] opencode main oauth refresh required for request",{hasAccess:Boolean(K.access),expiresInMs:K.expires?K.expires-Date.now():void 0,expiredAgoMs:K.expires&&K.expires<Date.now()?Date.now()-K.expires:void 0});let k=F();K.access=await P(),N.mark("refresh_main_access",{ms:A(F()-k)})}if(!K.access)throw N.done("missing_access_error"),Error("OAuth access token is missing after refresh");function B(){if(O?.quota?.showToasts!==!0)return;let L=V.getMain();if(!L)return;let U=(O?.accounts??[]).filter((p)=>p.enabled!==!1&&e(p)).map((p)=>({...p,quota:V.getFallback(p.id,p.access)?.quota??p.quota})),k=b0(L.quota,O),t;if(k)t="main";else t=U.find((p)=>b0(p.quota,O))?.id??"main";q0(L.quota,U,t)}if(T&&Y0(O))try{let L=F(),U=V.getMain(K.access),k=U?.quota;if(!k)k=await V.refreshMain(K.access),U=V.getMain(K.access),B();else if(V.needsRefresh(d))if(O0(k))k=await V.refreshMain(K.access),U=V.getMain(K.access);else V.refreshMain(K.access).then(()=>{j0(),B()}).catch(()=>{});if(u(O,{activeId:"main",route:"main",mainAccessToken:K.access,mainRefreshToken:K.refresh}),N.mark("main_quota_for_routing",{ms:A(F()-L),passes:b0(k,O)}),!b0(k,O)){let t=F();_=await c0(O,{includeApiRoutes:Boolean(U&&U.refreshAfter>Date.now()&&O0(U.quota))}),N.mark("preselect_fallback_accounts",{ms:A(F()-t),accounts:_.length});let p=await n0(Y,I,_,O,void 0,N,{onSuccess:(c)=>Z(c.id,"fallback")});if(p)return N.done("return_preselected_fallback",{status:p.status}),f0(p,{perf:(c,i)=>N.mark(c,i)})}}catch(L){N.mark("main_quota_for_routing_error",{error:L instanceof Error?L.message:String(L)})}let Q=V.getMain(K.access)?.quota;if(O?.quota?.failClosedOnUnknownQuota&&!Q&&V.isBackedOff()){let L=V.getLastApiError(),U=L?Aj(L,Date.now()):"Quota API unavailable";return q("[quota] blocked: quota API backed off (failClosed)",{nextRetryAt:L?.nextRetryAt,retryCount:L?.retryCount}),new Response(JSON.stringify({type:"error",error:{type:"rate_limit_error",message:U}}),{status:429,headers:{"content-type":"application/json","retry-after":String(L?.nextRetryAt?Math.max(1,Math.ceil((L.nextRetryAt-Date.now())/1000)):60)}})}if(h0(O)){if(V.needsRefresh(d))try{let U=(O?.accounts??[]).filter((k)=>k.enabled!==!1&&e(k)&&Boolean(k.access));await Promise.all([V.refreshMain(K.access),V.refreshAllFallbacks(U)])}catch(U){q("[quota] killswitch refresh failed",{error:U instanceof Error?U.message:String(U),backedOff:V.isBackedOff()})}Q=V.getMain(K.access)?.quota}if(h0(O)&&!X1(Q,O)){let U=R(Y,I?.body)?await c0(O,{includeApiRoutes:Q1(K.access)}):[];if(U.length>0){q("[route] skipping main (killswitch), trying fallbacks");let c=await n0(Y,I,U,O,void 0,N,{onSuccess:(i)=>Z(i.id,"fallback")});if(c)return N.done("return_killswitch_fallback",{status:c.status}),f0(c,{perf:(i,X0)=>N.mark(i,X0)})}let k=Date.now(),t=(O?.accounts??[]).filter((c)=>c.enabled!==!1&&e(c)).map((c)=>({...c,quota:L0(c)})),p=kj(Q,t,k);return new Response(JSON.stringify({type:"error",error:{type:"rate_limit_error",message:`Killswitch: no routable accounts. Retry in ${Math.floor(p/60)}m ${p%60}s.`}}),{status:429,headers:{"content-type":"application/json","retry-after":String(p)}})}let l=await u0(Y,I,K.access,N,"main",O),m=!1,C=await YJ(Y,I,l,_,N,O,K.access,(L)=>{m=!0,Z(L.id,"fallback")});if(!m)Z("main","main");return N.done("return_response",{status:C.status}),f0(C,{perf:(L,U)=>N.mark(L,U)})}}}return{}},methods:[{label:"Claude Pro/Max",type:"oauth",authorize:async()=>{let X=await H1("max");return{url:X.url,instructions:"Paste the authorization code here:",method:"code",callback:async(G)=>{return x1(G,X.verifier,X.redirectUri,X.state)}}}},{label:"Create an API Key",type:"oauth",authorize:async()=>{let X=await H1("console");return{url:X.url,instructions:"Paste the authorization code here:",method:"code",callback:async(G)=>{let D=await x1(G,X.verifier,X.redirectUri,X.state);if(D.type==="failed")return D;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 ${D.access}`}}).then((P)=>P.json())).raw_key}}}}},{provider:"anthropic",label:"Manually enter API Key",type:"api"}]}}};export{_3 as AnthropicAuthPlugin};
15
+ `)&&p.length<65536){let{done:V,value:w}=await z.read();if(V)break;if(x.push(w),_+=w.byteLength,p+=X.decode(w,{stream:!0}),O0(p))break}if(O0(p))return await z.cancel().catch(()=>{}),Y?.mark("inspect_stream_first_event",{ms:h(C()-q),bytes:_,rateLimited:!0}),{response:Z,rateLimited:!0};let T=new ReadableStream({start(V){for(let w of x)V.enqueue(w)},async pull(V){let{done:w,value:B}=await z.read();if(w){V.close();return}V.enqueue(B)},cancel(V){return z.cancel(V)}});return Y?.mark("inspect_stream_first_event",{ms:h(C()-q),bytes:_,rateLimited:!1}),{response:new Response(T,{status:Z.status,statusText:Z.statusText,headers:Z.headers}),rateLimited:!1}}async function B0(Z,Y,q,z,x="api_fallback",X){let p=C(),_=L1(Z,Y),T=_.get("x-session-affinity")||_.get("x-opencode-session"),V=y(_);_.delete("x-parent-session-id"),_.delete("x-session-affinity"),_.delete("x-opencode-session");let w=Y?.body,B=typeof w==="string"?w.length:void 0;if(w&&typeof w==="string"){let F=C(),Q=(()=>{if(!Z1())return!1;try{return A0(JSON.parse(w).model)}catch{return!1}})();if(w=await B1(w,{cache1hEnabled:!V&&x0(),cache1hMode:q0(),fastModeEnabled:Q,perf:(M,g)=>z?.mark(`rewrite_body_${M}`,{route:x,...g})}),_0(_,q),_.set("anthropic-beta",v0(_.get("anthropic-beta"),[])),Q)W1(_);z?.mark("rewrite_body",{route:x,ms:h(C()-F),originalBytes:B,rewrittenBytes:w.length,cacheEnabled:!V&&x0(),cacheMode:q0(),fastModeEnabled:Q,subagent:V})}else _0(_,q);let U=M1(Z,{baseURL:q.baseURL}),c=C(),n;try{n=await fetch(U.input,{...Y,body:w,headers:_,...U1()&&{tls:{rejectUnauthorized:!1}}})}catch(F){if(typeof w==="string")await d0({affinity:T,route:x,error:vW(F),bodyText:w,url:U.url?.toString()??J1(U.input),method:P1(Z,Y),headers:_});throw F}if(typeof w==="string")await d0({affinity:T,route:x,status:n.status,bodyText:w,url:U.url?.toString()??J1(U.input),method:P1(Z,Y),headers:_});return z?.mark("send_headers_received",{route:x,ms:h(C()-c),status:n.status,relayConfigured:!1,totalSendWithAccessMs:h(C()-p),baseURL:q.baseURL}),n}async function c0(Z,Y,q,z,x="unknown",X){let p=C(),_=X,T=async()=>{return _??=await A(j),_},V=L1(Z,Y),w=V.get("x-session-affinity")||V.get("x-opencode-session"),B=y(V);V.delete("x-parent-session-id"),V.delete("x-session-affinity"),V.delete("x-opencode-session");let U=Y?.body,c;if(U&&typeof U==="string"){let o=C();try{let N0=JSON.parse(U);if(typeof N0.model==="string")c=N0.model}catch{}z?.mark("model_parse_for_identity",{route:x,ms:h(C()-o),bodyBytes:U.length})}let n=C(),F=await S1(q,c);z?.mark("resolve_claude_code_identity",{route:x,ms:h(C()-n),hasAccountUuid:Boolean(F.accountUuid)});let Q=typeof U==="string"?U.length:void 0;if(U&&typeof U==="string"){let o=C(),N0=(()=>{if(!Z1())return!1;try{return A0(JSON.parse(U).model)}catch{return!1}})();U=await B1(U,{cache1hEnabled:!B&&x0(),cache1hMode:q0(),fastModeEnabled:N0,identity:F,perf:(B4,C4)=>z?.mark(`rewrite_body_${B4}`,{route:x,...C4})});let F0=C();try{k0(V,q,{body:JSON.parse(U),identity:F}),z?.mark("set_oauth_headers_body_parse",{route:x,ms:h(C()-F0),bodyBytes:U.length,parsed:!0})}catch{k0(V,q,{identity:F}),z?.mark("set_oauth_headers_body_parse",{route:x,ms:h(C()-F0),bodyBytes:U.length,parsed:!1})}if(N0)W1(V);z?.mark("rewrite_body",{route:x,ms:h(C()-o),originalBytes:Q,rewrittenBytes:U.length,cacheEnabled:!B&&x0(),cacheMode:q0(),fastModeEnabled:N0,subagent:B})}let M=M1(Z);if(x==="main"&&typeof U==="string"&&!B&&x0()&&q0()==="hybrid"){let o=await T(),N0=C(),F0=H.track({sessionId:w,url:M.url?.toString()??M.input.toString(),headers:V,bodyText:U,storage:o,cacheMode:"hybrid"});z?.mark("cachekeep_track",{session:w,ms:h(C()-N0),tracked:F0.tracked,reason:F0.tracked?void 0:F0.reason,bodyBytes:U.length})}let g=async()=>{try{let o=await fetch(M.input,{...Y,body:U,headers:V,...U1()&&{tls:{rejectUnauthorized:!1}}});if(typeof U==="string")await d0({affinity:w,route:x,status:o.status,bodyText:U,url:M.url?.toString()??J1(M.input),method:P1(Z,Y),headers:V});return o}catch(o){if(typeof U==="string")await d0({affinity:w,route:x,error:vW(o),bodyText:U,url:M.url?.toString()??J1(M.input),method:P1(Z,Y),headers:V});throw o}},e=p1(await T()),u=C(),t=await Y4({config:e,input:M.input,init:Y,headers:V,body:U,fallback:g,affinity:w,optimisticResponse:e?.transport==="websocket"});return z?.mark("send_headers_received",{route:x,ms:h(C()-u),status:t.status,relayConfigured:e!=null,totalSendWithAccessMs:h(C()-p)}),t}async function U4(Z){if(!Z)return!1;try{return await P.refreshMain(Z),z1(Z)}catch{return!1}}async function o0(Z,Y={}){let q=await G.getUsableFallbackAccounts(Z),z=new Map(q.map((X)=>[X.id,X])),x=[];for(let X of Z?.accounts??[]){if(W0(X)){let p=z.get(X.id);if(p)x.push(p);continue}if(Y.includeApiRoutes===!0&&h0(X)&&X.enabled!==!1&&X.apiKey&&f1(X.baseURL))x.push(X)}if(!i0(Z))return x;return x.filter((X)=>W0(X)?G1(C0(X),Z,X.id):!0)}async function r0(Z,Y,q,z,x,X,p){if(!q.length)return x??null;let _=p?.returnLastOnExhausted??!0;await x?.body?.cancel().catch(()=>{});let T=x??null;for(let[V,w]of q.entries()){let B;if(h0(w)){if(!w.apiKey)continue;B=await B0(Z,Y,w,X,`api_fallback_${V}`,z)}else{let c=w.access;if(!c)continue;B=await c0(Z,Y,c,X,`fallback_${V}`,z)}T=B;let U=x1(B.status,z);if(!U){let c=await V0(B,X);B=c.response,T=B,U=c.rateLimited}if(!U){if(await G.markUsed(w),p?.onSuccess?.(w),W0(w)&&w.access&&P.shouldRefreshOnRequestCount(j0))P.refreshFallback(w.id,w.access).then(()=>p?.onSuccess?.(w)).catch(()=>{});return B}if(V<q.length-1||!_)await B.body?.cancel().catch(()=>{})}return _?T:null}async function M4(Z,Y,q,z,x,X,p,_){if(!f(Z,Y?.body))return q;let T=C(),V=X??await A(j);if(x?.mark("fallback_load_storage",{ms:h(C()-T),cached:!!X}),!(V?.accounts??[]).some((Q)=>Q.enabled!==!1&&(W0(Q)||h0(Q)&&Boolean(Q.apiKey)&&f1(Q.baseURL))))return q;let B=q,U=x1(B.status,V),c=d1(B,!1);if(!U){let Q=await V0(B,x);B=Q.response,U=Q.rateLimited,c=d1(B,Q.rateLimited)}if(!U)return B;let n=!1;if(z)n=z.some(h0);else if(c)n=await U4(p);let F=z;if(!F){let Q=C();F=await o0(V,{includeApiRoutes:n}),x?.mark("fallback_get_accounts",{ms:h(C()-Q),accounts:F.length})}if(i0(V)){let Q=F.length;if(F=F.filter((M)=>W0(M)?G1(C0(M),V,M.id):!0),F.length<Q)S("[killswitch] filtered fallbacks",{before:Q,after:F.length})}return await r0(Z,Y,F,V,B,x,{onSuccess:_})??B}return{apiKey:"",async fetch(Z,Y){let q=Y?.body,z=Bj({bodyBytes:typeof q==="string"?q.length:void 0}),x=C(),X=await $();if(z.mark("get_auth",{ms:h(C()-x),authType:X.type,hasAccess:Boolean(X.access)}),X.type!=="oauth"){let Q=await fetch(Z,Y);return z.done("non_oauth_passthrough",{status:Q.status}),Q}await J0(X.refresh);let p=C(),_=await A();z.mark("load_storage",{ms:h(C()-p)}),P.updateStorage(_),P.seedMainFromStorage(_,X.access),P.seedFallbacksFromAccounts((_?.accounts??[]).filter(W0));let T=f(Z,Y?.body);if(T)j0++;if(T&&X.access&&(!X.expires||X.expires>Date.now()))r(_,X.access);let V=(Q,M)=>m(_,{activeId:Q,route:M,mainAccessToken:X.access,mainRefreshToken:X.refresh}),w;if(T&&K1(_)==="fallback-first")try{let Q=C();w=await o0(_,{includeApiRoutes:z1(X.access)}),z.mark("fallback_first_get_accounts",{ms:h(C()-Q),accounts:w.length});let M=await r0(Z,Y,w,_,void 0,z,{returnLastOnExhausted:!1,onSuccess:(g)=>V(g.id,"fallback-first")});if(M)return z.done("return_fallback_first",{status:M.status}),y0(M,{perf:(g,e)=>z.mark(g,e)});w=void 0}catch(Q){z.mark("fallback_first_error",{error:Q instanceof Error?Q.message:String(Q)})}if(!X.access||!X.expires||X.expires<Date.now()){let M=(await A())?.refresh?.mainLastRefreshError;if(X.refresh&&M&&f0(M,X.refresh,Date.now()))throw S("[refresh] opencode main oauth request skipped backoff",{nextRetryAt:M.nextRetryAt,retryCount:M.retryCount,expiresInMs:X.expires?X.expires-Date.now():void 0}),Error(q1(M,Date.now()));S("[refresh] opencode main oauth refresh required for request",{hasAccess:Boolean(X.access),expiresInMs:X.expires?X.expires-Date.now():void 0,expiredAgoMs:X.expires&&X.expires<Date.now()?Date.now()-X.expires:void 0});let g=C();X.access=await D(),z.mark("refresh_main_access",{ms:h(C()-g)})}if(!X.access)throw z.done("missing_access_error"),Error("OAuth access token is missing after refresh");function B(){if(_?.quota?.showToasts!==!0)return;let Q=P.getMain();if(!Q)return;let M=(_?.accounts??[]).filter((u)=>u.enabled!==!1&&W0(u)).map((u)=>({...u,quota:P.getFallback(u.id,u.access)?.quota??u.quota})),g=p0(Q.quota,_),e;if(g)e="main";else e=M.find((u)=>p0(u.quota,_))?.id??"main";u0(Q.quota,M,e)}if(T&&Z0(_))try{let Q=C(),M=P.getMain(X.access),g=M?.quota;if(!g)g=await P.refreshMain(X.access),M=P.getMain(X.access),B();else if(P.needsRefresh(j0))if(Y0(g))g=await P.refreshMain(X.access),M=P.getMain(X.access);else P.refreshMain(X.access).then(()=>{E(),B()}).catch(()=>{});if(m(_,{activeId:"main",route:"main",mainAccessToken:X.access,mainRefreshToken:X.refresh}),z.mark("main_quota_for_routing",{ms:h(C()-Q),passes:p0(g,_)}),!p0(g,_)){let e=C();w=await o0(_,{includeApiRoutes:Boolean(M&&M.refreshAfter>Date.now()&&Y0(M.quota))}),z.mark("preselect_fallback_accounts",{ms:h(C()-e),accounts:w.length});let u=await r0(Z,Y,w,_,void 0,z,{onSuccess:(t)=>V(t.id,"fallback")});if(u)return z.done("return_preselected_fallback",{status:u.status}),y0(u,{perf:(t,o)=>z.mark(t,o)})}}catch(Q){z.mark("main_quota_for_routing_error",{error:Q instanceof Error?Q.message:String(Q)})}let U=P.getMain(X.access)?.quota;if(_?.quota?.failClosedOnUnknownQuota&&!U&&P.isBackedOff()){let Q=P.getLastApiError(),M=Q?uW(Q,Date.now()):"Quota API unavailable";return S("[quota] blocked: quota API backed off (failClosed)",{nextRetryAt:Q?.nextRetryAt,retryCount:Q?.retryCount}),new Response(JSON.stringify({type:"error",error:{type:"rate_limit_error",message:M}}),{status:429,headers:{"content-type":"application/json","retry-after":String(Q?.nextRetryAt?Math.max(1,Math.ceil((Q.nextRetryAt-Date.now())/1000)):60)}})}if(i0(_)){if(P.needsRefresh(j0))try{let M=(_?.accounts??[]).filter((g)=>g.enabled!==!1&&W0(g)&&Boolean(g.access));await Promise.all([P.refreshMain(X.access),P.refreshAllFallbacks(M)])}catch(M){S("[quota] killswitch refresh failed",{error:M instanceof Error?M.message:String(M),backedOff:P.isBackedOff()})}U=P.getMain(X.access)?.quota}if(i0(_)&&!G1(U,_)){let M=f(Z,Y?.body)?await o0(_,{includeApiRoutes:z1(X.access)}):[];if(M.length>0){S("[route] skipping main (killswitch), trying fallbacks");let t=await r0(Z,Y,M,_,void 0,z,{onSuccess:(o)=>V(o.id,"fallback")});if(t)return z.done("return_killswitch_fallback",{status:t.status}),y0(t,{perf:(o,N0)=>z.mark(o,N0)})}let g=Date.now(),e=(_?.accounts??[]).filter((t)=>t.enabled!==!1&&W0(t)).map((t)=>({...t,quota:C0(t)})),u=oW(U,e,g);return new Response(JSON.stringify({type:"error",error:{type:"rate_limit_error",message:`Killswitch: no routable accounts. Retry in ${Math.floor(u/60)}m ${u%60}s.`}}),{status:429,headers:{"content-type":"application/json","retry-after":String(u)}})}let c=await c0(Z,Y,X.access,z,"main",_),n=!1,F=await M4(Z,Y,c,w,z,_,X.access,(Q)=>{n=!0,V(Q.id,"fallback")});if(!n)V("main","main");return z.done("return_response",{status:F.status}),y0(F,{perf:(Q,M)=>z.mark(Q,M)})}}}return{}},methods:[{label:"Claude Pro/Max",type:"oauth",authorize:async()=>{let $=await F1("max");return{url:$.url,instructions:"Paste the authorization code here:",method:"code",callback:async(N)=>{return H1(N,$.verifier,$.redirectUri,$.state)}}}},{label:"Create an API Key",type:"oauth",authorize:async()=>{let $=await F1("console");return{url:$.url,instructions:"Paste the authorization code here:",method:"code",callback:async(N)=>{let K=await H1(N,$.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((D)=>D.json())).raw_key}}}}},{provider:"anthropic",label:"Manually enter API Key",type:"api"}]}}};export{sj as AnthropicAuthPlugin};
@@ -0,0 +1,5 @@
1
+ import type { OpenDialogPayload, RpcNotification } from './protocol';
2
+ export declare function pushNotification(payload: OpenDialogPayload, sessionId?: string): void;
3
+ export declare function drainNotifications(lastReceivedId?: number, sessionId?: string): RpcNotification[];
4
+ export declare function isTuiConnected(sessionId?: string): boolean;
5
+ export declare function resetNotificationsForTest(): void;
@@ -0,0 +1,12 @@
1
+ export interface PortFileEntry {
2
+ port: number;
3
+ token: string;
4
+ pid: number;
5
+ startedAt: number;
6
+ }
7
+ export declare function writePortFile(dir: string, entry: {
8
+ port: number;
9
+ token: string;
10
+ pid: number;
11
+ }): Promise<string>;
12
+ export declare function discoverPortFile(dir: string): Promise<PortFileEntry | null>;
@@ -0,0 +1 @@
1
+ import{db as a,eb as b}from"../index-jb14nj5c.js";import"../index-p8j7mmfc.js";export{a as writePortFile,b as discoverPortFile};
@@ -0,0 +1,20 @@
1
+ export type CommandModalName = 'claude-cache' | 'claude-cachekeep' | 'claude-quota' | 'claude-dump' | 'claude-fast' | 'claude-routing' | 'claude-killswitch';
2
+ export interface OpenDialogPayload {
3
+ command: CommandModalName;
4
+ text: string;
5
+ knobs: Record<string, unknown>;
6
+ }
7
+ export interface RpcNotification {
8
+ id: number;
9
+ type: 'open-dialog';
10
+ payload: OpenDialogPayload;
11
+ sessionId?: string;
12
+ }
13
+ export interface ApplyRequest {
14
+ command: CommandModalName;
15
+ arguments: string;
16
+ }
17
+ export interface ApplyResult {
18
+ text: string;
19
+ knobs: Record<string, unknown>;
20
+ }
File without changes
@@ -0,0 +1,6 @@
1
+ import type { ApplyRequest, ApplyResult, RpcNotification } from './protocol';
2
+ export interface RpcClient {
3
+ pending: (lastReceivedId: number, sessionId?: string) => Promise<RpcNotification[]>;
4
+ apply: (request: ApplyRequest) => Promise<ApplyResult>;
5
+ }
6
+ export declare function createRpcClient(dir: string): RpcClient;
@@ -0,0 +1 @@
1
+ import{eb as a}from"../index-jb14nj5c.js";import"../index-p8j7mmfc.js";async function s(e,t,n){let o=await a(e);if(!o)return null;let i=new AbortController,l=setTimeout(()=>i.abort(),2000);try{let r=await fetch(`http://127.0.0.1:${o.port}/rpc/${t}`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${o.token}`},body:JSON.stringify(n),signal:i.signal});if(!r.ok)return null;return await r.json()}catch{return null}finally{clearTimeout(l)}}function c(e){return{async pending(t,n){return(await s(e,"pending-notifications",{lastReceivedId:t,sessionId:n}))?.messages??[]},async apply(t){return await s(e,"apply",{...t})??{text:"apply failed",knobs:{}}}}}export{c as createRpcClient};
@@ -0,0 +1,3 @@
1
+ import { tmpdir } from 'node:os';
2
+ export declare function getRpcDir(projectDirectory: string): string;
3
+ export { tmpdir };
@@ -0,0 +1 @@
1
+ import{fb as a,gb as b}from"../index-3ynbghx3.js";import"../index-p8j7mmfc.js";export{a as tmpdir,b as getRpcDir};
@@ -0,0 +1,13 @@
1
+ import type { drainNotifications } from './notifications';
2
+ import type { ApplyRequest, ApplyResult } from './protocol';
3
+ export interface RpcServerHandle {
4
+ port: number;
5
+ token: string;
6
+ stop: () => Promise<void>;
7
+ }
8
+ export interface RpcServerOptions {
9
+ dir: string;
10
+ drain: typeof drainNotifications;
11
+ apply: (request: ApplyRequest) => Promise<ApplyResult>;
12
+ }
13
+ export declare function startRpcServer(options: RpcServerOptions): Promise<RpcServerHandle>;
@@ -1 +1 @@
1
- import{$a as f,Wa as a,Xa as b,Ya as c,Za as d,_a as e,ab as g,bb as h,cb as i}from"./index-9yjbmhf1.js";import"./index-agh52sak.js";export{d as setSidebarState,e as resolveActiveAccount,a as getSidebarStateFile,c as getSidebarState,f as getCollapsedQuotaSummary,i as computeQuotaPacing,h as SEVEN_DAY_MS,g as FIVE_HOUR_MS,b as DEFAULT_SIDEBAR_STATE};
1
+ import{$a as f,Wa as a,Xa as b,Ya as c,Za as d,_a as e,ab as g,bb as h,cb as i}from"./index-9yjbmhf1.js";import"./index-p8j7mmfc.js";export{d as setSidebarState,e as resolveActiveAccount,a as getSidebarStateFile,c as getSidebarState,f as getCollapsedQuotaSummary,i as computeQuotaPacing,h as SEVEN_DAY_MS,g as FIVE_HOUR_MS,b as DEFAULT_SIDEBAR_STATE};
@@ -0,0 +1,8 @@
1
+ /** @jsxImportSource @opentui/solid */
2
+ import type { TuiPluginApi } from '@opencode-ai/plugin/tui';
3
+ import type { OpenDialogPayload } from '../rpc/protocol.js';
4
+ type ApplyFn = (command: OpenDialogPayload['command'], args: string) => Promise<{
5
+ text: string;
6
+ }>;
7
+ export declare function openCommandDialog(api: TuiPluginApi, payload: OpenDialogPayload, apply: ApplyFn): void;
8
+ export {};
@@ -1,4 +1,4 @@
1
- import{db as P,eb as C,fb as _}from"./index-agh52sak.js";var g=C((T,L)=>{(function(Q){if(typeof L==="object"&&typeof L.exports==="object"){var J=Q(_,T);if(J!==void 0)L.exports=J}else if(typeof define==="function"&&define.amd)define(["require","exports","./impl/format","./impl/edit","./impl/scanner","./impl/parser"],Q)})(function(Q,J){Object.defineProperty(J,"__esModule",{value:!0}),J.applyEdits=J.modify=J.format=J.printParseErrorCode=J.ParseErrorCode=J.stripComments=J.visit=J.getNodeValue=J.getNodePath=J.findNodeAtOffset=J.findNodeAtLocation=J.parseTree=J.parse=J.getLocation=J.SyntaxKind=J.ScanError=J.createScanner=void 0;let X=Q("./impl/format"),Z=Q("./impl/edit"),G=Q("./impl/scanner"),$=Q("./impl/parser");J.createScanner=G.createScanner;var W;(function(z){z[z.None=0]="None",z[z.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",z[z.UnexpectedEndOfString=2]="UnexpectedEndOfString",z[z.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",z[z.InvalidUnicode=4]="InvalidUnicode",z[z.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",z[z.InvalidCharacter=6]="InvalidCharacter"})(W||(J.ScanError=W={}));var H;(function(z){z[z.OpenBraceToken=1]="OpenBraceToken",z[z.CloseBraceToken=2]="CloseBraceToken",z[z.OpenBracketToken=3]="OpenBracketToken",z[z.CloseBracketToken=4]="CloseBracketToken",z[z.CommaToken=5]="CommaToken",z[z.ColonToken=6]="ColonToken",z[z.NullKeyword=7]="NullKeyword",z[z.TrueKeyword=8]="TrueKeyword",z[z.FalseKeyword=9]="FalseKeyword",z[z.StringLiteral=10]="StringLiteral",z[z.NumericLiteral=11]="NumericLiteral",z[z.LineCommentTrivia=12]="LineCommentTrivia",z[z.BlockCommentTrivia=13]="BlockCommentTrivia",z[z.LineBreakTrivia=14]="LineBreakTrivia",z[z.Trivia=15]="Trivia",z[z.Unknown=16]="Unknown",z[z.EOF=17]="EOF"})(H||(J.SyntaxKind=H={})),J.getLocation=$.getLocation,J.parse=$.parse,J.parseTree=$.parseTree,J.findNodeAtLocation=$.findNodeAtLocation,J.findNodeAtOffset=$.findNodeAtOffset,J.getNodePath=$.getNodePath,J.getNodeValue=$.getNodeValue,J.visit=$.visit,J.stripComments=$.stripComments;var q;(function(z){z[z.InvalidSymbol=1]="InvalidSymbol",z[z.InvalidNumberFormat=2]="InvalidNumberFormat",z[z.PropertyNameExpected=3]="PropertyNameExpected",z[z.ValueExpected=4]="ValueExpected",z[z.ColonExpected=5]="ColonExpected",z[z.CommaExpected=6]="CommaExpected",z[z.CloseBraceExpected=7]="CloseBraceExpected",z[z.CloseBracketExpected=8]="CloseBracketExpected",z[z.EndOfFileExpected=9]="EndOfFileExpected",z[z.InvalidCommentToken=10]="InvalidCommentToken",z[z.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",z[z.UnexpectedEndOfString=12]="UnexpectedEndOfString",z[z.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",z[z.InvalidUnicode=14]="InvalidUnicode",z[z.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",z[z.InvalidCharacter=16]="InvalidCharacter"})(q||(J.ParseErrorCode=q={}));function D(z){switch(z){case 1:return"InvalidSymbol";case 2:return"InvalidNumberFormat";case 3:return"PropertyNameExpected";case 4:return"ValueExpected";case 5:return"ColonExpected";case 6:return"CommaExpected";case 7:return"CloseBraceExpected";case 8:return"CloseBracketExpected";case 9:return"EndOfFileExpected";case 10:return"InvalidCommentToken";case 11:return"UnexpectedEndOfComment";case 12:return"UnexpectedEndOfString";case 13:return"UnexpectedEndOfNumber";case 14:return"InvalidUnicode";case 15:return"InvalidEscapeCharacter";case 16:return"InvalidCharacter"}return"<unknown ParseErrorCode>"}J.printParseErrorCode=D;function m(z,U,j){return X.format(z,U,j)}J.format=m;function f(z,U,j,A){return Z.setProperty(z,U,j,A)}J.modify=f;function u(z,U){let j=U.slice(0).sort((I,Y)=>{let F=I.offset-Y.offset;if(F===0)return I.length-Y.length;return F}),A=z.length;for(let I=j.length-1;I>=0;I--){let Y=j[I];if(Y.offset+Y.length<=A)z=Z.applyEdit(z,Y);else throw Error("Overlapping edit");A=Y.offset}return z}J.applyEdits=u})});var M=P(g(),1);import{watch as K}from"node:fs";import{mkdir as c,readFile as O,rename as y,writeFile as S}from"node:fs/promises";import{homedir as E}from"node:os";import{basename as l,dirname as v,join as k}from"node:path";var p="OPENCODE_TUI_PREFERENCES_FILE",x="tui-preferences.jsonc";function w(){let Q=process.env[p];if(Q)return Q;let J=process.env.OPENCODE_CONFIG_DIR||k(process.env.XDG_CONFIG_HOME||k(E(),".config"),"opencode");return k(J,x)}function N(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}async function Xz(){try{let Q=await O(w(),"utf8"),J=[],X=M.parse(Q,J,{allowTrailingComma:!0});if(J.length>0)return{};return N(X)?X:{}}catch{return{}}}var i="anthropic-auth",s=160,b={forceToTop:!1,order:s,startCollapsed:!1,rememberCollapsed:!0,collapsed:null,pollMs:1500,refreshDebounceMs:200,header:{label:"CLAUDE",showVersion:!0},sections:{quota:!0,fallbackAccounts:!0,routing:!0,cache:!0,health:!0,pacing:!0},appearance:{barWidth:10,barFilledChar:"█",barEmptyChar:"░",warnThreshold:50,errorThreshold:80}};function V(Q,J){return typeof Q==="boolean"?Q:J}function B(Q,J,X,Z){if(typeof Q!=="number"||!Number.isFinite(Q))return J;return Math.min(Math.max(Math.round(Q),X),Z)}function d(Q,J,X){if(typeof Q!=="string"||Q.length===0)return J;return Q.slice(0,X)}function h(Q,J){if(typeof Q!=="string")return J;return[...Q][0]??J}function Zz(Q){let J=Q[i];if(!N(J))return structuredClone(b);let X=b,Z=N(J.header)?J.header:{},G=N(J.sections)?J.sections:{},$=N(J.appearance)?J.appearance:{},W=B($.warnThreshold,X.appearance.warnThreshold,0,99),H=Math.max(B($.errorThreshold,X.appearance.errorThreshold,0,100),Math.min(W+1,100));return{forceToTop:V(J.forceToTop,X.forceToTop),order:B(J.order,X.order,-1e4,1e4),startCollapsed:V(J.startCollapsed,X.startCollapsed),rememberCollapsed:V(J.rememberCollapsed,X.rememberCollapsed),collapsed:typeof J.collapsed==="boolean"?J.collapsed:null,pollMs:B(J.pollMs,X.pollMs,500,30000),refreshDebounceMs:B(J.refreshDebounceMs,X.refreshDebounceMs,50,5000),header:{label:d(Z.label,X.header.label,20),showVersion:V(Z.showVersion,X.header.showVersion)},sections:{quota:V(G.quota,X.sections.quota),fallbackAccounts:V(G.fallbackAccounts,X.sections.fallbackAccounts),routing:V(G.routing,X.sections.routing),cache:V(G.cache,X.sections.cache),health:V(G.health,X.sections.health),pacing:V(G.pacing,X.sections.pacing)},appearance:{barWidth:B($.barWidth,X.appearance.barWidth,4,40),barFilledChar:h($.barFilledChar,X.appearance.barFilledChar),barEmptyChar:h($.barEmptyChar,X.appearance.barEmptyChar),warnThreshold:W,errorThreshold:H}}}var n=-1e5;function $z(Q,J,X){let Z=Q[J];if(!N(Z))return X;if(Z.forceToTop===!0)return n+Object.keys(Q).indexOf(J);return B(Z.order,X,-1e4,1e4)}var t=`// Shared preferences for opencode TUI plugins.
1
+ import{hb as P,ib as C,jb as _}from"./index-p8j7mmfc.js";var g=C((T,L)=>{(function(Q){if(typeof L==="object"&&typeof L.exports==="object"){var J=Q(_,T);if(J!==void 0)L.exports=J}else if(typeof define==="function"&&define.amd)define(["require","exports","./impl/format","./impl/edit","./impl/scanner","./impl/parser"],Q)})(function(Q,J){Object.defineProperty(J,"__esModule",{value:!0}),J.applyEdits=J.modify=J.format=J.printParseErrorCode=J.ParseErrorCode=J.stripComments=J.visit=J.getNodeValue=J.getNodePath=J.findNodeAtOffset=J.findNodeAtLocation=J.parseTree=J.parse=J.getLocation=J.SyntaxKind=J.ScanError=J.createScanner=void 0;let X=Q("./impl/format"),Z=Q("./impl/edit"),G=Q("./impl/scanner"),$=Q("./impl/parser");J.createScanner=G.createScanner;var W;(function(z){z[z.None=0]="None",z[z.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",z[z.UnexpectedEndOfString=2]="UnexpectedEndOfString",z[z.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",z[z.InvalidUnicode=4]="InvalidUnicode",z[z.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",z[z.InvalidCharacter=6]="InvalidCharacter"})(W||(J.ScanError=W={}));var H;(function(z){z[z.OpenBraceToken=1]="OpenBraceToken",z[z.CloseBraceToken=2]="CloseBraceToken",z[z.OpenBracketToken=3]="OpenBracketToken",z[z.CloseBracketToken=4]="CloseBracketToken",z[z.CommaToken=5]="CommaToken",z[z.ColonToken=6]="ColonToken",z[z.NullKeyword=7]="NullKeyword",z[z.TrueKeyword=8]="TrueKeyword",z[z.FalseKeyword=9]="FalseKeyword",z[z.StringLiteral=10]="StringLiteral",z[z.NumericLiteral=11]="NumericLiteral",z[z.LineCommentTrivia=12]="LineCommentTrivia",z[z.BlockCommentTrivia=13]="BlockCommentTrivia",z[z.LineBreakTrivia=14]="LineBreakTrivia",z[z.Trivia=15]="Trivia",z[z.Unknown=16]="Unknown",z[z.EOF=17]="EOF"})(H||(J.SyntaxKind=H={})),J.getLocation=$.getLocation,J.parse=$.parse,J.parseTree=$.parseTree,J.findNodeAtLocation=$.findNodeAtLocation,J.findNodeAtOffset=$.findNodeAtOffset,J.getNodePath=$.getNodePath,J.getNodeValue=$.getNodeValue,J.visit=$.visit,J.stripComments=$.stripComments;var q;(function(z){z[z.InvalidSymbol=1]="InvalidSymbol",z[z.InvalidNumberFormat=2]="InvalidNumberFormat",z[z.PropertyNameExpected=3]="PropertyNameExpected",z[z.ValueExpected=4]="ValueExpected",z[z.ColonExpected=5]="ColonExpected",z[z.CommaExpected=6]="CommaExpected",z[z.CloseBraceExpected=7]="CloseBraceExpected",z[z.CloseBracketExpected=8]="CloseBracketExpected",z[z.EndOfFileExpected=9]="EndOfFileExpected",z[z.InvalidCommentToken=10]="InvalidCommentToken",z[z.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",z[z.UnexpectedEndOfString=12]="UnexpectedEndOfString",z[z.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",z[z.InvalidUnicode=14]="InvalidUnicode",z[z.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",z[z.InvalidCharacter=16]="InvalidCharacter"})(q||(J.ParseErrorCode=q={}));function D(z){switch(z){case 1:return"InvalidSymbol";case 2:return"InvalidNumberFormat";case 3:return"PropertyNameExpected";case 4:return"ValueExpected";case 5:return"ColonExpected";case 6:return"CommaExpected";case 7:return"CloseBraceExpected";case 8:return"CloseBracketExpected";case 9:return"EndOfFileExpected";case 10:return"InvalidCommentToken";case 11:return"UnexpectedEndOfComment";case 12:return"UnexpectedEndOfString";case 13:return"UnexpectedEndOfNumber";case 14:return"InvalidUnicode";case 15:return"InvalidEscapeCharacter";case 16:return"InvalidCharacter"}return"<unknown ParseErrorCode>"}J.printParseErrorCode=D;function m(z,U,j){return X.format(z,U,j)}J.format=m;function f(z,U,j,A){return Z.setProperty(z,U,j,A)}J.modify=f;function u(z,U){let j=U.slice(0).sort((I,Y)=>{let F=I.offset-Y.offset;if(F===0)return I.length-Y.length;return F}),A=z.length;for(let I=j.length-1;I>=0;I--){let Y=j[I];if(Y.offset+Y.length<=A)z=Z.applyEdit(z,Y);else throw Error("Overlapping edit");A=Y.offset}return z}J.applyEdits=u})});var M=P(g(),1);import{watch as K}from"node:fs";import{mkdir as c,readFile as O,rename as y,writeFile as S}from"node:fs/promises";import{homedir as E}from"node:os";import{basename as l,dirname as v,join as k}from"node:path";var p="OPENCODE_TUI_PREFERENCES_FILE",x="tui-preferences.jsonc";function w(){let Q=process.env[p];if(Q)return Q;let J=process.env.OPENCODE_CONFIG_DIR||k(process.env.XDG_CONFIG_HOME||k(E(),".config"),"opencode");return k(J,x)}function N(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}async function Xz(){try{let Q=await O(w(),"utf8"),J=[],X=M.parse(Q,J,{allowTrailingComma:!0});if(J.length>0)return{};return N(X)?X:{}}catch{return{}}}var i="anthropic-auth",s=160,b={forceToTop:!1,order:s,startCollapsed:!1,rememberCollapsed:!0,collapsed:null,pollMs:1500,refreshDebounceMs:200,header:{label:"CLAUDE",showVersion:!0},sections:{quota:!0,fallbackAccounts:!0,routing:!0,cache:!0,health:!0,pacing:!0},appearance:{barWidth:10,barFilledChar:"█",barEmptyChar:"░",warnThreshold:50,errorThreshold:80}};function V(Q,J){return typeof Q==="boolean"?Q:J}function B(Q,J,X,Z){if(typeof Q!=="number"||!Number.isFinite(Q))return J;return Math.min(Math.max(Math.round(Q),X),Z)}function d(Q,J,X){if(typeof Q!=="string"||Q.length===0)return J;return Q.slice(0,X)}function h(Q,J){if(typeof Q!=="string")return J;return[...Q][0]??J}function Zz(Q){let J=Q[i];if(!N(J))return structuredClone(b);let X=b,Z=N(J.header)?J.header:{},G=N(J.sections)?J.sections:{},$=N(J.appearance)?J.appearance:{},W=B($.warnThreshold,X.appearance.warnThreshold,0,99),H=Math.max(B($.errorThreshold,X.appearance.errorThreshold,0,100),Math.min(W+1,100));return{forceToTop:V(J.forceToTop,X.forceToTop),order:B(J.order,X.order,-1e4,1e4),startCollapsed:V(J.startCollapsed,X.startCollapsed),rememberCollapsed:V(J.rememberCollapsed,X.rememberCollapsed),collapsed:typeof J.collapsed==="boolean"?J.collapsed:null,pollMs:B(J.pollMs,X.pollMs,500,30000),refreshDebounceMs:B(J.refreshDebounceMs,X.refreshDebounceMs,50,5000),header:{label:d(Z.label,X.header.label,20),showVersion:V(Z.showVersion,X.header.showVersion)},sections:{quota:V(G.quota,X.sections.quota),fallbackAccounts:V(G.fallbackAccounts,X.sections.fallbackAccounts),routing:V(G.routing,X.sections.routing),cache:V(G.cache,X.sections.cache),health:V(G.health,X.sections.health),pacing:V(G.pacing,X.sections.pacing)},appearance:{barWidth:B($.barWidth,X.appearance.barWidth,4,40),barFilledChar:h($.barFilledChar,X.appearance.barFilledChar),barEmptyChar:h($.barEmptyChar,X.appearance.barEmptyChar),warnThreshold:W,errorThreshold:H}}}var n=-1e5;function $z(Q,J,X){let Z=Q[J];if(!N(Z))return X;if(Z.forceToTop===!0)return n+Object.keys(Q).indexOf(J);return B(Z.order,X,-1e4,1e4)}var t=`// Shared preferences for opencode TUI plugins.
2
2
  // One top-level key per plugin (short name). See each plugin's README for
3
3
  // its supported settings. This file is safe to hand-edit; plugins update
4
4
  // individual keys in place and preserve comments.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-anthropic-auth",
3
- "version": "1.9.4",
3
+ "version": "1.10.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,13 +36,15 @@
36
36
  "files": [
37
37
  "dist",
38
38
  "src/tui.tsx",
39
+ "src/tui/command-dialogs.tsx",
39
40
  "src/sidebar-state.ts",
40
41
  "src/tui-preferences.ts",
42
+ "src/rpc",
41
43
  "README.md",
42
44
  "LICENSE"
43
45
  ],
44
46
  "scripts": {
45
- "build": "rm -rf dist && bun build src/index.ts src/cli.ts src/sidebar-state.ts src/tui-preferences.ts --outdir dist --target node --format esm --splitting --external @opencode-ai/plugin --minify && tsc -p tsconfig.build.json --emitDeclarationOnly",
47
+ "build": "rm -rf dist && bun build src/index.ts src/cli.ts src/sidebar-state.ts src/tui-preferences.ts src/rpc/rpc-client.ts src/rpc/port-file.ts src/rpc/protocol.ts src/rpc/rpc-dir.ts --outdir dist --target node --format esm --splitting --external @opencode-ai/plugin --minify && tsc -p tsconfig.build.json --emitDeclarationOnly",
46
48
  "build:dev": "rm -rf dist && tsc -p tsconfig.build.json",
47
49
  "dev": "bun ../../scripts/dev.ts",
48
50
  "dev:clean": "bun ../../scripts/dev-clean.ts",
@@ -56,7 +58,7 @@
56
58
  "@opencode-ai/plugin": "*"
57
59
  },
58
60
  "dependencies": {
59
- "@cortexkit/anthropic-auth-core": "1.9.4",
61
+ "@cortexkit/anthropic-auth-core": "1.10.0",
60
62
  "@opentui/core": ">=0.4.0",
61
63
  "@opentui/solid": ">=0.4.0",
62
64
  "jsonc-parser": "^3.3.1",
@@ -0,0 +1,54 @@
1
+ import type { OpenDialogPayload, RpcNotification } from './protocol'
2
+
3
+ const QUEUE_CAP = 100
4
+ const TUI_CONNECTED_WINDOW_MS = 3_000
5
+
6
+ let queue: RpcNotification[] = []
7
+ let nextId = 1
8
+ let lastDrainAtAny = 0
9
+ const lastDrainAtBySession = new Map<string, number>()
10
+
11
+ export function pushNotification(
12
+ payload: OpenDialogPayload,
13
+ sessionId?: string,
14
+ ): void {
15
+ queue.push({ id: nextId++, type: 'open-dialog', payload, sessionId })
16
+ if (queue.length > QUEUE_CAP) queue = queue.slice(queue.length - QUEUE_CAP)
17
+ }
18
+
19
+ export function drainNotifications(
20
+ lastReceivedId = 0,
21
+ sessionId?: string,
22
+ ): RpcNotification[] {
23
+ const now = Date.now()
24
+ lastDrainAtAny = now
25
+ if (sessionId !== undefined) lastDrainAtBySession.set(sessionId, now)
26
+ const matches = (n: RpcNotification) =>
27
+ sessionId === undefined ||
28
+ n.sessionId === undefined ||
29
+ n.sessionId === sessionId
30
+ if (lastReceivedId > 0) {
31
+ queue = queue.filter((n) => {
32
+ if (n.id > lastReceivedId) return true
33
+ if (sessionId === undefined) return false
34
+ return n.sessionId !== sessionId
35
+ })
36
+ }
37
+ return queue.filter((n) => n.id > lastReceivedId && matches(n))
38
+ }
39
+
40
+ export function isTuiConnected(sessionId?: string): boolean {
41
+ const now = Date.now()
42
+ if (sessionId !== undefined) {
43
+ const at = lastDrainAtBySession.get(sessionId) ?? 0
44
+ return at > 0 && now - at < TUI_CONNECTED_WINDOW_MS
45
+ }
46
+ return lastDrainAtAny > 0 && now - lastDrainAtAny < TUI_CONNECTED_WINDOW_MS
47
+ }
48
+
49
+ export function resetNotificationsForTest(): void {
50
+ queue = []
51
+ nextId = 1
52
+ lastDrainAtAny = 0
53
+ lastDrainAtBySession.clear()
54
+ }
@@ -0,0 +1,64 @@
1
+ import {
2
+ mkdir,
3
+ readdir,
4
+ readFile,
5
+ rename,
6
+ unlink,
7
+ writeFile,
8
+ } from 'node:fs/promises'
9
+ import { join } from 'node:path'
10
+
11
+ export interface PortFileEntry {
12
+ port: number
13
+ token: string
14
+ pid: number
15
+ startedAt: number
16
+ }
17
+
18
+ function pidAlive(pid: number): boolean {
19
+ try {
20
+ process.kill(pid, 0)
21
+ return true
22
+ } catch (error) {
23
+ return (error as NodeJS.ErrnoException).code === 'EPERM'
24
+ }
25
+ }
26
+
27
+ export async function writePortFile(
28
+ dir: string,
29
+ entry: { port: number; token: string; pid: number },
30
+ ): Promise<string> {
31
+ await mkdir(dir, { recursive: true })
32
+ const full: PortFileEntry = { ...entry, startedAt: Date.now() }
33
+ const target = join(dir, `port-${entry.pid}.json`)
34
+ const tmp = `${target}.${process.pid}.tmp`
35
+ await writeFile(tmp, JSON.stringify(full), { encoding: 'utf8', mode: 0o600 })
36
+ await rename(tmp, target)
37
+ return target
38
+ }
39
+
40
+ export async function discoverPortFile(
41
+ dir: string,
42
+ ): Promise<PortFileEntry | null> {
43
+ let names: string[]
44
+ try {
45
+ names = await readdir(dir)
46
+ } catch {
47
+ return null
48
+ }
49
+ const live: PortFileEntry[] = []
50
+ for (const name of names) {
51
+ if (!name.startsWith('port-') || !name.endsWith('.json')) continue
52
+ try {
53
+ const parsed = JSON.parse(
54
+ await readFile(join(dir, name), 'utf8'),
55
+ ) as PortFileEntry
56
+ if (Number.isFinite(parsed.port)) {
57
+ if (pidAlive(parsed.pid)) live.push(parsed)
58
+ else unlink(join(dir, name)).catch(() => {})
59
+ }
60
+ } catch {}
61
+ }
62
+ if (live.length === 0) return null
63
+ return live.sort((a, b) => b.startedAt - a.startedAt)[0] ?? null
64
+ }
@@ -0,0 +1,31 @@
1
+ export type CommandModalName =
2
+ | 'claude-cache'
3
+ | 'claude-cachekeep'
4
+ | 'claude-quota'
5
+ | 'claude-dump'
6
+ | 'claude-fast'
7
+ | 'claude-routing'
8
+ | 'claude-killswitch'
9
+
10
+ export interface OpenDialogPayload {
11
+ command: CommandModalName
12
+ text: string
13
+ knobs: Record<string, unknown>
14
+ }
15
+
16
+ export interface RpcNotification {
17
+ id: number
18
+ type: 'open-dialog'
19
+ payload: OpenDialogPayload
20
+ sessionId?: string
21
+ }
22
+
23
+ export interface ApplyRequest {
24
+ command: CommandModalName
25
+ arguments: string
26
+ }
27
+
28
+ export interface ApplyResult {
29
+ text: string
30
+ knobs: Record<string, unknown>
31
+ }
@@ -0,0 +1,55 @@
1
+ import { discoverPortFile } from './port-file'
2
+ import type { ApplyRequest, ApplyResult, RpcNotification } from './protocol'
3
+
4
+ export interface RpcClient {
5
+ pending: (
6
+ lastReceivedId: number,
7
+ sessionId?: string,
8
+ ) => Promise<RpcNotification[]>
9
+ apply: (request: ApplyRequest) => Promise<ApplyResult>
10
+ }
11
+
12
+ async function call<T>(
13
+ dir: string,
14
+ method: string,
15
+ params: Record<string, unknown>,
16
+ ): Promise<T | null> {
17
+ const entry = await discoverPortFile(dir)
18
+ if (!entry) return null
19
+ const controller = new AbortController()
20
+ const timer = setTimeout(() => controller.abort(), 2_000)
21
+ try {
22
+ const res = await fetch(`http://127.0.0.1:${entry.port}/rpc/${method}`, {
23
+ method: 'POST',
24
+ headers: {
25
+ 'content-type': 'application/json',
26
+ authorization: `Bearer ${entry.token}`,
27
+ },
28
+ body: JSON.stringify(params),
29
+ signal: controller.signal,
30
+ })
31
+ if (!res.ok) return null
32
+ return (await res.json()) as T
33
+ } catch {
34
+ return null
35
+ } finally {
36
+ clearTimeout(timer)
37
+ }
38
+ }
39
+
40
+ export function createRpcClient(dir: string): RpcClient {
41
+ return {
42
+ async pending(lastReceivedId, sessionId) {
43
+ const out = await call<{ messages: RpcNotification[] }>(
44
+ dir,
45
+ 'pending-notifications',
46
+ { lastReceivedId, sessionId },
47
+ )
48
+ return out?.messages ?? []
49
+ },
50
+ async apply(request) {
51
+ const out = await call<ApplyResult>(dir, 'apply', { ...request })
52
+ return out ?? { text: 'apply failed', knobs: {} }
53
+ },
54
+ }
55
+ }
@@ -0,0 +1,19 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { homedir, tmpdir } from 'node:os'
3
+ import { join } from 'node:path'
4
+
5
+ const RPC_DIR_ENV = 'OPENCODE_ANTHROPIC_AUTH_RPC_DIR'
6
+
7
+ // Both processes must resolve the SAME dir from the SAME project directory.
8
+ export function getRpcDir(projectDirectory: string): string {
9
+ const override = process.env[RPC_DIR_ENV]?.trim()
10
+ if (override) return override
11
+ const hash = createHash('sha256')
12
+ .update(projectDirectory)
13
+ .digest('hex')
14
+ .slice(0, 16)
15
+ const base = process.env.XDG_STATE_HOME || join(homedir(), '.local', 'state')
16
+ return join(base, 'cortexkit', 'anthropic-auth', 'rpc', hash)
17
+ }
18
+
19
+ export { tmpdir }
@@ -0,0 +1,121 @@
1
+ import { randomBytes, timingSafeEqual } from 'node:crypto'
2
+ import { unlink } from 'node:fs/promises'
3
+ import {
4
+ createServer,
5
+ type IncomingMessage,
6
+ type ServerResponse,
7
+ } from 'node:http'
8
+ import { join } from 'node:path'
9
+ import type { drainNotifications } from './notifications'
10
+ import { writePortFile } from './port-file'
11
+ import type { ApplyRequest, ApplyResult } from './protocol'
12
+
13
+ export interface RpcServerHandle {
14
+ port: number
15
+ token: string
16
+ stop: () => Promise<void>
17
+ }
18
+
19
+ export interface RpcServerOptions {
20
+ dir: string
21
+ drain: typeof drainNotifications
22
+ apply: (request: ApplyRequest) => Promise<ApplyResult>
23
+ }
24
+
25
+ function readBody(req: IncomingMessage): Promise<string> {
26
+ return new Promise((resolve, reject) => {
27
+ const chunks: Buffer[] = []
28
+ let size = 0
29
+ req.on('data', (chunk: Buffer) => {
30
+ size += chunk.length
31
+ if (size > 1_000_000) {
32
+ req.destroy()
33
+ reject(new Error('body too large'))
34
+ return
35
+ }
36
+ chunks.push(chunk)
37
+ })
38
+ req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
39
+ req.on('error', reject)
40
+ })
41
+ }
42
+
43
+ function tokenOk(header: string | undefined, token: string): boolean {
44
+ if (!header?.startsWith('Bearer ')) return false
45
+ const got = Buffer.from(header.slice(7))
46
+ const want = Buffer.from(token)
47
+ return got.length === want.length && timingSafeEqual(got, want)
48
+ }
49
+
50
+ export async function startRpcServer(
51
+ options: RpcServerOptions,
52
+ ): Promise<RpcServerHandle> {
53
+ const token = randomBytes(32).toString('hex')
54
+ const server = createServer((req, res) => {
55
+ void dispatch(req, res)
56
+ })
57
+
58
+ async function dispatch(req: IncomingMessage, res: ServerResponse) {
59
+ const json = (status: number, value: unknown) => {
60
+ res.writeHead(status, { 'content-type': 'application/json' })
61
+ res.end(JSON.stringify(value))
62
+ }
63
+ try {
64
+ const url = req.url ?? ''
65
+ if (req.method === 'GET' && url === '/health')
66
+ return json(200, { ok: true })
67
+ if (req.method !== 'POST' || !url.startsWith('/rpc/'))
68
+ return json(404, { error: 'not found' })
69
+ if (!tokenOk(req.headers.authorization, token))
70
+ return json(401, { error: 'unauthorized' })
71
+ const method = url.slice('/rpc/'.length)
72
+ const params = JSON.parse((await readBody(req)) || '{}') as Record<
73
+ string,
74
+ unknown
75
+ >
76
+ if (method === 'pending-notifications') {
77
+ const messages = options.drain(
78
+ Number(params.lastReceivedId ?? 0),
79
+ typeof params.sessionId === 'string' ? params.sessionId : undefined,
80
+ )
81
+ return json(200, { messages })
82
+ }
83
+ if (method === 'apply') {
84
+ const result = await options.apply(params as unknown as ApplyRequest)
85
+ return json(200, result)
86
+ }
87
+ return json(404, { error: 'unknown method' })
88
+ } catch (error) {
89
+ json(500, {
90
+ error: error instanceof Error ? error.message : String(error),
91
+ })
92
+ }
93
+ }
94
+
95
+ const port = await new Promise<number>((resolve, reject) => {
96
+ server.on('error', reject)
97
+ server.listen(0, '127.0.0.1', () => {
98
+ const addr = server.address()
99
+ if (addr && typeof addr === 'object') resolve(addr.port)
100
+ else reject(new Error('no port'))
101
+ })
102
+ })
103
+ server.unref()
104
+ try {
105
+ await writePortFile(options.dir, { port, token, pid: process.pid })
106
+ } catch (error) {
107
+ await new Promise<void>((resolve) => server.close(() => resolve()))
108
+ throw error
109
+ }
110
+
111
+ return {
112
+ port,
113
+ token,
114
+ async stop() {
115
+ await new Promise<void>((resolve) => server.close(() => resolve()))
116
+ await unlink(join(options.dir, `port-${process.pid}.json`)).catch(
117
+ () => {},
118
+ )
119
+ },
120
+ }
121
+ }
@@ -0,0 +1,229 @@
1
+ /** @jsxImportSource @opentui/solid */
2
+ import type { TuiPluginApi } from '@opencode-ai/plugin/tui'
3
+ import type { OpenDialogPayload } from '../rpc/protocol.js'
4
+
5
+ type ApplyFn = (
6
+ command: OpenDialogPayload['command'],
7
+ args: string,
8
+ ) => Promise<{ text: string }>
9
+
10
+ function showText(api: TuiPluginApi, text: string) {
11
+ api.ui.dialog.setSize('xlarge')
12
+ api.ui.dialog.replace(() => (
13
+ <box flexDirection='column' padding={1} width='100%'>
14
+ <text>{text}</text>
15
+ </box>
16
+ ))
17
+ }
18
+
19
+ export function openCommandDialog(
20
+ api: TuiPluginApi,
21
+ payload: OpenDialogPayload,
22
+ apply: ApplyFn,
23
+ ) {
24
+ if (payload.command === 'claude-routing') {
25
+ const current = (payload.knobs.mode as string) ?? 'main-first'
26
+ const DialogSelect = api.ui.DialogSelect<string>
27
+ api.ui.dialog.setSize('xlarge')
28
+ api.ui.dialog.replace(() => (
29
+ <DialogSelect
30
+ title='Claude routing'
31
+ current={current}
32
+ options={[
33
+ {
34
+ title: 'Main first',
35
+ value: 'main-first',
36
+ description: 'Use the main account until exhausted',
37
+ },
38
+ {
39
+ title: 'Fallback first',
40
+ value: 'fallback-first',
41
+ description: 'Prefer fallback accounts, preserve main',
42
+ },
43
+ ]}
44
+ onSelect={(option) => {
45
+ void apply('claude-routing', String(option.value)).then((r) => {
46
+ api.ui.toast({ message: r.text })
47
+ api.ui.dialog.clear()
48
+ })
49
+ }}
50
+ />
51
+ ))
52
+ return
53
+ }
54
+
55
+ if (payload.command === 'claude-fast' || payload.command === 'claude-dump') {
56
+ const enabled = payload.knobs.enabled === true
57
+ const label =
58
+ payload.command === 'claude-fast' ? 'fast mode' : 'request dump'
59
+ const DialogConfirm = api.ui.DialogConfirm
60
+ api.ui.dialog.setSize('xlarge')
61
+ api.ui.dialog.replace(() => (
62
+ <DialogConfirm
63
+ title={`Claude ${label}`}
64
+ message={`${payload.text}\n\n${enabled ? 'Disable' : 'Enable'} ${label}?`}
65
+ onConfirm={() => {
66
+ void apply(payload.command, enabled ? 'off' : 'on').then((r) => {
67
+ api.ui.toast({ message: r.text })
68
+ api.ui.dialog.clear()
69
+ })
70
+ }}
71
+ onCancel={() => api.ui.dialog.clear()}
72
+ />
73
+ ))
74
+ return
75
+ }
76
+
77
+ if (payload.command === 'claude-cache') {
78
+ const enabled = payload.knobs.enabled === true
79
+ const mode = (payload.knobs.mode as string) ?? 'hybrid'
80
+ const currentValue = enabled ? mode : 'off'
81
+ const DialogSelect = api.ui.DialogSelect<string>
82
+ api.ui.dialog.setSize('xlarge')
83
+ api.ui.dialog.replace(() => (
84
+ <DialogSelect
85
+ title='Claude 1h cache'
86
+ current={currentValue}
87
+ options={[
88
+ { title: 'Off', value: 'off', description: 'Disable 1h cache' },
89
+ {
90
+ title: 'Explicit',
91
+ value: 'explicit',
92
+ description: 'Existing OpenCode breakpoints',
93
+ },
94
+ {
95
+ title: 'Automatic',
96
+ value: 'automatic',
97
+ description: 'Top-level cache_control only',
98
+ },
99
+ {
100
+ title: 'Hybrid',
101
+ value: 'hybrid',
102
+ description: 'system + messages[0] + top-level',
103
+ },
104
+ ]}
105
+ onSelect={(option) => {
106
+ if (option.value === 'off') {
107
+ void apply('claude-cache', 'off').then((r) => {
108
+ api.ui.toast({ message: r.text })
109
+ api.ui.dialog.clear()
110
+ })
111
+ return
112
+ }
113
+ void apply('claude-cache', `mode ${option.value}`)
114
+ .then(() => apply('claude-cache', 'on'))
115
+ .then((r) => {
116
+ api.ui.toast({ message: r.text })
117
+ api.ui.dialog.clear()
118
+ })
119
+ }}
120
+ />
121
+ ))
122
+ return
123
+ }
124
+
125
+ if (payload.command === 'claude-cachekeep') {
126
+ const window = payload.knobs.window as
127
+ | { startHour: number; endHour: number }
128
+ | undefined
129
+ const seed = window
130
+ ? `${String(window.startHour).padStart(2, '0')}-${String(window.endHour).padStart(2, '0')}`
131
+ : ''
132
+ const DialogPrompt = api.ui.DialogPrompt
133
+ api.ui.dialog.setSize('xlarge')
134
+ api.ui.dialog.replace(() => (
135
+ <DialogPrompt
136
+ title='Claude cachekeep window'
137
+ description={() => <text>{payload.text}</text>}
138
+ placeholder="HH-HH (e.g. 08-20) or 'off'"
139
+ value={seed}
140
+ onConfirm={(value: string) => {
141
+ void apply('claude-cachekeep', value.trim()).then((r) => {
142
+ api.ui.toast({ message: r.text })
143
+ api.ui.dialog.clear()
144
+ })
145
+ }}
146
+ onCancel={() => api.ui.dialog.clear()}
147
+ />
148
+ ))
149
+ return
150
+ }
151
+
152
+ if (payload.command === 'claude-killswitch') {
153
+ const config = (payload.knobs.config ?? {}) as {
154
+ enabled?: boolean
155
+ main?: Record<string, number>
156
+ accounts?: Record<string, Record<string, number>>
157
+ }
158
+ const accountIds = (payload.knobs.accountIds as string[]) ?? []
159
+ const enabled = config.enabled === true
160
+ const readT = (t: Record<string, number> | undefined) => {
161
+ const fh = t?.five_hour ?? t?.['5h'] ?? 5
162
+ const sd = t?.seven_day ?? t?.['1w'] ?? 10
163
+ return { fh, sd }
164
+ }
165
+ const mainT = readT(config.main)
166
+ const seedParts = [`main:${mainT.fh},${mainT.sd}`]
167
+ for (const id of accountIds) {
168
+ const t = readT(config.accounts?.[id] ?? config.main)
169
+ seedParts.push(`${id}:${t.fh},${t.sd}`)
170
+ }
171
+ const seed = seedParts.join(' ')
172
+
173
+ const openEdit = () => {
174
+ const DialogPrompt = api.ui.DialogPrompt
175
+ api.ui.dialog.setSize('xlarge')
176
+ api.ui.dialog.replace(() => (
177
+ <DialogPrompt
178
+ title='Killswitch thresholds'
179
+ description={() => <text>{payload.text}</text>}
180
+ placeholder='main:5,10 work-alt:5,10'
181
+ value={seed}
182
+ onConfirm={(value: string) => {
183
+ void apply('claude-killswitch', `set ${value.trim()}`).then((r) => {
184
+ api.ui.toast({ message: r.text })
185
+ api.ui.dialog.clear()
186
+ })
187
+ }}
188
+ onCancel={() => api.ui.dialog.clear()}
189
+ />
190
+ ))
191
+ }
192
+
193
+ const DialogSelect = api.ui.DialogSelect<string>
194
+ api.ui.dialog.setSize('xlarge')
195
+ api.ui.dialog.replace(() => (
196
+ <DialogSelect
197
+ title='Claude killswitch'
198
+ options={[
199
+ {
200
+ title: enabled ? 'Disable killswitch' : 'Enable killswitch',
201
+ value: enabled ? 'off' : 'on',
202
+ description: enabled
203
+ ? 'Stop hard-blocking on low quota'
204
+ : 'Hard-block requests when quota drops below thresholds',
205
+ },
206
+ {
207
+ title: 'Edit thresholds…',
208
+ value: 'edit',
209
+ description: 'Set per-account 5h,1w cutoffs',
210
+ },
211
+ ]}
212
+ onSelect={(option) => {
213
+ if (option.value === 'edit') {
214
+ openEdit()
215
+ return
216
+ }
217
+ void apply('claude-killswitch', String(option.value)).then((r) => {
218
+ api.ui.toast({ message: r.text })
219
+ api.ui.dialog.clear()
220
+ })
221
+ }}
222
+ />
223
+ ))
224
+ return
225
+ }
226
+
227
+ // fallback for quota (display-only)
228
+ showText(api, payload.text)
229
+ }
package/src/tui.tsx CHANGED
@@ -16,7 +16,8 @@ import {
16
16
  onCleanup,
17
17
  Show,
18
18
  } from 'solid-js'
19
-
19
+ import { createRpcClient } from './rpc/rpc-client.js'
20
+ import { getRpcDir } from './rpc/rpc-dir.js'
20
21
  import {
21
22
  type AccountQuota,
22
23
  computeQuotaPacing,
@@ -29,6 +30,7 @@ import {
29
30
  SEVEN_DAY_MS,
30
31
  type SidebarState,
31
32
  } from './sidebar-state.js'
33
+ import { openCommandDialog } from './tui/command-dialogs.js'
32
34
  import {
33
35
  type AnthropicAuthTuiPrefs,
34
36
  type AppearancePrefs,
@@ -41,6 +43,9 @@ import {
41
43
  watchTuiPreferences,
42
44
  } from './tui-preferences.js'
43
45
 
46
+ const RPC_POLL_MS = 500
47
+ let rpcPollStarted = false
48
+
44
49
  const ID = 'cortexkit.anthropic-auth'
45
50
 
46
51
  // Plugin version for the header (mirrors the Magic Context / AFT convention).
@@ -345,6 +350,67 @@ function AccountBlock(props: {
345
350
  )
346
351
  }
347
352
 
353
+ // --- Quota dialog content ---------------------------------------------------
354
+
355
+ // Renders the same rich visualization as the sidebar (account blocks with
356
+ // quota bars + pacing) so the modal matches the sidebar look.
357
+ function QuotaDialogContent(props: {
358
+ api: TuiPluginApi
359
+ controller: SidebarController
360
+ }) {
361
+ const prefs = props.controller.prefs
362
+ const [state, setState] = createSignal<SidebarState>(DEFAULT_SIDEBAR_STATE)
363
+ let lastUpdated = 0
364
+ async function refresh() {
365
+ const next = await readStateFromFile()
366
+ if (next.lastUpdated !== lastUpdated) {
367
+ lastUpdated = next.lastUpdated
368
+ setState(next)
369
+ }
370
+ }
371
+ createEffect(() => {
372
+ const timer = setInterval(refresh, prefs().pollMs)
373
+ onCleanup(() => clearInterval(timer))
374
+ })
375
+ setTimeout(refresh, 0)
376
+ const theme = () => props.api.theme.current
377
+ const enabledFallbacks = () => state().fallbacks.filter((f) => f.enabled)
378
+ return (
379
+ <box flexDirection='column' padding={2} width='100%' alignItems='center'>
380
+ <box flexDirection='column' width={58}>
381
+ <box width='100%' justifyContent='center' marginBottom={1}>
382
+ <text fg={theme().text}>
383
+ <b>Quota</b>
384
+ </text>
385
+ </box>
386
+ <AccountBlock
387
+ theme={theme()}
388
+ appearance={prefs().appearance}
389
+ name='main'
390
+ quota={state().main.quota}
391
+ active={state().activeId === 'main'}
392
+ pacingEnabled={prefs().sections.pacing}
393
+ />
394
+ <Show when={prefs().sections.fallbackAccounts}>
395
+ <For each={enabledFallbacks()}>
396
+ {(fb) => (
397
+ <AccountBlock
398
+ theme={theme()}
399
+ appearance={prefs().appearance}
400
+ name={fb.label ?? fb.id}
401
+ quota={fb.quota}
402
+ active={state().activeId === fb.id}
403
+ pacingEnabled={prefs().sections.pacing}
404
+ marginTop={1}
405
+ />
406
+ )}
407
+ </For>
408
+ </Show>
409
+ </box>
410
+ </box>
411
+ )
412
+ }
413
+
348
414
  // --- State plumbing ---------------------------------------------------------
349
415
 
350
416
  async function readStateFromFile(): Promise<SidebarState> {
@@ -701,6 +767,44 @@ const tui: TuiPlugin = async (api) => {
701
767
  },
702
768
  },
703
769
  })
770
+
771
+ if (!rpcPollStarted) {
772
+ rpcPollStarted = true
773
+ const rpcClient = createRpcClient(getRpcDir(api.state.path.directory ?? ''))
774
+ let lastNotificationId = 0
775
+ let rpcInFlight = false
776
+ setInterval(() => {
777
+ if (rpcInFlight) return
778
+ const current = (api.route as { current?: unknown }).current
779
+ const resolved =
780
+ typeof current === 'function' ? (current as () => unknown)() : current
781
+ const sessionId = (
782
+ resolved as { params?: { sessionID?: string } } | undefined
783
+ )?.params?.sessionID
784
+ rpcInFlight = true
785
+ void rpcClient
786
+ .pending(lastNotificationId, sessionId)
787
+ .then((messages) => {
788
+ for (const message of [...messages].sort((a, b) => a.id - b.id)) {
789
+ lastNotificationId = Math.max(lastNotificationId, message.id)
790
+ if (message.payload.command === 'claude-quota') {
791
+ api.ui.dialog.setSize('xlarge')
792
+ api.ui.dialog.replace(() => (
793
+ <QuotaDialogContent api={api} controller={controller} />
794
+ ))
795
+ continue
796
+ }
797
+ openCommandDialog(api, message.payload, (command, args) =>
798
+ rpcClient.apply({ command, arguments: args }),
799
+ )
800
+ }
801
+ })
802
+ .catch(() => {})
803
+ .finally(() => {
804
+ rpcInFlight = false
805
+ })
806
+ }, RPC_POLL_MS)
807
+ }
704
808
  }
705
809
 
706
810
  const plugin: TuiPluginModule & { id: string } = {