@cortexkit/opencode-anthropic-auth 1.20.0 → 1.21.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 CHANGED
@@ -36,6 +36,7 @@ This repo is a Bun workspace monorepo with two user-facing integrations and one
36
36
  - **Adaptive reasoning visibility**: request summarized adaptive thinking for Claude Fable 5, Mythos 5, and Opus 5. OpenCode receives native `low`, `medium`, `high`, `xhigh`, and `max` Opus 5 effort variants rather than legacy manual-thinking budgets.
37
37
  - **Fable/Opus 5 safety fallback**: eligible OAuth requests try Anthropic's server-side safety fallback first. The plugin preserves Anthropic's fallback conversation boundary across OpenCode history and automatically starts its deterministic 10-response Opus 4.8 recovery if the response still ends in refusal. The TUI sidebar and OpenCode Desktop report the active target model and restoration. Set `OPENCODE_ANTHROPIC_AUTH_FALLBACK_MODE=legacy` to bypass the server policy and use client-side recovery exclusively.
38
38
  - **Live quota visibility**: use `/claude-quota` to see main and fallback quota state, reset times, and refresh errors.
39
+ - **Host-local quota feed**: optionally publish sanitized response-header quota observations so another local CortexKit process can reuse fresh account state without polling Anthropic's rate-limited usage endpoint.
39
40
  - **Killswitch**: per-account hard-block thresholds that stop requests before hitting Anthropic's rate limits, with synthetic 429 retry-after when all accounts are exhausted.
40
41
  - **User-owned Cloudflare relay**: optionally provision your own Worker relay to reduce repeated client upload bytes for large OpenCode or Pi requests.
41
42
  - **Claude-compatible request hardening**: final-body billing signing, safer token refresh persistence, replay-safe fallback retries, and subagent cache isolation.
@@ -180,6 +181,9 @@ Example:
180
181
  "failClosedOnUnknownQuota": true,
181
182
  "showToasts": false
182
183
  },
