@cortexkit/opencode-anthropic-auth 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -3
- package/dist/cli.js +6 -4
- package/dist/index-gcmgg93d.js +335 -0
- package/dist/index-s5ckbbqq.js +2 -0
- package/dist/index.js +6 -6
- package/dist/sidebar-state.d.ts +5 -0
- package/dist/sidebar-state.js +1 -1
- package/dist/transform.d.ts +8 -2
- package/package.json +2 -2
- package/src/sidebar-state.ts +18 -0
- package/src/tui.tsx +19 -27
- package/dist/index-q0d64q8d.js +0 -2
- package/dist/index-ykvgffhr.js +0 -335
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
var $f="9d1c250a-e61b-44d9-88ed-5944d1962f5e",m_={console:"https://platform.claude.com/oauth/authorize",max:"https://claude.ai/oauth/authorize"},Yf="https://platform.claude.com/oauth/code/callback",Wf="https://platform.claude.com/v1/oauth/token",$_=["org:create_api_key","user:profile","user:inference","user:sessions:claude_code","user:mcp_servers","user:file_upload"],Om="mcp_";var C_="fast-mode-2026-02-01";function Sm(f,_){let E=(f??"").split(",").map((D)=>D.trim()).filter(Boolean);return[...new Set([...E,..._])].join(",")}function Hm(f){return typeof f==="string"&&(f.startsWith("claude-opus-4-6")||f.startsWith("claude-opus-4-7")||f.startsWith("claude-opus-4-8"))}var Nm="You are OpenCode",bm="You are a Claude agent, built on Anthropic's Claude Agent SDK.",Fm=["<use_parallel_tool_calls>","For maximum efficiency, whenever you perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially. Prioritize calling independent tools in parallel whenever possible. For example, when reading 3 known files, run 3 tool calls in parallel to read all 3 files into context at the same time. When running multiple independent read-only commands like `ls` or `list_dir`, run all of those commands in parallel. Err on the side of maximizing parallel tool calls for independent work rather than running too many tools sequentially.","","Do not parallelize tool calls when one call depends on the output of another call. If a tool call needs an ID, filename, search result, or any other value returned by a previous tool call, run the first call, wait for its result, then run the dependent call using the real returned value. Never invent placeholder IDs, guessed task IDs, or other guessed values for dependent tool calls just to place them in the same parallel block.","</use_parallel_tool_calls>"].join(`
|
|
2
|
+
`);var q="2.1.141",Xf="67b",M_="sdk-cli",L_="0.94.0",A_="v24.3.0",U_="claude-cli/2.1.141 (external, sdk-cli)",O_=["explicit","automatic","hybrid"],Cf="explicit",Bm=["github.com/anomalyco/opencode","opencode.ai/docs"],Km=[{match:"if OpenCode honestly",replacement:"if the assistant honestly"},{match:"Here is some useful information about the environment you are running in:",replacement:"Environment context you are running in:"}];function S_(f){let _="";for(let E of f)_+=String.fromCharCode(E);return btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function H_(){let f=new Uint8Array(64);crypto.getRandomValues(f);let _=S_(f),E=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(_));return{verifier:_,challenge:S_(new Uint8Array(E)),method:"S256"}}function W0(f){if(!f)return;let _=Number(f);if(Number.isFinite(_)&&_>0)return Math.ceil(_);let E=Date.parse(f);if(Number.isFinite(E)){let D=Math.ceil((E-Date.now())/1000);return D>0?D:void 0}return}class i extends Error{status;body;retryAfter;constructor(f,_,E){super(`Claude OAuth refresh failed: ${f} — ${_}`);this.status=f,this.body=_,this.name="ClaudeOAuthRefreshError",this.retryAfter=W0(E??void 0)}}function X0(f){if(!(f instanceof Error))return!1;let _=f.code;return f.message.includes("fetch failed")||_==="ECONNRESET"||_==="ECONNREFUSED"||_==="ETIMEDOUT"||_==="UND_ERR_CONNECT_TIMEOUT"}async function N_(f){let _=f.fetchImpl??fetch,E=f.maxRetries??2,D=f.baseDelayMs??500;for(let m=0;m<=E;m++)try{if(m>0){let L=D*2**(m-1);await new Promise((A)=>setTimeout(A,L))}let $=await _(Wf,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","User-Agent":"axios/1.13.6"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:f.refreshToken,client_id:$f})});if(!$.ok){if($.status>=500&&m<E){await $.body?.cancel().catch(()=>{});continue}let L=await $.text().catch(()=>"");throw new i($.status,L,$.headers.get("retry-after"))}let C=await $.json(),M=f.now?.()??Date.now();return{access:C.access_token,refresh:C.refresh_token??f.refreshToken,expires:M+C.expires_in*1000,expiresIn:C.expires_in}}catch($){if($ instanceof i)throw $;if(m<E&&X0($))continue;throw $}throw Error("Token refresh exhausted all retries")}function Z0(){return crypto.randomUUID().replace(/-/g,"")}function h0(f){let _=f.trim();try{let C=new URL(_),M=C.searchParams.get("code"),L=C.searchParams.get("state");if(M&&L)return{code:M,state:L}}catch{}let E=_.split("#");if(E.length===2&&E[0]&&E[1])return{code:E[0],state:E[1]};let D=new URLSearchParams(_),m=D.get("code"),$=D.get("state");if(m&&$)return{code:m,state:$};return null}async function V0(f,_,E){let D=await fetch(Wf,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json, text/plain, */*","User-Agent":"axios/1.13.6"},body:JSON.stringify({code:f.code,state:f.state,grant_type:"authorization_code",client_id:$f,redirect_uri:E,code_verifier:_})});if(!D.ok)return{type:"failed"};let m=await D.json();return{type:"success",refresh:m.refresh_token,access:m.access_token,expires:Date.now()+m.expires_in*1000}}async function Ym(f){let _=await H_(),E=Z0(),D=new URL(m_[f],import.meta.url);return D.searchParams.set("code","true"),D.searchParams.set("client_id",$f),D.searchParams.set("response_type","code"),D.searchParams.set("redirect_uri",Yf),D.searchParams.set("scope",$_.join(" ")),D.searchParams.set("code_challenge",_.challenge),D.searchParams.set("code_challenge_method","S256"),D.searchParams.set("state",E),{url:D.toString(),redirectUri:Yf,state:E,verifier:_.verifier}}async function Wm(f,_,E,D){let m=h0(f);if(!m)return{type:"failed"};if(D&&m.state!==D)return{type:"failed"};return V0(m,_,E)}import*as b_ from"node:fs";import*as F_ from"node:os";import*as B_ from"node:path";var x0=B_.join(F_.tmpdir(),"opencode-anthropic-auth.log"),K_=!1,Q0=500,I0=50,t=[],n=null;function Zf(){if(n)clearTimeout(n),n=null;if(t.length===0)return;let f=t.join("");t=[];try{b_.appendFileSync(x0,f)}catch{}}function P0(){if(n)return;n=setTimeout(()=>{n=null,Zf()},Q0)}function R0(f){if(f===void 0)return"";if(f instanceof Error)return` ${f.message}${f.stack?`
|
|
3
|
+
${f.stack}`:""}`;return` ${JSON.stringify(f)}`}function V(f,_){if(K_)return;try{if(t.push(`[${new Date().toISOString()}] ${f}${R0(_)}
|
|
4
|
+
`),t.length>=I0)Zf();else P0()}catch{}}function b(f,_){V(`[relay] ${f}`,_)}if(!K_)process.on("exit",Zf);import{createHash as h_,randomUUID as Rf}from"node:crypto";import{mkdir as q0,readFile as xf,rename as T0,rm as j_,stat as w0,writeFile as Qf}from"node:fs/promises";import{homedir as i0}from"node:os";import{dirname as V_,join as a}from"node:path";var l0=globalThis.setTimeout.bind(globalThis),y0=globalThis.clearTimeout.bind(globalThis),x_="anthropic-auth.json",k0="anthropic-auth-state.json",p0="https://api.anthropic.com/api/oauth/usage";function x(f){return f.type==="oauth"}function qm(f){return f.type==="api"}function v0(f){let _=f?.trim();if(!_)return!1;try{let E=new URL(_);return(E.protocol==="http:"||E.protocol==="https:")&&!E.username&&!E.password}catch{return!1}}var d0=[401,403,429],Q_=240,u0=Q_;var g0=300000,n0=3600000,r0=86400000,s0=60000,c0=900000,t0=300000,o0=5,G_={five_hour:0,seven_day:0},a0=!0,e0=60000,fE=60000,_E=600000,EE=1e4,DE=100;function mE(){if(process.env.OPENCODE_CONFIG_DIR?.trim())return process.env.OPENCODE_CONFIG_DIR.trim();return a(process.env.XDG_CONFIG_HOME||a(i0(),".config"),"opencode")}function z(){return process.env.OPENCODE_ANTHROPIC_AUTH_FILE?.trim()||a(mE(),x_)}function qf(f=z()){let _=process.env.OPENCODE_ANTHROPIC_AUTH_STATE_FILE?.trim();if(_)return _;return f.endsWith(x_)?a(V_(f),k0):`${f}.state.json`}function H(f){return f!=null&&typeof f==="object"&&!Array.isArray(f)}function z_(f){return{id:typeof f.id==="string"&&f.id.trim()?f.id.trim():Rf(),label:typeof f.label==="string"?f.label:void 0,enabled:typeof f.enabled==="boolean"?f.enabled:void 0,addedAt:typeof f.addedAt==="number"?f.addedAt:void 0,lastUsed:typeof f.lastUsed==="number"?f.lastUsed:void 0}}function $E(f){if(!H(f))return null;if(f.type==="api"){let _=typeof f.baseURL==="string"?f.baseURL.trim():"",E=typeof f.apiKey==="string"?f.apiKey.trim():"";if(!v0(_))return null;let D=f.authHeader==="x-api-key"?"x-api-key":"authorization-bearer";return{...z_(f),type:"api",apiKey:E||void 0,baseURL:_,authHeader:D}}if(f.type!=="oauth")return null;if(typeof f.refresh!=="string"||!f.refresh.trim())return null;return{...z_(f),type:"oauth",access:typeof f.access==="string"?f.access:void 0,refresh:f.refresh,expires:typeof f.expires==="number"?f.expires:void 0,lastRefreshedAt:typeof f.lastRefreshedAt==="number"?f.lastRefreshedAt:void 0,lastRefreshError:J_(f.lastRefreshError),lastQuotaRefreshError:J_(f.lastQuotaRefreshError),quota:CE(f.quota)}}function J_(f){if(!H(f))return;if(typeof f.message!=="string")return;let _=Number(f.checkedAt);if(!Number.isFinite(_))return;let E=Number(f.nextRetryAt),D=Number(f.retryCount);return{message:f.message,checkedAt:_,nextRetryAt:Number.isFinite(E)?E:void 0,retryCount:Number.isFinite(D)?D:void 0,tokenHash:typeof f.tokenHash==="string"?f.tokenHash:void 0}}function CE(f){if(!H(f))return;let _={};for(let E of["five_hour","seven_day"]){let D=f[E];if(!H(D))continue;let m=Number(D.usedPercent),$=Number(D.remainingPercent),C=Number(D.checkedAt);if(!Number.isFinite(m)||!Number.isFinite($)||!Number.isFinite(C))continue;_[E]={usedPercent:m,remainingPercent:$,checkedAt:C,resetsAt:typeof D.resetsAt==="string"?D.resetsAt:void 0}}return Object.keys(_).length?_:void 0}function ME(f){if(!H(f)||!Array.isArray(f.accounts))return null;return{version:1,main:{type:"opencode",provider:"anthropic"},routing:H(f.routing)?f.routing:void 0,fallbackOn:Array.isArray(f.fallbackOn)?f.fallbackOn.filter((_)=>Number.isInteger(_)):void 0,refresh:H(f.refresh)?f.refresh:void 0,quota:H(f.quota)?f.quota:void 0,claudeCache:H(f.claudeCache)?f.claudeCache:void 0,dump:H(f.dump)?f.dump:void 0,claudeFast:H(f.claudeFast)?f.claudeFast:void 0,cacheKeep:H(f.cacheKeep)?f.cacheKeep:void 0,relay:H(f.relay)?f.relay:void 0,killswitch:H(f.killswitch)?f.killswitch:void 0,accounts:f.accounts.map($E).filter((_)=>_!=null)}}async function Mf(f){try{return{exists:!0,value:JSON.parse(await xf(f,"utf8"))}}catch(_){if(_.code==="ENOENT")return{exists:!1,value:null};return{exists:!1,value:null}}}function T(f){return Object.fromEntries(Object.entries(f).filter(([,_])=>_!==void 0))}function LE(f,_){if(!H(f))return f;let E=H(_)?_:{},D=H(E.main)?E.main:void 0,m=H(E.accounts)?E.accounts:{},$=H(f.quota)?f.quota:{},C=H(f.refresh)?f.refresh:{},M=D??$,L=D??C,A=Array.isArray(f.accounts)?f.accounts.map((U)=>{if(!H(U))return U;let N=typeof U.id==="string"&&H(m[U.id])?m[U.id]:{};return{...U,...N}}):[];return{...f,refresh:T({...C,mainLastRefreshError:L.lastRefreshError,mainRefreshLeaseId:L.refreshLeaseId,mainRefreshLeaseUntil:L.refreshLeaseUntil,mainRefreshLeaseTokenHash:L.refreshLeaseTokenHash}),quota:T({...$,mainQuota:M.quota,mainQuotaCheckedAt:M.quotaCheckedAt,mainQuotaToken:M.quotaToken,mainLastQuotaApiError:M.lastQuotaApiError}),accounts:A}}async function h(f=z()){let _=await Mf(f);if(!_.exists)return null;let E=await Mf(qf(f));return ME(LE(_.value,E.value))}async function AE(f){let _=await Mf(f);return H(_.value)?_.value:{}}function UE(f){return Object.fromEntries(Object.entries(f).filter(([,_])=>_!==void 0))}function OE(f){return T({id:f.id,label:f.label,type:f.type,enabled:f.enabled,addedAt:f.addedAt,baseURL:f.type==="api"?f.baseURL:void 0,authHeader:f.type==="api"?f.authHeader:void 0})}function I_(f){if(f.type==="api")return T({apiKey:f.apiKey,lastUsed:f.lastUsed});return T({access:f.access,refresh:f.refresh,expires:f.expires,lastUsed:f.lastUsed,lastRefreshedAt:f.lastRefreshedAt,lastRefreshError:f.lastRefreshError,lastQuotaRefreshError:f.lastQuotaRefreshError,quota:f.quota})}function SE(f){let _=f.refresh?T({enabled:f.refresh.enabled,intervalMinutes:f.refresh.intervalMinutes,refreshBeforeExpiryMinutes:f.refresh.refreshBeforeExpiryMinutes}):void 0,E=f.quota?T({enabled:f.quota.enabled,checkIntervalMinutes:f.quota.checkIntervalMinutes,refreshEveryNRequests:f.quota.refreshEveryNRequests,minimumRemaining:f.quota.minimumRemaining,failClosedOnUnknownQuota:f.quota.failClosedOnUnknownQuota,showToasts:f.quota.showToasts}):void 0;return UE({version:1,main:f.main,routing:f.routing,fallbackOn:f.fallbackOn,refresh:_,quota:E,claudeCache:f.claudeCache,dump:f.dump,claudeFast:f.claudeFast,cacheKeep:f.cacheKeep,relay:f.relay,killswitch:f.killswitch,accounts:f.accounts.map(OE)})}function HE(f){let _=Object.fromEntries(f.accounts.map((E)=>[E.id,I_(E)]));return{version:1,main:T({quota:f.quota?.mainQuota,quotaCheckedAt:f.quota?.mainQuotaCheckedAt,quotaToken:f.quota?.mainQuotaToken,lastQuotaApiError:f.quota?.mainLastQuotaApiError,lastRefreshError:f.refresh?.mainLastRefreshError,refreshLeaseId:f.refresh?.mainRefreshLeaseId,refreshLeaseUntil:f.refresh?.mainRefreshLeaseUntil,refreshLeaseTokenHash:f.refresh?.mainRefreshLeaseTokenHash}),accounts:_}}async function If(f,_){await q0(V_(f),{recursive:!0});let E=`${f}.${Rf()}.tmp`;await Qf(E,`${JSON.stringify(_,null,2)}
|
|
5
|
+
`,{encoding:"utf8",mode:384}),await T0(E,f)}async function Q(f,_=z()){let D={...await AE(_),...SE(f)};await If(_,D),await If(qf(_),HE(f))}function NE(f,_){f.main=f.main??{},f.main.quota=_.quota?.mainQuota,f.main.quotaCheckedAt=_.quota?.mainQuotaCheckedAt,f.main.quotaToken=_.quota?.mainQuotaToken,f.main.lastQuotaApiError=_.quota?.mainLastQuotaApiError}function bE(f,_){f.main=f.main??{},f.main.lastRefreshError=_.refresh?.mainLastRefreshError,f.main.refreshLeaseId=_.refresh?.mainRefreshLeaseId,f.main.refreshLeaseUntil=_.refresh?.mainRefreshLeaseUntil,f.main.refreshLeaseTokenHash=_.refresh?.mainRefreshLeaseTokenHash}function Pf(f){if(Array.isArray(f))return f.map(Pf);if(!H(f))return f;return Object.fromEntries(Object.entries(f).filter(([,_])=>_!==void 0).map(([_,E])=>[_,Pf(E)]))}async function FE(f,_=z(),E={mainQuota:!0,mainRefresh:!0,accounts:!0}){let D=qf(_),m=(await Mf(D)).value,$=H(m)?{...m,version:1}:{version:1};if(E.mainQuota)NE($,f);if(E.mainRefresh)bE($,f);if(E.accounts){let C=E.accounts===!0?null:new Set(E.accounts);$.accounts={...H($.accounts)?$.accounts:{}};for(let M of f.accounts){if(C&&!C.has(M.id))continue;$.accounts[M.id]=I_(M)}if(C){for(let M of C)if(!f.accounts.some((L)=>L.id===M))delete $.accounts[M]}}await If(D,Pf($))}async function Lf(f){let E=`${f.path??z()}.${f.name}.lock`,D=a(E,"owner.json"),m=Rf(),$=f.now??Date.now,C=null,M=!1;async function L(){try{return JSON.parse(await xf(E,"utf8"))}catch(K){if(K.code!=="EISDIR")throw K;return JSON.parse(await xf(D,"utf8"))}}async function A(){await Qf(E,`${JSON.stringify({ownerId:m,expiresAt:$()+f.ttlMs})}
|
|
6
|
+
`,{encoding:"utf8",mode:384})}async function U(){try{return await Qf(E,`${JSON.stringify({ownerId:m,expiresAt:$()+f.ttlMs})}
|
|
7
|
+
`,{encoding:"utf8",mode:384,flag:"wx"}),!0}catch(K){let j=K.code;if(j==="EEXIST"||j==="EISDIR")return!1;throw K}}function N(){if(!f.renew||M)return;let K=f.renewIntervalMs??Math.max(1000,Math.floor(f.ttlMs/3));if(C=l0(()=>{(async()=>{try{let j=await L(),R=$();if(M||j?.ownerId!==m||Number(j?.expiresAt)<=R)return;await A(),N()}catch{}})()},K),"unref"in C)C.unref()}if(!await U()){try{let K=await L();if(Number(K?.expiresAt)>$())return null}catch{try{if((await w0(E)).mtimeMs+f.ttlMs>Date.now())return null}catch{return null}}if(await j_(E,{recursive:!0,force:!0}).catch(()=>{}),!await U())return null}return N(),{release:async()=>{if(M=!0,C)y0(C),C=null;try{if((await L())?.ownerId!==m)return}catch{return}await j_(E,{recursive:!0,force:!0}).catch(()=>{})}}}function Tm(f){return f?.claudeCache?.enabled===!0}function BE(f){return typeof f==="string"&&O_.includes(f)?f:Cf}function KE(f){return BE(f?.claudeCache?.mode)}async function wm(f,_,E=z()){let D=await h(E)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};return D.claudeCache={...D.claudeCache??{},enabled:f,mode:_??KE(D)},await Q(D,E),D}async function im(f,_=z()){let E=await h(_)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};return E.claudeCache={...E.claudeCache??{},enabled:E.claudeCache?.enabled===!0,mode:f},await Q(E,_),E}function lm(f){return f?.dump?.enabled===!0}async function ym(f,_=z()){let E=await h(_)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};return E.dump={...E.dump??{},enabled:f},await Q(E,_),E}function km(f){return f?.claudeFast?.enabled===!0}async function pm(f,_=z()){let E=await h(_)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};return E.claudeFast={...E.claudeFast??{},enabled:f},await Q(E,_),E}async function vm(f,_,E=z()){let D=await h(E)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};return D.cacheKeep={enabled:!0,startHour:f,endHour:_},await Q(D,E),D}async function dm(f,_=z()){let E=await h(_)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};return E.cacheKeep={...E.cacheKeep??{},enabled:f},await Q(E,_),E}function jE(f){return f?.fallbackOn?.length?f.fallbackOn:d0}function um(f,_){return jE(_).includes(f)}function P_(f){let _=f?.quota?.minimumRemaining||{};return{five_hour:_.five_hour??_["5h"]??G_.five_hour,seven_day:_.seven_day??_["1w"]??G_.seven_day}}function e(f){return f?.quota?.enabled!==!1}function GE(f){return f?.refresh?.enabled!==!1}function zE(f){return Math.floor(Math.random()*Math.max(0,f))}function JE(f){let _=f?.refresh?.refreshBeforeExpiryMinutes??u0;return Math.max(Q_,_)*60000}function R_(f){return h_("sha256").update(f).digest("hex")}function YE(f){if(f instanceof i)return f.status===429||f.status>=500;if(!(f instanceof Error))return!1;return f.message.includes("fetch failed")||"code"in f&&(f.code==="ECONNRESET"||f.code==="ECONNREFUSED"||f.code==="ETIMEDOUT"||f.code==="UND_ERR_CONNECT_TIMEOUT")}function WE(f){let _=R_(f.refreshToken),D=(f.previous?.tokenHash===_?f.previous.retryCount??0:0)+1,m;if(f.error instanceof i&&f.error.retryAfter)m=f.error.retryAfter*1000;else if(YE(f.error))m=Math.min(n0,g0*2**Math.min(D-1,6));else m=r0;return{message:ff(f.error),checkedAt:f.now,nextRetryAt:f.now+m,retryCount:D,tokenHash:_}}function o(f,_,E){if(!f?.nextRetryAt||f.nextRetryAt<=E)return!1;if(!_)return!0;return f.tokenHash===R_(_)}function hf(f,_){return`Claude OAuth refresh is backed off for ${Math.max(1,Math.ceil(((f.nextRetryAt??_)-_)/1000))}s after: ${f.message}`}function Af(f){let E=(f.previous?.retryCount??0)+1,D=i_(f.error)?Math.min(c0,s0*2**Math.min(E-1,6)):t0;return{message:ff(f.error),checkedAt:f.now,nextRetryAt:f.now+D,retryCount:E}}function r(f,_){if(!f?.nextRetryAt||f.nextRetryAt<=_)return!1;return!0}function gm(f,_){return`Quota API backed off for ${Math.max(1,Math.ceil(((f.nextRetryAt??_)-_)/1000))}s after: ${f.message}`}function X(f){let _=f?.quota?.checkIntervalMinutes??o0;return Math.max(1,_)*60000}function q_(f){if(!f?.quota?.mainQuota||!f.quota.mainQuotaCheckedAt)return null;return{quota:f.quota.mainQuota,checkedAt:f.quota.mainQuotaCheckedAt,tokenFingerprint:f.quota.mainQuotaToken}}function T_(f){let _=f?.quota?.refreshEveryNRequests;return typeof _==="number"&&Number.isFinite(_)&&_>0?Math.floor(_):0}function Tf(f){return f?.quota?.failClosedOnUnknownQuota??a0}function w_(f,_){if(!e(_))return!0;let E=P_(_);for(let D of["five_hour","seven_day"]){let m=f?.[D];if(!m)return!Tf(_);if(m.remainingPercent<E[D])return!1}return!0}var Z={five_hour:5,seven_day:10};function Y_(f){return{five_hour:f?.five_hour??f?.["5h"]??Z.five_hour,seven_day:f?.seven_day??f?.["1w"]??Z.seven_day}}function XE(f){return f?.killswitch?.enabled===!0}function ZE(f,_){if(!f?.killswitch)return Z;if(_&&f.killswitch.accounts?.[_])return Y_(f.killswitch.accounts[_]);return Y_(f.killswitch.main)}function nm(f,_,E){if(!XE(_))return!0;let D=ZE(_,E),m=!1;for(let $ of["five_hour","seven_day"]){let C=f?.[$];if(!C){m=!0;continue}if(C.remainingPercent<D[$])return!1}if(m)return!Tf(_);return!0}function rm(f,_,E){let D=[],m=[f,..._.map(($)=>$.quota)];for(let $ of m)for(let C of["five_hour","seven_day"]){let M=$?.[C]?.resetsAt;if(!M)continue;let L=Date.parse(M);if(Number.isFinite(L)&&L>E)D.push(L)}if(!D.length)return 300;return Math.max(1,Math.ceil((Math.min(...D)-E)/1000))+60}function sm(f){return f?.killswitch??{enabled:!1}}async function cm(f,_=z()){let E=await h(_)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};return E.killswitch=f,await Q(E,_),E}function wf(f,_,E){if(!e(_))return E+X(_);let D=P_(_),m=[];for(let $ of["five_hour","seven_day"]){let C=f?.[$];if(!C)return E+X(_);if(C.remainingPercent>=D[$])continue;let M=C.resetsAt?Date.parse(C.resetsAt):Number.NaN;if(!Number.isFinite(M)||M<=E)return E+X(_);m.push(M)}if(!m.length)return E+X(_);return Math.min(...m)+60000}function l(f,_,E){return!f.access||!f.expires||f.expires-E<=JE(_)}function Vf(f,_,E){if(!e(_))return!1;let D=X(_);return["five_hour","seven_day"].some((m)=>{let $=f.quota?.[m];return!$||E-$.checkedAt>=D})}function hE(f,_){if(!f)return!1;if(!f.resetsAt)return!0;let E=Date.parse(f.resetsAt);return!Number.isFinite(E)||E>_}function VE(f,_){return["five_hour","seven_day"].every((E)=>hE(f?.[E],_))}function i_(f){let _=ff(f);if(/Claude quota check failed: (429|5\d\d)\b/.test(_))return!0;if(!(f instanceof Error))return!1;let E=f.code;return _.includes("fetch failed")||E==="ECONNRESET"||E==="ECONNREFUSED"||E==="ETIMEDOUT"||E==="UND_ERR_CONNECT_TIMEOUT"}function xE(f,_,E,D){return i_(E)&&w_(f.quota,_)&&VE(f.quota,D)}function W_(f){if(!Number.isFinite(f))return 0;if(f<0)return 0;if(f>100)return 100;return f}function X_(f,_){if(typeof f?.utilization!=="number")return;let E=W_(f.utilization);return{usedPercent:E,remainingPercent:W_(100-E),resetsAt:f.resets_at,checkedAt:_}}async function Uf(f){let E=await(f.fetchImpl??fetch)(p0,{method:"GET",headers:{Authorization:`Bearer ${f.accessToken}`,Accept:"application/json","Content-Type":"application/json","anthropic-beta":"oauth-2025-04-20","User-Agent":`claude-code/${q}`}});if(!E.ok){let $=await E.text().catch(()=>"");throw Error(`Claude quota check failed: ${E.status} — ${$}`)}let D=f.now?.()??Date.now(),m=await E.json();return{five_hour:X_(m.five_hour,D),seven_day:X_(m.seven_day,D)}}function W(f,_){let E=f.accounts.findIndex((D)=>D.id===_.id);if(E>=0)f.accounts[E]=_}function ff(f){return f instanceof Error?f.message:String(f)}function l_(f,_,E){f.lastRefreshError=WE({error:_,now:E,refreshToken:f.refresh,previous:f.lastRefreshError})}function Z_(f,_,E){if(f.lastQuotaRefreshError=Af({error:_,now:E,previous:f.lastQuotaRefreshError}),_ instanceof i)l_(f,_,E)}function QE(f){return`fallback-oauth-refresh-${h_("sha256").update(f).digest("hex").slice(0,16)}`}class IE{now;fetchImpl;configPath;refreshPromises=new Map;refreshTimer=null;quotaTimer=null;quotaManager;onFallbackStorageChanged;constructor(f={}){this.now=f.now??Date.now,this.fetchImpl=f.fetchImpl??fetch,this.configPath=f.configPath??z(),this.quotaManager=f.quotaManager??null,this.onFallbackStorageChanged=f.onFallbackStorageChanged}seedFallbackQuota(f,_){if(!this.quotaManager)return;if(this.quotaManager.getFallback(f.id,f.access))return;if(!f.quota)return;let E=Math.max(f.quota.five_hour?.checkedAt??0,f.quota.seven_day?.checkedAt??0);if(E<=0)return;let D=X(_);this.quotaManager.setFallback(f.id,{quota:f.quota,refreshAfter:E+D,checkedAt:E},f.access)}async load(){return h(this.configPath)}async save(f,_){await FE(f,this.configPath,{accounts:_??!0})}startBackgroundRefresh(){let f=async()=>{await this.refreshDueAccounts(),await this.refreshQuotaForDueAccounts()};if(f().catch(()=>{}),!this.refreshTimer){if(this.refreshTimer=setInterval(()=>{f().catch(()=>{})},e0+zE(fE)),"unref"in this.refreshTimer)this.refreshTimer.unref()}}stopBackgroundRefresh(){if(this.refreshTimer)clearInterval(this.refreshTimer);if(this.quotaTimer)clearInterval(this.quotaTimer);this.refreshTimer=null,this.quotaTimer=null}async getUsableFallbackAccounts(f){let _=f!==void 0?f:await this.load();if(!_)return[];let E=[],D=!1;for(let m of _.accounts){if(m.enabled===!1||!x(m))continue;try{let $=m;if(l($,_,this.now())){let M=$.lastRefreshError;if(M&&o(M,$.refresh,this.now()))throw Error(hf(M,this.now()));$=await this.refreshAccount($,_),D=!0}if(this.seedFallbackQuota($,_),(this.quotaManager?this.quotaManager.isFallbackStale($.id,$.access):Vf($,_,this.now()))&&!r($.lastQuotaRefreshError,this.now()))$=await this.refreshAccountQuota($,_),D=!0;if(this.accountPassesQuotaPolicy(this.quotaPolicyAccount($),_))E.push($)}catch($){if(xE(m,_,$,this.now()))V("[refresh] fallback quota using cached quota after refresh error",{accountId:m.id,error:ff($)}),E.push(m);else if(!Tf(_))E.push(m)}}if(D)await this.save(_);return E}async markUsed(f){let _=await this.load();if(!_)return;let E=_.accounts.find((D)=>D.id===f.id);if(!E)return;E.lastUsed=this.now(),await this.save(_)}accountPassesQuotaPolicy(f,_){return w_(f.quota,_)}quotaPolicyAccount(f){if(!this.quotaManager)return f;let _=this.quotaManager.getFallback(f.id,f.access)?.quota;return _?{...f,quota:_}:f}async refreshDueAccounts(){let f=await this.load();if(!f||!GE(f))return;let _=!1;for(let E of f.accounts){if(E.enabled===!1||!x(E))continue;if(!l(E,f,this.now()))continue;if(o(E.lastRefreshError,E.refresh,this.now()))continue;try{V("[refresh] fallback oauth background due",{accountId:E.id,expiresInMs:E.expires?E.expires-this.now():void 0}),await this.refreshAccount(E,f),_=!0}catch(D){V("[refresh] fallback oauth background failed",{accountId:E.id,error:D instanceof Error?D.message:String(D)}),l_(E,D,this.now()),W(f,E),_=!0}}if(_)await this.save(f)}async refreshQuotaForDueAccounts(){let f=await this.load();if(!f||!e(f))return;let _=!1;for(let E of f.accounts){if(E.enabled===!1||!x(E))continue;let D=E;try{if(l(D,f,this.now())){if(o(D.lastRefreshError,D.refresh,this.now()))continue;D=await this.refreshAccount(D,f),_=!0}if(r(D.lastQuotaRefreshError,this.now()))continue;if(this.seedFallbackQuota(D,f),!(this.quotaManager?this.quotaManager.isFallbackStale(D.id,D.access):Vf(D,f,this.now())))continue;await this.refreshAccountQuota(D,f),_=!0}catch(m){Z_(E,m,this.now()),W(f,E),_=!0}}if(_)await this.save(f),this.onFallbackStorageChanged?.()}async refreshQuotaForAllAccounts(f={}){let _=await this.load(),E=[];if(!_||!e(_))return{storage:_,errors:E};let D=f.force??!1,m=!1;for(let $ of _.accounts){if($.enabled===!1||!x($))continue;let C=$;try{if(l(C,_,this.now())){let M=C.lastRefreshError;if(M&&o(M,C.refresh,this.now()))throw Error(hf(M,this.now()));C=await this.refreshAccount(C,_),m=!0}if(!D&&!Vf(C,_,this.now())){if(C.lastQuotaRefreshError)C.lastQuotaRefreshError=void 0,W(_,C),m=!0;continue}await this.refreshAccountQuota(C,_),m=!0}catch(M){Z_($,M,this.now()),W(_,$),m=!0,E.push({accountId:$.id,message:ff(M)})}}if(m)await this.save(_);return{storage:_,errors:E}}async refreshAccount(f,_,E={}){let D=this.refreshPromises.get(f.id);if(D){let C=await D;return W(_,C),C}let m=this.refreshAccountNow(f,_,E).finally(()=>{this.refreshPromises.delete(f.id)});this.refreshPromises.set(f.id,m);let $=await m;return W(_,$),$}async waitForConcurrentFallbackRefresh(f,_,E,D){let m=Date.now()+EE;while(Date.now()<m){await new Promise((A)=>setTimeout(A,DE));let $=await this.load(),C=$?.accounts.find((A)=>A.id===f.id&&x(A));if(!C)continue;if((C.access!==E.access||C.refresh!==E.refresh||(C.expires??0)>(E.expires??0)+60000)&&(D.force||!l(C,$,this.now())))return W(_,C),V("[refresh] fallback oauth joined concurrent refresh",{accountId:C.id,expiresInMs:C.expires?C.expires-this.now():void 0}),C;let L=C.lastRefreshError;if(L&&o(L,C.refresh,this.now()))throw W(_,C),Error(hf(L,this.now()))}return null}async refreshAccountNow(f,_,E){let D=await this.load(),m=D?.accounts.find((M)=>M.id===f.id&&x(M));if(m&&!E.force&&!l(m,D,this.now()))return W(_,m),m;let $=m??f,C=await Lf({name:QE($.id),ttlMs:_E,path:this.configPath,now:this.now,renew:!0});if(!C){V("[refresh] fallback oauth refresh skipped file lock",{accountId:$.id});let M=await this.waitForConcurrentFallbackRefresh(f,_,$,E);if(M)return M;throw Error("Fallback OAuth refresh is already in progress")}try{if(D=await this.load(),m=D?.accounts.find((A)=>A.id===f.id&&x(A)),m&&!E.force&&!l(m,D,this.now()))return W(_,m),m;$=m??$;let M=$.refresh;V("[refresh] fallback oauth refresh request start",{accountId:$.id,force:E.force===!0,expiresInMs:$.expires?$.expires-this.now():void 0});let L=await N_({refreshToken:M,fetchImpl:this.fetchImpl,now:this.now});return $.access=L.access,$.refresh=L.refresh,$.expires=L.expires,$.lastRefreshedAt=L.expires-L.expiresIn*1000,$.lastRefreshError=void 0,W(_,$),await this.save(_),V("[refresh] fallback oauth refresh succeeded",{accountId:$.id,expiresInMs:$.expires?$.expires-this.now():void 0}),$}finally{await C.release()}}async refreshAccountQuota(f,_){let E=f;if(!E.access)throw Error(`Fallback account ${f.id} has no access token`);let D=(m)=>this.quotaManager?this.quotaManager.refreshFallback(E.id,m):Uf({accessToken:m,fetchImpl:this.fetchImpl,now:this.now});try{E.quota=await D(E.access)}catch(m){if(!(m instanceof Error?m.message:String(m)).includes("Claude quota check failed: 401"))throw m;if(E=await this.refreshAccount(f,_,{force:!0}),!E.access)throw m;E.quota=await D(E.access)}if(E.lastQuotaRefreshError=void 0,W(_,E),this.quotaManager&&E.quota){let m=this.now();this.quotaManager.setFallback(E.id,{quota:E.quota,refreshAfter:m+X(_),checkedAt:m},E.access)}return E}}var am="claude-cache",y_="## Claude Cache Status",PE="## Claude Cache Enabled",RE="## Claude Cache Disabled",qE="## Claude Cache Usage",TE="Usage: `/claude-cache`, `/claude-cache on`, `/claude-cache off`, or `/claude-cache mode explicit|automatic|hybrid`.",Of=!1,Sf=Cf;function em(){return Of}function f1(){return Sf}function _1(f){Of=f.enabled,Sf=f.mode}function wE(f){let _=f.trim().split(/\s+/).filter(Boolean);if(_.length===0)return{type:"status"};if(_.length===1&&_[0]==="on")return{type:"enable"};if(_.length===1&&_[0]==="off")return{type:"disable"};if(_.length===2&&_[0]==="mode"&&(_[1]==="explicit"||_[1]==="automatic"||_[1]==="hybrid"))return{type:"mode",mode:_[1]};return{type:"usage"}}function _f(f){let _=f?.enabled??Of,E=f?.mode??Sf;return[y_,"",`- Enabled: ${_?"enabled":"disabled"}`,`- Mode: ${E}`,"- Persisted: ~/.config/opencode/anthropic-auth.json","- Scope: main sessions only; subagent sessions keep default ephemeral cache behavior","- Modes: explicit = existing OpenCode breakpoints; automatic = top-level cache_control only; hybrid = system + messages[0] + top-level cache_control","- TTL: 1h when enabled for main sessions; default ephemeral cache behavior otherwise"].join(`
|
|
8
|
+
`)}function E1(f){let _=wE(f.argumentsText),E=f.enabled??Of,D=f.mode??Sf;if(_.type==="status")return _f({enabled:E,mode:D});if(_.type==="enable")return[PE,"",_f({enabled:!0,mode:D})].join(`
|
|
9
|
+
`);if(_.type==="disable")return[RE,"",_f({enabled:!1,mode:D})].join(`
|
|
10
|
+
`);if(_.type==="mode")return[y_,"",`Mode updated to \`${_.mode}\`.`,"",_f({enabled:E,mode:_.mode})].join(`
|
|
11
|
+
`);return[qE,"",TE,"",_f({enabled:E,mode:D})].join(`
|
|
12
|
+
`)}import{randomBytes as iE,randomUUID as v_}from"node:crypto";var lE=1000,y=new Map;function Ef(f,_,E){if(!f.has(_)&&f.size>=lE){let D=f.keys().next().value;if(D!==void 0)f.delete(D)}f.set(_,E)}function d_(f){let _=f||"anonymous",E=y.get(_);if(E)return E;let D={deviceId:iE(32).toString("hex"),sessionId:v_()};return Ef(y,_,D),D}var yE=86400000,kE=300000,lf=new Map,k_=new Map;async function pE(f,_){if(!f.startsWith("sk-ant-oat"))return null;let E=new AbortController,D=setTimeout(()=>E.abort(),5000);try{let m=new URL("https://api.anthropic.com/api/claude_cli/bootstrap");if(m.searchParams.set("entrypoint",M_),_)m.searchParams.set("model",_);let $=await fetch(m,{method:"GET",headers:{accept:"application/json, text/plain, */*",authorization:`Bearer ${f}`,"content-type":"application/json","anthropic-beta":"oauth-2025-04-20","user-agent":`claude-code/${q}`},signal:E.signal});if(!$.ok)return null;let M=(await $.json().catch(()=>null))?.oauth_account?.account_uuid;return typeof M==="string"&&M?M:null}catch{return null}finally{clearTimeout(D)}}async function C1(f,_){let E=d_(f);if(!f.startsWith("sk-ant-oat"))return E;let D=Date.now(),m=k_.get(f);if(m&&m.expiresAt>D){if(!m.accountUuid)return E;let A=`account:${m.accountUuid}`,U=y.get(A);if(U)return Ef(y,f,U),U}let $=lf.get(f);if(!$)$=pE(f,_),lf.set(f,$);let C=await $.finally(()=>{lf.delete(f)});if(Ef(k_,f,{accountUuid:C,expiresAt:D+(C?yE:kE)}),!C)return E;let M=`account:${C}`,L=y.get(M);if(L)return Ef(y,f,L),L;return E.accountUuid=C,Ef(y,M,E),E}function k(f){return f!=null&&typeof f==="object"&&!Array.isArray(f)}function vE(f){if(!f.accountUuid)return null;return JSON.stringify({device_id:f.deviceId,account_uuid:f.accountUuid,session_id:f.sessionId})}function M1(f,_){let E=vE(_);if(!E){if(k(f.metadata))delete f.metadata.user_id;return!1}if(!k(f.metadata))f.metadata={};let D=f.metadata;if(k(D))D.user_id=E;return!0}var dE=["claude-code-20250219","oauth-2025-04-20","interleaved-thinking-2025-05-14","context-management-2025-06-27","prompt-caching-scope-2026-01-05","advisor-tool-2026-03-01","advanced-tool-use-2025-11-20","context-1m-2025-08-07","effort-2025-11-24","extended-cache-ttl-2025-04-11","cache-diagnosis-2026-04-07"],uE=["oauth-2025-04-20","interleaved-thinking-2025-05-14","context-management-2025-06-27","prompt-caching-scope-2026-01-05","advisor-tool-2026-03-01","structured-outputs-2025-12-15","cache-diagnosis-2026-04-07"],p_=["oauth-2025-04-20","interleaved-thinking-2025-05-14","context-management-2025-06-27","prompt-caching-scope-2026-01-05","advisor-tool-2026-03-01","cache-diagnosis-2026-04-07"];function gE(f){return f.output_config?.format?.type==="json_schema"}function nE(f){return Array.isArray(f.tools)&&f.tools.length>0&&Array.isArray(f.system)&&k(f.thinking)&&k(f.context_management)&&k(f.output_config)&&k(f.diagnostics)}function rE(f,_=[]){let E=f?nE(f)?[...dE]:gE(f)?[...uE]:[...p_]:[...p_];if(f?.speed==="fast")E.push(C_);for(let D of _){let m=D.trim();if(m)E.push(m)}return[...new Set(E)].join(",")}function sE(){switch(process.platform){case"darwin":return"MacOS";case"win32":return"Windows";case"linux":return"Linux";case"freebsd":return"FreeBSD";default:return"Unknown"}}function cE(){switch(process.arch){case"arm64":return"arm64";case"x64":return"x64";case"ia32":return"x32";default:return process.arch}}function L1(f,_,E={}){let D=E.identity??d_(_),$=[...(f.get("anthropic-beta")??"").split(",").map((C)=>C.trim()).filter(Boolean),...E.extraBetas??[]];return f.set("accept","application/json"),f.set("authorization",`Bearer ${_}`),f.set("content-type","application/json"),f.set("user-agent",U_),f.set("anthropic-beta",rE(E.body,$)),f.set("anthropic-dangerous-direct-browser-access","true"),f.set("anthropic-version","2023-06-01"),f.set("x-app","cli"),f.set("x-client-request-id",v_()),f.set("x-claude-code-session-id",D.sessionId),f.set("x-stainless-arch",cE()),f.set("x-stainless-lang","js"),f.set("x-stainless-os",sE()),f.set("x-stainless-package-version",L_),f.set("x-stainless-retry-count","0"),f.set("x-stainless-runtime","node"),f.set("x-stainless-runtime-version",A_),f.set("x-stainless-timeout","600"),f.delete("x-api-key"),f}var tE=["model","messages","system","tools","tool_choice","metadata","max_tokens","temperature","thinking","context_management","output_config","diagnostics","stream","speed"];function u_(f){let _={};for(let E of tE)if(Object.hasOwn(f,E))_[E]=f[E];for(let[E,D]of Object.entries(f))if(!Object.hasOwn(_,E))_[E]=D;return _}import{createHash as aE}from"node:crypto";var oE=new Uint8Array([0,97,115,109,1,0,0,0,1,48,8,96,3,127,127,127,1,127,96,3,127,127,127,0,96,2,127,127,0,96,1,127,1,127,96,3,127,127,126,1,126,96,3,126,127,127,1,126,96,2,127,126,0,96,1,127,1,126,3,11,10,0,0,2,1,3,4,5,6,1,7,5,3,1,0,1,7,85,9,3,109,101,109,2,0,5,120,120,104,51,50,0,0,6,105,110,105,116,51,50,0,2,8,117,112,100,97,116,101,51,50,0,3,8,100,105,103,101,115,116,51,50,0,4,5,120,120,104,54,52,0,5,6,105,110,105,116,54,52,0,7,8,117,112,100,97,116,101,54,52,0,8,8,100,105,103,101,115,116,54,52,0,9,10,251,22,10,242,1,1,4,127,32,0,32,1,106,33,3,32,1,65,16,79,4,127,32,3,65,16,107,33,6,32,2,65,168,136,141,161,2,106,33,3,32,2,65,137,235,208,208,7,107,33,4,32,2,65,207,140,162,142,6,106,33,5,3,64,32,3,32,0,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,33,3,32,4,32,0,65,4,106,34,0,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,33,4,32,2,32,0,65,4,106,34,0,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,33,2,32,5,32,0,65,4,106,34,0,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,33,5,32,6,32,0,65,4,106,34,0,79,13,0,11,32,2,65,12,119,32,5,65,18,119,106,32,4,65,7,119,106,32,3,65,1,119,106,5,32,2,65,177,207,217,178,1,106,11,32,1,106,32,0,32,1,65,15,113,16,1,11,146,1,0,32,1,32,2,106,33,2,3,64,32,1,65,4,106,32,2,75,69,4,64,32,0,32,1,40,2,0,65,189,220,202,149,124,108,106,65,17,119,65,175,214,211,190,2,108,33,0,32,1,65,4,106,33,1,12,1,11,11,3,64,32,1,32,2,79,69,4,64,32,0,32,1,45,0,0,65,177,207,217,178,1,108,106,65,11,119,65,177,243,221,241,121,108,33,0,32,1,65,1,106,33,1,12,1,11,11,32,0,32,0,65,15,118,115,65,247,148,175,175,120,108,34,0,65,13,118,32,0,115,65,189,220,202,149,124,108,34,0,65,16,118,32,0,115,11,63,0,32,0,65,8,106,32,1,65,168,136,141,161,2,106,54,2,0,32,0,65,12,106,32,1,65,137,235,208,208,7,107,54,2,0,32,0,65,16,106,32,1,54,2,0,32,0,65,20,106,32,1,65,207,140,162,142,6,106,54,2,0,11,195,4,1,6,127,32,1,32,2,106,33,6,32,0,65,24,106,33,4,32,0,65,40,106,40,2,0,33,3,32,0,32,0,40,2,0,32,2,106,54,2,0,32,0,65,4,106,34,5,32,5,40,2,0,32,2,65,16,79,32,0,40,2,0,65,16,79,114,114,54,2,0,32,2,32,3,106,65,16,73,4,64,32,3,32,4,106,32,1,32,2,252,10,0,0,32,0,65,40,106,32,2,32,3,106,54,2,0,15,11,32,3,4,64,32,3,32,4,106,32,1,65,16,32,3,107,34,2,252,10,0,0,32,0,65,8,106,34,3,32,3,40,2,0,32,4,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,54,2,0,32,0,65,12,106,34,3,32,3,40,2,0,32,4,65,4,106,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,54,2,0,32,0,65,16,106,34,3,32,3,40,2,0,32,4,65,8,106,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,54,2,0,32,0,65,20,106,34,3,32,3,40,2,0,32,4,65,12,106,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,54,2,0,32,0,65,40,106,65,0,54,2,0,32,1,32,2,106,33,1,11,32,1,32,6,65,16,107,77,4,64,32,6,65,16,107,33,8,32,0,65,8,106,40,2,0,33,2,32,0,65,12,106,40,2,0,33,3,32,0,65,16,106,40,2,0,33,5,32,0,65,20,106,40,2,0,33,7,3,64,32,2,32,1,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,33,2,32,3,32,1,65,4,106,34,1,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,33,3,32,5,32,1,65,4,106,34,1,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,33,5,32,7,32,1,65,4,106,34,1,40,2,0,65,247,148,175,175,120,108,106,65,13,119,65,177,243,221,241,121,108,33,7,32,8,32,1,65,4,106,34,1,79,13,0,11,32,0,65,8,106,32,2,54,2,0,32,0,65,12,106,32,3,54,2,0,32,0,65,16,106,32,5,54,2,0,32,0,65,20,106,32,7,54,2,0,11,32,1,32,6,73,4,64,32,4,32,1,32,6,32,1,107,34,1,252,10,0,0,32,0,65,40,106,32,1,54,2,0,11,11,97,1,1,127,32,0,65,16,106,40,2,0,33,1,32,0,65,4,106,40,2,0,4,127,32,1,65,12,119,32,0,65,20,106,40,2,0,65,18,119,106,32,0,65,12,106,40,2,0,65,7,119,106,32,0,65,8,106,40,2,0,65,1,119,106,5,32,1,65,177,207,217,178,1,106,11,32,0,40,2,0,106,32,0,65,24,106,32,0,65,40,106,40,2,0,16,1,11,255,3,2,3,126,1,127,32,0,32,1,106,33,6,32,1,65,32,79,4,126,32,6,65,32,107,33,6,32,2,66,214,235,130,238,234,253,137,245,224,0,124,33,3,32,2,66,177,169,172,193,173,184,212,166,61,125,33,4,32,2,66,249,234,208,208,231,201,161,228,225,0,124,33,5,3,64,32,3,32,0,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,33,3,32,4,32,0,65,8,106,34,0,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,33,4,32,2,32,0,65,8,106,34,0,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,33,2,32,5,32,0,65,8,106,34,0,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,33,5,32,6,32,0,65,8,106,34,0,79,13,0,11,32,2,66,12,137,32,5,66,18,137,124,32,4,66,7,137,124,32,3,66,1,137,124,32,3,66,207,214,211,190,210,199,171,217,66,126,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,133,66,135,149,175,175,152,182,222,155,158,127,126,66,157,163,181,234,131,177,141,138,250,0,125,32,4,66,207,214,211,190,210,199,171,217,66,126,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,133,66,135,149,175,175,152,182,222,155,158,127,126,66,157,163,181,234,131,177,141,138,250,0,125,32,2,66,207,214,211,190,210,199,171,217,66,126,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,133,66,135,149,175,175,152,182,222,155,158,127,126,66,157,163,181,234,131,177,141,138,250,0,125,32,5,66,207,214,211,190,210,199,171,217,66,126,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,133,66,135,149,175,175,152,182,222,155,158,127,126,66,157,163,181,234,131,177,141,138,250,0,125,5,32,2,66,197,207,217,178,241,229,186,234,39,124,11,32,1,173,124,32,0,32,1,65,31,113,16,6,11,134,2,0,32,1,32,2,106,33,2,3,64,32,2,32,1,65,8,106,79,4,64,32,1,41,3,0,66,207,214,211,190,210,199,171,217,66,126,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,32,0,133,66,27,137,66,135,149,175,175,152,182,222,155,158,127,126,66,157,163,181,234,131,177,141,138,250,0,125,33,0,32,1,65,8,106,33,1,12,1,11,11,32,1,65,4,106,32,2,77,4,64,32,0,32,1,53,2,0,66,135,149,175,175,152,182,222,155,158,127,126,133,66,23,137,66,207,214,211,190,210,199,171,217,66,126,66,249,243,221,241,153,246,153,171,22,124,33,0,32,1,65,4,106,33,1,11,3,64,32,1,32,2,73,4,64,32,0,32,1,49,0,0,66,197,207,217,178,241,229,186,234,39,126,133,66,11,137,66,135,149,175,175,152,182,222,155,158,127,126,33,0,32,1,65,1,106,33,1,12,1,11,11,32,0,32,0,66,33,136,133,66,207,214,211,190,210,199,171,217,66,126,34,0,32,0,66,29,136,133,66,249,243,221,241,153,246,153,171,22,126,34,0,32,0,66,32,136,133,11,77,0,32,0,65,8,106,32,1,66,214,235,130,238,234,253,137,245,224,0,124,55,3,0,32,0,65,16,106,32,1,66,177,169,172,193,173,184,212,166,61,125,55,3,0,32,0,65,24,106,32,1,55,3,0,32,0,65,32,106,32,1,66,249,234,208,208,231,201,161,228,225,0,124,55,3,0,11,244,4,2,3,127,4,126,32,1,32,2,106,33,5,32,0,65,40,106,33,4,32,0,65,200,0,106,40,2,0,33,3,32,0,32,0,41,3,0,32,2,173,124,55,3,0,32,2,32,3,106,65,32,73,4,64,32,3,32,4,106,32,1,32,2,252,10,0,0,32,0,65,200,0,106,32,2,32,3,106,54,2,0,15,11,32,3,4,64,32,3,32,4,106,32,1,65,32,32,3,107,34,2,252,10,0,0,32,0,65,8,106,34,3,32,3,41,3,0,32,4,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,55,3,0,32,0,65,16,106,34,3,32,3,41,3,0,32,4,65,8,106,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,55,3,0,32,0,65,24,106,34,3,32,3,41,3,0,32,4,65,16,106,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,55,3,0,32,0,65,32,106,34,3,32,3,41,3,0,32,4,65,24,106,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,55,3,0,32,0,65,200,0,106,65,0,54,2,0,32,1,32,2,106,33,1,11,32,1,65,32,106,32,5,77,4,64,32,5,65,32,107,33,2,32,0,65,8,106,41,3,0,33,6,32,0,65,16,106,41,3,0,33,7,32,0,65,24,106,41,3,0,33,8,32,0,65,32,106,41,3,0,33,9,3,64,32,6,32,1,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,33,6,32,7,32,1,65,8,106,34,1,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,33,7,32,8,32,1,65,8,106,34,1,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,33,8,32,9,32,1,65,8,106,34,1,41,3,0,66,207,214,211,190,210,199,171,217,66,126,124,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,33,9,32,2,32,1,65,8,106,34,1,79,13,0,11,32,0,65,8,106,32,6,55,3,0,32,0,65,16,106,32,7,55,3,0,32,0,65,24,106,32,8,55,3,0,32,0,65,32,106,32,9,55,3,0,11,32,1,32,5,73,4,64,32,4,32,1,32,5,32,1,107,34,1,252,10,0,0,32,0,65,200,0,106,32,1,54,2,0,11,11,188,2,1,5,126,32,0,65,24,106,41,3,0,33,1,32,0,41,3,0,34,2,66,32,90,4,126,32,0,65,8,106,41,3,0,34,3,66,1,137,32,0,65,16,106,41,3,0,34,4,66,7,137,124,32,1,66,12,137,32,0,65,32,106,41,3,0,34,5,66,18,137,124,124,32,3,66,207,214,211,190,210,199,171,217,66,126,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,133,66,135,149,175,175,152,182,222,155,158,127,126,66,157,163,181,234,131,177,141,138,250,0,125,32,4,66,207,214,211,190,210,199,171,217,66,126,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,133,66,135,149,175,175,152,182,222,155,158,127,126,66,157,163,181,234,131,177,141,138,250,0,125,32,1,66,207,214,211,190,210,199,171,217,66,126,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,133,66,135,149,175,175,152,182,222,155,158,127,126,66,157,163,181,234,131,177,141,138,250,0,125,32,5,66,207,214,211,190,210,199,171,217,66,126,66,31,137,66,135,149,175,175,152,182,222,155,158,127,126,133,66,135,149,175,175,152,182,222,155,158,127,126,66,157,163,181,234,131,177,141,138,250,0,125,5,32,1,66,197,207,217,178,241,229,186,234,39,124,11,32,2,124,32,0,65,40,106,32,2,66,31,131,167,16,6,11]);async function g_(){return function(f){let{exports:{mem:_,xxh32:E,xxh64:D,init32:m,update32:$,digest32:C,init64:M,update64:L,digest64:A}}=f,U=new Uint8Array(_.buffer);function N(O,G){if(_.buffer.byteLength<O+G){let zf=Math.ceil((O+G-_.buffer.byteLength)/65536);_.grow(zf),U=new Uint8Array(_.buffer)}}function K(O,G,zf,z0,J0,Y0){N(O);let c=new Uint8Array(O);return U.set(c),zf(0,G),c.set(U.subarray(0,O)),{update(g){let Jf;return U.set(c),typeof g=="string"?(N(3*g.length,O),Jf=S.encodeInto(g,U.subarray(O)).written):(N(g.byteLength,O),U.set(g,O),Jf=g.byteLength),z0(0,O,Jf),c.set(U.subarray(0,O)),this},digest:()=>(U.set(c),Y0(J0(0)))}}function j(O){return O>>>0}let R=2n**64n-1n;function J(O){return O&R}let S=new TextEncoder,v=0,d=0n;function u(O,G=v){return N(3*O.length,0),j(E(0,S.encodeInto(O,U).written,G))}function mf(O,G=d){return N(3*O.length,0),J(D(0,S.encodeInto(O,U).written,G))}return{h32:u,h32ToString:(O,G=v)=>u(O,G).toString(16).padStart(8,"0"),h32Raw:(O,G=v)=>(N(O.byteLength,0),U.set(O),j(E(0,O.byteLength,G))),create32:(O=v)=>K(48,O,m,$,C,j),h64:mf,h64ToString:(O,G=d)=>mf(O,G).toString(16).padStart(16,"0"),h64Raw:(O,G=d)=>(N(O.byteLength,0),U.set(O),J(D(0,O.byteLength,G))),create64:(O=d)=>K(88,O,M,L,A,J)}}((await WebAssembly.instantiate(oE)).instance)}var eE=0x6e52736ac806831en,fD="cch=00000;";var kf=/("system":\[\{"type":"text","text":"x-anthropic-billing-header: cc_version=[^;"]+; cc_entrypoint=[^;"]+; )cch=([0-9a-f]{5});/,_D=/("system":\[\{"type":"text","text":"x-anthropic-billing-header: cc_version=[^;"]+; cc_entrypoint=[^;"]+; )cch=00000;/,n_=null,yf=null;async function ED(){if(yf)return;n_??=(async()=>{yf=(await g_()).h64Raw})(),await n_}async function DD(f){return await ED(),((yf?.(f,eE)??0n)&0xfffffn).toString(16).padStart(5,"0")}function mD(f){return f.replace(kf,`$1${fD}`)}function r_(f){return kf.exec(f)?.[2]??null}async function s_(f){if(!kf.test(f))return f;let _=mD(f),E=await DD(new TextEncoder().encode(_));return _.replace(_D,`$1cch=${E};`)}function $D(f=q,_=new Date){if(f===q)return Xf;return aE("sha256").update(f).digest("hex").slice(0,3)}function N1(f,_=q,E,D=new Date){let m=$D(_,D);return`x-anthropic-billing-header: cc_version=${_}.${m}; cc_entrypoint=${E}; cch=00000;`}var K1="claude-cachekeep",df=3600000,pf=300000,CD=60000,j1="extended-cache-ttl-2025-04-11",MD=32,c_=16777216,LD=2*df,AD="## Claude Cache Keep Status",UD="## Claude Cache Keep Enabled",OD="## Claude Cache Keep Disabled",SD="## Claude Cache Keep Usage",HD="Usage: `/claude-cachekeep`, `/claude-cachekeep off`, or `/claude-cachekeep HH-HH`.";function Nf(f){return String(f).padStart(2,"0")}function ND(f){let _=f.trim();if(!_)return{type:"status"};if(_==="off")return{type:"disable"};let E=/^(\d{1,2})-(\d{1,2})$/.exec(_);if(!E)return{type:"usage"};let D=Number(E[1]),m=Number(E[2]);if(!Number.isInteger(D)||!Number.isInteger(m)||D<0||D>23||m<0||m>23||D===m)return{type:"usage"};return{type:"window",startHour:D,endHour:m}}function uf(f){let _=Number(f?.cacheKeep?.startHour),E=Number(f?.cacheKeep?.endHour);if(!Number.isInteger(_)||!Number.isInteger(E)||_<0||_>23||E<0||E>23||_===E)return;return{startHour:_,endHour:E}}function a_(f){return f?.cacheKeep?.enabled===!0&&!!uf(f)}function bD(f){return a_(f)&&f?.claudeCache?.enabled===!0&&f.claudeCache.mode==="hybrid"}function t_(f,_=new Date){if(!f)return!1;let E=_.getHours();if(f.startHour<f.endHour)return E>=f.startHour&&E<f.endHour;return E>=f.startHour||E<f.endHour}function o_(f=new Date){return`${f.getFullYear()}-${Nf(f.getMonth()+1)}-${Nf(f.getDate())}`}function vf(f,_=new Date){if(f&&f.startHour>f.endHour&&_.getHours()<f.endHour){let E=new Date(_);return E.setDate(E.getDate()-1),o_(E)}return o_(_)}function Hf(f){let _=f.window?`${Nf(f.window.startHour)}-${Nf(f.window.endHour)}`:"not configured",E=[`Cache keep: ${f.enabled?"enabled":"disabled"}`,`Window: ${_}`,"Mode requirement: `/claude-cache mode hybrid` must be active."];if(typeof f.hybridActive==="boolean")E.push(`Hybrid active: ${f.hybridActive?"yes":"no"}`);if(typeof f.trackedSessions==="number")E.push(`Tracked sessions: ${f.trackedSessions}`);if(f.nextPrewarmAt)E.push(`Next prewarm: ${new Date(f.nextPrewarmAt).toLocaleString()}`);return E.join(`
|
|
13
|
+
`)}function G1(f){let _=ND(f.argumentsText),E={enabled:f.enabled??!1,window:f.window,trackedSessions:f.trackedSessions,nextPrewarmAt:f.nextPrewarmAt,hybridActive:f.hybridActive};if(_.type==="status")return[AD,"",Hf(E)].join(`
|
|
14
|
+
`);if(_.type==="disable")return[OD,"",Hf({...E,enabled:!1})].join(`
|
|
15
|
+
`);if(_.type==="window")return[UD,"",Hf({...E,enabled:!0,window:{startHour:_.startHour,endHour:_.endHour}})].join(`
|
|
16
|
+
`);return[SD,"",HD,"",Hf(E)].join(`
|
|
17
|
+
`)}function gf(f){if(!f||typeof f!=="object")return!1;if(Array.isArray(f))return f.some(gf);let _=f,E=_.cache_control;if(E&&typeof E==="object"&&E.type==="ephemeral")return!0;return Object.values(_).some(gf)}async function FD(f){let _;try{_=JSON.parse(f)}catch{return{ok:!1,reason:"body is not valid JSON"}}if(!gf(_))return{ok:!1,reason:"body has no explicit cache breakpoints"};let E=structuredClone(_);if(E.max_tokens=0,delete E.stream,E.thinking?.type==="enabled")delete E.thinking;if(E.output_config?.format)delete E.output_config;let $=E.tool_choice;if($?.type==="tool"||$?.type==="any")delete E.tool_choice;return{ok:!0,bodyText:await s_(JSON.stringify(u_(E)))}}class BD{options;targets=new Map;timer=null;constructor(f){this.options=f}start(){if(this.timer)return;if(this.timer=setInterval(()=>{this.tick().catch((f)=>{this.options.log?.("[cachekeep] tick failed",{error:f instanceof Error?f.message:String(f)})})},CD),"unref"in this.timer)this.timer.unref()}stop(){if(this.timer)clearInterval(this.timer);this.timer=null}stats(f,_=this.options.now?.()??Date.now()){let E=vf(f,new Date(_)),D=[...this.targets.values()].filter(($)=>$.dayKey===E),m=D.length?Math.min(...D.map(($)=>$.cacheExpiresAt-pf)):void 0;return{trackedSessions:D.length,nextPrewarmAt:m}}trackedCount(){return this.targets.size}totalBodyBytes(){return[...this.targets.values()].reduce((f,_)=>f+_.bodyText.length,0)}evictOldestTarget(){let f=this.targets.keys().next().value;if(f!==void 0)this.targets.delete(f)}pruneTargets(f,_){for(let[E,D]of this.targets){if(_&&D.dayKey!==_){this.targets.delete(E);continue}if(f-D.cacheExpiresAt>LD)this.targets.delete(E)}while(this.targets.size>MD)this.evictOldestTarget();while(this.totalBodyBytes()>c_){let E=this.targets.size;if(this.evictOldestTarget(),this.targets.size===E)break}}track(f){if(!f.sessionId)return{tracked:!1,reason:"missing session id"};if(!a_(f.storage))return{tracked:!1,reason:"cachekeep disabled"};if(f.cacheMode!=="hybrid")return{tracked:!1,reason:"cache mode is not hybrid"};if(f.bodyText.length>c_)return{tracked:!1,reason:"body exceeds cachekeep memory budget"};let _=this.options.now?.()??Date.now(),E=uf(f.storage);if(!t_(E,new Date(_)))return{tracked:!1,reason:"outside configured window"};let D=vf(E,new Date(_));if(this.pruneTargets(_,D),this.targets.has(f.sessionId))this.targets.delete(f.sessionId);let m={};return f.headers.forEach(($,C)=>{m[C]=$}),this.targets.set(f.sessionId,{id:f.sessionId,url:f.url,headers:m,bodyText:f.bodyText,cacheExpiresAt:_+df,dayKey:D}),this.pruneTargets(_,D),this.start(),{tracked:!0}}async tick(){let f=await this.options.loadStorage(),_=uf(f),E=this.options.now?.()??Date.now(),D=vf(_,new Date(E));if(this.pruneTargets(E,D),!this.targets.size){this.stop();return}if(!bD(f))return;if(!t_(_,new Date(E)))return;let m=E+pf;for(let $ of this.targets.values()){if($.cacheExpiresAt>m)continue;await this.prewarm($,E)}}async prewarm(f,_){let E=await FD(f.bodyText);if(!E.ok){this.options.log?.("[cachekeep] prewarm skipped",{session:f.id,reason:E.reason}),this.targets.delete(f.id);return}let D=this.options.fetchImpl??fetch,m={...f,bodyText:E.bodyText},$=this.options.prepareHeaders?await this.options.prepareHeaders(new Headers(f.headers),m):new Headers(f.headers);$.delete("content-length"),$.delete("transfer-encoding");let C=await D(f.url,{method:"POST",headers:$,body:E.bodyText});if(!C.ok){this.options.log?.("[cachekeep] prewarm failed",{session:f.id,status:C.status,body:await C.text().catch(()=>"")}),f.cacheExpiresAt=_+pf+300000;return}await C.body?.cancel().catch(()=>{}),f.cacheExpiresAt=_+df,this.options.log?.("[cachekeep] prewarm succeeded",{session:f.id})}}import{createHash as KD}from"node:crypto";import{mkdir as jD,writeFile as nf}from"node:fs/promises";import{tmpdir as GD}from"node:os";import{join as _0}from"node:path";var V1="claude-dump",zD="## Claude Dump Status",JD="## Claude Dump Enabled",YD="## Claude Dump Disabled",WD="## Claude Dump Usage",XD="Usage: `/claude-dump`, `/claude-dump on`, or `/claude-dump off`.",ZD="OPENCODE_ANTHROPIC_AUTH_DUMP_DIR",hD=_0(GD(),"opencode-anthropic-auth-dumps"),Ff=!1,e_=0;function x1(f){Ff=f}function E0(){return process.env[ZD]||hD}function VD(f){let _=f.trim().split(/\s+/).filter(Boolean);if(_.length===0)return{type:"status"};if(_.length===1&&_[0]==="on")return{type:"enable"};if(_.length===1&&_[0]==="off")return{type:"disable"};return{type:"usage"}}function bf(f){let _=f?.enabled??Ff;return[zD,"",`- Enabled: ${_?"enabled":"disabled"}`,`- Directory: ${E0()}`,"- Persisted: ~/.config/opencode/anthropic-auth.json","- Captures: final rewritten Anthropic body plus redacted relay payload metadata","- Warning: body dumps may contain prompt/session content; turn this off after debugging"].join(`
|
|
18
|
+
`)}function Q1(f){let _=VD(f.argumentsText),E=f.enabled??Ff;if(_.type==="status")return bf({enabled:E});if(_.type==="enable")return[JD,"",bf({enabled:!0})].join(`
|
|
19
|
+
`);if(_.type==="disable")return[YD,"",bf({enabled:!1})].join(`
|
|
20
|
+
`);return[WD,"",XD,"",bf({enabled:E})].join(`
|
|
21
|
+
`)}function f0(f){return f.length<=16?f:`${f.slice(0,12)}…`}function xD(f){let _=f.trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");if(!_)return"session-unknown";return _.length<=80?_:_.slice(0,80)}function D0(f){return KD("sha256").update(f).digest("hex")}function QD(f){return r_(f)}function ID(f,_){if(f==null)return null;if(f===_)return{changed:!1,firstByte:-1,lastPreviousByte:-1,lastCurrentByte:-1,previousBytes:f.length,currentBytes:_.length};let E=0;while(E<f.length&&E<_.length&&f[E]===_[E])E+=1;let D=f.length-1,m=_.length-1;while(D>=E&&m>=E&&f[D]===_[m])D-=1,m-=1;return{changed:!0,firstByte:E,lastPreviousByte:D,lastCurrentByte:m,changedPreviousBytes:D-E+1,changedCurrentBytes:m-E+1,previousBytes:f.length,currentBytes:_.length}}function PD(f){try{let _=JSON.parse(f);return _!=null&&typeof _==="object"&&!Array.isArray(_)?_:null}catch(_){return b(`dump body parse failed: ${_ instanceof Error?_.message:String(_)}`),null}}function rf(f){return D0(JSON.stringify(f))}function RD(f){let _=PD(f);if(!_)return{parseable:!1};let E=Array.isArray(_.messages)?_.messages:[],D=Array.isArray(_.system)?_.system:[],m=E[0],$=E.slice(1);return{parseable:!0,model:typeof _.model==="string"?_.model:void 0,stream:_.stream,systemCount:D.length,messagesCount:E.length,systemHash:rf(D),message0Hash:m===void 0?null:rf(m),message0Bytes:m===void 0?0:JSON.stringify(m).length,messagesAfter0Hash:rf($),messagesAfter0Bytes:JSON.stringify($).length,cch:QD(f)}}function sf(f){if(Array.isArray(f))return f.map(sf);if(f==null||typeof f!=="object")return f;let _={};for(let[E,D]of Object.entries(f)){let m=E.toLowerCase();if(m==="authorization"||m==="x-api-key"||m==="cookie"||m==="set-cookie"){_[E]="[redacted]";continue}_[E]=sf(D)}return _}async function m0(f){if(!Ff)return;e_+=1;let _=`${new Date().toISOString().replace(/[:.]/g,"-")}-${String(e_).padStart(5,"0")}-${xD(f.affinity)}-${f.transport}-p${f.protocol}-${f.mode}`,E=E0(),D=_0(E,_);try{await jD(E,{recursive:!0});let m={id:_,createdAt:new Date().toISOString(),session:f0(f.affinity),transport:f.transport,protocol:f.protocol,mode:f.mode,status:f.status,bodyBytes:f.bodyText.length,relayBytes:f.relayBytes,bodyHash:D0(f.bodyText),diff:ID(f.previousBodyText,f.bodyText),body:RD(f.bodyText),files:{body:`${D}.body.json`,relay:`${D}.relay.json`,metadata:`${D}.meta.json`}};await Promise.all([nf(`${D}.body.json`,f.bodyText,"utf8"),nf(`${D}.relay.json`,`${JSON.stringify(sf(f.payload),null,2)}
|
|
22
|
+
`,"utf8"),nf(`${D}.meta.json`,`${JSON.stringify(m,null,2)}
|
|
23
|
+
`,"utf8")]),b(`dumped request id=${_} session=${f0(f.affinity)} body=${D}.body.json meta=${D}.meta.json`)}catch(m){b(`dump failed: ${m instanceof Error?m.message:String(m)}`)}}var P1="claude-fast";var Kf=!1;function R1(){return Kf}function q1(f){Kf=f}function qD(f){let _=f.trim().split(/\s+/).filter(Boolean);if(_.length===0)return{type:"status"};if(_.length===1&&_[0]==="on")return{type:"enable"};if(_.length===1&&_[0]==="off")return{type:"disable"};return{type:"usage"}}function Bf(f){return["## Claude Fast Mode Status","",`- Enabled: ${f?.enabled??Kf?"enabled":"disabled"}`,"- Persisted: ~/.config/opencode/anthropic-auth.json","- Scope: adds Anthropic fast mode to supported Opus requests","- Supported models: claude-opus-4-6, claude-opus-4-7, and claude-opus-4-8",'- Request changes: adds `speed: "fast"` and the `fast-mode-2026-02-01` beta header',"- Note: fast and standard speeds do not share prompt-cache prefixes"].join(`
|
|
24
|
+
`)}function T1(f){let _=qD(f.argumentsText),E=f.enabled??Kf;if(_.type==="status")return Bf({enabled:E});if(_.type==="enable")return["## Claude Fast Mode Enabled","",Bf({enabled:!0})].join(`
|
|
25
|
+
`);if(_.type==="disable")return["## Claude Fast Mode Disabled","",Bf({enabled:!1})].join(`
|
|
26
|
+
`);return["## Claude Fast Mode Usage","","Usage: `/claude-fast`, `/claude-fast on`, or `/claude-fast off`.","",Bf({enabled:E})].join(`
|
|
27
|
+
`)}var Df="claude-killswitch";function TD(f){let _=f.trim().split(/\s+/).filter(Boolean);if(_.length===0)return{type:"status"};if(_.length===1&&_[0]==="on")return{type:"on"};if(_.length===1&&_[0]==="off")return{type:"off"};if(_[0]==="set"){let E=[];for(let D=1;D<_.length;D++){let m=_[D]?.match(/^([^:]+):(\d+),(\d+)$/);if(!m)return{type:"usage"};let[,$,C,M]=m;E.push({account:$,fh:Number.parseInt(C,10),sd:Number.parseInt(M,10)})}if(E.length===0)return{type:"usage"};return{type:"set",entries:E}}return{type:"usage"}}function jf(f,_){let E=f.enabled===!0,D=["## Killswitch","",`Status: **${E?"ON":"OFF"}**`];if(E){D.push(""),D.push("| Account | 5h threshold | 1w threshold |"),D.push("| ------- | ------------ | ------------ |");let m=f.main??{},$=m.five_hour??m["5h"]??Z.five_hour,C=m.seven_day??m["1w"]??Z.seven_day;D.push(`| main | ≥ ${$}% | ≥ ${C}% |`);for(let M of _){let L=f.accounts?.[M]??f.main??{},A=L.five_hour??L["5h"]??Z.five_hour,U=L.seven_day??L["1w"]??Z.seven_day;D.push(`| ${M} | ≥ ${A}% | ≥ ${U}% |`)}}return D.join(`
|
|
28
|
+
`)}var $0=["## Killswitch Commands","","```",`/${Df} — show status`,`/${Df} on — enable with current or default thresholds`,`/${Df} off — disable`,`/${Df} set all:5,10 — set all accounts to 5h≥5%, 1w≥10%`,`/${Df} set main:3,8 work-alt:5,10 — per-account`,"```"].join(`
|
|
29
|
+
`);function l1(f){let _=TD(f.argumentsText);if(_.type==="status")return{text:`${jf(f.config,f.accountIds)}
|
|
30
|
+
|
|
31
|
+
${$0}`};if(_.type==="on"){let D={...f.config,enabled:!0,main:f.config.main??{five_hour:Z.five_hour,seven_day:Z.seven_day}};return{text:`## Killswitch Enabled
|
|
32
|
+
|
|
33
|
+
${jf(D,f.accountIds)}`,updatedConfig:D}}if(_.type==="off")return{text:"## Killswitch Disabled",updatedConfig:{...f.config,enabled:!1}};if(_.type==="set"){let D={...f.config.accounts??{}},m={...f.config,enabled:!0,accounts:D};for(let C of _.entries){let M={five_hour:C.fh,seven_day:C.sd};if(C.account==="main")m.main=M;else if(C.account==="all"){m.main=M;for(let L of f.accountIds)D[L]=M}else D[C.account]=M}return{text:`## Killswitch Updated
|
|
34
|
+
|
|
35
|
+
${jf(m,f.accountIds)}`,updatedConfig:m}}return{text:`${jf(f.config,f.accountIds)}
|
|
36
|
+
|
|
37
|
+
${$0}`}}var wD=["claude-fable-5","claude-mythos-5"],k1={input:10,output:50,cacheRead:1,cacheWrite5m:12.5,cacheWrite1h:20},p1=1e6,v1=128000,d1="2026-06-09",u1={["claude-fable-5"]:{id:"claude-fable-5",name:"Claude Fable 5"},["claude-mythos-5"]:{id:"claude-mythos-5",name:"Claude Mythos 5",limited:!0}};function g1(f){return typeof f==="string"&&wD.some((_)=>f===_||f.startsWith(`${_}-`))}import{createHash as iD}from"node:crypto";var lD=globalThis.setTimeout;function I(f){return iD("sha256").update(f).digest("hex").slice(0,16)}class w{main=null;mainTokenFp=null;fallbacks=new Map;fallbackTokenFps=new Map;inflightMain=null;inflightFallbacks=new Map;mainLastApiError=void 0;fallbackApiErrors=new Map;fallbackErrorTokenFps=new Map;apiGate=Promise.resolve();lastApiCallAt=0;storage;fetchImpl;now;onMainQuotaFetched;onApiError;constructor(f){this.storage=f.storage,this.fetchImpl=f.fetchImpl??fetch,this.now=f.now??Date.now,this.onMainQuotaFetched=f.onMainQuotaFetched,this.onApiError=f.onApiError;let _=q_(f.storage);if(_)this.main={quota:_.quota,refreshAfter:wf(_.quota,f.storage,_.checkedAt),checkedAt:_.checkedAt},this.mainTokenFp=_.tokenFingerprint??null;let E=f.storage?.quota?.mainLastQuotaApiError;if(E&&r(E,this.now()))this.mainLastApiError=E}getMain(f){if(f&&this.main&&this.mainTokenFp&&this.mainTokenFp!==I(f))this.main=null,this.mainTokenFp=null;return this.main}getFallback(f,_){let E=this.fallbacks.get(f)??null;if(!_||!E)return E;if(this.fallbackTokenFps.get(f)!==I(_))return this.fallbacks.delete(f),this.fallbackTokenFps.delete(f),null;return E}getAllFallbacks(){return this.fallbacks}setMain(f,_){this.mainTokenFp=I(f),this.main=_}setFallback(f,_,E){if(this.fallbacks.set(f,_),E)this.fallbackTokenFps.set(f,I(E));else this.fallbackTokenFps.delete(f)}async refreshMain(f){let _=I(f);if(this.mainTokenFp&&this.mainTokenFp!==_)this.main=null,this.mainTokenFp=null;if(this.inflightMain)return this.inflightMain;if(this.isBackedOff()){if(this.main)return this.main.quota;throw Error("Quota API rate-limited — try again later")}return this.inflightMain=this._fetchMain(f),this.inflightMain}async refreshFallback(f,_){let E=w.fallbackInflightKey(f,_),D=this.inflightFallbacks.get(E);if(D)return D;if(this.isFallbackBackedOff(f,_)){let $=this.getFallback(f,_);if($)return $.quota;throw Error("Quota API rate-limited — try again later")}let m=this._fetchFallback(f,_);return this.inflightFallbacks.set(E,m),m}async refreshAllFallbacks(f){let _=this.now();for(let E of f){if(E.enabled===!1)continue;if(!E.access)continue;let D=this.getFallback(E.id,E.access);if(D&&_<D.refreshAfter)continue;try{await this.refreshFallback(E.id,E.access)}catch{}}}refreshMainInBackground(f){if(this.inflightMain)return;if(this.isBackedOff())return;this.refreshMain(f).catch(()=>{})}isMainStale(){if(!this.main)return!0;return this.now()>=this.main.refreshAfter}isFallbackStale(f,_){let E=this.getFallback(f,_);if(!E)return!0;return this.now()>=E.refreshAfter}shouldRefreshOnRequestCount(f){let _=T_(this.storage);if(_<=0)return!1;return f>0&&f%_===0}needsRefresh(f){return this.isMainStale()||this.shouldRefreshOnRequestCount(f)}updateStorage(f){this.storage=f}seedFallbacksFromAccounts(f){let _=X(this.storage);for(let E of f){if(E.enabled===!1)continue;if(this.getFallback(E.id,E.access))continue;if(!E.quota)continue;let D=Math.max(E.quota.five_hour?.checkedAt??0,E.quota.seven_day?.checkedAt??0);if(D<=0)continue;this.setFallback(E.id,{quota:E.quota,refreshAfter:D+_,checkedAt:D},E.access)}}isBackedOff(){return r(this.mainLastApiError,this.now())}isFallbackBackedOff(f,_){if(_){if(this.fallbackErrorTokenFps.get(f)!==I(_))return!1}return r(this.fallbackApiErrors.get(f),this.now())}getLastApiError(){return this.mainLastApiError}static API_CALL_GAP_MS=1000;static fallbackInflightKey(f,_){return JSON.stringify([f,I(_)])}static quotaLockName(f){return`opencode-fallback-quota-refresh-${f.replace(/[^a-zA-Z0-9._-]+/g,"-")||"account"}`}_enqueueApiFetch(f){let _=async()=>{let D=this.now()-this.lastApiCallAt;if(D<w.API_CALL_GAP_MS)await new Promise((m)=>{let $=lD(m,w.API_CALL_GAP_MS-D);if(typeof $==="object"&&"unref"in $)$.unref()});return this.lastApiCallAt=this.now(),f()},E=this.apiGate.then(_,_);return this.apiGate=E.catch(()=>{}),E}async _fetchMain(f){return this._enqueueApiFetch(async()=>{try{if(this.isBackedOff()){if(this.main)return this.main.quota;throw Error("Quota API rate-limited — try again later")}let _=await Lf({name:"opencode-main-quota-refresh",ttlMs:30000});if(!_){if(this.main)return this.main.quota;throw Error("Quota refresh is already in progress")}try{let E=await Uf({accessToken:f,fetchImpl:this.fetchImpl,now:this.now}),D=this.now();return this.mainTokenFp=I(f),this.main={quota:E,refreshAfter:wf(E,this.storage,D),checkedAt:D},this.mainLastApiError=void 0,this.onMainQuotaFetched?.(E,D,this.mainTokenFp),E}catch(E){throw this._handleMainFetchError(E),E}finally{await _.release()}}finally{this.inflightMain=null}})}async _fetchFallback(f,_){return this._enqueueApiFetch(async()=>{try{if(this.isFallbackBackedOff(f,_)){let D=this.getFallback(f,_);if(D)return D.quota;throw Error("Quota API rate-limited — try again later")}let E=await Lf({name:w.quotaLockName(f),ttlMs:30000});if(!E){let D=this.getFallback(f,_);if(D)return D.quota;throw Error("Quota refresh is already in progress")}try{let D=await Uf({accessToken:_,fetchImpl:this.fetchImpl,now:this.now}),m=this.now();return this.setFallback(f,{quota:D,refreshAfter:m+X(this.storage),checkedAt:m},_),this.fallbackApiErrors.delete(f),this.fallbackErrorTokenFps.delete(f),D}finally{await E.release()}}catch(E){throw this._handleFallbackFetchError(f,_,E),E}finally{this.inflightFallbacks.delete(w.fallbackInflightKey(f,_))}})}static isAuthError(f){let _=f instanceof Error?f.message:String(f);return/quota check failed: 401\b/.test(_)}_handleMainFetchError(f){if(w.isAuthError(f))return;this.mainLastApiError=Af({error:f,now:this.now(),previous:this.mainLastApiError}),this.onApiError?.(this.mainLastApiError)}_handleFallbackFetchError(f,_,E){if(w.isAuthError(E))return;let D=I(_),m=this.fallbackErrorTokenFps.get(f)===D?this.fallbackApiErrors.get(f):void 0;this.fallbackApiErrors.set(f,Af({error:E,now:this.now(),previous:m})),this.fallbackErrorTokenFps.set(f,D)}}var o1="claude-quota",C0={five_hour:"5h",seven_day:"1w"};function M0(f){return`${Math.round(f*10)/10}%`}function cf(f,_){let E=Math.max(0,_-f),D=Math.floor(E/60000);if(D<1)return"just now";if(D===1)return"1m ago";if(D<60)return`${D}m ago`;let m=Math.floor(D/60),$=D%60;if($===0)return`${m}h ago`;return`${m}h ${$}m ago`}function yD(f,_){let E=Date.parse(f);if(!Number.isFinite(E))return f;let D=E-_;if(D<=0)return"now";let m=Math.max(1,Math.ceil(D/60000));if(m<60)return`in ${m}m`;let $=Math.floor(m/60),C=m%60;if(C===0)return`in ${$}h`;return`in ${$}h ${C}m`}function kD(f,_){if(!f)return"";return`, resets ${yD(f,_)}`}function L0(f,_,E){if(!_)return` - ${C0[f]}: unknown`;return[` - ${C0[f]}: ${M0(_.remainingPercent)} remaining`,` (${M0(_.usedPercent)} used`,`${kD(_.resetsAt,E)}, checked ${cf(_.checkedAt,E)})`].join("")}function pD(f){return f.label?.trim()||f.id}function vD(f){return f.lastQuotaRefreshError?.message??f.lastRefreshError?.message}function a1(f,_=new Map){if(!f?.accounts.length)return[];return f.accounts.filter(x).map((E)=>{let D=_.get(E.id)??vD(E);return{name:pD(E),role:"fallback",enabled:E.enabled!==!1,quota:E.quota,lastRefreshedAt:E.lastRefreshedAt,...D&&{error:D}}})}function e1(f){let _=f.now??Date.now(),E=["## Claude Quotas",""];if(f.refreshedAt)E.push(`Refreshed: ${cf(f.refreshedAt,_)}`,"");if(!f.accounts.length)return E.push("No Claude OAuth accounts found yet."),E.join(`
|
|
38
|
+
`);for(let D of f.accounts){let m=D.role==="main"?"main":"fallback",$=D.enabled===!1?" disabled":"";if(E.push(`### ${D.name} (${m}${$})`),D.lastRefreshedAt)E.push(` - Last token refresh: ${cf(D.lastRefreshedAt,_)}`);if(D.error)E.push(` - Error: ${D.error}`);E.push(L0("five_hour",D.quota?.five_hour,_)),E.push(L0("seven_day",D.quota?.seven_day,_)),E.push("")}return E.join(`
|
|
39
|
+
`).trimEnd()}import{Buffer as F0}from"node:buffer";import{createHash as dD,randomBytes as uD}from"node:crypto";class of extends Error{}class af extends Error{code="ECONNRESET";syscall="websocket";closeCode;closeReason;wasClean;constructor(f,_){super(f);this.name="RelayWebSocketConnectionResetError",this.closeCode=_?.code,this.closeReason=_?.reason,this.wasClean=_?.wasClean}}var P=new Map,p=new Map,A0=new Set,gD=7200000,nD=1800000,rD=128,sD=32,U0=0;function tf(){return U0+=1,`req_${Date.now().toString(36)}_${U0.toString(36)}`}function Gf(f){if(A0.has(f))return;A0.add(f),b(f)}function $$(f){let _=f?.relay;if(!_)return Gf("disabled: no relay config found"),null;if(_.enabled!==!0)return Gf("disabled: relay.enabled is not true"),null;if(!_.url?.trim()||!_.token?.trim())return Gf("disabled: missing relay url or token"),null;let E=_.transport==="http"?"http":"websocket";return Gf(`configured transport=${E} protocol=${E==="websocket"?2:1} url=${_.url.trim()} fallbackToDirect=${_.fallbackToDirect!==!1}`),{enabled:!0,url:_.url.trim(),token:_.token.trim(),fallbackToDirect:_.fallbackToDirect!==!1,transport:E}}function C$(){return uD(32).toString("base64url")}function cD(f){return`sha256:${dD("sha256").update(f).digest("hex")}`}function O0(f,_){let E=0,D=Math.min(f.length,_.length);while(E<D&&f.charCodeAt(E)===_.charCodeAt(E))E++;let m=f.length,$=_.length;while(m>E&&$>E&&f.charCodeAt(m-1)===_.charCodeAt($-1))m--,$--;return{start:E,deleteCount:m-E,insert:_.slice(E,$)}}function tD(f){return f.deleteCount===0&&f.insert.length===0}function S0(f){let _=f.match(/\bcch=([0-9a-f]{5});/),E=_?.[1];if(!E||_.index==null)return null;let D=_.index+4;return{start:D,end:D+E.length,token:E}}function oD(f,_,E,D){return`${f.slice(0,_)}${D}${f.slice(E)}`}function B0(f,_){let E=S0(f),D=S0(_);if(E&&D&&E.start===D.start&&E.end-E.start===D.end-D.start&&E.token!==D.token){let m={start:E.start,deleteCount:E.end-E.start,insert:D.token},$=oD(f,E.start,E.end,D.token),C=O0($,_);return tD(C)?m:[m,C]}return O0(f,_)}function aD(f,_){if(typeof _!=="string")return!1;try{let E=f instanceof Request?new URL(f.url):new URL(f.toString());return E.pathname==="/v1/messages"||E.pathname==="/messages"}catch{return!1}}function eD(f){let _={};for(let[E,D]of f.entries()){if(E==="x-session-affinity"||E==="x-opencode-session")continue;_[E]=D}return _}async function H0(f,_,E){let D=F(),m=JSON.stringify(_);return s("http_payload_stringify",{session:B(_.affinity),ms:Y(F()-D),relayBytes:m.length,mode:_.mode}),fetch(f.url,{method:"POST",headers:{"content-type":"application/json","x-relay-token":f.token},body:m,signal:E??void 0})}function B(f){return f.length>12?`${f.slice(0,12)}…`:f}function F(){return performance.now()}function Y(f){return Math.round(f*10)/10}function fm(){return process.env.OPENCODE_ANTHROPIC_AUTH_PERF==="1"}function s(f,_){if(!fm())return;b(`[perf] relay ${f} ${JSON.stringify(_)}`)}function _m(f){let{input:_,init:E,headers:D,bodyText:m,affinity:$,previous:C,nextHash:M}=f,L=_ instanceof Request?_.url:_.toString(),A={protocol:1,type:"request",affinity:$,upstream:{url:L,method:E?.method||(_ instanceof Request?_.method:"POST"),headers:eD(D)},next_hash:M};return C?{...A,mode:"patch",base_hash:C.hash,revision:C.revision+1,patch:B0(C.body,m)}:{...A,mode:"full_sync",revision:1,body:m}}function ef(f,_){return{protocol:f.protocol,type:"request",affinity:f.affinity,upstream:f.upstream,next_hash:f.next_hash,mode:"full_sync",revision:1,body:_}}function K0(f,_,E,D){let m=Date.now();P.delete(f),P.set(f,{body:_,hash:E,revision:D,updatedAt:m}),f_(m)}async function N0(f){let{config:_,payload:E,bodyText:D,fallback:m,signal:$}=f,C=E,M=await H0(_,C,$);if(M.status===409&&C.mode==="patch")b(`state mismatch from relay session=${B(C.affinity)}; retrying full_sync`),await M.body?.cancel().catch(()=>{}),C=ef(C,D),M=await H0(_,C,$);if(!M.ok&&M.status>=500&&_.fallbackToDirect)return b(`relay returned ${M.status}; falling back direct session=${B(C.affinity)}`),await M.body?.cancel().catch(()=>{}),{response:await m(),payload:C,transport:"http",protocol:C.protocol,usedRelay:!1};return{response:M,payload:C,transport:"http",protocol:C.protocol,usedRelay:!0}}function Em(f,_){let E=new URL(f);return E.protocol=E.protocol==="http:"?"ws:":"wss:",E.pathname="/ws",E.searchParams.set("token",_),E.toString()}function Dm(f){return new Uint8Array(F0.from(f,"base64"))}function mm(f){if(f instanceof Uint8Array)return f;if(f instanceof ArrayBuffer)return new Uint8Array(f);if(ArrayBuffer.isView(f))return new Uint8Array(f.buffer,f.byteOffset,f.byteLength);return new Uint8Array(F0.from(String(f)))}function $m(f){return JSON.parse(f)}function b0(f){let _=f,E=[`code=${_.code??"unknown"}`,`wasClean=${_.wasClean??"unknown"}`];if(_.reason)E.push(`reason=${JSON.stringify(_.reason)}`);return E.join(" ")}function Cm(f){let _=f.message||"relay websocket error";return f.status?`relay websocket error ${f.status}: ${_}`:_}class j0{config;affinity;socket;connecting;queue=Promise.resolve();pending;serverState;lastUsedAt=Date.now();constructor(f,_){this.config=f,this.affinity=_}touch(f=Date.now()){this.lastUsedAt=f}canEvict(f=Date.now()){return!this.pending&&!this.connecting&&f-this.lastUsedAt>nD}dispose(){this.socket?.close(),this.socket=void 0,this.serverState=void 0,this.connecting=void 0}send(f,_,E=!1){this.touch();let D=F(),m=this.queue.catch(()=>{}).then(()=>this.startQueued(f,_,D,E)),$=m.then(async({response:C,getPayload:M})=>({response:await C,payload:M(),transport:"websocket",protocol:2,usedRelay:!0}));return this.queue=m.then(({done:C})=>C.catch(()=>{}),()=>{}),$}async startQueued(f,_,E,D){let m=F();await this.ensureConnected();let $=F(),C=P.get(this.affinity),M=this.serverState?.hash,L={...f,protocol:2,id:tf()};if(L.mode==="patch"&&(!M||M!==L.base_hash))L.mode="full_sync",L.revision=(this.serverState?.revision??0)+1,delete L.base_hash,delete L.patch,L.body=_;if(L.mode==="patch"&&C)L.patch=B0(C.body,_);b(`perf websocket send_start session=${B(this.affinity)} request=${L.id} mode=${L.mode} queueMs=${Y($-E)} connectMs=${Y($-m)} bodyBytes=${_.length} relayBytes=${JSON.stringify(L).length}`);let A=L,U=this.sendPayload(L,_,D);U.done.catch(()=>{});let N=U.done,K=U.response.catch((R)=>{if(!(R instanceof of)||L.mode!=="patch")throw R;let J=ef(L,_);J.protocol=2,J.id=tf(),J.revision=(this.serverState?.revision??0)+1,A=J;let S=this.sendPayload(J,_,D);return S.done.catch(()=>{}),N=S.done,S.response}),j=K.then(()=>N,()=>N.catch(()=>{}));return{response:K,done:j,getPayload:()=>A}}async ensureConnected(){if(this.socket?.readyState===WebSocket.OPEN&&this.serverState!==void 0)return;if(this.connecting)return await this.connecting;this.connecting=new Promise((f,_)=>{let E=Em(this.config.url,this.config.token),D=new URL(E);D.searchParams.set("affinity",this.affinity);let m=new WebSocket(D.toString());this.socket=m,this.serverState=void 0;let $=setTimeout(()=>{m.close(),_(Error("relay websocket ready timed out"))},15000);m.addEventListener("message",(C)=>{try{if(typeof C.data!=="string"){this.handleBinaryChunk(C.data);return}let M=$m(C.data);if(M.type==="ready"){clearTimeout($),this.serverState=M.state,f();return}this.handleMessage(M)}catch(M){clearTimeout($),_(M),this.failPending(M),m.close()}}),m.addEventListener("error",()=>{clearTimeout($);let C=new af("relay websocket error");_(C),this.failPending(C)}),m.addEventListener("close",(C)=>{if(clearTimeout($),this.socket===m)this.socket=void 0,this.serverState=void 0,this.connecting=void 0;if(this.pending){if(this.pending.retryingBeforeResponse)return;let M=this.pending.responseStartedAt!=null,L=M?"closed after response_start before stream bytes":"closed before response";if(this.retryPendingBeforeResponse(this.pending,L,C))return;let A=M?new af("relay websocket closed during response stream",C):Error("relay websocket closed before response");b(`websocket ${M?"closed during response stream":"closed before response without retry"} session=${B(this.affinity)} request=${this.pending.payload.id} chunks=${this.pending.streamChunkCount} bytes=${this.pending.streamByteCount} ${b0(C)}`),this.failPending(A)}})}).finally(()=>{this.connecting=void 0}),await this.connecting}sendPayload(f,_,E){let D=this.socket;if(!D||D.readyState!==WebSocket.OPEN)throw Error("relay websocket is not connected");let m=F(),$,C,M=new Promise((A,U)=>{$=A,C=U});return{response:new Promise((A,U)=>{let N={payload:f,bodyText:_,resolve:A,reject:U,streamDone:!1,accepted:!1,responseStarted:!1,resolveDone:$,rejectDone:C,sentAt:m,optimisticResponse:E,streamChunkCount:0,streamByteCount:0,retryAttempts:0,retryingBeforeResponse:!1};if(this.pending=N,this.resetPendingTimeout(N),D.send(JSON.stringify(f)),E)this.resolvePendingResponse(N,200,"OK",{"content-type":"text/event-stream","x-cortexkit-relay-optimistic":"true"})}),done:M}}resetPendingTimeout(f){clearTimeout(f.timeout),f.timeout=setTimeout(()=>{if(this.pending!==f)return;if(this.retryPendingBeforeResponse(f,"response timed out"))return;this.failPending(Error("relay websocket response timed out")),this.socket?.close()},45000)}retryPendingBeforeResponse(f,_,E){if(f.responseStartedAt!=null&&f.streamByteCount>0)return!1;if(f.streamDone)return!1;if(f.retryAttempts>=1)return!1;f.retryAttempts+=1,f.retryingBeforeResponse=!0,clearTimeout(f.timeout);let D=f.retryAttempts,m=f.payload.id;return b(`websocket ${_}; reconnecting and retrying full_sync session=${B(this.affinity)} request=${m} retry=${D} chunks=${f.streamChunkCount} bytes=${f.streamByteCount}${E?` ${b0(E)}`:""}`),this.socket?.close(),this.socket=void 0,this.serverState=void 0,this.connecting=void 0,(async()=>{try{if(await this.ensureConnected(),this.pending!==f)return;let $=ef(f.payload,f.bodyText);$.protocol=2,$.id=tf(),$.revision=(this.serverState?.revision??0)+1,f.payload=$,f.accepted=!1,f.acceptedAt=void 0,f.responseStartedAt=void 0,f.sentAt=F(),f.retryingBeforeResponse=!1;let C=this.socket;if(!C||C.readyState!==WebSocket.OPEN)throw Error("relay websocket is not connected");this.resetPendingTimeout(f),b(`perf websocket retry_send session=${B(this.affinity)} request=${$.id} previous=${m} mode=full_sync retry=${D} bodyBytes=${f.bodyText.length} relayBytes=${JSON.stringify($).length}`),C.send(JSON.stringify($))}catch($){if(f.retryingBeforeResponse=!1,this.pending===f)this.failPending($)}})(),!0}enqueueStreamChunk(f,_){f.streamChunkCount+=1,f.streamByteCount+=_.byteLength,f.streamController?.enqueue(_)}handleBinaryChunk(f){let _=this.pending;if(!_?.responseStarted)return;this.enqueueStreamChunk(_,mm(f))}resolvePendingResponse(f,_,E,D){if(f.responseStarted)return;f.responseStarted=!0;let m=new ReadableStream({start:($)=>{f.streamController=$},cancel:()=>{this.socket?.close()}});f.resolve(new Response(m,{status:_,statusText:E,headers:D}))}handleMessage(f){if(f.type==="keepalive"){if(this.pending)this.resetPendingTimeout(this.pending);return}let _=this.pending;if(!_)return;if("id"in f&&f.id&&f.id!==_.payload.id)return;if(f.type==="accepted"){let E=F();_.accepted=!0,_.acceptedAt=E,b(`perf websocket accepted session=${B(this.affinity)} request=${_.payload.id} sentMs=${Y(E-_.sentAt)} mode=${_.payload.mode}`),this.serverState={hash:f.hash,revision:f.revision},K0(this.affinity,_.bodyText,f.hash,f.revision),this.resetPendingTimeout(_);return}if(f.type==="response_start"){let E=F();if(_.responseStartedAt=E,b(`perf websocket response_start session=${B(this.affinity)} request=${_.payload.id} sentMs=${Y(E-_.sentAt)} upstreamMs=${_.acceptedAt==null?"unknown":Y(E-_.acceptedAt)} status=${f.status}`),clearTimeout(_.timeout),this.resolvePendingResponse(_,f.status,f.statusText,f.headers),_.optimisticResponse&&f.status>=400)_.streamController?.enqueue(new TextEncoder().encode(`event: error
|
|
40
|
+
data: ${JSON.stringify({type:"error",error:{type:"relay_upstream_error",message:`Relay upstream returned HTTP ${f.status}`}})}
|
|
41
|
+
|
|
42
|
+
`)),this.finishPending();return}if(f.type==="chunk"){this.enqueueStreamChunk(_,Dm(f.base64));return}if(f.type==="done"){this.finishPending();return}if(f.type==="error"){if(_.optimisticResponse&&_.responseStartedAt!=null){b(`websocket relay error during optimistic response session=${B(this.affinity)} request=${_.payload.id} status=${f.status} message=${f.message||"unknown"} chunks=${_.streamChunkCount} bytes=${_.streamByteCount}`),_.streamController?.enqueue(new TextEncoder().encode(`event: error
|
|
43
|
+
data: ${JSON.stringify({type:"error",error:{type:"relay_error",message:f.message||"relay error"}})}
|
|
44
|
+
|
|
45
|
+
`)),this.finishPending(),this.socket?.close();return}if(f.status===409&&this.retryPendingBeforeResponse(_,f.message||"state mismatch"))return;let E=f.status===409?new of(f.message||"state mismatch"):Error(Cm(f));this.failPending(E)}}finishPending(){let f=this.pending;if(!f)return;let _=F();if(b(`perf websocket done session=${B(this.affinity)} request=${f.payload.id} sentMs=${Y(_-f.sentAt)} streamMs=${f.responseStartedAt==null?"unknown":Y(_-f.responseStartedAt)} chunks=${f.streamChunkCount} bytes=${f.streamByteCount}`),clearTimeout(f.timeout),!f.streamDone)f.streamDone=!0,f.streamController?.close();f.resolveDone(),this.pending=void 0}failPending(f){let _=this.pending;if(!_)return;if(clearTimeout(_.timeout),this.pending=void 0,_.responseStarted)_.streamController?.error(f);else _.reject(f);_.rejectDone(f)}}function f_(f=Date.now()){for(let[_,E]of P)if(f-E.updatedAt>gD)P.delete(_);while(P.size>rD){let _=P.keys().next().value;if(_===void 0)break;P.delete(_)}for(let[_,E]of p)if(E.canEvict(f))E.dispose(),p.delete(_);while(p.size>sD){let _=!1;for(let[E,D]of p){if(!D.canEvict(f))continue;D.dispose(),p.delete(E),_=!0;break}if(!_)break}}function Mm(f,_){f_();let E=p.get(_);if(E)return E.touch(),E;let D=new j0(f,_);return p.set(_,D),f_(),D}async function M$(f){let{config:_,input:E,init:D,headers:m,body:$,fallback:C,affinity:M,optimisticResponse:L}=f;if(!_||!aD(E,$))return C();let A=M||m.get("x-session-affinity")||m.get("x-opencode-session");if(!A)return b("skipping relay: missing x-session-affinity header"),C();let U=$,N=F(),K=cD(U);s("hash_body",{session:B(A),ms:Y(F()-N),bodyBytes:U.length});let j=P.get(A),R=F(),J=_m({input:E,init:D,headers:m,bodyText:U,affinity:A,previous:j,nextHash:K});s("create_payload",{session:B(A),ms:Y(F()-R),mode:J.mode,bodyBytes:U.length,previousBytes:j?.body.length});try{let S,v=F();if(_.transport==="websocket")try{S=await Mm(_,A).send(J,U,L===!0)}catch(O){b(`websocket relay failed session=${B(A)}; trying http relay: ${O instanceof Error?O.message:String(O)}`),S=await N0({config:_,payload:J,bodyText:U,fallback:C,signal:D?.signal})}else S=await N0({config:_,payload:J,bodyText:U,fallback:C,signal:D?.signal});if(s("send",{session:B(A),ms:Y(F()-v),transport:S.transport,protocol:S.protocol,mode:S.payload.mode,status:S.response.status,usedRelay:S.usedRelay}),!S.usedRelay)return S.response;if(S.transport==="http")K0(A,U,S.payload.next_hash,S.payload.revision);let d=F(),u=JSON.stringify(S.payload).length;s("payload_stringify",{session:B(A),ms:Y(F()-d),relayBytes:u}),b(`used relay transport=${S.transport} protocol=${S.protocol} mode=${S.payload.mode} status=${S.response.status} session=${B(A)} bodyBytes=${U.length} relayBytes=${u}`);let mf=F();return await m0({affinity:A,transport:S.transport,protocol:S.protocol,mode:S.payload.mode,status:S.response.status,bodyText:U,previousBodyText:j?.body,payload:S.payload,relayBytes:u}),s("dump",{session:B(A),ms:Y(F()-mf),enabled:!0}),S.response}catch(S){if(!_.fallbackToDirect)throw b(`relay failed session=${B(A)} and fallbackToDirect=false: ${S instanceof Error?S.message:String(S)}`),S;return b(`relay failed; falling back direct session=${B(A)}: ${S instanceof Error?S.message:String(S)}`),C()}}var L$=`
|
|
46
|
+
async function hashBody(body) {
|
|
47
|
+
const bytes = new TextEncoder().encode(body)
|
|
48
|
+
const digest = await crypto.subtle.digest('SHA-256', bytes)
|
|
49
|
+
const hex = [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, '0')).join('')
|
|
50
|
+
return 'sha256:' + hex
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function applyPatch(base, patch) {
|
|
54
|
+
return base.slice(0, patch.start) + patch.insert + base.slice(patch.start + patch.deleteCount)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function applyPatchSet(base, patch) {
|
|
58
|
+
if (!Array.isArray(patch)) return applyPatch(base, patch)
|
|
59
|
+
if (patch.length === 0) return base
|
|
60
|
+
|
|
61
|
+
let result = ''
|
|
62
|
+
let cursor = 0
|
|
63
|
+
for (const item of patch) {
|
|
64
|
+
if (item.start < cursor) return { error: 'overlapping patch', status: 400 }
|
|
65
|
+
result += base.slice(cursor, item.start)
|
|
66
|
+
result += item.insert
|
|
67
|
+
cursor = item.start + item.deleteCount
|
|
68
|
+
}
|
|
69
|
+
return result + base.slice(cursor)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function readState(env, affinity) {
|
|
73
|
+
const raw = await env.RELAY_STATE.get('session:' + affinity)
|
|
74
|
+
return raw ? JSON.parse(raw) : null
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async function writeState(env, affinity, state) {
|
|
78
|
+
await env.RELAY_STATE.put('session:' + affinity, JSON.stringify(state), { expirationTtl: 86400 })
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function resolveBody(env, payload) {
|
|
82
|
+
if (payload.mode === 'full_sync') return payload.body
|
|
83
|
+
if (payload.mode === 'patch') {
|
|
84
|
+
const state = await readState(env, payload.affinity)
|
|
85
|
+
if (!state || state.hash !== payload.base_hash) {
|
|
86
|
+
return { error: 'state mismatch', status: 409 }
|
|
87
|
+
}
|
|
88
|
+
return applyPatchSet(state.body, payload.patch)
|
|
89
|
+
}
|
|
90
|
+
return { error: 'unknown mode', status: 400 }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function prepareUpstream(env, payload) {
|
|
94
|
+
if ((payload.protocol !== 1 && payload.protocol !== 2) || payload.type !== 'request' || !payload.affinity || !payload.upstream?.url || !payload.next_hash) {
|
|
95
|
+
return { error: 'invalid payload', status: 400 }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const body = await resolveBody(env, payload)
|
|
99
|
+
if (body && typeof body === 'object' && 'error' in body) return body
|
|
100
|
+
|
|
101
|
+
if (typeof body !== 'string' || (await hashBody(body)) !== payload.next_hash) {
|
|
102
|
+
return { error: 'hash mismatch', status: 409 }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const stateWrite = writeState(env, payload.affinity, { body, hash: payload.next_hash, revision: payload.revision }).catch(() => {})
|
|
106
|
+
console.log(JSON.stringify({
|
|
107
|
+
relay: 'opencode-anthropic-auth',
|
|
108
|
+
transport: 'relay',
|
|
109
|
+
mode: payload.mode,
|
|
110
|
+
revision: payload.revision,
|
|
111
|
+
affinity: String(payload.affinity).slice(0, 12),
|
|
112
|
+
bodyBytes: body.length,
|
|
113
|
+
}))
|
|
114
|
+
|
|
115
|
+
return { body, stateWrite }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function resolveBodyFromState(state, payload) {
|
|
119
|
+
if (payload.mode === 'full_sync') return payload.body
|
|
120
|
+
if (payload.mode === 'patch') {
|
|
121
|
+
if (!state || state.hash !== payload.base_hash) {
|
|
122
|
+
return { error: 'state mismatch', status: 409 }
|
|
123
|
+
}
|
|
124
|
+
return applyPatchSet(state.body, payload.patch)
|
|
125
|
+
}
|
|
126
|
+
return { error: 'unknown mode', status: 400 }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function deferWorkerTask(task) {
|
|
130
|
+
return new Promise((resolve) => setTimeout(resolve, 0)).then(task)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function checkpointWebSocketState(env, payload, body, nextState) {
|
|
134
|
+
return deferWorkerTask(async () => {
|
|
135
|
+
try {
|
|
136
|
+
if ((await hashBody(body)) !== payload.next_hash) {
|
|
137
|
+
throw new Error('hash mismatch')
|
|
138
|
+
}
|
|
139
|
+
await writeState(env, payload.affinity, nextState)
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.log(JSON.stringify({
|
|
142
|
+
relay: 'opencode-anthropic-auth',
|
|
143
|
+
transport: 'websocket',
|
|
144
|
+
event: 'checkpoint_write_failed',
|
|
145
|
+
affinity: String(payload.affinity).slice(0, 12),
|
|
146
|
+
message: error instanceof Error ? error.message : String(error),
|
|
147
|
+
}))
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function prepareWebSocketUpstream(env, state, payload) {
|
|
153
|
+
if (payload.protocol !== 2 || payload.type !== 'request' || !payload.id || !payload.affinity || !payload.upstream?.url || !payload.next_hash) {
|
|
154
|
+
return { error: 'invalid payload', status: 400 }
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const body = resolveBodyFromState(state, payload)
|
|
158
|
+
if (body && typeof body === 'object' && 'error' in body) return body
|
|
159
|
+
if (typeof body !== 'string') return { error: 'invalid body', status: 400 }
|
|
160
|
+
if ((await hashBody(body)) !== payload.next_hash) {
|
|
161
|
+
return { error: 'hash mismatch', status: 409 }
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const nextState = { body, hash: payload.next_hash, revision: payload.revision }
|
|
165
|
+
const checkpoint = checkpointWebSocketState(env, payload, body, nextState)
|
|
166
|
+
const logAccepted = () => console.log(JSON.stringify({
|
|
167
|
+
relay: 'opencode-anthropic-auth',
|
|
168
|
+
transport: 'websocket',
|
|
169
|
+
mode: payload.mode,
|
|
170
|
+
revision: payload.revision,
|
|
171
|
+
affinity: String(payload.affinity).slice(0, 12),
|
|
172
|
+
bodyBytes: body.length,
|
|
173
|
+
}))
|
|
174
|
+
|
|
175
|
+
return { body, state: nextState, checkpoint, logAccepted }
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function headersToObject(headers) {
|
|
179
|
+
const result = {}
|
|
180
|
+
for (const [key, value] of headers.entries()) result[key] = value
|
|
181
|
+
return result
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function handleRelayPayload(env, payload) {
|
|
185
|
+
const prepared = await prepareUpstream(env, payload)
|
|
186
|
+
if (prepared.error) return prepared
|
|
187
|
+
const upstream = await fetch(payload.upstream.url, {
|
|
188
|
+
method: payload.upstream.method || 'POST',
|
|
189
|
+
headers: payload.upstream.headers,
|
|
190
|
+
body: prepared.body,
|
|
191
|
+
})
|
|
192
|
+
return { upstream, stateWrite: prepared.stateWrite }
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function handleWebSocket(socket, env, ctx, payload, getState, setState) {
|
|
196
|
+
const heartbeat = setInterval(() => {
|
|
197
|
+
try {
|
|
198
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'keepalive' }))
|
|
199
|
+
} catch {
|
|
200
|
+
clearInterval(heartbeat)
|
|
201
|
+
}
|
|
202
|
+
}, 15000)
|
|
203
|
+
try {
|
|
204
|
+
const result = await prepareWebSocketUpstream(env, getState(), payload)
|
|
205
|
+
if (result.error) {
|
|
206
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'error', id: payload.id, status: result.status, message: result.error }))
|
|
207
|
+
return
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
setState(result.state)
|
|
211
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'accepted', id: payload.id, hash: result.state.hash, revision: result.state.revision }))
|
|
212
|
+
ctx?.waitUntil?.(deferWorkerTask(result.logAccepted))
|
|
213
|
+
|
|
214
|
+
const upstreamPromise = fetch(payload.upstream.url, {
|
|
215
|
+
method: payload.upstream.method || 'POST',
|
|
216
|
+
headers: payload.upstream.headers,
|
|
217
|
+
body: result.body,
|
|
218
|
+
})
|
|
219
|
+
ctx?.waitUntil?.(result.checkpoint)
|
|
220
|
+
const upstream = await upstreamPromise
|
|
221
|
+
socket.send(JSON.stringify({
|
|
222
|
+
protocol: 2,
|
|
223
|
+
type: 'response_start',
|
|
224
|
+
id: payload.id,
|
|
225
|
+
status: upstream.status,
|
|
226
|
+
statusText: upstream.statusText,
|
|
227
|
+
headers: headersToObject(upstream.headers),
|
|
228
|
+
}))
|
|
229
|
+
|
|
230
|
+
const reader = upstream.body?.getReader()
|
|
231
|
+
if (reader) {
|
|
232
|
+
while (true) {
|
|
233
|
+
const { done, value } = await reader.read()
|
|
234
|
+
if (done) break
|
|
235
|
+
socket.send(value)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'done', id: payload.id }))
|
|
239
|
+
} catch (error) {
|
|
240
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'error', id: payload.id, status: 500, message: error instanceof Error ? error.message : String(error) }))
|
|
241
|
+
} finally {
|
|
242
|
+
clearInterval(heartbeat)
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export default {
|
|
247
|
+
async fetch(request, env, ctx) {
|
|
248
|
+
if (request.headers.get('Upgrade') === 'websocket') {
|
|
249
|
+
const url = new URL(request.url)
|
|
250
|
+
const token = url.searchParams.get('token')
|
|
251
|
+
const affinity = url.searchParams.get('affinity')
|
|
252
|
+
if (token !== env.RELAY_TOKEN) return new Response('unauthorized', { status: 401 })
|
|
253
|
+
if (!affinity) return new Response('missing affinity', { status: 400 })
|
|
254
|
+
const pair = new WebSocketPair()
|
|
255
|
+
const client = pair[0]
|
|
256
|
+
const server = pair[1]
|
|
257
|
+
server.binaryType = 'arraybuffer'
|
|
258
|
+
let state = null
|
|
259
|
+
let ready = false
|
|
260
|
+
server.accept()
|
|
261
|
+
const loadState = readState(env, affinity).then((loadedState) => {
|
|
262
|
+
state = loadedState
|
|
263
|
+
ready = true
|
|
264
|
+
server.send(JSON.stringify({
|
|
265
|
+
protocol: 2,
|
|
266
|
+
type: 'ready',
|
|
267
|
+
state: state ? { hash: state.hash, revision: state.revision } : null,
|
|
268
|
+
}))
|
|
269
|
+
}).catch((error) => {
|
|
270
|
+
server.send(JSON.stringify({ protocol: 2, type: 'error', status: 500, message: error instanceof Error ? error.message : String(error) }))
|
|
271
|
+
server.close(1011, 'state load failed')
|
|
272
|
+
})
|
|
273
|
+
ctx?.waitUntil?.(loadState)
|
|
274
|
+
if (!ctx?.waitUntil) void loadState
|
|
275
|
+
let busy = false
|
|
276
|
+
server.addEventListener('message', (event) => {
|
|
277
|
+
if (!ready) {
|
|
278
|
+
server.send(JSON.stringify({ protocol: 2, type: 'error', status: 425, message: 'relay state is not ready' }))
|
|
279
|
+
return
|
|
280
|
+
}
|
|
281
|
+
if (busy) {
|
|
282
|
+
server.send(JSON.stringify({ protocol: 2, type: 'error', status: 429, message: 'request already in flight' }))
|
|
283
|
+
return
|
|
284
|
+
}
|
|
285
|
+
let payload
|
|
286
|
+
try {
|
|
287
|
+
payload = JSON.parse(event.data)
|
|
288
|
+
} catch {
|
|
289
|
+
server.send(JSON.stringify({ protocol: 2, type: 'error', status: 400, message: 'invalid JSON payload' }))
|
|
290
|
+
return
|
|
291
|
+
}
|
|
292
|
+
payload.affinity = affinity
|
|
293
|
+
busy = true
|
|
294
|
+
const run = handleWebSocket(server, env, ctx, payload, () => state, (nextState) => { state = nextState }).finally(() => { busy = false })
|
|
295
|
+
ctx?.waitUntil?.(run)
|
|
296
|
+
if (!ctx?.waitUntil) void run
|
|
297
|
+
})
|
|
298
|
+
return new Response(null, { status: 101, webSocket: client })
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (request.method === 'GET') {
|
|
302
|
+
return Response.json({ status: 'ok', transports: ['http', 'websocket'] })
|
|
303
|
+
}
|
|
304
|
+
if (request.method !== 'POST') return new Response('method not allowed', { status: 405 })
|
|
305
|
+
if (request.headers.get('x-relay-token') !== env.RELAY_TOKEN) {
|
|
306
|
+
return new Response('unauthorized', { status: 401 })
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
const payload = await request.json()
|
|
311
|
+
const result = await handleRelayPayload(env, payload)
|
|
312
|
+
if (result.error) return Response.json({ error: result.error }, { status: result.status })
|
|
313
|
+
|
|
314
|
+
if (result.stateWrite) ctx.waitUntil(result.stateWrite)
|
|
315
|
+
|
|
316
|
+
const upstream = result.upstream
|
|
317
|
+
return new Response(upstream.body, {
|
|
318
|
+
status: upstream.status,
|
|
319
|
+
statusText: upstream.statusText,
|
|
320
|
+
headers: upstream.headers,
|
|
321
|
+
})
|
|
322
|
+
} catch (error) {
|
|
323
|
+
return Response.json(
|
|
324
|
+
{ error: error instanceof Error ? error.message : 'internal relay error' },
|
|
325
|
+
{ status: 502 },
|
|
326
|
+
)
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
}
|
|
330
|
+
`;var O$="claude-routing",E_=["main-first","fallback-first"],D_="main-first",G0="Usage: `/claude-routing`, `/claude-routing main-first`, or `/claude-routing fallback-first`.";function Lm(f){return typeof f==="string"&&E_.includes(f)?f:D_}function S$(f){return Lm(f?.routing?.mode)}async function H$(f,_=z()){let E=await h(_)??{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]};return E.routing={...E.routing??{},mode:f},await Q(E,_),E}function Am(f){let _=f.trim().toLowerCase().split(/\s+/).filter(Boolean);if(_.length===0)return{type:"status"};if(_.length===1&&E_.includes(_[0]))return{type:"mode",mode:_[0]};if(_.length===2&&_[0]==="mode"&&E_.includes(_[1]))return{type:"mode",mode:_[1]};return{type:"usage"}}function Um(f){if(f==="fallback-first")return"Try usable fallback accounts before the main account. If no fallback succeeds, try the main account.";return"Try the main account first. Use fallback accounts only when quota policy or fallback errors require it."}function __(f){let _=f?.mode??D_;return["## Claude Routing Status","",`- Mode: \`${_}\``,`- Behavior: ${Um(_)}`,"",G0].join(`
|
|
331
|
+
`)}function N$(f){let _=Am(f.argumentsText),E=f.mode??D_;if(_.type==="status")return __({mode:E});if(_.type==="mode")return["## Claude Routing Updated","",`Mode updated to \`${_.mode}\`.`,"",...__({mode:_.mode}).split(`
|
|
332
|
+
`).slice(2)].join(`
|
|
333
|
+
`);return["## Claude Routing Usage","",G0,"",...__({mode:E}).split(`
|
|
334
|
+
`).slice(2)].join(`
|
|
335
|
+
`)}export{Om as a,C_ as b,Sm as c,Hm as d,Nm as e,bm as f,Fm as g,M_ as h,Bm as i,Km as j,i as k,N_ as l,Ym as m,Wm as n,V as o,x as p,qm as q,v0 as r,z as s,h as t,Q as u,FE as v,Lf as w,Tm as x,KE as y,wm as z,im as A,lm as B,ym as C,km as D,pm as E,vm as F,dm as G,um as H,R_ as I,WE as J,o as K,hf as L,gm as M,w_ as N,XE as O,nm as P,rm as Q,sm as R,cm as S,IE as T,am as U,em as V,f1 as W,_1 as X,wE as Y,E1 as Z,s_ as _,N1 as $,C1 as aa,M1 as ba,L1 as ca,u_ as da,K1 as ea,j1 as fa,ND as ga,uf as ha,a_ as ia,bD as ja,G1 as ka,BD as la,V1 as ma,x1 as na,VD as oa,Q1 as pa,P1 as qa,R1 as ra,q1 as sa,qD as ta,T1 as ua,Df as va,l1 as wa,k1 as xa,p1 as ya,v1 as za,d1 as Aa,u1 as Ba,g1 as Ca,w as Da,o1 as Ea,a1 as Fa,e1 as Ga,$$ as Ha,C$ as Ia,M$ as Ja,L$ as Ka,O$ as La,S$ as Ma,H$ as Na,Am as Oa,N$ as Pa};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{mkdir as O,readFile as Q,writeFile as W}from"node:fs/promises";import{tmpdir as X}from"node:os";import{dirname as Y,join as K}from"node:path";var Z="OPENCODE_ANTHROPIC_AUTH_SIDEBAR_STATE_FILE",$=K(X(),"opencode-anthropic-auth"),x=K($,"sidebar-state.json");function M(){return process.env[Z]||x}var B={main:{quota:null},fallbacks:[],activeId:void 0,route:"main",relay:null,fastMode:!1,lastUpdated:0};async function h(){try{let G=await Q(M(),"utf8");return JSON.parse(G)}catch{return B}}async function j(G){try{let z=M();await O(Y(z),{recursive:!0}),await W(z,JSON.stringify(G),"utf8")}catch{}}function w(G){let z=G.activeId;if(z&&z!=="main"){let C=G.fallbacks.find((J)=>J.enabled&&J.id===z);if(C)return{id:C.id,name:C.label??C.id,quota:C.quota}}return{id:"main",name:"main",quota:G.main.quota}}function R(G){let z=G?.five_hour?.usedPercent??null,C=G?.seven_day?.usedPercent??null;if(z==null&&C==null)return{fiveHourUsedPercent:z,sevenDayUsedPercent:C,text:null};return{fiveHourUsedPercent:z,sevenDayUsedPercent:C,text:`5h: ${z==null?"—":`${Math.round(z)}%`} 7d: ${C==null?"—":`${Math.round(C)}%`}`}}
|
|
2
|
+
export{M as Qa,B as Ra,h as Sa,j as Ta,w as Ua,R as Va};
|