@cortexkit/opencode-anthropic-auth 1.14.0 → 1.15.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
@@ -32,6 +32,7 @@ This repo is a Bun workspace monorepo with two user-facing integrations and one
32
32
  - **Cache keepalive**: use `/claude-cachekeep HH-HH` to pre-warm hybrid cache anchors for active sessions before the 1-hour TTL expires.
33
33
  - **Fast mode toggle**: use `/claude-fast on|off` to request Anthropic fast mode for supported Opus models.
34
34
  - **Fable/Mythos reasoning visibility**: request summarized adaptive thinking for Claude Fable 5 and Mythos 5 so agents can display reasoning summaries instead of blank signed-thinking blocks.
35
+ - **Fable content-filter recovery**: when Fable ends a session response with Anthropic's `refusal` content-filter reason, transparently retry with Opus 4.8 for 10 successful model responses. After each Opus response, a zero-output Fable prewarm advances the same prompt cache using the OAuth account that served the filtered Fable request. The latest Opus cache boundary is retained so a later refusal can bridge back to Opus even after more than 20 Fable content blocks; the selected OpenCode model remains Fable. The TUI sidebar shows the per-session recovery countdown and return to Fable, while OpenCode Desktop receives ignored `promptAsync` notices for both transitions.
35
36
  - **Live quota visibility**: use `/claude-quota` to see main and fallback quota state, reset times, and refresh errors.
36
37
  - **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.