184
+ "quotaHeaderFeed": {
185
+ "enabled": false
186
+ },
183
187
  "killswitch": {
184
188
  "enabled": false,
185
189
  "main": { "five_hour": 5, "seven_day": 10, "scoped": 0 },
@@ -217,6 +221,8 @@ Example:
217
221
 
218
222
  The `routing` block controls `/claude-routing`, `claudeCache` controls `/claude-cache`, `cacheKeep` controls `/claude-cachekeep`, and `claudeFast` controls `/claude-fast`. OpenCode zeroes Anthropic OAuth model costs by default because OAuth usage is quota-based; set `costZeroing.enabled` to `false` only if you want OpenCode to display the provider's model pricing instead. Set `quota.showToasts` to `true` to opt into OpenCode quota toast notifications after quota refreshes. The `main` field identifies OpenCode's primary auth entry; Pi keeps primary OAuth credentials in Pi's own credential store, but uses the same sidecar shape for CortexKit settings and fallback account labels.
219
223
 
224
+ `quotaHeaderFeed.enabled` is an OpenCode-only, restart-required opt-in. It publishes only allowlisted quota-window values, an opaque account reference, an observation timestamp, and the configured OAuth-account count; it never publishes tokens, raw headers, request bodies, model IDs, or refresh errors. Per-process lease files use owner-only permissions under `$TMPDIR/opencode-anthropic-auth/quota-header-feed`, expire after three minutes, and can be redirected with `OPENCODE_ANTHROPIC_AUTH_QUOTA_FEED_DIR`.
225
+
220
226
  Runtime data is stored separately in `anthropic-auth-state.json`: fallback OAuth tokens, API-route keys, token refresh backoff, quota snapshots, and quota API backoff. Sticky session assignments use `anthropic-auth-routing-state.json` and store only SHA-256 hashes of session IDs. Background refresh and quota checks write only runtime state, so editing `anthropic-auth.json` does not get overwritten by another running plugin instance.
221
227
 
222
228
  ## OpenCode lane-start setting
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{G as z,H as N,J as P,Ja as U,L,N as E,P as K,R as S,hc as T,jc as q}from"./index-ebq5g321.js";import"./index-vkecgsm3.js";import{Uc as w}from"./index-nqs7chg0.js";import{stdin as x,stdout as v}from"node:process";import{createInterface as y}from"node:readline/promises";function R(){return{version:1,main:{type:"opencode",provider:"anthropic"},fallbackOn:[401,403,429],refresh:{enabled:!0,intervalMinutes:10,refreshBeforeExpiryMinutes:240},quota:{enabled:!0,checkIntervalMinutes:5,minimumRemaining:{five_hour:10,seven_day:20},failClosedOnUnknownQuota:!0},accounts:[]}}function _(){console.log(`Usage:
2
+ import{G as z,H as N,I as P,K as L,Ka as U,M as E,P as K,R as S,mc as T,oc as q}from"./index-yskwj5e6.js";import"./index-4nz423bt.js";import{Zc as w}from"./index-4x20896x.js";import{stdin as x,stdout as v}from"node:process";import{createInterface as y}from"node:readline/promises";function R(){return{version:1,main:{type:"opencode",provider:"anthropic"},fallbackOn:[401,403,429],refresh:{enabled:!0,intervalMinutes:10,refreshBeforeExpiryMinutes:240},quota:{enabled:!0,checkIntervalMinutes:5,minimumRemaining:{five_hour:10,seven_day:20},failClosedOnUnknownQuota:!0},accounts:[]}}function _(){console.log(`Usage:
3
3
  opencode-anthropic-auth login [label]
4
4
  opencode-anthropic-auth api add [label]
5
5
  opencode-anthropic-auth list
@@ -1,2 +1,2 @@
1
1
  var e=["claude-account","claude-cache","claude-cachekeep","claude-prime","claude-start","claude-quota","claude-dump","claude-fast","claude-routing","claude-killswitch","claude-logging"];
2
- export{e as Pc};
2
+ export{e as Uc};
@@ -1,4 +1,4 @@
1
1
  import*as j from"node:fs";import*as P from"node:os";import*as V from"node:path";var U={error:0,warn:1,info:2,debug:3,trace:4},O=new Set(Object.keys(U));function F(q){if(!q)return null;let Q=q.trim().toLowerCase();return O.has(Q)?Q:null}var S=F(process.env.OPENCODE_ANTHROPIC_AUTH_LOG_LEVEL),M=S??"info";function L(q){M=q}function i(){return M}function X(q){return U[q]<=U[M]}var J=process.env.OPENCODE_ANTHROPIC_AUTH_LOG_FILE??V.join(P.tmpdir(),"opencode-anthropic-auth.log");function h(){return J}var R=5242880,N=3;function I(){try{if(!j.existsSync(J))return;if(j.statSync(J).size<R)return}catch{return}try{for(let q=N;q>=1;q--){let Q=q===1?J:`${J}.${q-1}`,W=`${J}.${q}`;try{if(q===N)try{j.unlinkSync(W)}catch{}if(j.existsSync(Q))j.renameSync(Q,W)}catch{}}}catch{}}var T=/^(authorization|x-api-key|cookie|set-cookie|refresh|access|token)$/i;function k(q){if(T.test(q))return!0;let Q=q.toLowerCase().replace(/[-_]/g,"");if(Q.includes("apikey"))return!0;if(Q.endsWith("secret")||Q.endsWith("password"))return!0;if(Q.endsWith("token")&&!Q.endsWith("tokens"))return!0;return!1}var f=[/Bearer\s+\S+/,/sk-[A-Za-z0-9-]+/,/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/];function _(q){if(typeof q!=="string")return!1;return f.some((Q)=>Q.test(q))}function G(q){if(q==null||Object.keys(q).length===0)return;let Q=new WeakSet;function W($){if($==null||typeof $!=="object"){if(_($))return"***REDACTED***";return $}if(Q.has($))return"[Circular]";Q.add($);try{if(Array.isArray($))return $.map(W);let x=$,B={};for(let[H,C]of Object.entries(x)){if(k(H)){B[H]="***REDACTED***";continue}B[H]=W(C)}return B}finally{Q.delete($)}}return W(q)}function g(q,Q,W,$){let x=new Date().toISOString(),B=q.toUpperCase().padEnd(5),H=Q?` [${Q}]`:"",C=(()=>{try{let w=G($),A=w?{...w,pid:process.pid}:{pid:process.pid};return` ${JSON.stringify(A)}`}catch{return` {"pid":${process.pid},"payload":"[unserializable]"}`}})();return`[${x}] ${B}${H} ${W}${C}`}var D=null;function E(q){D=q}function Y(q,Q,W,$){if(!X(q))return;if(D)try{D({level:q,channel:Q,message:W,payload:G($)})}catch{}if(Z)return;try{let x=`${g(q,Q,W,$)}
2
2
  `;if(K.push(x),K.length>=p)b();else r()}catch{}}var m={error(q,Q,W){Y("error",q,Q,W)},warn(q,Q,W){Y("warn",q,Q,W)},info(q,Q,W){Y("info",q,Q,W)},debug(q,Q,W){Y("debug",q,Q,W)},trace(q,Q,W){Y("trace",q,Q,W)}},Z=!1,c=500,p=50,K=[],z=null;function b(){if(z)clearTimeout(z),z=null;if(K.length===0)return;let q=K.join("");K=[];try{I(),j.appendFileSync(J,q)}catch{}}function r(){if(z)return;z=setTimeout(()=>{z=null,b()},c)}var y=/^\[([\w-]+)\]\s*/;function o(q,Q){if(!X("debug"))return;if(Z)return;try{let W="",$=q,x=q.match(y);if(x)W=x[1]??"",$=q.slice(x[0].length);let B;if(Q!=null){if(Q instanceof Error)B={error:`${Q.message}${Q.stack?`
3
3
  ${Q.stack}`:""}`};else if(typeof Q==="object")B=Q}Y("debug",W,$,B)}catch{}}function v(q,Q){if(!X("debug"))return;if(Z)return;try{let W;if(Q!=null){if(typeof Q==="object"&&!(Q instanceof Error))W=Q}Y("debug","relay",q,W)}catch{}}if(!Z)process.on("exit",b);
4
- export{F as Ac,L as Bc,i as Cc,X as Dc,h as Ec,T as Fc,k as Gc,G as Hc,g as Ic,E as Jc,m as Kc,o as Lc,v as Mc};
4
+ export{F as Fc,L as Gc,i as Hc,X as Ic,h as Jc,T as Kc,k as Lc,G as Mc,g as Nc,E as Oc,m as Pc,o as Qc,v as Rc};
@@ -1,2 +1,2 @@
1
1
  import{createRequire as q}from"node:module";var j=Object.create;var{getPrototypeOf:k,defineProperty:i,getOwnPropertyNames:l}=Object;var m=Object.prototype.hasOwnProperty;function n(a){return this[a]}var o,p,r=(a,b,d)=>{var f=a!=null&&typeof a==="object";if(f){var g=b?o??=new WeakMap:p??=new WeakMap,h=g.get(a);if(h)return h}d=a!=null?j(k(a)):{};let c=b||!a||!a.__esModule?i(d,"default",{value:a,enumerable:!0}):d;for(let e of l(a))if(!m.call(c,e))i(c,e,{get:n.bind(a,e),enumerable:!0});if(f)g.set(a,c);return c};var s=(a,b)=>()=>(b||a((b={exports:{}}).exports,b),b.exports);var u=q(import.meta.url);
2
- export{r as Sc,s as Tc,u as Uc};
2
+ export{r as Xc,s as Yc,u as Zc};
@@ -1,2 +1,2 @@
1
1
  import{mkdir as l,readdir as u,readFile as c,rename as p,unlink as m,writeFile as d}from"node:fs/promises";import{join as a}from"node:path";function f(t){try{return process.kill(t,0),!0}catch(r){return r.code==="EPERM"}}async function b(t,r){await l(t,{recursive:!0});let s={...r,startedAt:Date.now()},e=a(t,`port-${r.pid}.json`),i=`${e}.${process.pid}.tmp`;return await d(i,JSON.stringify(s),{encoding:"utf8",mode:384}),await p(i,e),e}async function h(t,r){let s;try{s=await u(t)}catch{return null}let e=[];for(let n of s){if(!n.startsWith("port-")||!n.endsWith(".json"))continue;try{let o=JSON.parse(await c(a(t,n),"utf8"));if(Number.isFinite(o.port))if(f(o.pid))e.push(o);else m(a(t,n)).catch(()=>{})}catch{}}if(e.length===0)return null;let i=r&&r>=1?e.filter((n)=>n.pid===r):[];return(i.length>0?i:e).sort((n,o)=>o.startedAt-n.startedAt)[0]??null}
2
- export{b as Nc,h as Oc};
2
+ export{b as Sc,h as Tc};
@@ -1,2 +1,2 @@
1
- import{Kc as O}from"./index-vkecgsm3.js";import{randomUUID as H}from"node:crypto";import{mkdir as I,readFile as k,rename as g,rm as N,rmdir as F,stat as P,unlink as w,writeFile as T}from"node:fs/promises";import{tmpdir as m}from"node:os";import{dirname as y,join as L}from"node:path";var d="OPENCODE_ANTHROPIC_AUTH_SIDEBAR_STATE_FILE",v=L(m(),"opencode-anthropic-auth"),c=L(v,"sidebar-state.json");function E(){return process.env[d]||c}var C={main:{quota:null},fallbacks:[],activeId:void 0,route:"main",relay:null,fastMode:!1,lastUpdated:0};function K(J){return J!==null&&typeof J==="object"&&!Array.isArray(J)}function q(J){return typeof J==="number"&&Number.isFinite(J)}function u(J){if(!K(J))return;let Z=Number(J.count),V=Number(J.inputTokens),x=Number(J.outputTokens),Y=Number(J.since);if(![Z,V,x,Y].every(Number.isFinite)||Z<0||V<0||x<0||Y<0)return;return{count:Math.floor(Z),inputTokens:Math.floor(V),outputTokens:Math.floor(x),since:Math.floor(Y)}}function n(J){if(!K(J))return;if(typeof J.id!=="string"||!J.id.trim())return;if(typeof J.label!=="string"||!J.label.trim())return;let Z={id:J.id.trim(),label:J.label.trim()};if(J.nextDueAt===null)Z.nextDueAt=null;else if(q(J.nextDueAt))Z.nextDueAt=J.nextDueAt;if(J.lastPrimedAt===null)Z.lastPrimedAt=null;else if(q(J.lastPrimedAt))Z.lastPrimedAt=J.lastPrimedAt;if(J.lastResult==="ok"||J.lastResult==="error")Z.lastResult=J.lastResult;let V=u(J.usage);if(V)Z.usage=V;if(q(J.estimatedCostUsd))Z.estimatedCostUsd=J.estimatedCostUsd;return Z}function i(J){if(!K(J))return;if(typeof J.enabled!=="boolean")return;let Z=Array.isArray(J.accounts)?J.accounts.map(n).filter((V)=>V!=null):[];return{enabled:J.enabled,accounts:Z}}function h(J){if(!K(J))return;let Z=Number(J.usedPercent),V=Number(J.remainingPercent);if(!Number.isFinite(Z)||!Number.isFinite(V))return;return{usedPercent:Z,remainingPercent:V,resetsAt:typeof J.resetsAt==="string"?J.resetsAt:void 0}}function b(J){if(!K(J))return null;let Z={},V=h(J.five_hour),x=h(J.seven_day);if(V)Z.five_hour=V;if(x)Z.seven_day=x;if(Array.isArray(J.scoped)){let Y=J.scoped.map((X)=>{if(!K(X))return;let $=h(X);if(!$)return;if(typeof X.id!=="string"||!X.id.trim())return;if(typeof X.title!=="string"||!X.title.trim())return;if(typeof X.modelName!=="string"||!X.modelName.trim())return;let j=typeof X.modelId==="string"&&X.modelId.trim()?X.modelId.trim():void 0;return{...$,id:X.id.trim(),title:X.title.trim(),...j&&{modelId:j},modelName:X.modelName.trim()}}).filter((X)=>X!=null);Z.scoped=Y}if(K(J.extraUsage)){let Y=A(J.extraUsage.used),X=A(J.extraUsage.limit);if(Y&&X&&typeof J.extraUsage.exhausted==="boolean")Z.extraUsage={used:Y,limit:X,...typeof J.extraUsage.utilizationPercent==="number"&&Number.isFinite(J.extraUsage.utilizationPercent)&&{utilizationPercent:J.extraUsage.utilizationPercent},...typeof J.extraUsage.severity==="string"&&{severity:J.extraUsage.severity},exhausted:J.extraUsage.exhausted}}if(typeof J.bindingWindow==="string"&&J.bindingWindow.trim())Z.bindingWindow=J.bindingWindow.trim();if(typeof J.fallbackAdvised==="boolean")Z.fallbackAdvised=J.fallbackAdvised;return Object.keys(Z).length?Z:null}function A(J){if(!K(J))return;if(!Number.isInteger(J.amountMinor)||typeof J.currency!=="string"||!/^[A-Za-z]{3}$/.test(J.currency.trim())||!Number.isInteger(J.exponent)||J.exponent<0||J.exponent>20)return;return{amountMinor:J.amountMinor,currency:J.currency.trim(),exponent:J.exponent}}function s(J){if(!K(J))return{...C};let Z={quota:null};if(K(J.main)){let $=J.main;if(Z.quota=b($.quota),typeof $.tierLabel==="string"&&$.tierLabel.trim())Z.tierLabel=$.tierLabel.trim();if(typeof $.quotaBackedOff==="boolean")Z.quotaBackedOff=$.quotaBackedOff;if(typeof $.quotaBackoffUntil==="number")Z.quotaBackoffUntil=$.quotaBackoffUntil;if(typeof $.refreshBackedOff==="boolean")Z.refreshBackedOff=$.refreshBackedOff;if(typeof $.refreshBackoffUntil==="number")Z.refreshBackoffUntil=$.refreshBackoffUntil}let V=Array.isArray(J.fallbacks)?J.fallbacks.filter(K).filter(($)=>typeof $.id==="string").map(($)=>({id:$.id,label:typeof $.label==="string"?$.label:void 0,quota:b($.quota),enabled:typeof $.enabled==="boolean"?$.enabled:!1,needsReauth:typeof $.needsReauth==="boolean"?$.needsReauth:!1,tierLabel:typeof $.tierLabel==="string"&&$.tierLabel.trim()?$.tierLabel.trim():void 0})):[],x=null;if(K(J.relay)){let $=J.relay;if(typeof $.enabled==="boolean"&&typeof $.transport==="string")x={enabled:$.enabled,transport:$.transport}}let Y;if(K(J.cacheKeep)){let $=J.cacheKeep;if(typeof $.enabled==="boolean")Y={enabled:$.enabled,window:typeof $.window==="string"?$.window:void 0,trackedSessions:typeof $.trackedSessions==="number"?$.trackedSessions:void 0}}let X=Array.isArray(J.fableRecoveries)?J.fableRecoveries.filter(K).flatMap(($)=>{if(typeof $.sessionId!=="string"||$.mode!=="opus"&&$.mode!=="fable"&&$.mode!=="server"||typeof $.remaining!=="number"||!Number.isFinite($.remaining)||typeof $.changedAt!=="number"||!Number.isFinite($.changedAt))return[];return[{sessionId:$.sessionId,mode:$.mode,remaining:Math.max(0,Math.floor($.remaining)),changedAt:$.changedAt,requestedModelId:typeof $.requestedModelId==="string"?$.requestedModelId:void 0,targetModelId:typeof $.targetModelId==="string"?$.targetModelId:void 0}]}):[];return{main:Z,fallbacks:V,activeId:typeof J.activeId==="string"?J.activeId:void 0,route:typeof J.route==="string"?J.route:C.route,relay:x,fastMode:typeof J.fastMode==="boolean"?J.fastMode:C.fastMode,cacheKeep:Y,prime:i(J.prime),fableRecoveries:X.length>0?X:void 0,lastUpdated:typeof J.lastUpdated==="number"?J.lastUpdated:0}}var W=Promise.resolve(),l=1000,o=2000,r=5,a=15,U=new Map;function QJ(J,Z=E()){if(J)U.set(Z,J);else U.delete(Z)}function M(J){return U.get(J)}var S=null;function BJ(J){S=J}function OJ(){return S}function t(J){return new Promise((Z)=>setTimeout(Z,J))}async function p(J){let Z=`${J}.lock`,V=M(J),x=V?.lockBudgetMs??l,Y=V?.lockRetryMinMs??r,X=V?.lockRetryMaxMs??a,$=Date.now()+x;while(!0){try{await I(Z);let G=H(),Q=L(Z,G);return await T(Q,"",{encoding:"utf8",mode:384,flag:"wx"}),await V?.onLockAcquired?.(Z),{ownsLock:async()=>{try{return await P(Q),!0}catch{return!1}},release:async()=>{try{await w(Q)}catch{return}await V?.beforeReleaseDirectoryRemoval?.(Z),await F(Z).catch(()=>{})}}}catch(G){if(G.code!=="EEXIST")return O.trace("sidebar","state lock unavailable; write skipped",{stateFile:J,error:G instanceof Error?G.message:String(G)}),null}try{let G=await P(Z);if(Date.now()-G.mtimeMs>o){await V?.afterStaleLockStat?.(Z);let Q=`${Z}.evict-${process.pid}-${H()}`;try{await g(Z,Q)}catch(z){if(z.code==="ENOENT")continue;throw z}await V?.onStaleLockClaimed?.(Z),await N(Q,{recursive:!0,force:!0}).catch(()=>{});continue}}catch(G){if(G.code==="ENOENT")continue;return O.trace("sidebar","state lock inspection failed; write skipped",{stateFile:J,error:G instanceof Error?G.message:String(G)}),null}let j=$-Date.now();if(j<=0)return O.warn("sidebar","lock budget exhausted, write skipped",{stateFile:J,budgetMs:x}),null;let B=Y+Math.floor(Math.random()*(X-Y+1));await t(Math.min(B,j))}}async function zJ(J){return(await p(J))?.release??null}async function e(J,Z,V){let x=M(J),Y=`${J}.${process.pid}.${H()}.tmp`;await T(Y,JSON.stringify(Z),{encoding:"utf8",mode:384});try{if(!await V())return O.trace("sidebar","state lock lost before rename; write aborted",{stateFile:J}),await N(Y,{force:!0}).catch(()=>{}),"lock-lost-before-rename";if(await x?.beforeRename?.(J,Y),!await V())return O.trace("sidebar","state lock lost before rename; write aborted",{stateFile:J}),await N(Y,{force:!0}).catch(()=>{}),"lock-lost-before-rename";if(await g(Y,J),await x?.afterRename?.(J),!await V())return"lock-lost-after-rename";return"written"}catch(X){throw await N(Y,{force:!0}).catch(()=>{}),X}}async function R(J=E()){try{let Z=await k(J,"utf8");return s(JSON.parse(Z))}catch{return C}}async function NJ(J,Z=E(),V={}){return W=W.then(async()=>{await I(y(Z),{recursive:!0});for(let x=0;x<2;x++){let Y=x===1,X=await p(Z);if(!X){if(Y)O.warn("sidebar","post-rename repair lock unavailable; write skipped",{stateFile:Z});return}let $=J,j;try{if(V.routingAuthoritative===!1){let B=await R(Z),G=await V.resolvePreservedRouting?.(B);if(G){let Q=G.state??J;$={...Q,activeId:G.activeId,route:G.route,lastUpdated:Math.max(Q.lastUpdated,B.lastUpdated)}}await M(Z)?.afterMergeRead?.(Z)}else if(Y){let B=await R(Z);$={...B,activeId:J.activeId,route:J.route,relay:J.relay,fastMode:J.fastMode,cacheKeep:J.cacheKeep,lastUpdated:Math.max(B.lastUpdated,J.lastUpdated)}}j=await e(Z,$,X.ownsLock)}finally{await X.release()}if(j==="lock-lost-after-rename"){if(Y){O.warn("sidebar","post-rename repair lost lock; write skipped",{stateFile:Z});return}O.warn("sidebar","state lock lost after rename; repairing write",{stateFile:Z});continue}if(j==="lock-lost-before-rename")return;V.onRoutingResolved?.({activeId:$.activeId,route:$.route});return}}).catch(()=>{}),W}async function CJ(){return W}function WJ(J){let Z=J.activeId;if(Z&&Z!=="main"){let V=J.fallbacks?.find((x)=>x.enabled&&x.id===Z);if(V)return{id:V.id,name:V.label??V.id,quota:V.quota}}return{id:"main",name:"main",quota:J.main?.quota??null}}function JJ(J){let Z=J.replace(/\s+only$/i,"").trim();return/^fable$/i.test(Z)?"Fa":Z}function f(J){if(J==="claude-fable-5"||J?.startsWith("claude-fable-5-"))return"Fable 5";if(J==="claude-opus-5"||J?.startsWith("claude-opus-5-"))return"Opus 5";if(J==="claude-opus-4-8"||J?.startsWith("claude-opus-4-8-"))return"Opus 4.8";return J??"Fable 5"}function D(J){return new Date(J).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}function ZJ(J){if(J===0)return"0";if(J<0.0001)return J.toExponential(2);return J.toFixed(Math.min(6,Math.max(0,4)))}function qJ(J){if(J.lastResult==="error")return{text:"err",hasError:!0};if(J.nextDueAt&&J.nextDueAt>Date.now())return{text:D(J.nextDueAt),hasError:!1};if(J.lastPrimedAt)return{text:`primed ${D(J.lastPrimedAt)} ✓`,hasError:!1};if(J.usage?.count)return{text:`✓ ${J.usage.count} ≈ $${ZJ(J.estimatedCostUsd??0)}`,hasError:!1};return{text:"—",hasError:!1}}function hJ(J,Z){let V=J.fableRecoveries?.find((x)=>x.sessionId===Z);if(!V)return;if(V.mode==="fable")return`${f(V.requestedModelId)} · restored`;if(V.mode==="server")return`${f(V.requestedModelId)}→${f(V.targetModelId)} · safety`;return`Opus 4.8 · ${V.remaining} left`}function fJ(J){let Z=J?.five_hour?.usedPercent??null,V=J?.seven_day?.usedPercent??null,x=J?.scoped??[],Y=x.map((j)=>j.usedPercent);if(Z==null&&V==null&&x.length===0)return{fiveHourUsedPercent:Z,sevenDayUsedPercent:V,scopedUsedPercents:Y,text:null};let X=x.map((j)=>`${JJ(j.title)}: ${Math.round(j.usedPercent)}%`),$=Z==null&&V==null?[]:[`5h: ${Z==null?"—":`${Math.round(Z)}%`}`,`7d: ${V==null?"—":`${Math.round(V)}%`}`];return{fiveHourUsedPercent:Z,sevenDayUsedPercent:V,scopedUsedPercents:Y,text:[...$,...X].join(" ")}}var HJ=18000000,UJ=604800000,$J=300000,VJ=0.01,XJ=1;function LJ(J,Z,V){if(!J.resetsAt)return null;let x=new Date(J.resetsAt).getTime();if(!Number.isFinite(x))return null;let Y=x-Z,X=V-Y;if(X<$J)return null;if(X<Z*VJ)return null;if(X>=Z)return null;let $=J.usedPercent,j=Math.min(Math.max(X/Z*100,0),100),B=$-j,G=Math.abs(B)<XJ?"on-pace":B>0?"deficit":"reserve",Q=null;if($>0){let z=X*100/$,_=Y+z;if(_<x)Q=new Date(_).toISOString()}return{pacePercent:j,deltaPercent:B,state:G,runsOutAt:Q}}
1
+ import{Pc as O}from"./index-4nz423bt.js";import{randomUUID as H}from"node:crypto";import{mkdir as I,readFile as k,rename as g,rm as N,rmdir as F,stat as P,unlink as w,writeFile as T}from"node:fs/promises";import{tmpdir as m}from"node:os";import{dirname as y,join as L}from"node:path";var d="OPENCODE_ANTHROPIC_AUTH_SIDEBAR_STATE_FILE",v=L(m(),"opencode-anthropic-auth"),c=L(v,"sidebar-state.json");function E(){return process.env[d]||c}var C={main:{quota:null},fallbacks:[],activeId:void 0,route:"main",relay:null,fastMode:!1,lastUpdated:0};function K(J){return J!==null&&typeof J==="object"&&!Array.isArray(J)}function q(J){return typeof J==="number"&&Number.isFinite(J)}function u(J){if(!K(J))return;let Z=Number(J.count),V=Number(J.inputTokens),x=Number(J.outputTokens),Y=Number(J.since);if(![Z,V,x,Y].every(Number.isFinite)||Z<0||V<0||x<0||Y<0)return;return{count:Math.floor(Z),inputTokens:Math.floor(V),outputTokens:Math.floor(x),since:Math.floor(Y)}}function n(J){if(!K(J))return;if(typeof J.id!=="string"||!J.id.trim())return;if(typeof J.label!=="string"||!J.label.trim())return;let Z={id:J.id.trim(),label:J.label.trim()};if(J.nextDueAt===null)Z.nextDueAt=null;else if(q(J.nextDueAt))Z.nextDueAt=J.nextDueAt;if(J.lastPrimedAt===null)Z.lastPrimedAt=null;else if(q(J.lastPrimedAt))Z.lastPrimedAt=J.lastPrimedAt;if(J.lastResult==="ok"||J.lastResult==="error")Z.lastResult=J.lastResult;let V=u(J.usage);if(V)Z.usage=V;if(q(J.estimatedCostUsd))Z.estimatedCostUsd=J.estimatedCostUsd;return Z}function i(J){if(!K(J))return;if(typeof J.enabled!=="boolean")return;let Z=Array.isArray(J.accounts)?J.accounts.map(n).filter((V)=>V!=null):[];return{enabled:J.enabled,accounts:Z}}function h(J){if(!K(J))return;let Z=Number(J.usedPercent),V=Number(J.remainingPercent);if(!Number.isFinite(Z)||!Number.isFinite(V))return;return{usedPercent:Z,remainingPercent:V,resetsAt:typeof J.resetsAt==="string"?J.resetsAt:void 0}}function b(J){if(!K(J))return null;let Z={},V=h(J.five_hour),x=h(J.seven_day);if(V)Z.five_hour=V;if(x)Z.seven_day=x;if(Array.isArray(J.scoped)){let Y=J.scoped.map((X)=>{if(!K(X))return;let $=h(X);if(!$)return;if(typeof X.id!=="string"||!X.id.trim())return;if(typeof X.title!=="string"||!X.title.trim())return;if(typeof X.modelName!=="string"||!X.modelName.trim())return;let j=typeof X.modelId==="string"&&X.modelId.trim()?X.modelId.trim():void 0;return{...$,id:X.id.trim(),title:X.title.trim(),...j&&{modelId:j},modelName:X.modelName.trim()}}).filter((X)=>X!=null);Z.scoped=Y}if(K(J.extraUsage)){let Y=A(J.extraUsage.used),X=A(J.extraUsage.limit);if(Y&&X&&typeof J.extraUsage.exhausted==="boolean")Z.extraUsage={used:Y,limit:X,...typeof J.extraUsage.utilizationPercent==="number"&&Number.isFinite(J.extraUsage.utilizationPercent)&&{utilizationPercent:J.extraUsage.utilizationPercent},...typeof J.extraUsage.severity==="string"&&{severity:J.extraUsage.severity},exhausted:J.extraUsage.exhausted}}if(typeof J.bindingWindow==="string"&&J.bindingWindow.trim())Z.bindingWindow=J.bindingWindow.trim();if(typeof J.fallbackAdvised==="boolean")Z.fallbackAdvised=J.fallbackAdvised;return Object.keys(Z).length?Z:null}function A(J){if(!K(J))return;if(!Number.isInteger(J.amountMinor)||typeof J.currency!=="string"||!/^[A-Za-z]{3}$/.test(J.currency.trim())||!Number.isInteger(J.exponent)||J.exponent<0||J.exponent>20)return;return{amountMinor:J.amountMinor,currency:J.currency.trim(),exponent:J.exponent}}function s(J){if(!K(J))return{...C};let Z={quota:null};if(K(J.main)){let $=J.main;if(Z.quota=b($.quota),typeof $.tierLabel==="string"&&$.tierLabel.trim())Z.tierLabel=$.tierLabel.trim();if(typeof $.quotaBackedOff==="boolean")Z.quotaBackedOff=$.quotaBackedOff;if(typeof $.quotaBackoffUntil==="number")Z.quotaBackoffUntil=$.quotaBackoffUntil;if(typeof $.refreshBackedOff==="boolean")Z.refreshBackedOff=$.refreshBackedOff;if(typeof $.refreshBackoffUntil==="number")Z.refreshBackoffUntil=$.refreshBackoffUntil}let V=Array.isArray(J.fallbacks)?J.fallbacks.filter(K).filter(($)=>typeof $.id==="string").map(($)=>({id:$.id,label:typeof $.label==="string"?$.label:void 0,quota:b($.quota),enabled:typeof $.enabled==="boolean"?$.enabled:!1,needsReauth:typeof $.needsReauth==="boolean"?$.needsReauth:!1,tierLabel:typeof $.tierLabel==="string"&&$.tierLabel.trim()?$.tierLabel.trim():void 0})):[],x=null;if(K(J.relay)){let $=J.relay;if(typeof $.enabled==="boolean"&&typeof $.transport==="string")x={enabled:$.enabled,transport:$.transport}}let Y;if(K(J.cacheKeep)){let $=J.cacheKeep;if(typeof $.enabled==="boolean")Y={enabled:$.enabled,window:typeof $.window==="string"?$.window:void 0,trackedSessions:typeof $.trackedSessions==="number"?$.trackedSessions:void 0}}let X=Array.isArray(J.fableRecoveries)?J.fableRecoveries.filter(K).flatMap(($)=>{if(typeof $.sessionId!=="string"||$.mode!=="opus"&&$.mode!=="fable"&&$.mode!=="server"||typeof $.remaining!=="number"||!Number.isFinite($.remaining)||typeof $.changedAt!=="number"||!Number.isFinite($.changedAt))return[];return[{sessionId:$.sessionId,mode:$.mode,remaining:Math.max(0,Math.floor($.remaining)),changedAt:$.changedAt,requestedModelId:typeof $.requestedModelId==="string"?$.requestedModelId:void 0,targetModelId:typeof $.targetModelId==="string"?$.targetModelId:void 0}]}):[];return{main:Z,fallbacks:V,activeId:typeof J.activeId==="string"?J.activeId:void 0,route:typeof J.route==="string"?J.route:C.route,relay:x,fastMode:typeof J.fastMode==="boolean"?J.fastMode:C.fastMode,cacheKeep:Y,prime:i(J.prime),fableRecoveries:X.length>0?X:void 0,lastUpdated:typeof J.lastUpdated==="number"?J.lastUpdated:0}}var W=Promise.resolve(),l=1000,o=2000,r=5,a=15,U=new Map;function QJ(J,Z=E()){if(J)U.set(Z,J);else U.delete(Z)}function M(J){return U.get(J)}var S=null;function BJ(J){S=J}function OJ(){return S}function t(J){return new Promise((Z)=>setTimeout(Z,J))}async function p(J){let Z=`${J}.lock`,V=M(J),x=V?.lockBudgetMs??l,Y=V?.lockRetryMinMs??r,X=V?.lockRetryMaxMs??a,$=Date.now()+x;while(!0){try{await I(Z);let G=H(),Q=L(Z,G);return await T(Q,"",{encoding:"utf8",mode:384,flag:"wx"}),await V?.onLockAcquired?.(Z),{ownsLock:async()=>{try{return await P(Q),!0}catch{return!1}},release:async()=>{try{await w(Q)}catch{return}await V?.beforeReleaseDirectoryRemoval?.(Z),await F(Z).catch(()=>{})}}}catch(G){if(G.code!=="EEXIST")return O.trace("sidebar","state lock unavailable; write skipped",{stateFile:J,error:G instanceof Error?G.message:String(G)}),null}try{let G=await P(Z);if(Date.now()-G.mtimeMs>o){await V?.afterStaleLockStat?.(Z);let Q=`${Z}.evict-${process.pid}-${H()}`;try{await g(Z,Q)}catch(z){if(z.code==="ENOENT")continue;throw z}await V?.onStaleLockClaimed?.(Z),await N(Q,{recursive:!0,force:!0}).catch(()=>{});continue}}catch(G){if(G.code==="ENOENT")continue;return O.trace("sidebar","state lock inspection failed; write skipped",{stateFile:J,error:G instanceof Error?G.message:String(G)}),null}let j=$-Date.now();if(j<=0)return O.warn("sidebar","lock budget exhausted, write skipped",{stateFile:J,budgetMs:x}),null;let B=Y+Math.floor(Math.random()*(X-Y+1));await t(Math.min(B,j))}}async function zJ(J){return(await p(J))?.release??null}async function e(J,Z,V){let x=M(J),Y=`${J}.${process.pid}.${H()}.tmp`;await T(Y,JSON.stringify(Z),{encoding:"utf8",mode:384});try{if(!await V())return O.trace("sidebar","state lock lost before rename; write aborted",{stateFile:J}),await N(Y,{force:!0}).catch(()=>{}),"lock-lost-before-rename";if(await x?.beforeRename?.(J,Y),!await V())return O.trace("sidebar","state lock lost before rename; write aborted",{stateFile:J}),await N(Y,{force:!0}).catch(()=>{}),"lock-lost-before-rename";if(await g(Y,J),await x?.afterRename?.(J),!await V())return"lock-lost-after-rename";return"written"}catch(X){throw await N(Y,{force:!0}).catch(()=>{}),X}}async function R(J=E()){try{let Z=await k(J,"utf8");return s(JSON.parse(Z))}catch{return C}}async function NJ(J,Z=E(),V={}){return W=W.then(async()=>{await I(y(Z),{recursive:!0});for(let x=0;x<2;x++){let Y=x===1,X=await p(Z);if(!X){if(Y)O.warn("sidebar","post-rename repair lock unavailable; write skipped",{stateFile:Z});return}let $=J,j;try{if(V.routingAuthoritative===!1){let B=await R(Z),G=await V.resolvePreservedRouting?.(B);if(G){let Q=G.state??J;$={...Q,activeId:G.activeId,route:G.route,lastUpdated:Math.max(Q.lastUpdated,B.lastUpdated)}}await M(Z)?.afterMergeRead?.(Z)}else if(Y){let B=await R(Z);$={...B,activeId:J.activeId,route:J.route,relay:J.relay,fastMode:J.fastMode,cacheKeep:J.cacheKeep,lastUpdated:Math.max(B.lastUpdated,J.lastUpdated)}}j=await e(Z,$,X.ownsLock)}finally{await X.release()}if(j==="lock-lost-after-rename"){if(Y){O.warn("sidebar","post-rename repair lost lock; write skipped",{stateFile:Z});return}O.warn("sidebar","state lock lost after rename; repairing write",{stateFile:Z});continue}if(j==="lock-lost-before-rename")return;V.onRoutingResolved?.({activeId:$.activeId,route:$.route});return}}).catch(()=>{}),W}async function CJ(){return W}function WJ(J){let Z=J.activeId;if(Z&&Z!=="main"){let V=J.fallbacks?.find((x)=>x.enabled&&x.id===Z);if(V)return{id:V.id,name:V.label??V.id,quota:V.quota}}return{id:"main",name:"main",quota:J.main?.quota??null}}function JJ(J){let Z=J.replace(/\s+only$/i,"").trim();return/^fable$/i.test(Z)?"Fa":Z}function f(J){if(J==="claude-fable-5"||J?.startsWith("claude-fable-5-"))return"Fable 5";if(J==="claude-opus-5"||J?.startsWith("claude-opus-5-"))return"Opus 5";if(J==="claude-opus-4-8"||J?.startsWith("claude-opus-4-8-"))return"Opus 4.8";return J??"Fable 5"}function D(J){return new Date(J).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}function ZJ(J){if(J===0)return"0";if(J<0.0001)return J.toExponential(2);return J.toFixed(Math.min(6,Math.max(0,4)))}function qJ(J){if(J.lastResult==="error")return{text:"err",hasError:!0};if(J.nextDueAt&&J.nextDueAt>Date.now())return{text:D(J.nextDueAt),hasError:!1};if(J.lastPrimedAt)return{text:`primed ${D(J.lastPrimedAt)} ✓`,hasError:!1};if(J.usage?.count)return{text:`✓ ${J.usage.count} ≈ $${ZJ(J.estimatedCostUsd??0)}`,hasError:!1};return{text:"—",hasError:!1}}function hJ(J,Z){let V=J.fableRecoveries?.find((x)=>x.sessionId===Z);if(!V)return;if(V.mode==="fable")return`${f(V.requestedModelId)} · restored`;if(V.mode==="server")return`${f(V.requestedModelId)}→${f(V.targetModelId)} · safety`;return`Opus 4.8 · ${V.remaining} left`}function fJ(J){let Z=J?.five_hour?.usedPercent??null,V=J?.seven_day?.usedPercent??null,x=J?.scoped??[],Y=x.map((j)=>j.usedPercent);if(Z==null&&V==null&&x.length===0)return{fiveHourUsedPercent:Z,sevenDayUsedPercent:V,scopedUsedPercents:Y,text:null};let X=x.map((j)=>`${JJ(j.title)}: ${Math.round(j.usedPercent)}%`),$=Z==null&&V==null?[]:[`5h: ${Z==null?"—":`${Math.round(Z)}%`}`,`7d: ${V==null?"—":`${Math.round(V)}%`}`];return{fiveHourUsedPercent:Z,sevenDayUsedPercent:V,scopedUsedPercents:Y,text:[...$,...X].join(" ")}}var HJ=18000000,UJ=604800000,$J=300000,VJ=0.01,XJ=1;function LJ(J,Z,V){if(!J.resetsAt)return null;let x=new Date(J.resetsAt).getTime();if(!Number.isFinite(x))return null;let Y=x-Z,X=V-Y;if(X<$J)return null;if(X<Z*VJ)return null;if(X>=Z)return null;let $=J.usedPercent,j=Math.min(Math.max(X/Z*100,0),100),B=$-j,G=Math.abs(B)<XJ?"on-pace":B>0?"deficit":"reserve",Q=null;if($>0){let z=X*100/$,_=Y+z;if(_<x)Q=new Date(_).toISOString()}return{pacePercent:j,deltaPercent:B,state:G,runsOutAt:Q}}
2
2
  export{E as a,C as b,s as c,QJ as d,BJ as e,OJ as f,zJ as g,R as h,NJ as i,CJ as j,WJ as k,JJ as l,f as m,D as n,ZJ as o,qJ as p,hJ as q,fJ as r,HJ as s,UJ as t,LJ as u};
@@ -1 +1 @@
1
- import{createHash as z}from"node:crypto";import{homedir as F,tmpdir as O}from"node:os";import{join as q,resolve as G}from"node:path";var J="OPENCODE_ANTHROPIC_AUTH_RPC_DIR";function T(g){let k=process.env[J]?.trim();if(k)return G(g,k);let w=z("sha256").update(g).digest("hex").slice(0,16),x=process.env.XDG_STATE_HOME||q(F(),".local","state");return q(x,"cortexkit","anthropic-auth","rpc",w)}export{O as Qc,T as Rc};
1
+ import{createHash as z}from"node:crypto";import{homedir as F,tmpdir as O}from"node:os";import{join as q,resolve as G}from"node:path";var J="OPENCODE_ANTHROPIC_AUTH_RPC_DIR";function T(g){let k=process.env[J]?.trim();if(k)return G(g,k);let w=z("sha256").update(g).digest("hex").slice(0,16),x=process.env.XDG_STATE_HOME||q(F(),".local","state");return q(x,"cortexkit","anthropic-auth","rpc",w)}export{O as Vc,T as Wc};