@cortexkit/opencode-anthropic-auth 1.15.1 → 1.17.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 +14 -6
- package/dist/cli.js +6 -6
- package/dist/fable-fallback.d.ts +2 -0
- package/dist/{index-qejbx8c9.js → index-63keqwnf.js} +1 -1
- package/dist/{index-jkbar3k3.js → index-am5pq04s.js} +1 -1
- package/dist/{index-qsaph2g4.js → index-f5r96vyv.js} +1 -1
- package/dist/index-gj7emmj5.js +2 -0
- package/dist/index-xvfesm3w.js +422 -0
- package/dist/{index-6gdd6e4s.js → index-y2n9h7p6.js} +1 -1
- package/dist/index.js +12 -12
- package/dist/{logger-vxnb5hjr.js → logger-ywfmddsw.js} +1 -1
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/sidebar-state.d.ts +52 -2
- package/dist/sidebar-state.js +1 -1
- package/dist/tui/command-dialogs.d.ts +12 -0
- package/dist/tui-preferences.js +1 -1
- package/dist/tui.d.ts +2 -0
- package/package.json +2 -2
- package/src/sidebar-state.ts +381 -4
- package/src/tui/command-dialogs.tsx +35 -13
- package/src/tui-compiled/sidebar-state.ts +381 -4
- package/src/tui-compiled/tui/command-dialogs.tsx +22 -10
- package/src/tui-compiled/tui.tsx +147 -104
- package/src/tui.tsx +34 -2
- package/dist/index-bxs26mw4.js +0 -2
- package/dist/index-z03wayzs.js +0 -417
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import{ec as e1,ic as P,jc as c,kc as f}from"./index-y2n9h7p6.js";import{rc as l_}from"./index-f5r96vyv.js";var Q0="9d1c250a-e61b-44d9-88ed-5944d1962f5e",l$={console:"https://platform.claude.com/oauth/authorize",max:"https://claude.com/cai/oauth/authorize"},$$="https://platform.claude.com/oauth/code/callback",_$="https://platform.claude.com/v1/oauth/token",C$="axios/1.15.2",p$=["org:create_api_key","user:profile","user:inference","user:sessions:claude_code","user:mcp_servers","user:file_upload"],g$="user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload",yG="mcp_";var d$="fast-mode-2026-02-01";function mG($,_){let C=($??"").split(",").map((K)=>K.trim()).filter(Boolean);return[...new Set([...C,..._])].join(",")}function vG($){return typeof $==="string"&&($.startsWith("claude-opus-4-6")||$.startsWith("claude-opus-4-7")||$.startsWith("claude-opus-4-8"))}var lG="You are OpenCode",pG="You are Claude Code, Anthropic's official CLI for Claude.",gG=["<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 p="2.1.177",K$="3bf",u$="cli",i$="0.94.0",c$="v24.3.0",r$="claude-cli/2.1.177 (external, cli)",s$=["explicit","automatic","hybrid"],B0="explicit",dG=["github.com/anomalyco/opencode","opencode.ai/docs"],uG=[{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 n$($){let _="";for(let C of $)_+=String.fromCharCode(C);return btoa(_).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function o$(){let $=new Uint8Array(64);crypto.getRandomValues($);let _=n$($),C=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(_));return{verifier:_,challenge:n$(new Uint8Array(C)),method:"S256"}}function j$($){if(!$)return;let _=Number($);if(Number.isFinite(_)&&_>0)return Math.ceil(_);let C=Date.parse($);if(Number.isFinite(C)){let K=Math.ceil((C-Date.now())/1000);return K>0?K:void 0}return}class G$ extends Error{status;body;retryAfter;isRefreshError=!0;constructor($,_,C){super(`Claude OAuth refresh failed: ${$} — ${_}`);this.status=$,this.body=_,this.name="ClaudeOAuthRefreshError",this.retryAfter=j$(C??void 0)}}function x_($){if(!($ instanceof Error))return!1;let _=$.code;return $.message.includes("fetch failed")||_==="ECONNRESET"||_==="ECONNREFUSED"||_==="ETIMEDOUT"||_==="UND_ERR_CONNECT_TIMEOUT"}async function a$($){let _=$.fetchImpl??fetch,C=$.maxRetries??2,K=$.baseDelayMs??500;for(let G=0;G<=C;G++)try{if(G>0){let z=K*2**(G-1);await new Promise((O)=>setTimeout(O,z))}let j=await _(_$,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json, text/plain, */*","User-Agent":C$},body:JSON.stringify({grant_type:"refresh_token",refresh_token:$.refreshToken,client_id:Q0,scope:g$})});if(!j.ok){if(j.status>=500&&G<C){await j.body?.cancel().catch(()=>{});continue}let z=await j.text().catch(()=>"");throw new G$(j.status,z,j.headers.get("retry-after"))}let J=await j.json(),Z=$.now?.()??Date.now();return{access:J.access_token,refresh:J.refresh_token??$.refreshToken,expires:Z+J.expires_in*1000,expiresIn:J.expires_in}}catch(j){if(j instanceof G$)throw j;if(G<C&&x_(j))continue;throw j}throw Error("Token refresh exhausted all retries")}function k_(){return crypto.randomUUID().replace(/-/g,"")}function y_($){let _=$.trim();try{let J=new URL(_),Z=J.searchParams.get("code"),z=J.searchParams.get("state");if(Z&&z)return{code:Z,state:z}}catch{}let C=_.split("#");if(C.length===2&&C[0]&&C[1])return{code:C[0],state:C[1]};let K=new URLSearchParams(_),G=K.get("code"),j=K.get("state");if(G&&j)return{code:G,state:j};return null}async function m_($,_,C){let K=await fetch(_$,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json, text/plain, */*","User-Agent":C$},body:JSON.stringify({code:$.code,state:$.state,grant_type:"authorization_code",client_id:Q0,redirect_uri:C,code_verifier:_})});if(!K.ok)return{type:"failed"};let G=await K.json();return{type:"success",refresh:G.refresh_token,access:G.access_token,expires:Date.now()+G.expires_in*1000}}async function nG($){let _=await o$(),C=k_(),K=new URL(l$[$],import.meta.url);return K.searchParams.set("code","true"),K.searchParams.set("client_id",Q0),K.searchParams.set("response_type","code"),K.searchParams.set("redirect_uri",$$),K.searchParams.set("scope",p$.join(" ")),K.searchParams.set("code_challenge",_.challenge),K.searchParams.set("code_challenge_method","S256"),K.searchParams.set("state",C),{url:K.toString(),redirectUri:$$,state:C,verifier:_.verifier}}async function oG($,_,C,K){let G=y_($);if(!G)return{type:"failed"};if(K&&G.state!==K)return{type:"failed"};return m_(G,_,C)}import{createHash as v_}from"node:crypto";function D($){return v_("sha256").update($).digest("hex").slice(0,16)}import{createHash as X1,randomUUID as Y0}from"node:crypto";import{mkdir as O$,readFile as D0,rename as Y1,rm as e,stat as t$,writeFile as S0}from"node:fs/promises";import{homedir as p_}from"node:os";import{dirname as X$,join as $0}from"node:path";var g_=globalThis.setTimeout.bind(globalThis),d_=globalThis.clearTimeout.bind(globalThis),N1="anthropic-auth.json",u_="anthropic-auth-state.json",i_="https://api.anthropic.com/api/oauth/usage";function k($){return $.type==="oauth"}function z2($){return $.type==="api"}function c_($){let _=$?.trim();if(!_)return!1;try{let C=new URL(_);return(C.protocol==="http:"||C.protocol==="https:")&&!C.username&&!C.password}catch{return!1}}function O2($){return $.costZeroing?.enabled!==!1}var r_=[401,403,429],L1=240,s_=L1;var n_=300000,o_=3600000,U1=86400000,a_=60000,t_=900000,e_=300000,$C=5,e$={five_hour:0,seven_day:0},_C=!0,CC=60000,KC=60000,GC=600000,jC=1e4,JC=100;function ZC(){if(process.env.OPENCODE_CONFIG_DIR?.trim())return process.env.OPENCODE_CONFIG_DIR.trim();return $0(process.env.XDG_CONFIG_HOME||$0(p_(),".config"),"opencode")}function V(){return process.env.OPENCODE_ANTHROPIC_AUTH_FILE?.trim()||$0(ZC(),N1)}function Y$($=V()){let _=process.env.OPENCODE_ANTHROPIC_AUTH_STATE_FILE?.trim();if(_)return _;return $.endsWith(N1)?$0(X$($),u_):`${$}.state.json`}function F($){return $!=null&&typeof $==="object"&&!Array.isArray($)}function $1($){return{id:typeof $.id==="string"&&$.id.trim()?$.id.trim():Y0(),label:typeof $.label==="string"?$.label:void 0,enabled:typeof $.enabled==="boolean"?$.enabled:void 0,addedAt:typeof $.addedAt==="number"?$.addedAt:void 0,lastUsed:typeof $.lastUsed==="number"?$.lastUsed:void 0}}function zC($){if(!F($))return null;if($.type==="api"){let _=typeof $.baseURL==="string"?$.baseURL.trim():"",C=typeof $.apiKey==="string"?$.apiKey.trim():"";if(!c_(_))return null;let K=$.authHeader==="x-api-key"?"x-api-key":"authorization-bearer";return{...$1($),type:"api",apiKey:C||void 0,baseURL:_,authHeader:K}}if($.type!=="oauth")return null;if(typeof $.refresh!=="string"||!$.refresh.trim())return null;return{...$1($),type:"oauth",access:typeof $.access==="string"?$.access:void 0,refresh:$.refresh,expires:typeof $.expires==="number"?$.expires:void 0,lastRefreshedAt:typeof $.lastRefreshedAt==="number"?$.lastRefreshedAt:void 0,lastRefreshError:_1($.lastRefreshError),lastQuotaRefreshError:_1($.lastQuotaRefreshError),quota:OC($.quota),profile:N0($.profile)}}function N0($){if(!F($))return;if(typeof $.tier!=="string"||!$.tier.trim()||typeof $.orgType!=="string"||!$.orgType.trim()||typeof $.checkedAt!=="number"||!Number.isFinite($.checkedAt))return;return{tier:$.tier.trim(),orgType:$.orgType.trim(),checkedAt:$.checkedAt,...typeof $.tokenFingerprint==="string"&&$.tokenFingerprint.trim()&&{tokenFingerprint:$.tokenFingerprint.trim()}}}function _1($){if(!F($))return;if(typeof $.message!=="string")return;let _=Number($.checkedAt);if(!Number.isFinite(_))return;let C=Number($.nextRetryAt),K=Number($.retryCount),G=Number($.status);return{message:$.message,checkedAt:_,nextRetryAt:Number.isFinite(C)?C:void 0,retryCount:Number.isFinite(K)?K:void 0,tokenHash:typeof $.tokenHash==="string"?$.tokenHash:void 0,status:Number.isFinite(G)?G:void 0,permanent:typeof $.permanent==="boolean"?$.permanent:void 0}}function C1($){if(!F($))return;let _=Number($.usedPercent),C=Number($.remainingPercent),K=Number($.checkedAt);if(!Number.isFinite(_)||!Number.isFinite(C)||!Number.isFinite(K))return;return{usedPercent:_,remainingPercent:C,checkedAt:K,resetsAt:typeof $.resetsAt==="string"?$.resetsAt:void 0}}function OC($){if(!F($))return;let _={};for(let C of["five_hour","seven_day"]){let K=C1($[C]);if(K)_[C]=K}if(typeof $.checkedAt==="number"&&Number.isFinite($.checkedAt))_.checkedAt=$.checkedAt;if(Array.isArray($.scoped)){let C=$.scoped.map((K)=>{if(!F(K))return;let G=C1(K);if(!G)return;if(typeof K.id!=="string"||!K.id.trim())return;if(typeof K.title!=="string"||!K.title.trim())return;if(typeof K.modelName!=="string"||!K.modelName.trim())return;let j=typeof K.modelId==="string"&&K.modelId.trim()?K.modelId.trim():void 0;return{...G,id:K.id.trim(),title:K.title.trim(),...j&&{modelId:j},modelName:K.modelName.trim()}}).filter((K)=>K!=null);_.scoped=C}if(F($.extraUsage)){let C=K1($.extraUsage.used),K=K1($.extraUsage.limit);if(C&&K&&typeof $.extraUsage.exhausted==="boolean")_.extraUsage={used:C,limit:K,...typeof $.extraUsage.utilizationPercent==="number"&&Number.isFinite($.extraUsage.utilizationPercent)&&{utilizationPercent:$.extraUsage.utilizationPercent},...typeof $.extraUsage.severity==="string"&&{severity:$.extraUsage.severity},exhausted:$.extraUsage.exhausted}}if(typeof $.bindingWindow==="string"&&$.bindingWindow.trim())_.bindingWindow=$.bindingWindow.trim();if($.bindingWindowSource==="poll"||$.bindingWindowSource==="headers")_.bindingWindowSource=$.bindingWindowSource;if(typeof $.fallbackAdvised==="boolean")_.fallbackAdvised=$.fallbackAdvised;if($.source==="poll"||$.source==="headers")_.source=$.source;return Object.keys(_).length?_:void 0}function K1($){if(!F($))return;if(typeof $.amountMinor!=="number"||!Number.isFinite($.amountMinor)||typeof $.currency!=="string"||!$.currency.trim()||typeof $.exponent!=="number"||!Number.isFinite($.exponent))return;return{amountMinor:$.amountMinor,currency:$.currency.trim(),exponent:$.exponent}}function I(){return{version:1,main:{type:"opencode",provider:"anthropic"},accounts:[]}}function XC($){if(!F($)||!Array.isArray($.accounts))return null;return{version:1,main:{type:"opencode",provider:"anthropic",profile:N0(F($.main)?$.main.profile:void 0)},routing:F($.routing)?$.routing:void 0,fallbackOn:Array.isArray($.fallbackOn)?$.fallbackOn.filter((_)=>Number.isInteger(_)):void 0,refresh:F($.refresh)?$.refresh:void 0,quota:F($.quota)?$.quota:void 0,claudeCache:F($.claudeCache)?$.claudeCache:void 0,dump:F($.dump)?$.dump:void 0,claudeFast:F($.claudeFast)?$.claudeFast:void 0,costZeroing:F($.costZeroing)?$.costZeroing:void 0,cacheKeep:F($.cacheKeep)?$.cacheKeep:void 0,relay:F($.relay)?$.relay:void 0,logging:F($.logging)?$.logging:void 0,killswitch:F($.killswitch)?$.killswitch:void 0,accounts:$.accounts.map(zC).filter((_)=>_!=null)}}async function L0($){try{return{exists:!0,value:JSON.parse(await D0($,"utf8"))}}catch(_){if(_.code==="ENOENT")return{exists:!1,value:null};let C=_ instanceof Error?_.message:String(_);throw Error(`account store at ${$} is corrupt or unreadable (${C}) — fix or remove it`)}}function s($){return Object.fromEntries(Object.entries($).filter(([,_])=>_!==void 0))}function R0($){return typeof $==="number"&&Number.isFinite($)?$:0}function z$($){return Math.max(R0($.lastRefreshedAt),R0($.lastUsed),R0($.addedAt))}function YC($,_){if($.type!=="oauth")return!1;if(typeof $.refresh!=="string"||!$.refresh.trim())return!1;if(!Boolean(typeof $.access==="string"&&typeof _.access==="string"&&$.access!==_.access||typeof $.refresh==="string"&&typeof _.refresh==="string"&&$.refresh!==_.refresh))return!1;return z$($)>z$(_)}function NC($,_){if(YC($,_)){let C={..._,...$},K=z$($);if(K>R0(C.lastRefreshedAt))C.lastRefreshedAt=K;return delete C.quota,delete C.lastRefreshError,delete C.lastQuotaRefreshError,C}return{...$,..._}}function LC($,_){if(!F($))return $;let C=F(_)?_:{},K=F(C.main)?C.main:void 0,G=F(C.accounts)?C.accounts:{},j=F($.quota)?$.quota:{},J=F($.refresh)?$.refresh:{},Z=K??j,z=K??J,O=Array.isArray($.accounts)?$.accounts.map((X)=>{if(!F(X))return X;let Y=typeof X.id==="string"&&F(G[X.id])?G[X.id]:{};return NC(X,Y)}):[];return{...$,main:{type:"opencode",provider:"anthropic",profile:N0(K?.profile)},refresh:s({...J,mainLastRefreshError:z.lastRefreshError,mainRefreshLeaseId:z.refreshLeaseId,mainRefreshLeaseUntil:z.refreshLeaseUntil,mainRefreshLeaseTokenHash:z.refreshLeaseTokenHash}),quota:s({...j,mainQuota:Z.quota,mainQuotaCheckedAt:Z.quotaCheckedAt,mainQuotaToken:Z.quotaToken,mainLastQuotaApiError:Z.lastQuotaApiError}),accounts:O}}async function S($=V()){let _=await L0($),C=await L0(Y$($));if(!_.exists&&!C.exists)return null;let K=_.exists?_.value:I();return XC(LC(K,C.value))}async function UC($){let _=await L0($);return F(_.value)?_.value:{}}function WC($){return Object.fromEntries(Object.entries($).filter(([,_])=>_!==void 0))}function HC($){return s({id:$.id,label:$.label,type:$.type,enabled:$.enabled,addedAt:$.addedAt,baseURL:$.type==="api"?$.baseURL:void 0,authHeader:$.type==="api"?$.authHeader:void 0})}function FC($){if($.type==="api")return s({apiKey:$.apiKey,lastUsed:$.lastUsed});return s({access:$.access,refresh:$.refresh,expires:$.expires,lastUsed:$.lastUsed,lastRefreshedAt:$.lastRefreshedAt,lastRefreshError:$.lastRefreshError,lastQuotaRefreshError:$.lastQuotaRefreshError,quota:$.quota,profile:$.profile})}function U0($){return Math.max($?.five_hour?.checkedAt??0,$?.seven_day?.checkedAt??0,...$?.scoped?.map((_)=>_.checkedAt)??[],$?.checkedAt??0)}function _0($){if($?.source==="poll")return 2;if($?.source==="headers")return 1;return 0}function MC($,_){if(!("scoped"in $))return _.scoped;if(!Array.isArray($.scoped)||$.scoped.length===0)return $.scoped;if(!Array.isArray(_.scoped)||_.scoped.length===0)return $.scoped;let C=new Map(_.scoped.map((K)=>[K.id,K]));for(let K of $.scoped){let G=C.get(K.id);if(!G||K.checkedAt>=G.checkedAt)C.set(K.id,K)}return[...C.values()]}function G1($,_,C){let K=$[C],G=_[C];if(!G)return K;if(!K)return G;if(G.checkedAt>K.checkedAt)return G;if(G.checkedAt<K.checkedAt)return K;return _0($)>_0(_)?K:G}function W1($,_){if(!$||_.source!=="headers")return _;let C=$.bindingWindowSource==="poll";return{...$,..._,five_hour:G1($,_,"five_hour"),seven_day:G1($,_,"seven_day"),scoped:MC($,_),extraUsage:$.extraUsage??_.extraUsage,bindingWindow:C?$.bindingWindow:_.bindingWindow??$.bindingWindow,bindingWindowSource:C?"poll":_.bindingWindowSource??$.bindingWindowSource}}function EC($,_){if(!F($))return _;let C=$,K=Boolean(C.access&&_.access&&C.access!==_.access||C.refresh&&_.refresh&&C.refresh!==_.refresh),G=Boolean(!K&&_.quota?.source==="headers"),j=G&&_.quota?{..._,quota:W1(C.quota,_.quota)}:_,J=U0(C.quota),Z=U0(j.quota),z=Boolean(J===Z&&_0(C.quota)>_0(j.quota));if(!G&&(J>Z||z)){let X=C.lastRefreshedAt??0,Y=j.lastRefreshedAt??0;if(K&&Y<=X){let U={...C};if(typeof j.lastUsed==="number"&&(typeof C.lastUsed!=="number"||j.lastUsed>C.lastUsed))U.lastUsed=j.lastUsed;return U}let L={...C,...j};if(K){if(!("profile"in j))delete L.profile;if(j.quota?.source)L.quota=j.quota;else delete L.quota;if(!("lastQuotaRefreshError"in j))delete L.lastQuotaRefreshError;if(!("lastRefreshError"in j))delete L.lastRefreshError;return L}return{...L,quota:C.quota,lastQuotaRefreshError:C.lastQuotaRefreshError}}let O={...C,...j};if(K){if(!("profile"in j))delete O.profile;if(!j.quota?.source)delete O.quota}if(!("lastQuotaRefreshError"in j))delete O.lastQuotaRefreshError;if(!("lastRefreshError"in j))delete O.lastRefreshError;return O}function VC($){let _=$.refresh?s({enabled:$.refresh.enabled,intervalMinutes:$.refresh.intervalMinutes,refreshBeforeExpiryMinutes:$.refresh.refreshBeforeExpiryMinutes}):void 0,C=$.quota?s({enabled:$.quota.enabled,checkIntervalMinutes:$.quota.checkIntervalMinutes,refreshEveryNRequests:$.quota.refreshEveryNRequests,minimumRemaining:$.quota.minimumRemaining,failClosedOnUnknownQuota:$.quota.failClosedOnUnknownQuota,showToasts:$.quota.showToasts}):void 0;return WC({version:1,main:{type:"opencode",provider:"anthropic"},routing:$.routing,fallbackOn:$.fallbackOn,refresh:_,quota:C,claudeCache:$.claudeCache,dump:$.dump,logging:$.logging,claudeFast:$.claudeFast,costZeroing:$.costZeroing,cacheKeep:$.cacheKeep,relay:$.relay,killswitch:$.killswitch,accounts:$.accounts.map(HC)})}var j1=Promise.resolve();function N$($){return new Promise((_,C)=>{j1=j1.then(()=>$().then(_,C),()=>$().then(_,C))})}async function L$($,_){await O$(X$($),{recursive:!0});let C=`${$}.${Y0()}.tmp`;await S0(C,`${JSON.stringify(_,null,2)}
|
|
3
|
+
`,{encoding:"utf8",mode:384});try{await Y1(C,$)}catch(K){throw await e(C,{force:!0}).catch(()=>{}),K}}function J1($,_){return $.id===_.id||Boolean($.label&&_.label&&$.label===_.label)}function fC($,_,C){let K=new Set(C.removedAccountIds??[]),G=$.filter((O)=>!K.has(O.id)),j=_.filter((O)=>!K.has(O.id)),J=G.filter((O)=>!j.some((X)=>J1(X,O)));if(!J.length)return[...j];if(C.preserveExistingAccountOrder===!1)return[...j,...J];let Z=new Set,z=G.map((O)=>{let X=j.findIndex((L,U)=>!Z.has(U)&&J1(L,O)),Y=j[X];if(!Y)return O;return Z.add(X),Y});for(let O=0;O<j.length;O++){let X=j[O];if(!Z.has(O)&&X)z.push(X)}return z}var bC=1e4,QC=12000,BC=1e4,DC=12000;async function H1($){let{path:_,name:C,ttlMs:K,waitMs:G,description:j}=$;await O$(X$(_),{recursive:!0});let J=Date.now()+G;while(!0){let Z=await n({name:C,ttlMs:K,path:_,renew:!0});if(Z)return Z;if(Date.now()>=J)throw Error(`Timed out waiting for the account ${j} lock`);await new Promise((z)=>setTimeout(z,25))}}function F1($){return H1({path:$,name:"config-write",ttlMs:bC,waitMs:QC,description:"configuration write"})}function U$($){return H1({path:$,name:"state-write",ttlMs:BC,waitMs:DC,description:"state write"})}function R($,_=V(),C={}){let K=_;return N$(()=>SC($,K,C))}async function SC($,_,C){let K=await F1(_);try{let G=await S(_),j={...$,accounts:fC(G?.accounts??[],$.accounts,C)},Z={...await UC(_),...VC(j)};await L$(_,Z);let z=await U$(_);try{await M1(j,_,{mainQuota:!0,mainRefresh:!0,accounts:!0})}finally{await z.release()}}finally{await K.release()}}function RC($,_){$.main=$.main??{},$.main.profile=_.main?.profile}function AC($,_){$.main=$.main??{};let C=_.quota?.mainQuota,K=Boolean($.main.quotaToken&&_.quota?.mainQuotaToken&&$.main.quotaToken===_.quota.mainQuotaToken),G=K&&C?.source==="headers"?W1($.main.quota,C):C,j=Boolean(K&&C?.source==="headers"),J=typeof $.main.quotaCheckedAt==="number"?$.main.quotaCheckedAt:U0($.main.quota),Z=typeof _.quota?.mainQuotaCheckedAt==="number"?_.quota.mainQuotaCheckedAt:U0(G);if(!j&&(J>Z||J===Z&&_0($.main.quota)>_0(G)))return;$.main.quota=G,$.main.quotaCheckedAt=j?Math.max(J,Z):_.quota?.mainQuotaCheckedAt,$.main.quotaToken=_.quota?.mainQuotaToken,$.main.lastQuotaApiError=_.quota?.mainLastQuotaApiError}function qC($,_){$.main=$.main??{},$.main.lastRefreshError=_.refresh?.mainLastRefreshError,$.main.refreshLeaseId=_.refresh?.mainRefreshLeaseId,$.main.refreshLeaseUntil=_.refresh?.mainRefreshLeaseUntil,$.main.refreshLeaseTokenHash=_.refresh?.mainRefreshLeaseTokenHash}function A0($){if(Array.isArray($))return $.map(A0);if(!F($))return $;return Object.fromEntries(Object.entries($).filter(([,_])=>_!==void 0).map(([_,C])=>[_,A0(C)]))}function PC($,_=V(),C={mainProfile:!0,mainQuota:!0,mainRefresh:!0,accounts:!0}){let K=_;return N$(async()=>{let G=await U$(K);try{await M1($,K,C)}finally{await G.release()}})}function X2($,_=V()){let C=_;return N$(async()=>{let K=await F1(C);try{let G=await U$(C);try{let j=await S(C),J=Y$(C),Z=(await L0(J)).value,z=F(Z)?{...Z,version:1}:{version:1},{accountId:O,expectedTokenFingerprint:X,profile:Y}=$;if(Y?.tokenFingerprint&&Y.tokenFingerprint!==X)return!1;if(O==="main"){z.main={...z.main??{}};let L=N0(z.main.profile),U=z.main.profileToken??L?.tokenFingerprint;if(!Y&&L&&U===X)return!1;if(Y){if(U&&U!==X)return!1;if(L&&L.checkedAt>Y.checkedAt)return!1}z.main.profile=Y,z.main.profileToken=X}else{let L=j?.accounts.find((M)=>M.id===O&&k(M));if(!L?.access||D(L.access)!==X)return!1;z.accounts={...F(z.accounts)?z.accounts:{}};let U=F(z.accounts[O])?{...z.accounts[O]}:{},H=N0(U.profile);if(!Y&&H?.tokenFingerprint===X)return!1;if(Y&&H&&H.checkedAt>Y.checkedAt)return!1;U.profile=Y,z.accounts[O]=U}return await L$(J,A0(z)),!0}finally{await G.release()}}finally{await K.release()}})}async function M1($,_,C){let K=Y$(_),G=(await L0(K)).value,j=F(G)?{...G,version:1}:{version:1};if(C.mainProfile)RC(j,$);if(C.mainQuota)AC(j,$);if(C.mainRefresh)qC(j,$);if(C.accounts){let J=C.accounts===!0?null:new Set(C.accounts);j.accounts={...F(j.accounts)?j.accounts:{}};for(let Z of $.accounts){if(J&&!J.has(Z.id))continue;j.accounts[Z.id]=EC(j.accounts[Z.id],FC(Z))}if(J){for(let Z of J)if(!$.accounts.some((z)=>z.id===Z))delete j.accounts[Z]}else{let Z=new Set($.accounts.map((z)=>z.id));for(let z of Object.keys(j.accounts))if(!Z.has(z))delete j.accounts[z]}}await L$(K,A0(j))}async function n($){let C=`${$.path??V()}.${$.name}.lock`,K=$0(C,"owner.json"),G=Y0(),j=$.now??Date.now,J=null,Z=!1;async function z(){try{return JSON.parse(await D0(C,"utf8"))}catch(U){if(U.code!=="EISDIR")throw U;return JSON.parse(await D0(K,"utf8"))}}async function O(){await S0(C,`${JSON.stringify({ownerId:G,expiresAt:j()+$.ttlMs})}
|
|
4
|
+
`,{encoding:"utf8",mode:384})}async function X(){try{return await S0(C,`${JSON.stringify({ownerId:G,expiresAt:j()+$.ttlMs})}
|
|
5
|
+
`,{encoding:"utf8",mode:384,flag:"wx"}),!0}catch(U){let H=U.code;if(H==="EEXIST"||H==="EISDIR")return!1;throw U}}function Y(){if(!$.renew||Z)return;let U=$.renewIntervalMs??Math.max(1000,Math.floor($.ttlMs/3));if(J=g_(()=>{(async()=>{try{let H=await z(),M=j();if(Z||H?.ownerId!==G||Number(H?.expiresAt)<=M)return;await O(),Y()}catch{}})()},U),"unref"in J)J.unref()}let L=await X();if(!L){let U=`${C}.evicting`,H=$0(U,"owner.json"),M=Y0(),b=5000,N=8;async function x(){await new Promise((A)=>setTimeout(A,Math.floor(Math.random()*4)))}async function u(){try{let A=await z();return Number(A?.expiresAt)>j()}catch{try{return(await t$(C)).mtimeMs+$.ttlMs>j()}catch{return!1}}}async function T(){try{return JSON.parse(await D0(H,"utf8"))?.ownerId===M}catch{return!1}}async function W(){await O$(U);try{await S0(H,`${JSON.stringify({ownerId:M,createdAt:j()})}
|
|
6
|
+
`,{encoding:"utf8",mode:384,flag:"wx"})}catch(A){if(A.code==="ENOENT")return!1;throw await E(),A}return await $.onStep?.("eviction-marker-acquired"),!0}async function E(){if(await T())await e(U,{recursive:!0,force:!0}).catch(()=>{})}for(let A=0;A<8;A++){if(L=await X(),L)break;if(await u())return null;try{if(!await W()){await x();continue}}catch(f0){if(f0.code!=="EEXIST")throw f0;let b0;try{b0=await t$(U)}catch(w){if(w.code==="ENOENT"){await x();continue}throw w}if(b0.mtimeMs+5000>j())return null;await $.onStep?.("stale-marker-stat");let l=`${U}.${Y0()}`;try{await Y1(U,l)}catch(w){if(w.code==="ENOENT"){await x();continue}throw w}await $.onStep?.("stale-marker-claimed"),await e(l,{recursive:!0,force:!0}).catch(()=>{}),await x();continue}try{if(await u())return null;if(!await T())return null;if(await $.onStep?.("stale-lock-confirmed"),!await T())return null;if(await e(C,{recursive:!0,force:!0}).catch(()=>{}),!await T())return null;if(L=await X(),!L)return null;if(!await T())return await e(C,{recursive:!0,force:!0}).catch(()=>{}),L=!1,null;break}finally{await E()}}}if(!L)return null;return Y(),{release:async()=>{if(Z=!0,J)d_(J),J=null;try{if((await z())?.ownerId!==G)return}catch{return}await e(C,{recursive:!0,force:!0}).catch(()=>{})}}}function Y2($){return $?.claudeCache?.enabled===!0}function IC($){return typeof $==="string"&&s$.includes($)?$:B0}function hC($){return IC($?.claudeCache?.mode)}async function N2($,_,C=V()){let K=await S(C)??I();return K.claudeCache={...K.claudeCache??{},enabled:$,mode:_??hC(K)},await R(K,C),K}async function L2($,_=V()){let C=await S(_)??I();return C.claudeCache={...C.claudeCache??{},enabled:C.claudeCache?.enabled===!0,mode:$},await R(C,_),C}function U2($){return $?.dump?.enabled===!0}async function W2($,_=V()){let C=await S(_)??I();return C.dump={...C.dump??{},enabled:$},await R(C,_),C}function H2($){return $?.claudeFast?.enabled===!0}async function F2($,_=V()){let C=await S(_)??I();return C.claudeFast={...C.claudeFast??{},enabled:$},await R(C,_),C}async function M2($,_,C=V()){let K=await S(C)??I();return K.cacheKeep={...K.cacheKeep??{},enabled:!0,always:!1,startHour:$,endHour:_},await R(K,C),K}async function E2($=V()){let _=await S($)??I();return _.cacheKeep={..._.cacheKeep??{},enabled:!0,always:!0},delete _.cacheKeep.startHour,delete _.cacheKeep.endHour,await R(_,$),_}async function V2($,_=V()){let C=await S(_)??I();return C.cacheKeep={...C.cacheKeep??{},enabled:$},await R(C,_),C}function f2($){return $?.cacheKeep?.subagents===!0}async function b2($,_=V()){let C=await S(_)??I();return C.cacheKeep={...C.cacheKeep??{},subagents:$},await R(C,_),C}function TC($){return $?.fallbackOn?.length?$.fallbackOn:r_}function Q2($,_){return TC(_).includes($)}function I0($){let _=$?.quota?.minimumRemaining||{};return{five_hour:_.five_hour??_["5h"]??e$.five_hour,seven_day:_.seven_day??_["1w"]??e$.seven_day}}function W0($){return $?.quota?.enabled!==!1}function wC($){return $?.refresh?.enabled!==!1}function xC($){return Math.floor(Math.random()*Math.max(0,$))}function kC($){let _=$?.refresh?.refreshBeforeExpiryMinutes??s_;return Math.max(L1,_)*60000}function E1($){return X1("sha256").update($).digest("hex")}function yC($){let _=$.status;if(typeof _==="number"&&Number.isFinite(_))return _===429||_>=500;if(!($ instanceof Error))return!1;return $.message.includes("fetch failed")||"code"in $&&($.code==="ECONNRESET"||$.code==="ECONNREFUSED"||$.code==="ETIMEDOUT"||$.code==="UND_ERR_CONNECT_TIMEOUT")}function mC($){let _=E1($.refreshToken),K=($.previous?.tokenHash===_?$.previous.retryCount??0:0)+1,G=$.error.retryAfter,j;if(typeof G==="number"&&G>0)j=G*1000;else if(yC($.error))j=Math.min(o_,n_*2**Math.min(K-1,6));else j=U1;let J=$.error.status,Z=typeof J==="number"&&Number.isFinite(J)?J:void 0,z=K0($.error),X=(typeof $.error.body==="string"?$.error.body:"").includes("invalid_grant")||z.includes("invalid_grant");return{message:z,checkedAt:$.now,nextRetryAt:$.now+j,retryCount:K,tokenHash:_,status:Z,permanent:Z===400&&X}}function B2($){if(!$)return!1;if(typeof $.permanent==="boolean")return $.permanent;if(typeof $.status==="number")return $.status===400;if(typeof $.nextRetryAt==="number")return $.nextRetryAt-$.checkedAt>=U1;return!1}function X0($,_,C){if(!$?.nextRetryAt||$.nextRetryAt<=C)return!1;if(!_)return!0;return $.tokenHash===E1(_)}function J$($,_){return`Claude OAuth refresh is backed off for ${Math.max(1,Math.ceil((($.nextRetryAt??_)-_)/1000))}s after: ${$.message}`}function W$($){if($.status===403)return!0;return/Claude quota check failed: 403\b/.test(K0($))}function h0($){let C=($.previous?.retryCount??0)+1,K=B1($.error)?Math.min(t_,a_*2**Math.min(C-1,6)):e_;return{message:K0($.error),checkedAt:$.now,nextRetryAt:$.now+K,retryCount:C}}function C0($,_){if(!$?.nextRetryAt||$.nextRetryAt<=_)return!1;return!0}function D2($,_){return`Quota API backed off for ${Math.max(1,Math.ceil((($.nextRetryAt??_)-_)/1000))}s after: ${$.message}`}function m($){let _=$?.quota?.checkIntervalMinutes??$C;return Math.max(1,_)*60000}function S2($){return $?.logging?.level}async function R2($,_=V()){let{setLogLevel:C}=await import("./logger-ywfmddsw.js"),K=await S(_)??I();K.logging={...K.logging??{},level:$},await R(K,_),C($)}function V1($){if(!$?.quota?.mainQuota||!$.quota.mainQuotaCheckedAt)return null;return{quota:$.quota.mainQuota,checkedAt:$.quota.mainQuotaCheckedAt,tokenFingerprint:$.quota.mainQuotaToken}}function f1($){let _=$?.quota?.refreshEveryNRequests;return typeof _==="number"&&Number.isFinite(_)&&_>0?Math.floor(_):0}function q0($){return $?.quota?.failClosedOnUnknownQuota??_C}function vC($){if(typeof $!=="string")return null;let _=$.toLowerCase();if(_.includes("fable"))return"fable";if(_.includes("mythos"))return"mythos";return null}function y($,_){let C=vC(_);if(!C)return;return $?.scoped?.find((K)=>{return[K.modelId,K.modelName,K.title].filter((j)=>typeof j==="string").join(" ").toLowerCase().includes(C)})}function lC($,_){let C=y($,_);return Boolean(C&&Number.isFinite(C.remainingPercent)&&C.remainingPercent<=0)}function Z1($,_){return!lC($,_)}function b1($,_){if(!W0(_))return!0;let C=I0(_);for(let K of["five_hour","seven_day"]){let G=$?.[K];if(!G)return!q0(_);if(!Number.isFinite(G.remainingPercent))return!q0(_);if(G.remainingPercent<C[K])return!1}return!0}var r={five_hour:5,seven_day:10,scoped:0};function H0($){let _=$?.five_hour??$?.["5h"],C=$?.seven_day??$?.["1w"],K=$?.scoped;return{five_hour:typeof _==="number"&&Number.isFinite(_)?_:r.five_hour,seven_day:typeof C==="number"&&Number.isFinite(C)?C:r.seven_day,scoped:typeof K==="number"&&Number.isFinite(K)?K:r.scoped}}function H$($){return $?.killswitch?.enabled===!0}function F$($,_){if(!$?.killswitch)return r;if(_&&$.killswitch.accounts?.[_])return H0($.killswitch.accounts[_]);return H0($.killswitch.main)}function A2($,_,C,K){if(!H$(_))return!0;let G=F$(_,C),j=!1;for(let J of["five_hour","seven_day"]){let Z=$?.[J];if(!Z){j=!0;continue}if(!Number.isFinite(Z.remainingPercent)){j=!0;continue}if(Z.remainingPercent<G[J])return!1}if(K){let J=y($,K);if(J&&Number.isFinite(J.remainingPercent)&&J.remainingPercent<=G.scoped)return!1}if(j)return!q0(_);return!0}function q2($,_,C,K){let G=[],j=[$,..._.map((J)=>J.quota)];for(let J of j)if(K){let z=y(J,K)?.resetsAt;if(!z)continue;let O=Date.parse(z);if(Number.isFinite(O)&&O>C)G.push(O)}else for(let Z of["five_hour","seven_day"]){let z=J?.[Z]?.resetsAt;if(!z)continue;let O=Date.parse(z);if(Number.isFinite(O)&&O>C)G.push(O)}if(!G.length)return 300;return Math.max(1,Math.ceil((Math.min(...G)-C)/1000))+60}function P2($){return $?.killswitch??{enabled:!1}}async function I2($,_=V()){let C=await S(_)??I();return C.killswitch=$,await R(C,_),C}async function h2($,_=V()){let C=await S(_);if(!C)return!1;let K=sC(C,$);if(K)await R(C,_,{removedAccountIds:[$]});return K}async function T2($,_=V()){let C=await S(_);if(!C)return;nC(C,$),await R(C,_,{preserveExistingAccountOrder:!1})}async function w2($,_,C=V()){let K=await S(C);if(!K)return!1;let G=oC(K,$,_);if(G)await R(K,C);return G}async function x2($,_=V()){let C=await S(_)??I();rC(C,$),await R(C,_)}function G0($,_,C){let K=m(_);if(!W0(_))return C+K;let G=Math.min(...[...["five_hour","seven_day"].map((z)=>$?.[z]?.checkedAt),...($?.scoped??[]).map((z)=>z.checkedAt)].filter((z)=>Number.isFinite(z)).map((z)=>z+K)),j=(z)=>Number.isFinite(G)?Math.min(z,G):z,J=I0(_),Z=[];for(let z of["five_hour","seven_day"]){let O=$?.[z];if(!O)return j(C+K);if(O.remainingPercent>=J[z])continue;let X=O.resetsAt?Date.parse(O.resetsAt):Number.NaN;if(!Number.isFinite(X)||X<=C)return j(C+K);Z.push(X)}if(!Z.length)return j(C+K);return j(Math.min(...Z)+60000)}function i($,_,C){return!$.access||!$.expires||$.expires-C<=kC(_)}function Q1($,_,C){if(!W0(_))return!0;let K=m(_);return["five_hour","seven_day"].every((G)=>{let j=$?.[G];return Boolean(j&&C-j.checkedAt<K)})}function Z$($,_,C,K){if(!Q1($.quota,_,C))return!0;let G=y($.quota,K);return Boolean(G&&C-G.checkedAt>=m(_))}function pC($,_){if(!$)return!1;if(!$.resetsAt)return!0;let C=Date.parse($.resetsAt);return!Number.isFinite(C)||C>_}function gC($,_){return["five_hour","seven_day"].every((C)=>pC($?.[C],_))}function B1($){let _=$.status;if(typeof _==="number"&&Number.isFinite(_)){if(_===429||_>=500)return!0}let C=K0($);if(/Claude quota check failed: (429|5\d\d)\b/.test(C))return!0;if(C.includes("Quota refresh is already in progress"))return!0;if(!($ instanceof Error))return!1;let{message:K,code:G}=$;return K.includes("fetch failed")||G==="ECONNRESET"||G==="ECONNREFUSED"||G==="ETIMEDOUT"||G==="UND_ERR_CONNECT_TIMEOUT"}function dC($,_,C,K){return B1(C)&&b1($.quota,_)&&gC($.quota,K)}function P0($){if(!Number.isFinite($))return 0;if($<0)return 0;if($>100)return 100;return $}function g($){return typeof $==="string"&&$.trim()?$.trim():void 0}function D1($){return $.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function uC($,_){if(!Array.isArray($))return[];let C=new Set,K=[];for(let G of $){if(G?.kind!=="weekly_scoped"||G.group!=="weekly")continue;if(typeof G.percent!=="number"||!Number.isFinite(G.percent))continue;let j=g(G.scope?.model?.display_name);if(!j)continue;let J=g(G.scope?.model?.id)??j,Z=D1(J);if(!Z)continue;let z=`claude-weekly-scoped-${Z}`;if(C.has(z))continue;C.add(z);let O=P0(G.percent),X=g(G.scope?.model?.id);K.push({id:z,title:`${j} only`,...X&&{modelId:X},modelName:j,usedPercent:O,remainingPercent:P0(100-O),resetsAt:G.resets_at,checkedAt:_})}return K}function iC($){if($.extra_usage?.is_enabled!==!0)return;let _=$.extra_usage.used_credits,C=$.extra_usage.monthly_limit;if(typeof _!=="number"||!Number.isFinite(_)||typeof C!=="number"||!Number.isFinite(C))return;let K=$.spend?.limit?.currency,G=K==null?"USD":g(K),j=$.spend?.limit?.exponent,J=j==null?2:j;if(!G||!/^[A-Za-z]{3}$/.test(G)||!Number.isInteger(J)||J<0||J>20)return;return{used:{amountMinor:_,currency:G,exponent:J},limit:{amountMinor:C,currency:G,exponent:J},...typeof $.extra_usage.utilization==="number"&&Number.isFinite($.extra_usage.utilization)&&{utilizationPercent:$.extra_usage.utilization},...g($.spend?.severity)&&{severity:g($.spend?.severity)},exhausted:_>=C}}function cC($){if(!Array.isArray($))return;let _=$.find((j)=>j?.is_active===!0);if(!_)return;if(_.kind==="session")return"five_hour";if(_.kind==="weekly_all")return"seven_day";if(_.kind!=="weekly_scoped"||_.group!=="weekly")return;let C=g(_.scope?.model?.display_name);if(!C)return;let K=g(_.scope?.model?.id)??C,G=D1(K);return G?`claude-weekly-scoped-${G}`:void 0}function z1($,_){if(typeof $?.utilization!=="number")return;if(!Number.isFinite($.utilization))return;let C=P0($.utilization);return{usedPercent:C,remainingPercent:P0(100-C),resetsAt:$.resets_at,checkedAt:_}}async function T0($){let C=await($.fetchImpl??fetch)(i_,{method:"GET",headers:{Authorization:`Bearer ${$.accessToken}`,Accept:"application/json","Content-Type":"application/json","anthropic-beta":"oauth-2025-04-20","User-Agent":`claude-code/${p}`}});if(!C.ok){let J=await C.text().catch(()=>"");throw Object.assign(Error(`Claude quota check failed: ${C.status} — ${J}`),{status:C.status,retryAfter:j$(C.headers.get("Retry-After"))})}let K=$.now?.()??Date.now(),G=await C.json(),j=cC(G.limits);return{five_hour:z1(G.five_hour,K),seven_day:z1(G.seven_day,K),scoped:uC(G.limits,K),extraUsage:iC(G),...j&&{bindingWindow:j,bindingWindowSource:"poll"},source:"poll",checkedAt:K}}function q($,_){let C=$.accounts.findIndex((K)=>K.id===_.id);if(C>=0)$.accounts[C]=_}function rC($,_){let C=$.accounts.findIndex((K)=>K.id===_.id||_.label&&K.label===_.label);if(C>=0){$.accounts[C]={...$.accounts[C],..._,addedAt:$.accounts[C]?.addedAt??_.addedAt,..._.type==="oauth"&&{quota:_.quota,profile:_.profile,lastRefreshedAt:_.lastRefreshedAt,lastRefreshError:_.lastRefreshError,lastQuotaRefreshError:_.lastQuotaRefreshError}};return}$.accounts.push(_)}function sC($,_){let C=$.accounts.findIndex((K)=>K.id===_);if(C<0)return!1;return $.accounts.splice(C,1),!0}function nC($,_){let C=new Map(_.map((j,J)=>[j,J])),K=$.accounts.filter((j)=>C.has(j.id)),G=$.accounts.filter((j)=>!C.has(j.id));K.sort((j,J)=>(C.get(j.id)??0)-(C.get(J.id)??0)),$.accounts=[...K,...G]}function oC($,_,C){let K=$.accounts.find((G)=>G.id===_);if(!K)return!1;return K.enabled=C,!0}function K0($){return $ instanceof Error?$.message:String($)}function S1($,_,C){$.lastRefreshError=mC({error:_,now:C,refreshToken:$.refresh,previous:$.lastRefreshError})}function O1($,_,C){if(W$(_))return;if($.lastQuotaRefreshError=h0({error:_,now:C,previous:$.lastQuotaRefreshError}),_.isRefreshError)S1($,_,C)}function aC($){return`fallback-oauth-refresh-${X1("sha256").update($).digest("hex").slice(0,16)}`}class tC{now;fetchImpl;configPath;refreshPromises=new Map;refreshTimer=null;quotaTimer=null;quotaManager;onFallbackStorageChanged;constructor($={}){this.now=$.now??Date.now,this.fetchImpl=$.fetchImpl??fetch,this.configPath=$.configPath??V(),this.quotaManager=$.quotaManager??null,this.onFallbackStorageChanged=$.onFallbackStorageChanged}seedFallbackQuota($,_){if(!this.quotaManager)return;if(!$.quota)return;let C=Math.max($.quota.five_hour?.checkedAt??0,$.quota.seven_day?.checkedAt??0);if(C<=0)return;let K=this.quotaManager.getFallback($.id,$.access);if(K&&K.checkedAt>=C)return;let G=m(_);this.quotaManager.setFallback($.id,{quota:$.quota,refreshAfter:C+G,checkedAt:C},$.access)}async load(){return S(this.configPath)}async save($,_){await PC($,this.configPath,{accounts:_??!0})}startBackgroundRefresh(){let $=async()=>{await this.refreshDueAccounts(),await this.refreshQuotaForDueAccounts()};if($().catch(()=>{}),!this.refreshTimer){if(this.refreshTimer=setInterval(()=>{$().catch(()=>{})},CC+xC(KC)),"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($,_={}){let C=$!==void 0?$:await this.load();if(!C)return[];let K=[],G=!1;for(let j of C.accounts){if(j.enabled===!1||!k(j))continue;try{let J=j;if(i(J,C,this.now())){let z=J.lastRefreshError;if(z&&X0(z,J.refresh,this.now()))throw Error(J$(z,this.now()));J=await this.refreshAccount(J,C),G=!0}if(this.seedFallbackQuota(J,C),(this.quotaManager?this.quotaManager.isFallbackStale(J.id,J.access,_.modelId):Z$(J,C,this.now(),_.modelId))&&!C0(J.lastQuotaRefreshError,this.now()))J=await this.refreshAccountQuota(J,C),G=!0;if(this.accountPassesQuotaPolicy(this.quotaPolicyAccount(J),C,{modelId:_.modelId}))K.push(J)}catch(J){if(dC(j,C,J,this.now())){if(c("[refresh] fallback quota using cached quota after refresh error",{accountId:j.id,error:K0(J)}),this.accountPassesQuotaPolicy(this.quotaPolicyAccount(j),C,{modelId:_.modelId}))K.push(j)}else if(!q0(C)&&Z1(j.quota,_.modelId))K.push(j)}}if(G)await this.save(C);return K}async markUsed($){let _=await this.load();if(!_)return;let C=_.accounts.find((K)=>K.id===$.id);if(!C)return;C.lastUsed=this.now(),await this.save(_)}accountPassesQuotaPolicy($,_,C={}){return b1($.quota,_)&&Z1($.quota,C.modelId)}quotaPolicyAccount($){if(!this.quotaManager)return $;let _=this.quotaManager.getFallback($.id,$.access)?.quota;return _?{...$,quota:_}:$}async refreshDueAccounts(){let $=await this.load();if(!$||!wC($))return;let _=!1;for(let C of $.accounts){if(C.enabled===!1||!k(C))continue;if(!i(C,$,this.now()))continue;if(X0(C.lastRefreshError,C.refresh,this.now()))continue;try{c("[refresh] fallback oauth background due",{accountId:C.id,expiresInMs:C.expires?C.expires-this.now():void 0}),await this.refreshAccount(C,$),_=!0}catch(K){P.warn("refresh","fallback oauth background failed",{accountId:C.id,error:K instanceof Error?K.message:String(K)}),S1(C,K,this.now()),q($,C),_=!0}}if(_)await this.save($)}async refreshQuotaForDueAccounts(){let $=await this.load();if(!$||!W0($))return;let _=!1;for(let C of $.accounts){if(C.enabled===!1||!k(C))continue;let K=C;try{if(i(K,$,this.now())){if(X0(K.lastRefreshError,K.refresh,this.now()))continue;K=await this.refreshAccount(K,$),_=!0}if(C0(K.lastQuotaRefreshError,this.now()))continue;if(this.seedFallbackQuota(K,$),!(this.quotaManager?this.quotaManager.isFallbackStale(K.id,K.access):Z$(K,$,this.now())))continue;await this.refreshAccountQuota(K,$),_=!0}catch(G){O1(C,G,this.now()),q($,C),_=!0}}if(_)await this.save($),this.onFallbackStorageChanged?.()}async refreshQuotaForAllAccounts($={}){let _=await this.load(),C=[];if(!_||!W0(_))return{storage:_,errors:C};let K=$.force??!1,G=!1;for(let j of _.accounts){if(j.enabled===!1||!k(j))continue;let J=j;try{if(i(J,_,this.now())){let Z=J.lastRefreshError;if(Z&&X0(Z,J.refresh,this.now()))throw Error(J$(Z,this.now()));J=await this.refreshAccount(J,_),G=!0}if(!K&&!Z$(J,_,this.now())){if(J.lastQuotaRefreshError)J.lastQuotaRefreshError=void 0,q(_,J),G=!0;continue}await this.refreshAccountQuota(J,_),G=!0}catch(Z){O1(j,Z,this.now()),q(_,j),G=!0,C.push({accountId:j.id,message:K0(Z)})}}if(G)await this.save(_);return{storage:_,errors:C}}async refreshAccount($,_,C={}){let K=this.refreshPromises.get($.id);if(K){let J=await K;return q(_,J),J}let G=this.refreshAccountNow($,_,C).finally(()=>{this.refreshPromises.delete($.id)});this.refreshPromises.set($.id,G);let j=await G;return q(_,j),j}async waitForConcurrentFallbackRefresh($,_,C,K){let G=Date.now()+jC;while(Date.now()<G){await new Promise((O)=>setTimeout(O,JC));let j=await this.load(),J=j?.accounts.find((O)=>O.id===$.id&&k(O));if(!J)continue;if((J.access!==C.access||J.refresh!==C.refresh||(J.expires??0)>(C.expires??0)+60000)&&(K.force||!i(J,j,this.now())))return q(_,J),c("[refresh] fallback oauth joined concurrent refresh",{accountId:J.id,expiresInMs:J.expires?J.expires-this.now():void 0}),J;let z=J.lastRefreshError;if(z&&X0(z,J.refresh,this.now()))throw q(_,J),Error(J$(z,this.now()))}return null}async refreshAccountNow($,_,C){let K=await this.load(),G=K?.accounts.find((Z)=>Z.id===$.id&&k(Z));if(G&&!C.force&&!i(G,K,this.now()))return q(_,G),G;let j=G??$,J=await n({name:aC(j.id),ttlMs:GC,path:this.configPath,now:this.now,renew:!0});if(!J){c("[refresh] fallback oauth refresh skipped file lock",{accountId:j.id});let Z=await this.waitForConcurrentFallbackRefresh($,_,j,C);if(Z)return Z;throw Error("Fallback OAuth refresh is already in progress")}try{if(K=await this.load(),G=K?.accounts.find((O)=>O.id===$.id&&k(O)),G&&!C.force&&!i(G,K,this.now()))return q(_,G),G;j=G??j;let Z=j.refresh;c("[refresh] fallback oauth refresh request start",{accountId:j.id,force:C.force===!0,expiresInMs:j.expires?j.expires-this.now():void 0});let z=await a$({refreshToken:Z,fetchImpl:this.fetchImpl,now:this.now});return j.access=z.access,j.refresh=z.refresh,j.expires=z.expires,j.lastRefreshedAt=z.expires-z.expiresIn*1000,j.lastRefreshError=void 0,q(_,j),await this.save(_),c("[refresh] fallback oauth refresh succeeded",{accountId:j.id,expiresInMs:j.expires?j.expires-this.now():void 0}),j}finally{await J.release()}}async refreshAccountQuota($,_){let C=$;if(!C.access)throw Error(`Fallback account ${$.id} has no access token`);let K=(Z)=>this.quotaManager?this.quotaManager.refreshFallback(C.id,Z):T0({accessToken:Z,fetchImpl:this.fetchImpl,now:this.now}),G=this.now();try{C.quota=await K(C.access)}catch(Z){if(!(Z instanceof Error?Z.message:String(Z)).includes("Claude quota check failed: 401"))throw Z;if(C=await this.refreshAccount($,_,{force:!0}),!C.access)throw Z;C.quota=await K(C.access)}let j=await this.load(),J=j?.accounts.find((Z)=>Z.id===C.id&&k(Z));if(j&&J&&J.access!==C.access)return this.seedFallbackQuota(J,j),q(_,J),J;if(j&&J?.access===C.access&&J.quota&&U0(J.quota)>=G&&Q1(J.quota,j,this.now()))return this.seedFallbackQuota(J,j),q(_,J),J;if(C.lastQuotaRefreshError=void 0,q(_,C),this.quotaManager&&C.quota){let Z=this.now();this.quotaManager.setFallback(C.id,{quota:C.quota,refreshAfter:Z+m(_),checkedAt:Z},C.access)}return C}}var m2="claude-cache",R1="## Claude Cache Status",eC="## Claude Cache Enabled",$6="## Claude Cache Disabled",_6="## Claude Cache Usage",C6="Usage: `/claude-cache`, `/claude-cache on`, `/claude-cache off`, or `/claude-cache mode explicit|automatic|hybrid`.",w0=!1,x0=B0;function v2(){return w0}function l2(){return x0}function p2($){w0=$.enabled,x0=$.mode}function K6($){let _=$.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 F0($){let _=$?.enabled??w0,C=$?.mode??x0;return[R1,"",`- Enabled: ${_?"enabled":"disabled"}`,`- Mode: ${C}`,"- 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(`
|
|
7
|
+
`)}function g2($){let _=K6($.argumentsText),C=$.enabled??w0,K=$.mode??x0;if(_.type==="status")return F0({enabled:C,mode:K});if(_.type==="enable")return[eC,"",F0({enabled:!0,mode:K})].join(`
|
|
8
|
+
`);if(_.type==="disable")return[$6,"",F0({enabled:!1,mode:K})].join(`
|
|
9
|
+
`);if(_.type==="mode")return[R1,"",`Mode updated to \`${_.mode}\`.`,"",F0({enabled:C,mode:_.mode})].join(`
|
|
10
|
+
`);return[_6,"",C6,"",F0({enabled:C,mode:K})].join(`
|
|
11
|
+
`)}import{randomBytes as G6,randomUUID as P1}from"node:crypto";var j6=1000,o=new Map;function M0($,_,C){if(!$.has(_)&&$.size>=j6){let K=$.keys().next().value;if(K!==void 0)$.delete(K)}$.set(_,C)}function I1($){let _=$||"anonymous",C=o.get(_);if(C)return C;let K={deviceId:G6(32).toString("hex"),sessionId:P1()};return M0(o,_,K),K}var J6=86400000,Z6=300000,M$=new Map,A1=new Map;async function z6($,_){if(!$.startsWith("sk-ant-oat"))return null;let C=new AbortController,K=setTimeout(()=>C.abort(),5000);try{let G=new URL("https://api.anthropic.com/api/claude_cli/bootstrap");if(G.searchParams.set("entrypoint",u$),_)G.searchParams.set("model",_);let j=await fetch(G,{method:"GET",headers:{accept:"application/json, text/plain, */*",authorization:`Bearer ${$}`,"content-type":"application/json","anthropic-beta":"oauth-2025-04-20","user-agent":`claude-code/${p}`},signal:C.signal});if(!j.ok)return null;let Z=(await j.json().catch(()=>null))?.oauth_account?.account_uuid;return typeof Z==="string"&&Z?Z:null}catch{return null}finally{clearTimeout(K)}}async function c2($,_){let C=I1($);if(!$.startsWith("sk-ant-oat"))return C;let K=Date.now(),G=A1.get($);if(G&&G.expiresAt>K){if(!G.accountUuid)return C;let O=`account:${G.accountUuid}`,X=o.get(O);if(X)return M0(o,$,X),X}let j=M$.get($);if(!j)j=z6($,_),M$.set($,j);let J=await j.finally(()=>{M$.delete($)});if(M0(A1,$,{accountUuid:J,expiresAt:K+(J?J6:Z6)}),!J)return C;let Z=`account:${J}`,z=o.get(Z);if(z)return M0(o,$,z),z;return C.accountUuid=J,M0(o,Z,C),C}function a($){return $!=null&&typeof $==="object"&&!Array.isArray($)}function O6($){if(!$.accountUuid)return null;return JSON.stringify({device_id:$.deviceId,account_uuid:$.accountUuid,session_id:$.sessionId})}function r2($,_){let C=O6(_);if(!C){if(a($.metadata))delete $.metadata.user_id;return!1}if(!a($.metadata))$.metadata={};let K=$.metadata;if(a(K))K.user_id=C;return!0}var X6=["oauth-2025-04-20","interleaved-thinking-2025-05-14","thinking-token-count-2026-05-13","context-management-2025-06-27","prompt-caching-scope-2026-01-05","claude-code-20250219","advisor-tool-2026-03-01","advanced-tool-use-2025-11-20","extended-cache-ttl-2025-04-11","cache-diagnosis-2026-04-07"],Y6=["oauth-2025-04-20","interleaved-thinking-2025-05-14","thinking-token-count-2026-05-13","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"],q1=["oauth-2025-04-20","interleaved-thinking-2025-05-14","thinking-token-count-2026-05-13","context-management-2025-06-27","prompt-caching-scope-2026-01-05","advisor-tool-2026-03-01","advanced-tool-use-2025-11-20","extended-cache-ttl-2025-04-11","cache-diagnosis-2026-04-07"];function N6($){return $.output_config?.format?.type==="json_schema"}function L6($){return Array.isArray($.tools)&&$.tools.length>0&&Array.isArray($.system)&&a($.thinking)&&a($.context_management)&&a($.output_config)&&a($.diagnostics)}function U6($,_=[]){let C=$?L6($)?[...X6]:N6($)?[...Y6]:[...q1]:[...q1];if($?.speed==="fast")C.push(d$);for(let K of _){let G=K.trim();if(G)C.push(G)}return[...new Set(C)].join(",")}function W6(){switch(process.platform){case"darwin":return"MacOS";case"win32":return"Windows";case"linux":return"Linux";case"freebsd":return"FreeBSD";default:return"Unknown"}}function H6(){switch(process.arch){case"arm64":return"arm64";case"x64":return"x64";case"ia32":return"x32";default:return process.arch}}function s2($,_,C={}){let K=C.identity??I1(_),j=[...($.get("anthropic-beta")??"").split(",").map((J)=>J.trim()).filter(Boolean),...C.extraBetas??[]];return $.set("accept","application/json"),$.set("authorization",`Bearer ${_}`),$.set("content-type","application/json"),$.set("user-agent",r$),$.set("anthropic-beta",U6(C.body,j)),$.set("anthropic-dangerous-direct-browser-access","true"),$.set("anthropic-version","2023-06-01"),$.set("x-app","cli"),$.set("x-client-request-id",P1()),$.set("x-claude-code-session-id",K.sessionId),$.set("x-stainless-arch",H6()),$.set("x-stainless-lang","js"),$.set("x-stainless-os",W6()),$.set("x-stainless-package-version",i$),$.set("x-stainless-retry-count","0"),$.set("x-stainless-runtime","node"),$.set("x-stainless-runtime-version",c$),$.set("x-stainless-timeout","600"),$.delete("x-api-key"),$}var F6=["model","messages","system","tools","tool_choice","metadata","max_tokens","temperature","thinking","context_management","output_config","diagnostics","stream","speed"];function h1($){let _={};for(let C of F6)if(Object.hasOwn($,C))_[C]=$[C];for(let[C,K]of Object.entries($))if(!Object.hasOwn(_,C))_[C]=K;return _}import{createHash as E6}from"node:crypto";var M6=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 T1(){return function($){let{exports:{mem:_,xxh32:C,xxh64:K,init32:G,update32:j,digest32:J,init64:Z,update64:z,digest64:O}}=$,X=new Uint8Array(_.buffer);function Y(W,E){if(_.buffer.byteLength<W+E){let A=Math.ceil((W+E-_.buffer.byteLength)/65536);_.grow(A),X=new Uint8Array(_.buffer)}}function L(W,E,A,f0,v$,b0){Y(W);let l=new Uint8Array(W);return X.set(l),A(0,E),l.set(X.subarray(0,W)),{update(w){let e0;return X.set(l),typeof w=="string"?(Y(3*w.length,W),e0=b.encodeInto(w,X.subarray(W)).written):(Y(w.byteLength,W),X.set(w,W),e0=w.byteLength),f0(0,W,e0),l.set(X.subarray(0,W)),this},digest:()=>(X.set(l),b0(v$(0)))}}function U(W){return W>>>0}let H=2n**64n-1n;function M(W){return W&H}let b=new TextEncoder,N=0,x=0n;function u(W,E=N){return Y(3*W.length,0),U(C(0,b.encodeInto(W,X).written,E))}function T(W,E=x){return Y(3*W.length,0),M(K(0,b.encodeInto(W,X).written,E))}return{h32:u,h32ToString:(W,E=N)=>u(W,E).toString(16).padStart(8,"0"),h32Raw:(W,E=N)=>(Y(W.byteLength,0),X.set(W),U(C(0,W.byteLength,E))),create32:(W=N)=>L(48,W,G,j,J,U),h64:T,h64ToString:(W,E=x)=>T(W,E).toString(16).padStart(16,"0"),h64Raw:(W,E=x)=>(Y(W.byteLength,0),X.set(W),M(K(0,W.byteLength,E))),create64:(W=x)=>L(88,W,Z,z,O,M)}}((await WebAssembly.instantiate(M6)).instance)}var V6=0x6e52736ac806831en,f6="cch=00000;";var V$=/("system":\[\{"type":"text","text":"x-anthropic-billing-header: cc_version=[^;"]+; cc_entrypoint=[^;"]+; )cch=([0-9a-f]{5});/,b6=/("system":\[\{"type":"text","text":"x-anthropic-billing-header: cc_version=[^;"]+; cc_entrypoint=[^;"]+; )cch=00000;/,w1=null,E$=null;async function Q6(){if(E$)return;w1??=(async()=>{E$=(await T1()).h64Raw})(),await w1}async function B6($){return await Q6(),((E$?.($,V6)??0n)&0xfffffn).toString(16).padStart(5,"0")}function D6($){return $.replace(V$,`$1${f6}`)}function x1($){return V$.exec($)?.[2]??null}async function k1($){if(!V$.test($))return $;let _=D6($),C=await B6(new TextEncoder().encode(_));return _.replace(b6,`$1cch=${C};`)}function S6($=p,_=new Date){if($===p)return K$;return E6("sha256").update($).digest("hex").slice(0,3)}function $4($,_=p,C,K=new Date){let G=S6(_,K);return`x-anthropic-billing-header: cc_version=${_}.${G}; cc_entrypoint=${C}; cch=00000;`}var j4="claude-cachekeep",f$=3600000,k0=300000,R6=60000,J4="extended-cache-ttl-2025-04-11",A6=32,y1=16777216,q6=2*f$,P6=30000,m1="## Claude Cache Keep Status",v1="## Claude Cache Keep Enabled",I6="## Claude Cache Keep Disabled",h6="## Claude Cache Keep Usage",T6="Usage: `/claude-cachekeep`, `/claude-cachekeep always`, `/claude-cachekeep off`, or `/claude-cachekeep HH-HH`.";function y0($){return String($).padStart(2,"0")}function w6($){let _=$.trim();if(!_)return{type:"status"};if(_==="off")return{type:"disable"};if(_==="always")return{type:"always"};if(_==="subagents on")return{type:"subagents",enabled:!0};if(_==="subagents off")return{type:"subagents",enabled:!1};let C=/^(\d{1,2})-(\d{1,2})$/.exec(_);if(!C)return{type:"usage"};let K=Number(C[1]),G=Number(C[2]);if(!Number.isInteger(K)||!Number.isInteger(G)||K<0||K>23||G<0||G>23||K===G)return{type:"usage"};return{type:"window",startHour:K,endHour:G}}function m0($){let _=Number($?.cacheKeep?.startHour),C=Number($?.cacheKeep?.endHour);if(!Number.isInteger(_)||!Number.isInteger(C)||_<0||_>23||C<0||C>23||_===C)return;return{startHour:_,endHour:C}}function v0($){return $?.cacheKeep?.enabled===!0&&$.cacheKeep.always===!0}function d1($){return $?.cacheKeep?.enabled===!0&&(v0($)||!!m0($))}function x6($){return d1($)&&$?.claudeCache?.enabled===!0&&$.claudeCache.mode==="hybrid"}function k6($,_=new Date){if(!$)return!1;let C=_.getHours();if($.startHour<$.endHour)return C>=$.startHour&&C<$.endHour;return C>=$.startHour||C<$.endHour}function l1($,_=new Date){if($?.cacheKeep?.enabled!==!0)return!1;return v0($)||k6(m0($),_)}function p1($=new Date){return`${$.getFullYear()}-${y0($.getMonth()+1)}-${y0($.getDate())}`}function u1($,_=new Date){if($&&$.startHour>$.endHour&&_.getHours()<$.endHour){let C=new Date(_);return C.setDate(C.getDate()-1),p1(C)}return p1(_)}function g1($,_,C=new Date){return v0($)?"always":u1(_,C)}function j0($){let _=$.always?"always (while this process is running)":$.window?`${y0($.window.startHour)}-${y0($.window.endHour)}`:"not configured",C=[`Cache keep: ${$.enabled?"enabled":"disabled"}`,`Schedule: ${_}`,"Mode requirement: `/claude-cache mode hybrid` must be active."];if(typeof $.hybridActive==="boolean")C.push(`Hybrid active: ${$.hybridActive?"yes":"no"}`);if(typeof $.trackedSessions==="number")C.push(`Tracked sessions: ${$.trackedSessions}`);if($.trackedSessionDetails?.length){C.push("Sessions:");for(let K of $.trackedSessionDetails)C.push(`- ${K.id}`)}if($.nextPrewarmAt)C.push(`Next prewarm: ${new Date($.nextPrewarmAt).toLocaleString()}`);return C.join(`
|
|
12
|
+
`)}function Z4($){let _=w6($.argumentsText),C={enabled:$.enabled??!1,always:$.always,window:$.window,trackedSessions:$.trackedSessions,trackedSessionDetails:$.trackedSessionDetails,nextPrewarmAt:$.nextPrewarmAt,hybridActive:$.hybridActive};if(_.type==="status")return[m1,"",j0(C)].join(`
|
|
13
|
+
`);if(_.type==="disable")return[I6,"",j0({...C,enabled:!1})].join(`
|
|
14
|
+
`);if(_.type==="always")return[v1,"",j0({...C,enabled:!0,always:!0,window:void 0})].join(`
|
|
15
|
+
`);if(_.type==="window")return[v1,"",j0({...C,enabled:!0,always:!1,window:{startHour:_.startHour,endHour:_.endHour}})].join(`
|
|
16
|
+
`);if(_.type==="subagents")return[m1,"",j0(C),"",`Subagent tracking: ${_.enabled?"enabled":"disabled"}`].join(`
|
|
17
|
+
`);return[h6,"",T6,"",j0(C)].join(`
|
|
18
|
+
`)}function b$($){if(!$||typeof $!=="object")return!1;if(Array.isArray($))return $.some(b$);let _=$,C=_.cache_control;if(C&&typeof C==="object"&&C.type==="ephemeral")return!0;return Object.values(_).some(b$)}async function y6($){let _;try{_=JSON.parse($)}catch{return{ok:!1,reason:"body is not valid JSON"}}if(!b$(_))return{ok:!1,reason:"body has no explicit cache breakpoints"};let C=structuredClone(_);if(C.max_tokens=0,delete C.stream,C.thinking?.type==="enabled")delete C.thinking;if(C.output_config?.format)delete C.output_config;let j=C.tool_choice;if(j?.type==="tool"||j?.type==="any")delete C.tool_choice;return{ok:!0,bodyText:await k1(JSON.stringify(h1(C)))}}class m6{options;targets=new Map;timer=null;constructor($){this.options=$}start(){if(this.timer)return;if(P.debug("cachekeep","started"),this.timer=setInterval(()=>{this.tick().catch(($)=>{P.warn("cachekeep","tick failed",{error:$ instanceof Error?$.message:String($)})})},R6),"unref"in this.timer)this.timer.unref()}stop(){if(!this.timer)return;P.debug("cachekeep","stopped"),clearInterval(this.timer),this.timer=null}stats($,_=this.options.now?.()??Date.now(),C=!1){let K=C?"always":u1($,new Date(_)),G=[...this.targets.values()].filter((J)=>J.dayKey===K),j=G.length?Math.min(...G.map((J)=>J.cacheExpiresAt-k0)):void 0;return{trackedSessions:G.length,nextPrewarmAt:j}}trackedSessions(){return[...this.targets.values()].map(($)=>({id:$.id,cacheExpiresAt:$.cacheExpiresAt,nextPrewarmAt:$.cacheExpiresAt-k0})).sort(($,_)=>$.id.localeCompare(_.id))}trackedOAuthRoute($){let _=this.targets.get($);return _?{oauthAccountId:_.oauthAccountId}:void 0}trackedCount(){return this.targets.size}publishTrackedSessions(){let $=this.options.onTrackedSessionsChanged;if(!$)return;try{Promise.resolve($(this.trackedSessions())).catch((_)=>{P.warn("cachekeep","failed to publish tracked sessions",{error:_ instanceof Error?_.message:String(_)})})}catch(_){P.warn("cachekeep","failed to publish tracked sessions",{error:_ instanceof Error?_.message:String(_)})}}totalBodyBytes(){return[...this.targets.values()].reduce(($,_)=>$+_.bodyText.length,0)}evictOldestTarget(){let $=this.targets.keys().next().value;if($!==void 0)this.targets.delete($)}pruneTargets($,_){for(let[C,K]of this.targets){if(_&&K.dayKey!==_){this.targets.delete(C);continue}if($-K.cacheExpiresAt>q6)this.targets.delete(C)}while(this.targets.size>A6)this.evictOldestTarget();while(this.totalBodyBytes()>y1){let C=this.targets.size;if(this.evictOldestTarget(),this.targets.size===C)break}}track($){if(!$.sessionId)return{tracked:!1,reason:"missing session id"};if(!d1($.storage))return{tracked:!1,reason:"cachekeep disabled"};if($.cacheMode!=="hybrid")return{tracked:!1,reason:"cache mode is not hybrid"};if($.bodyText.length>y1)return{tracked:!1,reason:"body exceeds cachekeep memory budget"};let _=this.options.now?.()??Date.now(),C=m0($.storage);if(!l1($.storage,new Date(_)))return{tracked:!1,reason:"outside configured schedule"};let K=g1($.storage,C,new Date(_));if(this.pruneTargets(_,K),this.targets.has($.sessionId))this.targets.delete($.sessionId);let G={};return $.headers.forEach((j,J)=>{G[J]=j}),this.targets.set($.sessionId,{id:$.sessionId,url:$.url,headers:G,bodyText:$.bodyText,cacheExpiresAt:_+f$,dayKey:K,oauthAccountId:$.oauthAccountId}),this.pruneTargets(_,K),this.publishTrackedSessions(),this.start(),{tracked:!0}}async prewarmNow($){let _={};$.headers.forEach((K,G)=>{_[G]=K});let C={id:$.sessionId,url:$.url,headers:_,bodyText:$.bodyText,cacheExpiresAt:this.options.now?.()??Date.now(),dayKey:"",oauthAccountId:$.oauthAccountId};return this.sendPrewarm(C)}async tick(){let $=await this.options.loadStorage(),_=m0($),C=this.options.now?.()??Date.now(),K=g1($,_,new Date(C));if(v0($))for(let j of this.targets.values())j.dayKey="always";if(this.pruneTargets(C,K),!this.targets.size){this.publishTrackedSessions(),this.stop();return}if(!x6($)){this.publishTrackedSessions();return}if(!l1($,new Date(C))){this.publishTrackedSessions();return}P.debug("cachekeep","fired",{targets:this.targets.size});let G=C+k0;for(let j of this.targets.values()){if(j.cacheExpiresAt>G)continue;await this.prewarm(j,C)}this.publishTrackedSessions()}async sendPrewarm($){let _=await y6($.bodyText);if(!_.ok)return _;let C=this.options.fetchImpl??fetch,K={...$,bodyText:_.bodyText},G=this.options.prepareHeaders?await this.options.prepareHeaders(new Headers($.headers),K):new Headers($.headers);G.delete("content-length"),G.delete("transfer-encoding");let j=await C($.url,{method:"POST",headers:G,body:_.bodyText,signal:AbortSignal.timeout(this.options.prewarmTimeoutMs??P6)});if(!j.ok)return{ok:!1,reason:await j.text().catch(()=>"").then((z)=>z||`HTTP ${j.status}`),status:j.status};let Z=(await j.json().catch(()=>null))?.usage;return{ok:!0,...Z&&{usage:Z}}}async prewarm($,_){let C=await this.sendPrewarm($);if(!C.ok){if(C.status==null)P.debug("cachekeep","prewarm skipped",{session:$.id,reason:C.reason}),this.targets.delete($.id);else P.warn("cachekeep","prewarm failed",{session:$.id,status:C.status,reason:C.reason}),$.cacheExpiresAt=_+k0+300000;return}$.cacheExpiresAt=_+f$,P.debug("cachekeep","prewarm succeeded",{session:$.id,...C.usage&&{usage:C.usage}})}}import{randomUUID as i1}from"node:crypto";import{mkdir as v6,readdir as l6,readFile as p6,rename as g6,rm as c1,writeFile as d6}from"node:fs/promises";import{tmpdir as u6}from"node:os";import{join as Q$}from"node:path";var i6=180000;function c6($){if(!$||typeof $!=="object"||Array.isArray($))return;let _=$;if(typeof _.id!=="string"||_.id.length===0||typeof _.cacheExpiresAt!=="number"||!Number.isFinite(_.cacheExpiresAt)||typeof _.nextPrewarmAt!=="number"||!Number.isFinite(_.nextPrewarmAt))return;return{id:_.id,cacheExpiresAt:_.cacheExpiresAt,nextPrewarmAt:_.nextPrewarmAt}}function r6($){if(!$||typeof $!=="object"||Array.isArray($))return;let _=$;if(_.version!==1||typeof _.updatedAt!=="number"||!Number.isFinite(_.updatedAt)||!Array.isArray(_.sessions))return;return{version:1,updatedAt:_.updatedAt,sessions:_.sessions.flatMap((C)=>{let K=c6(C);return K?[K]:[]})}}function L4($){return Q$(u6(),"opencode-anthropic-auth","cachekeep-sessions",$)}class s6{options;filePath;writeChain=Promise.resolve();constructor($){this.options=$;let _=$.instanceId??`${process.pid}-${i1()}`;this.filePath=Q$($.directory,`${_}.json`)}publish($){let _=$.map((C)=>({...C}));return this.writeChain=this.writeChain.catch(()=>{}).then(async()=>{if(_.length===0){await c1(this.filePath,{force:!0});return}await v6(this.options.directory,{recursive:!0,mode:448});let C=`${this.filePath}.${i1()}.tmp`,K={version:1,updatedAt:this.options.now?.()??Date.now(),sessions:_};await d6(C,`${JSON.stringify(K)}
|
|
19
|
+
`,{mode:384}),await g6(C,this.filePath)}),this.writeChain}async list($=[]){await this.writeChain.catch(()=>{});let _=this.options.now?.()??Date.now(),C=this.options.leaseMs??i6,K;try{K=(await l6(this.options.directory)).filter((J)=>J.endsWith(".json"))}catch{K=[]}let G=await Promise.all(K.map(async(J)=>{try{let Z=await p6(Q$(this.options.directory,J),"utf8");return r6(JSON.parse(Z))}catch{return}})),j=new Map;for(let J of G){if(!J||_-J.updatedAt>C||J.updatedAt>_)continue;for(let Z of J.sessions){let z=j.get(Z.id);if(!z||Z.cacheExpiresAt>z.cacheExpiresAt)j.set(Z.id,Z)}}for(let J of $){let Z=j.get(J.id);if(!Z||J.cacheExpiresAt>Z.cacheExpiresAt)j.set(J.id,{...J})}return[...j.values()].sort((J,Z)=>J.id.localeCompare(Z.id))}async dispose(){await this.writeChain.catch(()=>{}),await c1(this.filePath,{force:!0})}}var r1={"5h":"five_hour","7d":"seven_day"};function W4($){return Object.keys(r1).some((_)=>Number.isFinite(B$($,`anthropic-ratelimit-unified-${_}-utilization`)))}function B$($,_){let C=$.get(_);if(C==null||C.trim()==="")return;let K=Number(C);return Number.isFinite(K)?K:void 0}function n6($,_,C){let K=B$($,`anthropic-ratelimit-unified-${_}-utilization`);if(K==null)return;let G=Math.min(100,Math.max(0,Math.round(K*100))),j=B$($,`anthropic-ratelimit-unified-${_}-reset`),J=j==null?void 0:new Date(j*1000),Z=J&&Number.isFinite(J.getTime())?J.toISOString():void 0;return{usedPercent:G,remainingPercent:100-G,...Z&&{resetsAt:Z},checkedAt:C}}function H4($,_=Date.now()){let C={fallbackAdvised:$.get("anthropic-ratelimit-unified-fallback")==="available",source:"headers",checkedAt:_};for(let[G,j]of Object.entries(r1)){let J=n6($,G,_);if(J)C[j]=J}let K=$.get("anthropic-ratelimit-unified-representative-claim");if(K)C.bindingWindow=K,C.bindingWindowSource="headers";return C}function l0($,_){return{...$,..._,scoped:$&&"scoped"in $?$.scoped:void 0,extraUsage:$?.extraUsage,bindingWindow:$?.bindingWindowSource==="poll"?$.bindingWindow:_.bindingWindow??$?.bindingWindow,bindingWindowSource:$?.bindingWindowSource==="poll"?"poll":_.bindingWindowSource??$?.bindingWindowSource,source:"headers"}}var o6=globalThis.setTimeout;function s1($,_){if($?.source!=="headers")return _;let C=Boolean($.five_hour&&$.five_hour.checkedAt>(_.five_hour?.checkedAt??0)),K=Boolean($.seven_day&&$.seven_day.checkedAt>(_.seven_day?.checkedAt??0));if(!C&&!K)return _;return l0(_,{...C&&{five_hour:$.five_hour},...K&&{seven_day:$.seven_day},fallbackAdvised:$.fallbackAdvised,...$.bindingWindowSource==="headers"&&{bindingWindow:$.bindingWindow,bindingWindowSource:$.bindingWindowSource},source:"headers",checkedAt:Math.max(C?$.five_hour?.checkedAt??0:0,K?$.seven_day?.checkedAt??0:0)})}class d{main=null;mainTokenFp=null;fallbacks=new Map;fallbackTokenFps=new Map;inflightMain=null;inflightMainFp=null;inflightFallbacks=new Map;mainLastApiError=void 0;fallbackApiErrors=new Map;fallbackErrorTokenFps=new Map;apiGate=Promise.resolve();lastApiCallAt=0;storage;fetchImpl;now;onMainQuotaFetched;onApiError;constructor($){this.storage=$.storage,this.fetchImpl=$.fetchImpl??fetch,this.now=$.now??Date.now,this.onMainQuotaFetched=$.onMainQuotaFetched,this.onApiError=$.onApiError,this.seedMainFromStorage($.storage),this.seedMainBackoffFromStorage($.storage)}getMain($){if($&&this.main&&this.mainTokenFp&&this.mainTokenFp!==D($))this.main=null,this.mainTokenFp=null;return this.main}getFallback($,_){let C=this.fallbacks.get($)??null;if(!_||!C)return C;if(this.fallbackTokenFps.get($)!==D(_))return this.fallbacks.delete($),this.fallbackTokenFps.delete($),null;return C}getAllFallbacks(){return this.fallbacks}setMain($,_){this.mainTokenFp=D($),this.main=_}setFallback($,_,C){if(this.fallbacks.set($,_),C)this.fallbackTokenFps.set($,D(C));else this.fallbackTokenFps.delete($)}pushMainFromHeaders($,_){let C=_.checkedAt??this.now(),K=D($),G=l0(this.mainTokenFp===K?this.main?.quota:void 0,_),j={quota:G,checkedAt:C,refreshAfter:G0(G,this.storage,C)};return this.setMain($,j),j}pushFallbackFromHeaders($,_,C){let K=C.checkedAt??this.now(),G=l0(this.getFallback($,_)?.quota,C),j={quota:G,checkedAt:K,refreshAfter:G0(G,this.storage,K)};return this.setFallback($,j,_),j}async refreshMain($){let _=D($);if(this.mainTokenFp&&this.mainTokenFp!==_)this.main=null,this.mainTokenFp=null;if(this.inflightMain&&this.inflightMainFp===_)return this.inflightMain;if(this.isBackedOff()){if(this.main)return this.main.quota;throw Error("Quota API rate-limited — try again later")}return this.inflightMainFp=_,this.inflightMain=this._fetchMain($),this.inflightMain}async refreshFallback($,_){let C=d.fallbackInflightKey($,_),K=this.inflightFallbacks.get(C);if(K)return K;if(this.isFallbackBackedOff($,_)){let j=this.getFallback($,_);if(j)return j.quota;throw Error("Quota API rate-limited — try again later")}let G=this._fetchFallback($,_);return this.inflightFallbacks.set(C,G),G}async refreshAllFallbacks($){let _=this.now();for(let C of $){if(C.enabled===!1)continue;if(!C.access)continue;let K=this.getFallback(C.id,C.access);if(K&&_<K.refreshAfter)continue;try{await this.refreshFallback(C.id,C.access)}catch{}}}refreshMainInBackground($){if(this.inflightMain)return;if(this.isBackedOff())return;this.refreshMain($).catch(()=>{})}scopedWindowIsStale($,_){let C=y($.quota,_);return Boolean(C&&this.now()-C.checkedAt>=m(this.storage))}isMainStale($){if(!this.main)return!0;return this.now()>=this.main.refreshAfter||this.scopedWindowIsStale(this.main,$)}isFallbackStale($,_,C){let K=this.getFallback($,_);if(!K)return!0;return this.now()>=K.refreshAfter||this.scopedWindowIsStale(K,C)}shouldRefreshOnRequestCount($){let _=f1(this.storage);if(_<=0)return!1;return $>0&&$%_===0}needsRefresh($,_){return this.isMainStale(_)||this.shouldRefreshOnRequestCount($)}updateStorage($){this.storage=$,this.seedMainFromStorage($),this.seedMainBackoffFromStorage($)}seedMainFromStorage($,_){let C=V1($);if(!C)return;let K=_?D(_):null;if(K&&C.tokenFingerprint&&C.tokenFingerprint!==K)return;let G={quota:C.quota,refreshAfter:G0(C.quota,$,C.checkedAt),checkedAt:C.checkedAt};if(this.main&&this.main.checkedAt>=G.checkedAt&&(!K||!this.mainTokenFp||this.mainTokenFp===K))return;this.main=G,this.mainTokenFp=C.tokenFingerprint??null}seedMainBackoffFromStorage($){let _=$?.quota?.mainLastQuotaApiError;this.mainLastApiError=_&&C0(_,this.now())?_:void 0}seedFallbacksFromAccounts($){let _=m(this.storage);for(let C of $){if(C.enabled===!1)continue;if(!C.quota)continue;let K=Math.max(C.quota.five_hour?.checkedAt??0,C.quota.seven_day?.checkedAt??0);if(K<=0)continue;let G=this.getFallback(C.id,C.access);if(G&&G.checkedAt>=K)continue;this.setFallback(C.id,{quota:C.quota,refreshAfter:K+_,checkedAt:K},C.access)}}isBackedOff(){return C0(this.mainLastApiError,this.now())}isFallbackBackedOff($,_){if(_){if(this.fallbackErrorTokenFps.get($)!==D(_))return!1}return C0(this.fallbackApiErrors.get($),this.now())}getLastApiError(){return this.mainLastApiError}static API_CALL_GAP_MS=1000;static fallbackInflightKey($,_){return JSON.stringify([$,D(_)])}static quotaLockName($){return`opencode-fallback-quota-refresh-${$.replace(/[^a-zA-Z0-9._-]+/g,"-")||"account"}`}_enqueueApiFetch($){let _=async()=>{let K=this.now()-this.lastApiCallAt;if(K<d.API_CALL_GAP_MS)await new Promise((G)=>{let j=o6(G,d.API_CALL_GAP_MS-K);if(typeof j==="object"&&"unref"in j)j.unref()});return this.lastApiCallAt=this.now(),$()},C=this.apiGate.then(_,_);return this.apiGate=C.catch(()=>{}),C}async _fetchMain($){let _=D($);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 C=await n({name:"opencode-main-quota-refresh",ttlMs:30000});if(!C){let K=this.main;if(K&&this.now()<K.refreshAfter)return K.quota;throw Error("Quota refresh is already in progress")}try{let K=this.now(),G=await T0({accessToken:$,fetchImpl:this.fetchImpl,now:this.now}),j=this.now(),J=s1(this.mainTokenFp===_?this.main?.quota:void 0,G);return this.mainTokenFp=D($),this.main={quota:J,refreshAfter:G0(J,this.storage,j),checkedAt:J.checkedAt??j},this.mainLastApiError=void 0,this.onMainQuotaFetched?.(J,j,this.mainTokenFp,K),J}catch(K){throw this._handleMainFetchError(K),K}finally{await C.release()}}finally{if(this.inflightMainFp===_)this.inflightMain=null,this.inflightMainFp=null}})}async _fetchFallback($,_){return this._enqueueApiFetch(async()=>{try{if(this.isFallbackBackedOff($,_)){let K=this.getFallback($,_);if(K)return K.quota;throw Error("Quota API rate-limited — try again later")}let C=await n({name:d.quotaLockName($),ttlMs:30000});if(!C){let K=this.getFallback($,_);if(K&&this.now()<K.refreshAfter)return K.quota;throw Error("Quota refresh is already in progress")}try{let K=await T0({accessToken:_,fetchImpl:this.fetchImpl,now:this.now}),G=this.now(),j=s1(this.getFallback($,_)?.quota,K);return this.setFallback($,{quota:j,refreshAfter:G0(j,this.storage,G),checkedAt:j.checkedAt??G},_),this.fallbackApiErrors.delete($),this.fallbackErrorTokenFps.delete($),j}finally{await C.release()}}catch(C){throw this._handleFallbackFetchError($,_,C),C}finally{this.inflightFallbacks.delete(d.fallbackInflightKey($,_))}})}static isAuthError($){if($.status===401||W$($))return!0;let C=$ instanceof Error?$.message:String($);return/quota check failed: 401\b/.test(C)}_handleMainFetchError($){if(d.isAuthError($))return;this.mainLastApiError=h0({error:$,now:this.now(),previous:this.mainLastApiError}),this.onApiError?.(this.mainLastApiError)}_handleFallbackFetchError($,_,C){if(d.isAuthError(C))return;let K=D(_),G=this.fallbackErrorTokenFps.get($)===K?this.fallbackApiErrors.get($):void 0;this.fallbackApiErrors.set($,h0({error:C,now:this.now(),previous:G})),this.fallbackErrorTokenFps.set($,K)}}var a6="https://api.anthropic.com/api/oauth/profile",t6=604800000;async function B4($){let _=await($.fetchImpl??fetch)(a6,{method:"GET",signal:$.signal,headers:{Authorization:`Bearer ${$.accessToken}`,Accept:"application/json","anthropic-beta":"oauth-2025-04-20"}});if(!_.ok)throw Error(`Claude profile check failed: ${_.status}`);let C=await _.json(),K=C.organization?.rate_limit_tier,G=C.organization?.organization_type;if(typeof K!=="string"||K.trim()===""||typeof G!=="string"||G.trim()==="")throw Error("Claude profile response is missing account metadata");return{tier:K,orgType:G,checkedAt:$.now?.()??Date.now(),tokenFingerprint:D($.accessToken)}}function D4($,_){return $?.tokenFingerprint===D(_)}function S4($,_=Date.now()){return Boolean($&&Number.isFinite($.checkedAt)&&_>=$.checkedAt&&_-$.checkedAt<t6)}function J0($){let _=$?.tier.match(/^default_claude_max_(\d+)x$/);if(!_)return;let C=`Max ${_[1]}x`;return $?.orgType==="claude_team"?`Team · ${C}`:C}var q4="claude-account";function e6($){let _=$.trim().split(/\s+/).filter(Boolean);if(_.length===0)return{type:"status"};let C=_[0],K=_.slice(1).join(" ");if(C==="enable"&&K)return{type:"enable",id:K};if(C==="disable"&&K)return{type:"disable",id:K};if(C==="remove"&&K)return{type:"remove",id:K};if(C==="move-up"&&K)return{type:"move-up",id:K};if(C==="move-down"&&K)return{type:"move-down",id:K};if(C==="add-apikey"&&K){let G=K,j,J,Z=G.match(/--base-url\s+(\S+)/);if(Z)j=Z[1],G=G.replace(Z[0],"").trim();let z=G.match(/--auth-header\s+(authorization-bearer|x-api-key)/);if(z)J=z[1],G=G.replace(z[0],"").trim();let O,X=G.match(/--label\s+(.+)/);if(X)O=X[1]?.trim()||void 0,G=G.replace(X[0],"").trim();let Y=G.indexOf(" ");if(Y===-1){if(!G)return{type:"usage"};return{type:"add-apikey",apiKey:G,baseURL:j,authHeader:J,label:O}}let L=G.slice(0,Y),U=G.slice(Y+1).trim();return{type:"add-apikey",apiKey:L,label:O??(U||void 0),baseURL:j,authHeader:J}}if(C==="add-oauth-start")return{type:"add-oauth-start"};if(C==="add-oauth-finish"&&K){let G=K,j,J=G.match(/--label\s+(.+)/);if(J)j=J[1]?.trim()||void 0,G=G.replace(J[0],"").trim();if(!G)return{type:"usage"};return{type:"add-oauth-finish",code:G,label:j}}return{type:"usage"}}function $K($){let _=[],C=$.quota?.mainQuota?.five_hour;_.push({id:"main",label:$.main?.provider==="anthropic"?"OpenCode anthropic":"Main",role:"main",enabled:!0,quotaPercent:C?.usedPercent??null,tierLabel:J0($.main?.profile)});for(let K of $.accounts){let G=K.quota?.five_hour;_.push({id:K.id,label:K.label??K.id,role:"fallback",enabled:K.enabled!==!1,quotaPercent:G?.usedPercent??null,tierLabel:K.type==="oauth"?J0(K.profile):void 0})}return _}var D$=["Usage:"," /claude-account Show account list"," /claude-account enable <id> Enable a fallback account"," /claude-account disable <id> Disable a fallback account"," /claude-account remove <id> Remove a fallback account"," /claude-account move-up <id> Move a fallback account up"," /claude-account move-down <id> Move a fallback account down"," /claude-account add-apikey <key> Add an API key fallback account"," /claude-account add-oauth-start Start OAuth device flow"," /claude-account add-oauth-finish <code> Complete OAuth flow"].join(`
|
|
20
|
+
`);function P4($){let _=e6($.argumentsText),C=$.storage.accounts,K="main";if(_.type==="status"){let j=$K($.storage),J=["## Claude Accounts",""];for(let Z of j){let z=Z.quotaPercent!=null?` ${Math.round(Z.quotaPercent)}%`:"",O=!Z.enabled?" (disabled)":"",X=Z.tierLabel?` · ${Z.tierLabel}`:"";J.push(`- **${Z.label}** [${Z.role}]${X}${O}${z}`)}return J.push("",D$),{text:J.join(`
|
|
21
|
+
`)}}if(_.type==="usage")return{text:D$};if(_.type==="add-apikey")return{text:"add-apikey"};if(_.type==="add-oauth-start")return{text:"add-oauth-start"};if(_.type==="add-oauth-finish")return{text:"add-oauth-finish"};let G=_.id;if(G==="main")return{text:`Cannot ${_.type} the main account (OpenCode managed).`};if(_.type==="enable"||_.type==="disable"){let j=C.find((J)=>J.id===G);if(!j)return{text:`Account "${G}" not found.`};return{text:`Account "${j.label??G}" ${_.type}d.`,updated:{id:G,action:_.type,enabled:_.type==="enable"}}}if(_.type==="remove"){let j=C.find((J)=>J.id===G);if(!j)return{text:`Account "${G}" not found.`};return{text:`Account "${j.label??G}" removed.`,updated:{id:G,action:"remove"}}}if(_.type==="move-up"){let j=C.findIndex((O)=>O.id===G);if(j<0)return{text:`Account "${G}" not found.`};if(j===0)return{text:`Account "${C[j]?.label??G}" is already first.`};let J=C.map((O)=>O.id),Z=[...C];[Z[j-1],Z[j]]=[Z[j],Z[j-1]];let z=Z.map((O)=>O.id);return{text:`Account "${C[j]?.label??G}" moved up.`,updated:{id:G,action:"reorder",previousOrder:J,newOrder:z}}}if(_.type==="move-down"){let j=C.findIndex((O)=>O.id===G);if(j<0)return{text:`Account "${G}" not found.`};if(j===C.length-1)return{text:`Account "${C[j]?.label??G}" is already last.`};let J=C.map((O)=>O.id),Z=[...C];[Z[j],Z[j+1]]=[Z[j+1],Z[j]];let z=Z.map((O)=>O.id);return{text:`Account "${C[j]?.label??G}" moved down.`,updated:{id:G,action:"reorder",previousOrder:J,newOrder:z}}}return{text:D$}}import{createHash as _K,randomBytes as CK}from"node:crypto";import{lstat as n1,mkdir as KK,readdir as GK,rename as jK,unlink as $_,writeFile as JK}from"node:fs/promises";import{tmpdir as ZK}from"node:os";import{join as q$,resolve as d0}from"node:path";var m4="claude-dump",zK="## Claude Dump Status",OK="## Claude Dump Enabled",XK="## Claude Dump Disabled",YK="## Claude Dump Usage",NK="Usage: `/claude-dump`, `/claude-dump on`, or `/claude-dump off`.",LK="OPENCODE_ANTHROPIC_AUTH_DUMP_DIR",UK="OPENCODE_ANTHROPIC_AUTH_DUMP_MAX_BYTES",WK=q$(ZK(),"opencode-anthropic-auth-dumps"),HK=536870912,FK=300000,MK=60000,EK=600000,VK=/\.(body|meta|relay|request)\.json$/,fK=/^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z-\d{5,}-(.+)$/,R$="[a-zA-Z0-9._-]",bK=new RegExp(`^${R$}{1,80}-direct(?:-${R$}{1,80})?$`),QK=new RegExp(`^${R$}{1,80}-(?:http|websocket)-p[12]-(?:full_sync|patch)$`),E0=!1,o1=0,a1=0,BK=100,Z0=new Map;function v4($){E0=$}function i0(){return process.env[LK]||WK}function DK(){let $=Number(process.env[UK]);return Number.isFinite($)&&$>=0?Math.floor($):HK}function SK($){return d0($)===d0(i0())}function A$($){let _=$.replace(VK,"");if(_===$)return!1;let K=fK.exec(_)?.[1];if(!K)return!1;return bK.test(K)||QK.test(K)}function RK($){if(!$.endsWith(".partial"))return!1;let _=$.slice(0,-8);if(A$(_))return!0;let C=_.lastIndexOf(".");if(C<0)return!1;let K=_.slice(C+1);return/^[a-f0-9]{24}$/.test(K)&&A$(_.slice(0,C))}async function p0($,_){for(let C=0;C<2;C+=1){let K=CK(12).toString("hex"),G=`${$}.${K}.partial`,j=!1;try{return await JK(G,_,{encoding:"utf8",flag:"wx"}),j=!0,await jK(G,$),!0}catch(J){if(J.code==="EEXIST")continue;if(j)await $_(G).catch(()=>{});throw J}}return!1}async function AK($){let _=$.dumpDir??i0(),C=$.maxBytes??DK(),K=$.now??Date.now(),G=$.minAgeMs??MK,j=$.partialStaleMs??EK,J={removed:0,freedBytes:0};if(!SK(_)||C<=0)return J;try{if((await n1(_)).isSymbolicLink())return J;let z=new Set(($.protectedPaths??[]).map((H)=>d0(H))),O=await GK(_,{withFileTypes:!0}),X=[];await Promise.all(O.map(async(H)=>{if(!H.isFile())return;let M=RK(H.name);if(!M&&!A$(H.name))return;let b=q$(_,H.name);try{let N=await n1(b);if(!N.isFile()||N.isSymbolicLink())return;X.push({path:b,size:N.size,mtimeMs:N.mtimeMs,partial:M})}catch{}}));let Y=X.reduce((H,M)=>H+M.size,0);X.sort((H,M)=>H.mtimeMs-M.mtimeMs||H.path.localeCompare(M.path));let L=0,U=0;for(let H of X){if(z.has(d0(H.path)))continue;let M=K-H.mtimeMs,b=H.partial&&M>=j;if(!b&&Y<=C)continue;if(H.partial?!b:M<G)continue;try{await $_(H.path),Y-=H.size,U+=H.size,L+=1}catch{}}if(L>0)P.debug("dump","removed old dump files",{removed:L,freedBytes:U});return{removed:L,freedBytes:U}}catch{return J}}function qK($,_){let C=Date.now();if(C-a1<FK)return;a1=C,AK({dumpDir:$,protectedPaths:_}).catch(()=>{})}function PK($){let _=$.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 g0($){let _=$?.enabled??E0;return[zK,"",`- Enabled: ${_?"enabled":"disabled"}`,`- Directory: ${i0()}`,"- Persisted: ~/.config/opencode/anthropic-auth.json","- Captures: final rewritten Anthropic body in direct and relay modes; request/relay metadata is redacted","- Warning: body dumps may contain prompt/session content; turn this off after debugging"].join(`
|
|
22
|
+
`)}function l4($){let _=PK($.argumentsText),C=$.enabled??E0;if(_.type==="status")return g0({enabled:C});if(_.type==="enable")return[OK,"",g0({enabled:!0})].join(`
|
|
23
|
+
`);if(_.type==="disable")return[XK,"",g0({enabled:!1})].join(`
|
|
24
|
+
`);return[YK,"",NK,"",g0({enabled:C})].join(`
|
|
25
|
+
`)}function t1($){return $.length<=16?$:`${$.slice(0,12)}…`}function __($){let _=$.trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");if(!_)return"session-unknown";return _.length<=80?_:_.slice(0,80)}function IK($){if($.transport!=="direct")return`${$.transport}-p${$.protocol}-${$.mode}`;return`direct${$.route?`-${__($.route)}`:""}`}function hK($){let _=$.affinity?.trim();if(_)return`session:${_}`;return`request:${$.route??"direct"}:${$.url??""}`}function TK($,_){if(!Z0.has($))while(Z0.size>=BK){let C=Z0.keys().next().value;if(C===void 0)break;Z0.delete(C)}Z0.set($,_)}function wK($){if($==null)return;return Object.fromEntries(new Headers($).entries())}function C_($){return _K("sha256").update($).digest("hex")}function xK($){return x1($)}function kK($,_){if($==null)return null;if($===_)return{changed:!1,firstByte:-1,lastPreviousByte:-1,lastCurrentByte:-1,previousBytes:$.length,currentBytes:_.length};let C=0;while(C<$.length&&C<_.length&&$[C]===_[C])C+=1;let K=$.length-1,G=_.length-1;while(K>=C&&G>=C&&$[K]===_[G])K-=1,G-=1;return{changed:!0,firstByte:C,lastPreviousByte:K,lastCurrentByte:G,changedPreviousBytes:K-C+1,changedCurrentBytes:G-C+1,previousBytes:$.length,currentBytes:_.length}}function yK($){try{let _=JSON.parse($);return _!=null&&typeof _==="object"&&!Array.isArray(_)?_:null}catch(_){return f(`dump body parse failed: ${_ instanceof Error?_.message:String(_)}`),null}}function S$($){return C_(JSON.stringify($))}function mK($){let _=yK($);if(!_)return{parseable:!1};let C=Array.isArray(_.messages)?_.messages:[],K=Array.isArray(_.system)?_.system:[],G=C[0],j=C.slice(1);return{parseable:!0,model:typeof _.model==="string"?_.model:void 0,stream:_.stream,systemCount:K.length,messagesCount:C.length,systemHash:S$(K),message0Hash:G===void 0?null:S$(G),message0Bytes:G===void 0?0:JSON.stringify(G).length,messagesAfter0Hash:S$(j),messagesAfter0Bytes:JSON.stringify(j).length,cch:xK($)}}function u0($){if(Array.isArray($))return $.map(u0);if($==null||typeof $!=="object")return $;let _={};for(let[C,K]of Object.entries($)){let G=C.toLowerCase();if(G==="authorization"||G==="x-api-key"||G==="cookie"||G==="set-cookie"||e1(C)){_[C]="[redacted]";continue}_[C]=u0(K)}return _}async function K_($){if(!E0)return;o1+=1;let _=$.affinity?.trim()||"session-unknown",C=`${new Date().toISOString().replace(/[:.]/g,"-")}-${String(o1).padStart(6,"0")}-${__(_)}-${IK($)}`,K=i0(),G=q$(K,C),j={body:`${G}.body.json`,metadata:`${G}.meta.json`};if($.payload!==void 0)j.relay=`${G}.relay.json`;if($.request!==void 0)j.request=`${G}.request.json`;try{await KK(K,{recursive:!0});let J={id:C,createdAt:new Date().toISOString(),session:t1(_),transport:$.transport,protocol:$.protocol,mode:$.mode,route:$.route,status:$.status,error:$.error,bodyBytes:$.bodyText.length,relayBytes:$.relayBytes,bodyHash:C_($.bodyText),diff:kK($.previousBodyText,$.bodyText),body:mK($.bodyText),files:j},Z=[p0(j.body,$.bodyText),p0(j.metadata,`${JSON.stringify(J,null,2)}
|
|
26
|
+
`)];if($.payload!==void 0&&j.relay)Z.push(p0(j.relay,`${JSON.stringify(u0($.payload),null,2)}
|
|
27
|
+
`));if($.request!==void 0&&j.request)Z.push(p0(j.request,`${JSON.stringify(u0({...$.request,headers:wK($.request.headers)}),null,2)}
|
|
28
|
+
`));await Promise.all(Z),qK(K,Object.values(j)),f(`dumped request id=${C} session=${t1(_)} body=${j.body} meta=${j.metadata}`)}catch(J){f(`dump failed: ${J instanceof Error?J.message:String(J)}`)}}async function p4($){if(!E0)return;let _=hK($),C=Z0.get(_);await K_({affinity:$.affinity,transport:"direct",route:$.route,status:$.status,error:$.error,bodyText:$.bodyText,previousBodyText:C,request:{url:$.url,method:$.method,headers:$.headers}}),TK(_,$.bodyText)}async function G_($){await K_({affinity:$.affinity,transport:$.transport,protocol:$.protocol,mode:$.mode,status:$.status,bodyText:$.bodyText,previousBodyText:$.previousBodyText,payload:$.payload,relayBytes:$.relayBytes})}var d4="claude-fast";var r0=!1;function u4(){return r0}function i4($){r0=$}function vK($){let _=$.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 c0($){return["## Claude Fast Mode Status","",`- Enabled: ${$?.enabled??r0?"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(`
|
|
29
|
+
`)}function c4($){let _=vK($.argumentsText),C=$.enabled??r0;if(_.type==="status")return c0({enabled:C});if(_.type==="enable")return["## Claude Fast Mode Enabled","",c0({enabled:!0})].join(`
|
|
30
|
+
`);if(_.type==="disable")return["## Claude Fast Mode Disabled","",c0({enabled:!1})].join(`
|
|
31
|
+
`);return["## Claude Fast Mode Usage","","Usage: `/claude-fast`, `/claude-fast on`, or `/claude-fast off`.","",c0({enabled:C})].join(`
|
|
32
|
+
`)}var z0="claude-killswitch";function lK($){let _=$.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 C=[];for(let K=1;K<_.length;K++){let G=_[K]?.match(/^([^:]+):(\d+),(\d+)(?:,(\d+))?$/);if(!G)return{type:"usage"};let[,j,J,Z,z]=G,O=typeof z==="string"&&z.length>0?Number.parseInt(z,10):void 0,X={account:j,fh:Number.parseInt(J,10),sd:Number.parseInt(Z,10)};if(O!==void 0)X.scoped=O;C.push(X)}if(C.length===0)return{type:"usage"};return{type:"set",entries:C}}return{type:"usage"}}function s0($,_){let C=$.enabled===!0,K=["## Killswitch","",`Status: **${C?"ON":"OFF"}**`];if(C){K.push(""),K.push("| Account | 5h threshold | 1w threshold | Scoped |"),K.push("| ------- | ------------ | ------------ | ------ |");let G=H0($.main);K.push(`| main | ≥ ${G.five_hour}% | ≥ ${G.seven_day}% | ≤ ${G.scoped}% |`);for(let j of _){let J=H0($.accounts?.[j]??$.main);K.push(`| ${j} | ≥ ${J.five_hour}% | ≥ ${J.seven_day}% | ≤ ${J.scoped}% |`)}}return K.join(`
|
|
33
|
+
`)}var j_=["## Killswitch Commands","","```",`/${z0} — show status`,`/${z0} on — enable with current or default thresholds`,`/${z0} off — disable`,`/${z0} set all:5,10 — set all accounts to 5h≥5%, 1w≥10%`,`/${z0} set main:3,8,0 — set 5h≥3%, 1w≥8%, scoped≤0%`,`/${z0} set main:3,8 work-alt:5,10 — per-account`,"```"].join(`
|
|
34
|
+
`);function n4($){let _=lK($.argumentsText);if(_.type==="status")return{text:`${s0($.config,$.accountIds)}
|
|
35
|
+
|
|
36
|
+
${j_}`};if(_.type==="on"){let K={...$.config,enabled:!0,main:$.config.main??{five_hour:r.five_hour,seven_day:r.seven_day}};return{text:`## Killswitch Enabled
|
|
37
|
+
|
|
38
|
+
${s0(K,$.accountIds)}`,updatedConfig:K}}if(_.type==="off")return{text:"## Killswitch Disabled",updatedConfig:{...$.config,enabled:!1}};if(_.type==="set"){let K={...$.config.accounts??{}},G={...$.config,enabled:!0,accounts:K};for(let J of _.entries){let Z={five_hour:J.fh,seven_day:J.sd};if(J.scoped!==void 0)Z.scoped=J.scoped;if(J.account==="main")G.main=Z;else if(J.account==="all"){G.main=Z;for(let z of $.accountIds)K[z]=Z}else K[J.account]=Z}return{text:`## Killswitch Updated
|
|
39
|
+
|
|
40
|
+
${s0(G,$.accountIds)}`,updatedConfig:G}}return{text:`${s0($.config,$.accountIds)}
|
|
41
|
+
|
|
42
|
+
${j_}`}}var a4="claude-logging",pK=["error","warn","info","debug","trace"];function gK($){let _=$.trim().toLowerCase().split(/\s+/).filter(Boolean);if(_.length===0)return{type:"status"};if(_.length===1&&pK.includes(_[0]))return{type:"level",level:_[0]};return{type:"usage"}}function P$($){return["## Claude Log Level","",`Current log level: \`${$?.level??"info"}\``,"- Persisted: ~/.config/opencode/anthropic-auth.json","- Valid levels: error, warn, info, debug, trace","","Usage: `/claude-logging`, `/claude-logging error|warn|info|debug|trace`."].join(`
|
|
43
|
+
`)}function t4($){let _=gK($.argumentsText),C=$.level??"info";if(_.type==="status")return P$({level:C});if(_.type==="level")return["## Claude Log Level Updated","",`Level set to \`${_.level}\`.`,"",...P$({level:_.level}).split(`
|
|
44
|
+
`).slice(2)].join(`
|
|
45
|
+
`);return["## Claude Log Level Usage","","Usage: `/claude-logging`, `/claude-logging error|warn|info|debug|trace`.","",...P$({level:C}).split(`
|
|
46
|
+
`).slice(2)].join(`
|
|
47
|
+
`)}var $j="claude-fable-5";var dK=["claude-fable-5","claude-mythos-5"],uK={type:"adaptive",display:"summarized"},_j={input:10,output:50,cacheRead:1,cacheWrite5m:12.5,cacheWrite1h:20},Cj=1e6,Kj=128000,Gj="2026-06-09",jj={["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 Z_($){return typeof $==="string"&&dK.some((_)=>$===_||$.startsWith(`${_}-`))}var J_="claude-sonnet-5",Jj=uK;function Zj($){return typeof $==="string"&&($===J_||$.startsWith(`${J_}-`))}function zj($){if(typeof $!=="string")return!1;if($.startsWith("gAAAA"))return!0;if(!$.startsWith("{"))return!1;try{let _=JSON.parse($);return _.type==="reasoning"&&typeof _.id==="string"&&_.id.startsWith("rs_")&&typeof _.encrypted_content==="string"&&_.encrypted_content.startsWith("gAAAA")}catch{return!1}}var Nj="claude-quota",z_={five_hour:"5h",seven_day:"1w"};function n0($){return`${Math.round($*10)/10}%`}function o0($,_){let C=Math.max(0,_-$),K=Math.floor(C/60000);if(K<1)return"just now";if(K===1)return"1m ago";if(K<60)return`${K}m ago`;let G=Math.floor(K/60),j=K%60;if(j===0)return`${G}h ago`;return`${G}h ${j}m ago`}function iK($,_){let C=Date.parse($);if(!Number.isFinite(C))return $;let K=C-_;if(K<=0)return"now";let G=Math.max(1,Math.ceil(K/60000));if(G<60)return`in ${G}m`;let j=Math.floor(G/60),J=G%60;if(J===0)return`in ${j}h`;return`in ${j}h ${J}m`}function Y_($,_){if(!$)return"";return`, resets ${iK($,_)}`}function O_($,_,C,K){if(!_)return` - ${z_[$]}: unknown`;let G=[` - ${z_[$]}: ${n0(_.remainingPercent)} remaining`,` (${n0(_.usedPercent)} used`,`${Y_(_.resetsAt,C)}, checked ${o0(_.checkedAt,C)})`].join("");return K===$?`${G} •`:G}function X_($){try{return new Intl.NumberFormat("en-US",{style:"currency",currency:$.currency,minimumFractionDigits:$.exponent,maximumFractionDigits:$.exponent}).format($.amountMinor/10**$.exponent)}catch{return`${$.amountMinor} ${$.currency}`}}function cK($,_){return[` - ${$.title}: ${n0($.remainingPercent)} remaining`,` (${n0($.usedPercent)} used`,`${Y_($.resetsAt,_)}, checked ${o0($.checkedAt,_)})`].join("")}function rK($){return $.label?.trim()||$.id}function sK($){return $.lastQuotaRefreshError?.message??$.lastRefreshError?.message}function Lj($,_=new Map){if(!$?.accounts.length)return[];return $.accounts.filter(k).map((C)=>{let K=_.get(C.id)??sK(C);return{name:rK(C),role:"fallback",enabled:C.enabled!==!1,quota:C.quota,...J0(C.profile)&&{tierLabel:J0(C.profile)},lastRefreshedAt:C.lastRefreshedAt,...K&&{error:K}}})}function Uj($){let _=$.now??Date.now(),C=["## Claude Quotas",""];if($.refreshedAt)C.push(`Refreshed: ${o0($.refreshedAt,_)}`,"");if(!$.accounts.length)return C.push("No Claude OAuth accounts found yet."),C.join(`
|
|
48
|
+
`);for(let K of $.accounts){let G=K.role==="main"?"main":"fallback",j=K.enabled===!1?" disabled":"";if(C.push(`### ${K.name} (${G}${j})`),K.tierLabel)C.push(` - Tier: ${K.tierLabel}`);if(K.lastRefreshedAt)C.push(` - Last token refresh: ${o0(K.lastRefreshedAt,_)}`);if(K.error)C.push(` - Error: ${K.error}`);C.push(O_("five_hour",K.quota?.five_hour,_,K.quota?.bindingWindow)),C.push(O_("seven_day",K.quota?.seven_day,_,K.quota?.bindingWindow));for(let Z of K.quota?.scoped??[]){let z=cK(Z,_);C.push(K.quota?.bindingWindow===Z.id?`${z} •`:z)}let J=K.quota?.extraUsage;if(J){let Z=X_(J.used),z=X_(J.limit);C.push(` - credits ${Z}/${z}${J.exhausted?" · exhausted":""}`)}if(K.quota?.fallbackAdvised===!0)C.push(" - → fallback advised");C.push("")}return C.join(`
|
|
49
|
+
`).trimEnd()}import{Buffer as E_}from"node:buffer";import{createHash as nK,randomBytes as oK}from"node:crypto";class h$ extends Error{}class T$ extends Error{code="ECONNRESET";syscall="websocket";closeCode;closeReason;wasClean;constructor($,_){super($);this.name="RelayWebSocketConnectionResetError",this.closeCode=_?.code,this.closeReason=_?.reason,this.wasClean=_?.wasClean}}var v=new Map,t=new Map,N_=new Set,aK=7200000,tK=1800000,eK=128,$G=32,L_=0;function I$(){return L_+=1,`req_${Date.now().toString(36)}_${L_.toString(36)}`}function a0($){if(N_.has($))return;N_.add($),f($)}function Vj($){let _=$?.relay;if(!_)return a0("disabled: no relay config found"),null;if(_.enabled!==!0)return a0("disabled: relay.enabled is not true"),null;if(!_.url?.trim()||!_.token?.trim())return a0("disabled: missing relay url or token"),null;let C=_.transport==="http"?"http":"websocket";return a0(`configured transport=${C} protocol=${C==="websocket"?2:1} url=${_.url.trim()} fallbackToDirect=${_.fallbackToDirect!==!1}`),{enabled:!0,url:_.url.trim(),token:_.token.trim(),fallbackToDirect:_.fallbackToDirect!==!1,transport:C}}function fj(){return oK(32).toString("base64url")}function _G($){return`sha256:${nK("sha256").update($).digest("hex")}`}function U_($,_){let C=0,K=Math.min($.length,_.length);while(C<K&&$.charCodeAt(C)===_.charCodeAt(C))C++;let G=$.length,j=_.length;while(G>C&&j>C&&$.charCodeAt(G-1)===_.charCodeAt(j-1))G--,j--;return{start:C,deleteCount:G-C,insert:_.slice(C,j)}}function CG($){return $.deleteCount===0&&$.insert.length===0}function W_($){let _=$.match(/\bcch=([0-9a-f]{5});/),C=_?.[1];if(!C||_.index==null)return null;let K=_.index+4;return{start:K,end:K+C.length,token:C}}function KG($,_,C,K){return`${$.slice(0,_)}${K}${$.slice(C)}`}function V_($,_){let C=W_($),K=W_(_);if(C&&K&&C.start===K.start&&C.end-C.start===K.end-K.start&&C.token!==K.token){let G={start:C.start,deleteCount:C.end-C.start,insert:K.token},j=KG($,C.start,C.end,K.token),J=U_(j,_);return CG(J)?G:[G,J]}return U_($,_)}function GG($,_){if(typeof _!=="string")return!1;try{let C=$ instanceof Request?new URL($.url):new URL($.toString());return C.pathname==="/v1/messages"||C.pathname==="/messages"}catch{return!1}}function jG($){let _={};for(let[C,K]of $.entries()){if(C==="x-session-affinity"||C==="x-opencode-session")continue;_[C]=K}return _}async function H_($,_,C){let K=Q(),G=JSON.stringify(_);return O0("http_payload_stringify",{session:B(_.affinity),ms:h(Q()-K),relayBytes:G.length,mode:_.mode}),fetch($.url,{method:"POST",headers:{"content-type":"application/json","x-relay-token":$.token},body:G,signal:C??void 0})}function B($){return $.length>12?`${$.slice(0,12)}…`:$}function Q(){return performance.now()}function h($){return Math.round($*10)/10}function JG(){return process.env.OPENCODE_ANTHROPIC_AUTH_PERF==="1"}function O0($,_){if(!JG())return;f(`[perf] relay ${$} ${JSON.stringify(_)}`)}function ZG($){let{input:_,init:C,headers:K,bodyText:G,affinity:j,previous:J,nextHash:Z}=$,z=_ instanceof Request?_.url:_.toString(),O={protocol:1,type:"request",affinity:j,upstream:{url:z,method:C?.method||(_ instanceof Request?_.method:"POST"),headers:jG(K)},next_hash:Z};return J?{...O,mode:"patch",base_hash:J.hash,revision:J.revision+1,patch:V_(J.body,G)}:{...O,mode:"full_sync",revision:1,body:G}}function w$($,_){return{protocol:$.protocol,type:"request",affinity:$.affinity,upstream:$.upstream,next_hash:$.next_hash,mode:"full_sync",revision:1,body:_}}function f_($,_,C,K){let G=Date.now();v.delete($),v.set($,{body:_,hash:C,revision:K,updatedAt:G}),x$(G)}async function F_($){let{config:_,payload:C,bodyText:K,fallback:G,signal:j}=$,J=C,Z=await H_(_,J,j);if(Z.status===409&&J.mode==="patch")f(`state mismatch from relay session=${B(J.affinity)}; retrying full_sync`),await Z.body?.cancel().catch(()=>{}),J=w$(J,K),Z=await H_(_,J,j);if(!Z.ok&&Z.status>=500&&_.fallbackToDirect)return f(`relay returned ${Z.status}; falling back direct session=${B(J.affinity)}`),await Z.body?.cancel().catch(()=>{}),{response:await G(),payload:J,transport:"http",protocol:J.protocol,usedRelay:!1};return{response:Z,payload:J,transport:"http",protocol:J.protocol,usedRelay:!0}}function zG($,_){let C=new URL($);return C.protocol=C.protocol==="http:"?"ws:":"wss:",C.pathname="/ws",C.searchParams.set("token",_),C.toString()}function OG($){return new Uint8Array(E_.from($,"base64"))}function XG($){if($ instanceof Uint8Array)return $;if($ instanceof ArrayBuffer)return new Uint8Array($);if(ArrayBuffer.isView($))return new Uint8Array($.buffer,$.byteOffset,$.byteLength);return new Uint8Array(E_.from(String($)))}function YG($){return JSON.parse($)}function M_($){let _=$,C=[`code=${_.code??"unknown"}`,`wasClean=${_.wasClean??"unknown"}`];if(_.reason)C.push(`reason=${JSON.stringify(_.reason)}`);return C.join(" ")}function NG($){let _=$.message||"relay websocket error";return $.status?`relay websocket error ${$.status}: ${_}`:_}class b_{config;affinity;socket;connecting;queue=Promise.resolve();pending;serverState;lastUsedAt=Date.now();constructor($,_){this.config=$,this.affinity=_}touch($=Date.now()){this.lastUsedAt=$}canEvict($=Date.now()){return!this.pending&&!this.connecting&&$-this.lastUsedAt>tK}dispose(){this.socket?.close(),this.socket=void 0,this.serverState=void 0,this.connecting=void 0}send($,_,C=!1,K){this.touch();let G=Q(),j=this.queue.catch(()=>{}).then(()=>this.startQueued($,_,G,C,K)),J=j.then(async({response:Z,getPayload:z})=>({response:await Z,payload:z(),transport:"websocket",protocol:2,usedRelay:!0}));return this.queue=j.then(({done:Z})=>Z.catch(()=>{}),()=>{}),J}async startQueued($,_,C,K,G){let j=Q();await this.ensureConnected();let J=Q(),Z=v.get(this.affinity),z=this.serverState?.hash,O={...$,protocol:2,id:I$()};if(O.mode==="patch"&&(!z||z!==O.base_hash))O.mode="full_sync",O.revision=(this.serverState?.revision??0)+1,delete O.base_hash,delete O.patch,O.body=_;if(O.mode==="patch"&&Z)O.patch=V_(Z.body,_);f(`perf websocket send_start session=${B(this.affinity)} request=${O.id} mode=${O.mode} queueMs=${h(J-C)} connectMs=${h(J-j)} bodyBytes=${_.length} relayBytes=${JSON.stringify(O).length}`);let X=O,Y=this.sendPayload(O,_,K,G);Y.done.catch(()=>{});let L=Y.done,U=Y.response.catch((M)=>{if(!(M instanceof h$)||O.mode!=="patch")throw M;let b=w$(O,_);b.protocol=2,b.id=I$(),b.revision=(this.serverState?.revision??0)+1,X=b;let N=this.sendPayload(b,_,K,G);return N.done.catch(()=>{}),L=N.done,N.response}),H=U.then(()=>L,()=>L.catch(()=>{}));return{response:U,done:H,getPayload:()=>X}}async ensureConnected(){if(this.socket?.readyState===WebSocket.OPEN&&this.serverState!==void 0)return;if(this.connecting)return await this.connecting;this.connecting=new Promise(($,_)=>{let C=zG(this.config.url,this.config.token),K=new URL(C);K.searchParams.set("affinity",this.affinity);let G=new WebSocket(K.toString());this.socket=G,this.serverState=void 0;let j=setTimeout(()=>{G.close(),_(Error("relay websocket ready timed out"))},15000);G.addEventListener("message",(J)=>{try{if(typeof J.data!=="string"){this.handleBinaryChunk(J.data);return}let Z=YG(J.data);if(Z.type==="ready"){clearTimeout(j),this.serverState=Z.state,$();return}this.handleMessage(Z)}catch(Z){clearTimeout(j),_(Z),this.failPending(Z),G.close()}}),G.addEventListener("error",()=>{clearTimeout(j);let J=new T$("relay websocket error");_(J),this.failPending(J)}),G.addEventListener("close",(J)=>{if(clearTimeout(j),this.socket===G)this.socket=void 0,this.serverState=void 0,this.connecting=void 0;if(this.pending){if(this.pending.retryingBeforeResponse)return;let Z=this.pending.responseStartedAt!=null,z=Z?"closed after response_start before stream bytes":"closed before response";if(this.retryPendingBeforeResponse(this.pending,z,J))return;let O=Z?new T$("relay websocket closed during response stream",J):Error("relay websocket closed before response");f(`websocket ${Z?"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} ${M_(J)}`),this.failPending(O)}})}).finally(()=>{this.connecting=void 0}),await this.connecting}sendPayload($,_,C,K){let G=this.socket;if(!G||G.readyState!==WebSocket.OPEN)throw Error("relay websocket is not connected");let j=Q(),J,Z,z=new Promise((X,Y)=>{J=X,Z=Y});return{response:new Promise((X,Y)=>{let L={payload:$,bodyText:_,resolve:X,reject:Y,streamDone:!1,accepted:!1,responseStarted:!1,resolveDone:J,rejectDone:Z,sentAt:j,optimisticResponse:C,streamChunkCount:0,streamByteCount:0,retryAttempts:0,retryingBeforeResponse:!1,onResponseHeaders:K,stagedResponseHeaders:void 0,responseHeadersDelivered:!1};if(this.pending=L,this.resetPendingTimeout(L),G.send(JSON.stringify($)),C)this.resolvePendingResponse(L,200,"OK",{"content-type":"text/event-stream","x-cortexkit-relay-optimistic":"true"})}),done:z}}resetPendingTimeout($){clearTimeout($.timeout),$.timeout=setTimeout(()=>{if(this.pending!==$)return;if(this.retryPendingBeforeResponse($,"response timed out"))return;this.failPending(Error("relay websocket response timed out")),this.socket?.close()},45000)}retryPendingBeforeResponse($,_,C){if($.responseStartedAt!=null&&$.streamByteCount>0)return!1;if($.streamDone)return!1;if($.retryAttempts>=1)return!1;$.retryAttempts+=1,$.retryingBeforeResponse=!0,clearTimeout($.timeout);let K=$.retryAttempts,G=$.payload.id;return f(`websocket ${_}; reconnecting and retrying full_sync session=${B(this.affinity)} request=${G} retry=${K} chunks=${$.streamChunkCount} bytes=${$.streamByteCount}${C?` ${M_(C)}`:""}`),this.socket?.close(),this.socket=void 0,this.serverState=void 0,this.connecting=void 0,(async()=>{try{if(await this.ensureConnected(),this.pending!==$)return;let j=w$($.payload,$.bodyText);j.protocol=2,j.id=I$(),j.revision=(this.serverState?.revision??0)+1,$.payload=j,$.accepted=!1,$.acceptedAt=void 0,$.responseStartedAt=void 0,$.stagedResponseHeaders=void 0,$.responseHeadersDelivered=!1,$.sentAt=Q(),$.retryingBeforeResponse=!1;let J=this.socket;if(!J||J.readyState!==WebSocket.OPEN)throw Error("relay websocket is not connected");this.resetPendingTimeout($),f(`perf websocket retry_send session=${B(this.affinity)} request=${j.id} previous=${G} mode=full_sync retry=${K} bodyBytes=${$.bodyText.length} relayBytes=${JSON.stringify(j).length}`),J.send(JSON.stringify(j))}catch(j){if($.retryingBeforeResponse=!1,this.pending===$)this.failPending(j)}})(),!0}enqueueStreamChunk($,_){this.deliverResponseHeaders($),$.streamChunkCount+=1,$.streamByteCount+=_.byteLength,$.streamController?.enqueue(_)}deliverResponseHeaders($){if($.responseHeadersDelivered||$.stagedResponseHeaders==null)return;$.responseHeadersDelivered=!0;try{$.onResponseHeaders?.($.stagedResponseHeaders)}catch{}}handleBinaryChunk($){let _=this.pending;if(!_?.responseStarted)return;this.enqueueStreamChunk(_,XG($))}resolvePendingResponse($,_,C,K){if($.responseStarted)return;$.responseStarted=!0;let G=new ReadableStream({start:(j)=>{$.streamController=j},cancel:()=>{this.socket?.close()}});$.resolve(new Response(G,{status:_,statusText:C,headers:K}))}handleMessage($){if($.type==="keepalive"){if(this.pending)this.resetPendingTimeout(this.pending);return}let _=this.pending;if(!_)return;if("id"in $&&$.id&&$.id!==_.payload.id)return;if($.type==="accepted"){let C=Q();_.accepted=!0,_.acceptedAt=C,f(`perf websocket accepted session=${B(this.affinity)} request=${_.payload.id} sentMs=${h(C-_.sentAt)} mode=${_.payload.mode}`),this.serverState={hash:$.hash,revision:$.revision},f_(this.affinity,_.bodyText,$.hash,$.revision),this.resetPendingTimeout(_);return}if($.type==="response_start"){if(_.responseStartedAt!=null)return;let C=Q();if(_.responseStartedAt=C,f(`perf websocket response_start session=${B(this.affinity)} request=${_.payload.id} sentMs=${h(C-_.sentAt)} upstreamMs=${_.acceptedAt==null?"unknown":h(C-_.acceptedAt)} status=${$.status}`),clearTimeout(_.timeout),$.headers)_.stagedResponseHeaders=new Headers($.headers);if(this.resolvePendingResponse(_,$.status,$.statusText,$.headers),_.optimisticResponse&&$.status>=400)this.deliverResponseHeaders(_),_.streamController?.enqueue(new TextEncoder().encode(`event: error
|
|
50
|
+
data: ${JSON.stringify({type:"error",error:{type:"relay_upstream_error",message:`Relay upstream returned HTTP ${$.status}`}})}
|
|
51
|
+
|
|
52
|
+
`)),this.finishPending();return}if($.type==="chunk"){this.enqueueStreamChunk(_,OG($.base64));return}if($.type==="done"){this.finishPending($);return}if($.type==="error"){if(_.optimisticResponse&&_.responseStartedAt!=null){f(`websocket relay error during optimistic response session=${B(this.affinity)} request=${_.payload.id} status=${$.status} message=${$.message||"unknown"} chunks=${_.streamChunkCount} bytes=${_.streamByteCount}`),this.deliverResponseHeaders(_),_.streamController?.enqueue(new TextEncoder().encode(`event: error
|
|
53
|
+
data: ${JSON.stringify({type:"error",error:{type:"relay_error",message:$.message||"relay error"}})}
|
|
54
|
+
|
|
55
|
+
`)),this.finishPending(),this.socket?.close();return}if($.status===409&&this.retryPendingBeforeResponse(_,$.message||"state mismatch"))return;let C=$.status===409?new h$($.message||"state mismatch"):Error(NG($));this.failPending(C)}}finishPending($){let _=this.pending;if(!_)return;let C=Q(),K=$&&"frames"in $?` upstreamChunks=${$.upstreamChunks??"unknown"} upstreamBytes=${$.upstreamBytes??"unknown"} frames=${$.frames} frameBytes=${$.frameBytes??"unknown"}`:"";if(f(`perf websocket done session=${B(this.affinity)} request=${_.payload.id} sentMs=${h(C-_.sentAt)} streamMs=${_.responseStartedAt==null?"unknown":h(C-_.responseStartedAt)} chunks=${_.streamChunkCount} bytes=${_.streamByteCount}${K}`),clearTimeout(_.timeout),!_.streamDone)this.deliverResponseHeaders(_),_.streamDone=!0,_.streamController?.close();_.resolveDone(),this.pending=void 0}failPending($){let _=this.pending;if(!_)return;if(clearTimeout(_.timeout),this.pending=void 0,_.responseStarted)_.streamController?.error($);else _.reject($);_.rejectDone($)}}function x$($=Date.now()){for(let[_,C]of v)if($-C.updatedAt>aK)v.delete(_);while(v.size>eK){let _=v.keys().next().value;if(_===void 0)break;v.delete(_)}for(let[_,C]of t)if(C.canEvict($))C.dispose(),t.delete(_);while(t.size>$G){let _=!1;for(let[C,K]of t){if(!K.canEvict($))continue;K.dispose(),t.delete(C),_=!0;break}if(!_)break}}function LG($,_){x$();let C=t.get(_);if(C)return C.touch(),C;let K=new b_($,_);return t.set(_,K),x$(),K}async function bj($){let{config:_,input:C,init:K,headers:G,body:j,fallback:J,affinity:Z,optimisticResponse:z,onResponseHeaders:O}=$;if(!_||!GG(C,j))return J();let X=Z||G.get("x-session-affinity")||G.get("x-opencode-session");if(!X)return f("skipping relay: missing x-session-affinity header"),J();let Y=j,L=Q(),U=_G(Y);O0("hash_body",{session:B(X),ms:h(Q()-L),bodyBytes:Y.length});let H=v.get(X),M=Q(),b=ZG({input:C,init:K,headers:G,bodyText:Y,affinity:X,previous:H,nextHash:U});O0("create_payload",{session:B(X),ms:h(Q()-M),mode:b.mode,bodyBytes:Y.length,previousBytes:H?.body.length});try{let N,x=Q();if(_.transport==="websocket")try{N=await LG(_,X).send(b,Y,z===!0,O)}catch(E){f(`websocket relay failed session=${B(X)}; trying http relay: ${E instanceof Error?E.message:String(E)}`),N=await F_({config:_,payload:b,bodyText:Y,fallback:J,signal:K?.signal})}else N=await F_({config:_,payload:b,bodyText:Y,fallback:J,signal:K?.signal});if(O0("send",{session:B(X),ms:h(Q()-x),transport:N.transport,protocol:N.protocol,mode:N.payload.mode,status:N.response.status,usedRelay:N.usedRelay}),!N.usedRelay)return N.response;if(N.transport==="http")try{O?.(N.response.headers)}catch{}if(N.transport==="http")f_(X,Y,N.payload.next_hash,N.payload.revision);let u=Q(),T=JSON.stringify(N.payload).length;O0("payload_stringify",{session:B(X),ms:h(Q()-u),relayBytes:T}),f(`used relay transport=${N.transport} protocol=${N.protocol} mode=${N.payload.mode} status=${N.response.status} session=${B(X)} bodyBytes=${Y.length} relayBytes=${T}`);let W=Q();return await G_({affinity:X,transport:N.transport,protocol:N.protocol,mode:N.payload.mode,status:N.response.status,bodyText:Y,previousBodyText:H?.body,payload:N.payload,relayBytes:T}),O0("dump",{session:B(X),ms:h(Q()-W),enabled:!0}),N.response}catch(N){if(!_.fallbackToDirect)throw f(`relay failed session=${B(X)} and fallbackToDirect=false: ${N instanceof Error?N.message:String(N)}`),N;return f(`relay failed; falling back direct session=${B(X)}: ${N instanceof Error?N.message:String(N)}`),J()}}var Qj=`
|
|
56
|
+
async function hashBody(body) {
|
|
57
|
+
const bytes = new TextEncoder().encode(body)
|
|
58
|
+
const digest = await crypto.subtle.digest('SHA-256', bytes)
|
|
59
|
+
const hex = [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, '0')).join('')
|
|
60
|
+
return 'sha256:' + hex
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function applyPatch(base, patch) {
|
|
64
|
+
return base.slice(0, patch.start) + patch.insert + base.slice(patch.start + patch.deleteCount)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function applyPatchSet(base, patch) {
|
|
68
|
+
if (!Array.isArray(patch)) return applyPatch(base, patch)
|
|
69
|
+
if (patch.length === 0) return base
|
|
70
|
+
|
|
71
|
+
let result = ''
|
|
72
|
+
let cursor = 0
|
|
73
|
+
for (const item of patch) {
|
|
74
|
+
if (item.start < cursor) return { error: 'overlapping patch', status: 400 }
|
|
75
|
+
result += base.slice(cursor, item.start)
|
|
76
|
+
result += item.insert
|
|
77
|
+
cursor = item.start + item.deleteCount
|
|
78
|
+
}
|
|
79
|
+
return result + base.slice(cursor)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function readState(env, affinity) {
|
|
83
|
+
const raw = await env.RELAY_STATE.get('session:' + affinity)
|
|
84
|
+
return raw ? JSON.parse(raw) : null
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function writeState(env, affinity, state) {
|
|
88
|
+
await env.RELAY_STATE.put('session:' + affinity, JSON.stringify(state), { expirationTtl: 86400 })
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function resolveBody(env, payload) {
|
|
92
|
+
if (payload.mode === 'full_sync') return payload.body
|
|
93
|
+
if (payload.mode === 'patch') {
|
|
94
|
+
const state = await readState(env, payload.affinity)
|
|
95
|
+
if (!state || state.hash !== payload.base_hash) {
|
|
96
|
+
return { error: 'state mismatch', status: 409 }
|
|
97
|
+
}
|
|
98
|
+
return applyPatchSet(state.body, payload.patch)
|
|
99
|
+
}
|
|
100
|
+
return { error: 'unknown mode', status: 400 }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function prepareUpstream(env, payload) {
|
|
104
|
+
if ((payload.protocol !== 1 && payload.protocol !== 2) || payload.type !== 'request' || !payload.affinity || !payload.upstream?.url || !payload.next_hash) {
|
|
105
|
+
return { error: 'invalid payload', status: 400 }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const body = await resolveBody(env, payload)
|
|
109
|
+
if (body && typeof body === 'object' && 'error' in body) return body
|
|
110
|
+
|
|
111
|
+
if (typeof body !== 'string' || (await hashBody(body)) !== payload.next_hash) {
|
|
112
|
+
return { error: 'hash mismatch', status: 409 }
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const stateWrite = writeState(env, payload.affinity, { body, hash: payload.next_hash, revision: payload.revision }).catch(() => {})
|
|
116
|
+
console.log(JSON.stringify({
|
|
117
|
+
relay: 'opencode-anthropic-auth',
|
|
118
|
+
transport: 'relay',
|
|
119
|
+
mode: payload.mode,
|
|
120
|
+
revision: payload.revision,
|
|
121
|
+
affinity: String(payload.affinity).slice(0, 12),
|
|
122
|
+
bodyBytes: body.length,
|
|
123
|
+
}))
|
|
124
|
+
|
|
125
|
+
return { body, stateWrite }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function resolveBodyFromState(state, payload) {
|
|
129
|
+
if (payload.mode === 'full_sync') return payload.body
|
|
130
|
+
if (payload.mode === 'patch') {
|
|
131
|
+
if (!state || state.hash !== payload.base_hash) {
|
|
132
|
+
return { error: 'state mismatch', status: 409 }
|
|
133
|
+
}
|
|
134
|
+
return applyPatchSet(state.body, payload.patch)
|
|
135
|
+
}
|
|
136
|
+
return { error: 'unknown mode', status: 400 }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function deferWorkerTask(task) {
|
|
140
|
+
return new Promise((resolve) => setTimeout(resolve, 0)).then(task)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const WEBSOCKET_STREAM_FLUSH_BYTES = 1024
|
|
144
|
+
const WEBSOCKET_STREAM_FLUSH_MS = 20
|
|
145
|
+
|
|
146
|
+
function createWebSocketStreamCoalescer(socket, options = {}) {
|
|
147
|
+
const flushBytes = options.flushBytes || WEBSOCKET_STREAM_FLUSH_BYTES
|
|
148
|
+
const flushMs = options.flushMs ?? WEBSOCKET_STREAM_FLUSH_MS
|
|
149
|
+
let chunks = []
|
|
150
|
+
let byteLength = 0
|
|
151
|
+
let flushTimer = null
|
|
152
|
+
const stats = {
|
|
153
|
+
upstreamChunks: 0,
|
|
154
|
+
upstreamBytes: 0,
|
|
155
|
+
frames: 0,
|
|
156
|
+
frameBytes: 0,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const clearFlushTimer = () => {
|
|
160
|
+
if (flushTimer === null) return
|
|
161
|
+
clearTimeout(flushTimer)
|
|
162
|
+
flushTimer = null
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const mergeChunks = () => {
|
|
166
|
+
if (chunks.length === 1) return chunks[0]
|
|
167
|
+
const frame = new Uint8Array(byteLength)
|
|
168
|
+
let offset = 0
|
|
169
|
+
for (const chunk of chunks) {
|
|
170
|
+
frame.set(chunk, offset)
|
|
171
|
+
offset += chunk.byteLength
|
|
172
|
+
}
|
|
173
|
+
return frame
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const flush = () => {
|
|
177
|
+
clearFlushTimer()
|
|
178
|
+
if (byteLength === 0) return
|
|
179
|
+
const frame = mergeChunks()
|
|
180
|
+
chunks = []
|
|
181
|
+
byteLength = 0
|
|
182
|
+
socket.send(frame)
|
|
183
|
+
stats.frames += 1
|
|
184
|
+
stats.frameBytes += frame.byteLength
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const scheduleFlush = () => {
|
|
188
|
+
if (flushTimer !== null) return
|
|
189
|
+
flushTimer = setTimeout(flush, flushMs)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
push(value) {
|
|
194
|
+
const chunk = value instanceof Uint8Array ? value : new Uint8Array(value)
|
|
195
|
+
if (chunk.byteLength === 0) return
|
|
196
|
+
stats.upstreamChunks += 1
|
|
197
|
+
stats.upstreamBytes += chunk.byteLength
|
|
198
|
+
chunks.push(chunk)
|
|
199
|
+
byteLength += chunk.byteLength
|
|
200
|
+
if (byteLength >= flushBytes) flush()
|
|
201
|
+
else scheduleFlush()
|
|
202
|
+
},
|
|
203
|
+
flush,
|
|
204
|
+
stats() {
|
|
205
|
+
return { ...stats, pendingBytes: byteLength }
|
|
206
|
+
},
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function checkpointWebSocketState(env, payload, body, nextState) {
|
|
211
|
+
return deferWorkerTask(async () => {
|
|
212
|
+
try {
|
|
213
|
+
if ((await hashBody(body)) !== payload.next_hash) {
|
|
214
|
+
throw new Error('hash mismatch')
|
|
215
|
+
}
|
|
216
|
+
await writeState(env, payload.affinity, nextState)
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.log(JSON.stringify({
|
|
219
|
+
relay: 'opencode-anthropic-auth',
|
|
220
|
+
transport: 'websocket',
|
|
221
|
+
event: 'checkpoint_write_failed',
|
|
222
|
+
affinity: String(payload.affinity).slice(0, 12),
|
|
223
|
+
message: error instanceof Error ? error.message : String(error),
|
|
224
|
+
}))
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async function prepareWebSocketUpstream(env, state, payload) {
|
|
230
|
+
if (payload.protocol !== 2 || payload.type !== 'request' || !payload.id || !payload.affinity || !payload.upstream?.url || !payload.next_hash) {
|
|
231
|
+
return { error: 'invalid payload', status: 400 }
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const body = resolveBodyFromState(state, payload)
|
|
235
|
+
if (body && typeof body === 'object' && 'error' in body) return body
|
|
236
|
+
if (typeof body !== 'string') return { error: 'invalid body', status: 400 }
|
|
237
|
+
if ((await hashBody(body)) !== payload.next_hash) {
|
|
238
|
+
return { error: 'hash mismatch', status: 409 }
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const nextState = { body, hash: payload.next_hash, revision: payload.revision }
|
|
242
|
+
const checkpoint = checkpointWebSocketState(env, payload, body, nextState)
|
|
243
|
+
const logAccepted = () => console.log(JSON.stringify({
|
|
244
|
+
relay: 'opencode-anthropic-auth',
|
|
245
|
+
transport: 'websocket',
|
|
246
|
+
mode: payload.mode,
|
|
247
|
+
revision: payload.revision,
|
|
248
|
+
affinity: String(payload.affinity).slice(0, 12),
|
|
249
|
+
bodyBytes: body.length,
|
|
250
|
+
}))
|
|
251
|
+
|
|
252
|
+
return { body, state: nextState, checkpoint, logAccepted }
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function headersToObject(headers) {
|
|
256
|
+
const result = {}
|
|
257
|
+
for (const [key, value] of headers.entries()) result[key] = value
|
|
258
|
+
return result
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async function handleRelayPayload(env, payload) {
|
|
262
|
+
const prepared = await prepareUpstream(env, payload)
|
|
263
|
+
if (prepared.error) return prepared
|
|
264
|
+
const upstream = await fetch(payload.upstream.url, {
|
|
265
|
+
method: payload.upstream.method || 'POST',
|
|
266
|
+
headers: payload.upstream.headers,
|
|
267
|
+
body: prepared.body,
|
|
268
|
+
})
|
|
269
|
+
return { upstream, stateWrite: prepared.stateWrite }
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async function handleWebSocket(socket, env, ctx, payload, getState, setState) {
|
|
273
|
+
const heartbeat = setInterval(() => {
|
|
274
|
+
try {
|
|
275
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'keepalive' }))
|
|
276
|
+
} catch {
|
|
277
|
+
clearInterval(heartbeat)
|
|
278
|
+
}
|
|
279
|
+
}, 15000)
|
|
280
|
+
let streamCoalescer = null
|
|
281
|
+
try {
|
|
282
|
+
const result = await prepareWebSocketUpstream(env, getState(), payload)
|
|
283
|
+
if (result.error) {
|
|
284
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'error', id: payload.id, status: result.status, message: result.error }))
|
|
285
|
+
return
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
setState(result.state)
|
|
289
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'accepted', id: payload.id, hash: result.state.hash, revision: result.state.revision }))
|
|
290
|
+
ctx?.waitUntil?.(deferWorkerTask(result.logAccepted))
|
|
291
|
+
|
|
292
|
+
const upstreamPromise = fetch(payload.upstream.url, {
|
|
293
|
+
method: payload.upstream.method || 'POST',
|
|
294
|
+
headers: payload.upstream.headers,
|
|
295
|
+
body: result.body,
|
|
296
|
+
})
|
|
297
|
+
ctx?.waitUntil?.(result.checkpoint)
|
|
298
|
+
const upstream = await upstreamPromise
|
|
299
|
+
socket.send(JSON.stringify({
|
|
300
|
+
protocol: 2,
|
|
301
|
+
type: 'response_start',
|
|
302
|
+
id: payload.id,
|
|
303
|
+
status: upstream.status,
|
|
304
|
+
statusText: upstream.statusText,
|
|
305
|
+
headers: headersToObject(upstream.headers),
|
|
306
|
+
}))
|
|
307
|
+
|
|
308
|
+
const reader = upstream.body?.getReader()
|
|
309
|
+
if (reader) {
|
|
310
|
+
streamCoalescer = createWebSocketStreamCoalescer(socket)
|
|
311
|
+
while (true) {
|
|
312
|
+
const { done, value } = await reader.read()
|
|
313
|
+
if (done) break
|
|
314
|
+
streamCoalescer.push(value)
|
|
315
|
+
}
|
|
316
|
+
streamCoalescer.flush()
|
|
317
|
+
}
|
|
318
|
+
const stats = streamCoalescer?.stats?.() || {}
|
|
319
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'done', id: payload.id, ...stats }))
|
|
320
|
+
} catch (error) {
|
|
321
|
+
try {
|
|
322
|
+
streamCoalescer?.flush?.()
|
|
323
|
+
} catch {}
|
|
324
|
+
socket.send(JSON.stringify({ protocol: 2, type: 'error', id: payload.id, status: 500, message: error instanceof Error ? error.message : String(error) }))
|
|
325
|
+
} finally {
|
|
326
|
+
clearInterval(heartbeat)
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export default {
|
|
331
|
+
async fetch(request, env, ctx) {
|
|
332
|
+
if (request.headers.get('Upgrade') === 'websocket') {
|
|
333
|
+
const url = new URL(request.url)
|
|
334
|
+
const token = url.searchParams.get('token')
|
|
335
|
+
const affinity = url.searchParams.get('affinity')
|
|
336
|
+
if (token !== env.RELAY_TOKEN) return new Response('unauthorized', { status: 401 })
|
|
337
|
+
if (!affinity) return new Response('missing affinity', { status: 400 })
|
|
338
|
+
const pair = new WebSocketPair()
|
|
339
|
+
const client = pair[0]
|
|
340
|
+
const server = pair[1]
|
|
341
|
+
server.binaryType = 'arraybuffer'
|
|
342
|
+
let state = null
|
|
343
|
+
let ready = false
|
|
344
|
+
server.accept()
|
|
345
|
+
const loadState = readState(env, affinity).then((loadedState) => {
|
|
346
|
+
state = loadedState
|
|
347
|
+
ready = true
|
|
348
|
+
server.send(JSON.stringify({
|
|
349
|
+
protocol: 2,
|
|
350
|
+
type: 'ready',
|
|
351
|
+
state: state ? { hash: state.hash, revision: state.revision } : null,
|
|
352
|
+
}))
|
|
353
|
+
}).catch((error) => {
|
|
354
|
+
server.send(JSON.stringify({ protocol: 2, type: 'error', status: 500, message: error instanceof Error ? error.message : String(error) }))
|
|
355
|
+
server.close(1011, 'state load failed')
|
|
356
|
+
})
|
|
357
|
+
ctx?.waitUntil?.(loadState)
|
|
358
|
+
if (!ctx?.waitUntil) void loadState
|
|
359
|
+
let busy = false
|
|
360
|
+
server.addEventListener('message', (event) => {
|
|
361
|
+
if (!ready) {
|
|
362
|
+
server.send(JSON.stringify({ protocol: 2, type: 'error', status: 425, message: 'relay state is not ready' }))
|
|
363
|
+
return
|
|
364
|
+
}
|
|
365
|
+
if (busy) {
|
|
366
|
+
server.send(JSON.stringify({ protocol: 2, type: 'error', status: 429, message: 'request already in flight' }))
|
|
367
|
+
return
|
|
368
|
+
}
|
|
369
|
+
let payload
|
|
370
|
+
try {
|
|
371
|
+
payload = JSON.parse(event.data)
|
|
372
|
+
} catch {
|
|
373
|
+
server.send(JSON.stringify({ protocol: 2, type: 'error', status: 400, message: 'invalid JSON payload' }))
|
|
374
|
+
return
|
|
375
|
+
}
|
|
376
|
+
payload.affinity = affinity
|
|
377
|
+
busy = true
|
|
378
|
+
const run = handleWebSocket(server, env, ctx, payload, () => state, (nextState) => { state = nextState }).finally(() => { busy = false })
|
|
379
|
+
ctx?.waitUntil?.(run)
|
|
380
|
+
if (!ctx?.waitUntil) void run
|
|
381
|
+
})
|
|
382
|
+
return new Response(null, { status: 101, webSocket: client })
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (request.method === 'GET') {
|
|
386
|
+
return Response.json({ status: 'ok', transports: ['http', 'websocket'] })
|
|
387
|
+
}
|
|
388
|
+
if (request.method !== 'POST') return new Response('method not allowed', { status: 405 })
|
|
389
|
+
if (request.headers.get('x-relay-token') !== env.RELAY_TOKEN) {
|
|
390
|
+
return new Response('unauthorized', { status: 401 })
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
try {
|
|
394
|
+
const payload = await request.json()
|
|
395
|
+
const result = await handleRelayPayload(env, payload)
|
|
396
|
+
if (result.error) return Response.json({ error: result.error }, { status: result.status })
|
|
397
|
+
|
|
398
|
+
if (result.stateWrite) ctx.waitUntil(result.stateWrite)
|
|
399
|
+
|
|
400
|
+
const upstream = result.upstream
|
|
401
|
+
return new Response(upstream.body, {
|
|
402
|
+
status: upstream.status,
|
|
403
|
+
statusText: upstream.statusText,
|
|
404
|
+
headers: upstream.headers,
|
|
405
|
+
})
|
|
406
|
+
} catch (error) {
|
|
407
|
+
return Response.json(
|
|
408
|
+
{ error: error instanceof Error ? error.message : 'internal relay error' },
|
|
409
|
+
{ status: 502 },
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
}
|
|
414
|
+
`;var Sj="claude-routing",k$=["main-first","fallback-first","sticky-balanced"],y$="main-first",Q_="Usage: `/claude-routing`, `/claude-routing main-first`, `/claude-routing fallback-first`, `/claude-routing sticky-balanced`, or `/claude-routing reset`.";function UG($){return typeof $==="string"&&k$.includes($)?$:y$}function Rj($){return UG($?.routing?.mode)}async function Aj($,_=V()){let C=await S(_)??I();return C.routing={...C.routing??{},mode:$},await R(C,_),C}function WG($){let _=$.trim().toLowerCase().split(/\s+/).filter(Boolean);if(_.length===0)return{type:"status"};if(_.length===1&&_[0]==="reset")return{type:"reset"};if(_.length===1&&k$.includes(_[0]))return{type:"mode",mode:_[0]};if(_.length===2&&_[0]==="mode"&&k$.includes(_[1]))return{type:"mode",mode:_[1]};return{type:"usage"}}function HG($){if($==="fallback-first")return"Try usable fallback accounts before the main account. If no fallback succeeds, try the main account.";if($==="sticky-balanced")return"Assign each session to a quota-weighted OAuth account, keep it sticky across transient failures, and migrate only for confirmed long-lived exhaustion or permanent account failure.";return"Try the main account first. Use fallback accounts only when quota policy or fallback errors require it."}function t0($){let _=$?.mode??y$;return["## Claude Routing Status","",`- Mode: \`${_}\``,`- Behavior: ${HG(_)}`,"",Q_].join(`
|
|
415
|
+
`)}function qj($){let _=WG($.argumentsText),C=$.mode??y$;if(_.type==="status")return t0({mode:C});if(_.type==="mode")return["## Claude Routing Updated","",`Mode updated to \`${_.mode}\`.`,"",...t0({mode:_.mode}).split(`
|
|
416
|
+
`).slice(2)].join(`
|
|
417
|
+
`);if(_.type==="reset")return["## Claude Routing Assignment Reset","","The current session will be assigned again on its next request.","",...t0({mode:C}).split(`
|
|
418
|
+
`).slice(2)].join(`
|
|
419
|
+
`);return["## Claude Routing Usage","",Q_,"",...t0({mode:C}).split(`
|
|
420
|
+
`).slice(2)].join(`
|
|
421
|
+
`)}import{createHash as h_,randomUUID as FG}from"node:crypto";import{mkdir as MG,readFile as EG,rename as VG,rm as fG,stat as bG,writeFile as QG}from"node:fs/promises";import{basename as BG,dirname as T_,join as DG}from"node:path";var SG="main",RG=900000,B_=604800000,AG=3600000,qG=1e4,PG=5000,IG=10,D_=4096,hG=0.000001;function m$($){return Boolean($)&&typeof $==="object"&&!Array.isArray($)}function V0($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function TG($){if(!m$($))return;if(typeof $.accountId!=="string"||!["fable","opus","general"].includes(String($.family)))return;let _=V0($.assignedAt),C=V0($.lastSeenAt),K=V0($.initialInputBytes),G=V0($.quotaCheckedAt);if(_===void 0||C===void 0||K===void 0||G===void 0)return;return{accountId:$.accountId,family:$.family,assignedAt:_,lastSeenAt:C,initialInputBytes:Math.max(0,K),quotaCheckedAt:G}}function wG($){if(!m$($)||$.version!==1||!m$($.assignments))return;let _={};for(let[C,K]of Object.entries($.assignments)){let G=TG(K);if(G)_[C]=G}return{version:1,updatedAt:V0($.updatedAt)??0,assignments:_}}function S_($){return{version:1,updatedAt:$,assignments:{}}}function R_($){return h_("sha256").update($).digest("hex")}function w_($,_,C=Date.now(),K){let G=m(_);if(!["five_hour","seven_day"].every((Z)=>{let z=$?.[Z];return Boolean(z&&C-z.checkedAt<G)}))return!1;let J=y($,K);return!J||C-J.checkedAt<G}function A_($){return Math.max($.checkedAt??0,$.five_hour?.checkedAt??0,$.seven_day?.checkedAt??0,...($.scoped??[]).map((_)=>_.checkedAt??0))}function q_($,_,C){let K=I0($),G=C==="five_hour"?K.five_hour:C==="seven_day"?K.seven_day:0;if(!H$($))return G;let j=F$($,_===SG?void 0:_);return Math.max(G,j[C])}function P_($,_,C,K){let G=Math.max(0,$-_);if(G<=0)return 0;if(!C)return G;let j=Date.parse(C);if(!Number.isFinite(j)||j<=K)return G;let J=Math.max((j-K)/3600000,0.016666666666666666);return G/J}function kj($){if(Z_($))return"fable";return typeof $==="string"&&$.toLowerCase().includes("opus")?"opus":"general"}function I_($){let _=$.now??Date.now(),{candidate:C,storage:K}=$;if(!w_(C.quota,K,_,$.modelId))return 0;let G=[];for(let j of["five_hour","seven_day"]){let J=C.quota[j];if(!J||!Number.isFinite(J.remainingPercent))return 0;G.push(P_(J.remainingPercent,q_(K,C.accountId,j),J.resetsAt,_))}if($.family==="fable"){let j=y(C.quota,$.modelId);if(j&&Number.isFinite(j.remainingPercent))G.push(P_(j.remainingPercent,q_(K,C.accountId,"scoped"),j.resetsAt,_))}return Math.min(...G)}function xG($,_,C=Date.now()){let K=y($.quota,"claude-fable-5");return Boolean(K&&w_($.quota,_,C,"claude-fable-5")&&Number.isFinite(K.remainingPercent)&&K.remainingPercent<=0)}function yj($){let _=$.now??Date.now();if(!$.quota)return{action:"retain",reason:"unknown"};let C=y($.quota,$.modelId);if(C&&Number.isFinite(C.remainingPercent)&&C.remainingPercent<=0)return{action:"migrate",reason:"model-scoped"};let K=$.quota.seven_day;if(K&&Number.isFinite(K.remainingPercent)&&K.remainingPercent<=0)return{action:"migrate",reason:"seven-day"};let G=$.quota.five_hour;if(G&&Number.isFinite(G.remainingPercent)&&G.remainingPercent<=0){let j=G.resetsAt?Date.parse(G.resetsAt):NaN;if(Number.isFinite(j)&&j>_&&j-_<=RG)return{action:"hold",reason:"five-hour-short-reset",retryAfterSeconds:Math.max(1,Math.ceil((j-_)/1000))};return{action:"migrate",reason:"five-hour"}}return{action:"retain",reason:"not-exhausted"}}function mj($){let _=BG($),C=_.endsWith(".json")?_.slice(0,-5):_;return DG(T_($),`${C}-routing-state.json`)}function vj($,_){let C=h_("sha256").update($).digest().readUInt32BE(0);return Math.max(1,Math.ceil(_))+C%21}class kG{options;loaded=!1;state;stateMtimeNs;touchChain=Promise.resolve();constructor($){this.options=$,this.state=S_(this.now())}now(){return this.options.now?.()??Date.now()}async readState(){try{let $=await EG(this.options.path,"utf8"),_=wG(JSON.parse($));if(!_)throw Error(`Invalid sticky routing state at ${this.options.path}`);return _}catch($){if($.code==="ENOENT")return S_(this.now());throw $}}async readStateMtimeNs(){try{return(await bG(this.options.path,{bigint:!0})).mtimeNs}catch($){if($.code==="ENOENT")return 0n;throw $}}async refreshStateIfChanged(){for(let $=0;$<3;$++){let _=await this.readStateMtimeNs();if(this.loaded&&_===this.stateMtimeNs)return;let C=await this.readState(),K=await this.readStateMtimeNs();if(_!==K)continue;this.state=C,this.stateMtimeNs=K,this.loaded=!0;return}this.state=await this.readState(),this.stateMtimeNs=await this.readStateMtimeNs(),this.loaded=!0}async acquireLock(){await MG(T_(this.options.path),{recursive:!0,mode:448});let $=this.now()+PG;while(!0){let _=await n({name:"write",path:this.options.path,ttlMs:qG,renew:!0});if(_)return _;if(this.now()>=$)throw Error("Timed out acquiring sticky routing state lock");await new Promise((C)=>setTimeout(C,IG))}}assignmentIsActive($){return $.lastSeenAt>=this.now()-(this.options.assignmentTtlMs??B_)}prune($){let _=this.now()-(this.options.assignmentTtlMs??B_);for(let[K,G]of Object.entries($.assignments))if(G.lastSeenAt<_)delete $.assignments[K];let C=Object.entries($.assignments);if(C.length<=D_)return;C.sort((K,G)=>G[1].lastSeenAt-K[1].lastSeenAt).slice(D_).forEach(([K])=>{delete $.assignments[K]})}async writeState($){this.prune($),$.updatedAt=this.now();let _=`${this.options.path}.${FG()}.tmp`;try{await QG(_,`${JSON.stringify($)}
|
|
422
|
+
`,{mode:384}),await VG(_,this.options.path)}finally{await fG(_,{force:!0}).catch(()=>{})}this.state=$,this.stateMtimeNs=await this.readStateMtimeNs(),this.loaded=!0}scheduleTouch($){this.touchChain=this.touchChain.catch(()=>{}).then(async()=>{let _=await this.acquireLock();try{let C=await this.readState(),K=C.assignments[$];if(!K)return;K.lastSeenAt=this.now(),await this.writeState(C)}finally{await _.release()}}).catch(()=>{})}selectCandidate($){let _=[...$.candidates];if($.family==="opus"){let G=_.filter((j)=>xG(j,$.storage,this.now()));if(G.length>0)_=G}let C=_.flatMap((G)=>{let j=I_({candidate:G,family:$.family,modelId:$.modelId,storage:$.storage,now:this.now()});return j>0?[{candidate:G,weight:j}]:[]});if(C.length===0)return;let K=new Map;for(let G of Object.values($.state.assignments)){let j=C.find((J)=>J.candidate.accountId===G.accountId)?.candidate;if(!j)continue;if(G.quotaCheckedAt!==A_(j.quota))continue;K.set(G.accountId,(K.get(G.accountId)??0)+G.initialInputBytes)}return C.map(({candidate:G,weight:j})=>({candidate:G,score:((K.get(G.accountId)??0)+$.inputBytes)/Math.max(j,hG)})).sort((G,j)=>G.score-j.score||G.candidate.order-j.candidate.order||G.candidate.accountId.localeCompare(j.candidate.accountId))[0]?.candidate}async resolve($){if(!$.sessionId)return null;await this.refreshStateIfChanged();let _=R_($.sessionId),C=this.state.assignments[_];if(C&&this.assignmentIsActive(C)&&$.retainAccountIds.has(C.accountId)&&!$.excludeAccountIds?.has(C.accountId)){if(this.now()-C.lastSeenAt>=AG)C.lastSeenAt=this.now(),this.scheduleTouch(_);return{accountId:C.accountId,assignment:{...C},created:!1,migrated:!1}}let K=await this.acquireLock();try{let G=await this.readState();this.prune(G);let j=G.assignments[_];if(j&&$.retainAccountIds.has(j.accountId)&&!$.excludeAccountIds?.has(j.accountId))return j.lastSeenAt=this.now(),await this.writeState(G),{accountId:j.accountId,assignment:{...j},created:!1,migrated:!1};let J=$.candidates.filter((Y)=>!$.excludeAccountIds?.has(Y.accountId)),z=($.preferredAccountId?J.find((Y)=>Y.accountId===$.preferredAccountId&&I_({candidate:Y,family:$.family,modelId:$.modelId,storage:$.storage,now:this.now()})>0):void 0)??this.selectCandidate({...$,candidates:J,state:G});if(!z){if(j)delete G.assignments[_],await this.writeState(G);return null}let O=this.now(),X={accountId:z.accountId,family:$.family,assignedAt:O,lastSeenAt:O,initialInputBytes:Math.max(1,$.inputBytes),quotaCheckedAt:A_(z.quota)};return G.assignments[_]=X,await this.writeState(G),{accountId:z.accountId,assignment:{...X},created:!j,migrated:Boolean(j&&j.accountId!==z.accountId)}}finally{await K.release()}}async clear($){if(!$)return;let _=R_($),C=await this.acquireLock();try{let K=await this.readState();if(!(_ in K.assignments))return;delete K.assignments[_],await this.writeState(K)}finally{await C.release()}}}export{yG as r,d$ as s,mG as t,vG as u,lG as v,pG as w,gG as x,u$ as y,dG as z,uG as A,a$ as B,nG as C,oG as D,D as E,k as F,z2 as G,c_ as H,O2 as I,V as J,I as K,S as L,R as M,PC as N,X2 as O,n as P,Y2 as Q,hC as R,N2 as S,L2 as T,U2 as U,W2 as V,H2 as W,F2 as X,M2 as Y,E2 as Z,V2 as _,f2 as $,b2 as aa,Q2 as ba,E1 as ca,mC as da,B2 as ea,X0 as fa,J$ as ga,D2 as ha,S2 as ia,R2 as ja,V1 as ka,y as la,lC as ma,Z1 as na,b1 as oa,H$ as pa,F$ as qa,A2 as ra,q2 as sa,P2 as ta,I2 as ua,h2 as va,T2 as wa,w2 as xa,x2 as ya,G0 as za,tC as Aa,m2 as Ba,v2 as Ca,l2 as Da,p2 as Ea,K6 as Fa,g2 as Ga,k1 as Ha,$4 as Ia,c2 as Ja,r2 as Ka,s2 as La,h1 as Ma,j4 as Na,J4 as Oa,w6 as Pa,m0 as Qa,v0 as Ra,d1 as Sa,x6 as Ta,Z4 as Ua,m6 as Va,L4 as Wa,s6 as Xa,W4 as Ya,H4 as Za,d as _a,B4 as $a,D4 as ab,S4 as bb,J0 as cb,q4 as db,e6 as eb,$K as fb,P4 as gb,m4 as hb,v4 as ib,PK as jb,l4 as kb,p4 as lb,d4 as mb,u4 as nb,i4 as ob,vK as pb,c4 as qb,z0 as rb,n4 as sb,a4 as tb,gK as ub,t4 as vb,$j as wb,uK as xb,_j as yb,Cj as zb,Kj as Ab,Gj as Bb,jj as Cb,Z_ as Db,Jj as Eb,Zj as Fb,zj as Gb,Nj as Hb,Lj as Ib,Uj as Jb,Vj as Kb,fj as Lb,bj as Mb,Qj as Nb,Sj as Ob,Rj as Pb,Aj as Qb,WG as Rb,qj as Sb,SG as Tb,w_ as Ub,kj as Vb,yj as Wb,mj as Xb,vj as Yb,kG as Zb};
|