37
38
  - **User-owned Cloudflare relay**: optionally provision your own Worker relay to reduce repeated client upload bytes for large OpenCode or Pi requests.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{ga as O,ib as S,kb as x,l as N,m as L,n as T,p as q,r as D,t as C,u as H}from"./index-fwjqfkj2.js";import"./index-se4sd5kz.js";import{Vb as z}from"./index-1gc9eney.js";import{stdin as y,stdout as v}from"node:process";import{createInterface as R}from"node:readline/promises";function P(){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 w(){console.log(`Usage:
2
+ import{ga as O,jb as S,l as N,lb as x,m as L,n as T,p as q,r as D,t as C,u as H}from"./index-z03wayzs.js";import"./index-6gdd6e4s.js";import{Xb as z}from"./index-qsaph2g4.js";import{stdin as y,stdout as v}from"node:process";import{createInterface as R}from"node:readline/promises";function P(){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 w(){console.log(`Usage:
3
3
  opencode-anthropic-auth login [label]
4
4
  opencode-anthropic-auth api add [label]
5
5
  opencode-anthropic-auth list
@@ -0,0 +1,34 @@
1
+ export declare const FABLE_FALLBACK_MODEL_ID = "claude-opus-4-8";
2
+ export declare const FABLE_FALLBACK_TURNS = 10;
3
+ export type FableStandbyCacheAnchor = {
4
+ fingerprint: string;
5
+ messageIndex: number;
6
+ messageCount: number;
7
+ oauthAccountId: string;
8
+ };
9
+ export type FableFallbackPlan = {
10
+ sessionId: string;
11
+ requestedModel: string;
12
+ effectiveModel: string;
13
+ bodyText: string;
14
+ downgraded: boolean;
15
+ cycle?: number;
16
+ cacheAccountId?: string;
17
+ standbyCacheAnchor?: FableStandbyCacheAnchor;
18
+ requestSequence?: number;
19
+ completed?: boolean;
20
+ };
21
+ export declare class FableFallbackManager {
22
+ private readonly now;
23
+ private readonly sessions;
24
+ private nextCycle;
25
+ constructor(now?: () => number);
26
+ private prune;
27
+ plan(sessionId: string | null | undefined, bodyText: unknown): FableFallbackPlan | null;
28
+ activate(plan: FableFallbackPlan, cacheAccountId?: string): number;
29
+ complete(plan: FableFallbackPlan, standbyCacheAnchor?: FableStandbyCacheAnchor): {
30
+ counted: boolean;
31
+ remaining: number;
32
+ };
33
+ remaining(sessionId: string): number;
34
+ }
@@ -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 qb,L as rb,i as sb,X as tb,h as ub,T as vb,k as wb,G as xb,g as yb,E as zb,m as Ab,o as Bb,v as Cb};
4
+ export{F as rb,L as sb,i as tb,X as ub,h as vb,T as wb,k as xb,G as yb,g as zb,E as Ab,m as Bb,o as Cb,v as Db};
@@ -0,0 +1,2 @@
1
+ import{mkdir as q,readFile as M,writeFile as L}from"node:fs/promises";import{tmpdir as k}from"node:os";import{dirname as b,join as g}from"node:path";var R="OPENCODE_ANTHROPIC_AUTH_SIDEBAR_STATE_FILE",F=g(k(),"opencode-anthropic-auth"),f=g(F,"sidebar-state.json");function h(){return process.env[R]||f}var K={main:{quota:null},fallbacks:[],activeId:void 0,route:"main",relay:null,fastMode:!1,lastUpdated:0};function G(x){return x!==null&&typeof x==="object"&&!Array.isArray(x)}function z(x){if(!G(x))return;let X=Number(x.usedPercent),Z=Number(x.remainingPercent);if(!Number.isFinite(X)||!Number.isFinite(Z))return;return{usedPercent:X,remainingPercent:Z,resetsAt:typeof x.resetsAt==="string"?x.resetsAt:void 0}}function N(x){if(!G(x))return null;let X={},Z=z(x.five_hour),$=z(x.seven_day);if(Z)X.five_hour=Z;if($)X.seven_day=$;if(Array.isArray(x.scoped)){let V=x.scoped.map((Y)=>{if(!G(Y))return;let J=z(Y);if(!J)return;if(typeof Y.id!=="string"||!Y.id.trim())return;if(typeof Y.title!=="string"||!Y.title.trim())return;if(typeof Y.modelName!=="string"||!Y.modelName.trim())return;let j=typeof Y.modelId==="string"&&Y.modelId.trim()?Y.modelId.trim():void 0;return{...J,id:Y.id.trim(),title:Y.title.trim(),...j&&{modelId:j},modelName:Y.modelName.trim()}}).filter((Y)=>Y!=null);X.scoped=V}return Object.keys(X).length?X:null}function I(x){if(!G(x))return{...K};let X={quota:null};if(G(x.main)){let J=x.main;if(X.quota=N(J.quota),typeof J.quotaBackedOff==="boolean")X.quotaBackedOff=J.quotaBackedOff;if(typeof J.quotaBackoffUntil==="number")X.quotaBackoffUntil=J.quotaBackoffUntil;if(typeof J.refreshBackedOff==="boolean")X.refreshBackedOff=J.refreshBackedOff;if(typeof J.refreshBackoffUntil==="number")X.refreshBackoffUntil=J.refreshBackoffUntil}let Z=Array.isArray(x.fallbacks)?x.fallbacks.filter(G).filter((J)=>typeof J.id==="string").map((J)=>({id:J.id,label:typeof J.label==="string"?J.label:void 0,quota:N(J.quota),enabled:typeof J.enabled==="boolean"?J.enabled:!1,needsReauth:typeof J.needsReauth==="boolean"?J.needsReauth:!1})):[],$=null;if(G(x.relay)){let J=x.relay;if(typeof J.enabled==="boolean"&&typeof J.transport==="string")$={enabled:J.enabled,transport:J.transport}}let V;if(G(x.cacheKeep)){let J=x.cacheKeep;if(typeof J.enabled==="boolean")V={enabled:J.enabled,window:typeof J.window==="string"?J.window:void 0,trackedSessions:typeof J.trackedSessions==="number"?J.trackedSessions:void 0}}let Y=Array.isArray(x.fableRecoveries)?x.fableRecoveries.filter(G).flatMap((J)=>{if(typeof J.sessionId!=="string"||J.mode!=="opus"&&J.mode!=="fable"||typeof J.remaining!=="number"||!Number.isFinite(J.remaining)||typeof J.changedAt!=="number"||!Number.isFinite(J.changedAt))return[];return[{sessionId:J.sessionId,mode:J.mode,remaining:Math.max(0,Math.floor(J.remaining)),changedAt:J.changedAt}]}):[];return{main:X,fallbacks:Z,activeId:typeof x.activeId==="string"?x.activeId:void 0,route:typeof x.route==="string"?x.route:K.route,relay:$,fastMode:typeof x.fastMode==="boolean"?x.fastMode:K.fastMode,cacheKeep:V,fableRecoveries:Y.length>0?Y:void 0,lastUpdated:typeof x.lastUpdated==="number"?x.lastUpdated:0}}var W=Promise.resolve();async function P(){try{let x=await M(h(),"utf8");return I(JSON.parse(x))}catch{return K}}async function A(x,X=h()){return W=W.then(async()=>{await q(b(X),{recursive:!0}),await L(X,JSON.stringify(x),"utf8")}).catch(()=>{}),W}async function m(){return W}function u(x){let X=x.activeId;if(X&&X!=="main"){let Z=x.fallbacks?.find(($)=>$.enabled&&$.id===X);if(Z)return{id:Z.id,name:Z.label??Z.id,quota:Z.quota}}return{id:"main",name:"main",quota:x.main?.quota??null}}function U(x){let X=x.replace(/\s+only$/i,"").trim();return/^fable$/i.test(X)?"Fa":X}function l(x,X){let Z=x.fableRecoveries?.find(($)=>$.sessionId===X);if(!Z)return;if(Z.mode==="fable")return"Fable 5 · restored";return`Opus 4.8 · ${Z.remaining} left`}function v(x){let X=x?.five_hour?.usedPercent??null,Z=x?.seven_day?.usedPercent??null,$=x?.scoped??[],V=$.map((j)=>j.usedPercent);if(X==null&&Z==null&&$.length===0)return{fiveHourUsedPercent:X,sevenDayUsedPercent:Z,scopedUsedPercents:V,text:null};let Y=$.map((j)=>`${U(j.title)}: ${Math.round(j.usedPercent)}%`),J=X==null&&Z==null?[]:[`5h: ${X==null?"—":`${Math.round(X)}%`}`,`7d: ${Z==null?"—":`${Math.round(Z)}%`}`];return{fiveHourUsedPercent:X,sevenDayUsedPercent:Z,scopedUsedPercents:V,text:[...J,...Y].join(" ")}}var y=18000000,d=604800000,D=300000,_=0.01,p=1;function w(x,X,Z){if(!x.resetsAt)return null;let $=new Date(x.resetsAt).getTime();if(!Number.isFinite($))return null;let V=$-X,Y=Z-V;if(Y<D)return null;if(Y<X*_)return null;if(Y>=X)return null;let J=x.usedPercent,j=Math.min(Math.max(Y/X*100,0),100),B=J-j,C=Math.abs(B)<p?"on-pace":B>0?"deficit":"reserve",O=null;if(J>0){let H=Y*100/J,Q=V+H;if(Q<$)O=new Date(Q).toISOString()}return{pacePercent:j,deltaPercent:B,state:C,runsOutAt:O}}
2
+ export{h as Eb,K as Fb,I as Gb,P as Hb,A as Ib,m as Jb,u as Kb,U as Lb,l as Mb,v as Nb,y as Ob,d as Pb,w as Qb};
@@ -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 Pb,h as Qb};
2
+ export{b as Rb,h as Sb};
@@ -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 Rb,T as Sb};
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 Tb,T as Ub};
@@ -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 Tb,s as Ub,u as Vb};
2
+ export{r as Vb,s as Wb,u as Xb};