@cortexkit/opencode-anthropic-auth 1.14.0 → 1.15.1

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/src/tui.tsx CHANGED
@@ -25,6 +25,7 @@ import {
25
25
  FIVE_HOUR_MS,
26
26
  formatScopedQuotaLabel,
27
27
  getCollapsedQuotaSummary,
28
+ getFableRecoverySummary,
28
29
  getSidebarState,
29
30
  type QuotaPacing,
30
31
  resolveActiveAccount,
@@ -49,21 +50,24 @@ let rpcPollStarted = false
49
50
 
50
51
  const ID = 'cortexkit.anthropic-auth'
51
52
 
52
- // Plugin version for the header (mirrors the Magic Context / AFT convention).
53
- // Read at runtime from package.json relative to this module — NOT a TS JSON
54
- // import, which would break the declaration build (package.json is outside
55
- // rootDir). tui.tsx ships as source (package.json exports["./tui"] →
56
- // "./src/tui.tsx") and is never compiled into a deeper dist tree, so `..` from
57
- // src/ is always the package root. Empty string on any failure → header shows
58
- // the badge with no version.
53
+ // Read package metadata from either the raw src/ entry or its generated
54
+ // src/tui-compiled/ counterpart. Avoid a JSON import because package.json sits
55
+ // outside the declaration build's rootDir.
59
56
  const PLUGIN_VERSION: string = (() => {
60
- try {
61
- const here = dirname(fileURLToPath(import.meta.url))
62
- const raw = readFileSync(join(here, '..', 'package.json'), 'utf8')
63
- return (JSON.parse(raw) as { version?: string }).version ?? ''
64
- } catch {
65
- return ''
57
+ const here = dirname(fileURLToPath(import.meta.url))
58
+ for (const packageFile of [
59
+ join(here, '..', 'package.json'),
60
+ join(here, '..', '..', 'package.json'),
61
+ ]) {
62
+ try {
63
+ const raw = readFileSync(packageFile, 'utf8')
64
+ const version = (JSON.parse(raw) as { version?: string }).version
65
+ if (version) return version
66
+ } catch {
67
+ // Try the path for the other TUI entry layout.
68
+ }
66
69
  }
70
+ return ''
67
71
  })()
68
72
 
69
73
  // biome-ignore lint/suspicious/noExplicitAny: opentui border prop not typed in plugin tui surface
@@ -501,6 +505,7 @@ function createSidebarController(
501
505
  function QuotaSidebar(props: {
502
506
  api: TuiPluginApi
503
507
  controller: SidebarController
508
+ sessionId: string
504
509
  }) {
505
510
  const prefs = props.controller.prefs
506
511
  const collapsed = props.controller.collapsed
@@ -604,6 +609,14 @@ function QuotaSidebar(props: {
604
609
  const needsReauth = () => enabledFallbacks().some((f) => f.needsReauth)
605
610
  const degraded = () => quotaBackedOff() || refreshBackedOff() || needsReauth()
606
611
 
612
+ const fableRecoverySummary = () =>
613
+ getFableRecoverySummary(state(), props.sessionId)
614
+ const fableRecoveryTone = (): Tone =>
615
+ state().fableRecoveries?.find(
616
+ (recovery) => recovery.sessionId === props.sessionId,
617
+ )?.mode === 'opus'
618
+ ? 'warn'
619
+ : 'ok'
607
620
  const cacheKeep = () => state().cacheKeep
608
621
  const showCache = () =>
609
622
  prefs().sections.cache && cacheKeep() != null && cacheKeep()?.window != null
@@ -679,6 +692,15 @@ function QuotaSidebar(props: {
679
692
  </text>
680
693
  </CollapsedRow>
681
694
  </Show>
695
+ <Show when={fableRecoverySummary()}>
696
+ {(summary: () => string) => (
697
+ <CollapsedRow theme={theme()} label='Recovery'>
698
+ <text fg={toneColor(theme(), fableRecoveryTone())}>
699
+ <b>{summary()}</b>
700
+ </text>
701
+ </CollapsedRow>
702
+ )}
703
+ </Show>
682
704
  </Show>
683
705
 
684
706
  {/* Expanded: full sections. Also render when there's no data so the
@@ -745,6 +767,17 @@ function QuotaSidebar(props: {
745
767
  />
746
768
  </Show>
747
769
 
770
+ <Show when={fableRecoverySummary()}>
771
+ {(summary: () => string) => (
772
+ <StatRow
773
+ theme={theme()}
774
+ label='Recovery'
775
+ value={summary()}
776
+ tone={fableRecoveryTone()}
777
+ />
778
+ )}
779
+ </Show>
780
+
748
781
  {/* Cache */}
749
782
  <Show when={showCache()}>
750
783
  <SectionHeader theme={theme()} title='Cache' />
@@ -795,8 +828,14 @@ const tui: TuiPlugin = async (api) => {
795
828
  api.slots.register({
796
829
  order: computeEffectiveOrder(root, PLUGIN_KEY, DEFAULT_SLOT_ORDER),
797
830
  slots: {
798
- sidebar_content(_ctx: unknown, _props: { session_id: string }) {
799
- return <QuotaSidebar api={api} controller={controller} />
831
+ sidebar_content(_ctx: unknown, props: { session_id: string }) {
832
+ return (
833
+ <QuotaSidebar
834
+ api={api}
835
+ controller={controller}
836
+ sessionId={props.session_id}
837
+ />
838
+ )
800
839
  },
801
840
  },
802
841
  })
@@ -1,2 +0,0 @@
1
- import{mkdir as q,readFile as M,writeFile as b}from"node:fs/promises";import{tmpdir as L}from"node:os";import{dirname as k,join as g}from"node:path";var R="OPENCODE_ANTHROPIC_AUTH_SIDEBAR_STATE_FILE",f=g(L(),"opencode-anthropic-auth"),I=g(f,"sidebar-state.json");function h(){return process.env[R]||I}var K={main:{quota:null},fallbacks:[],activeId:void 0,route:"main",relay:null,fastMode:!1,lastUpdated:0};function G(J){return J!==null&&typeof J==="object"&&!Array.isArray(J)}function z(J){if(!G(J))return;let X=Number(J.usedPercent),Y=Number(J.remainingPercent);if(!Number.isFinite(X)||!Number.isFinite(Y))return;return{usedPercent:X,remainingPercent:Y,resetsAt:typeof J.resetsAt==="string"?J.resetsAt:void 0}}function N(J){if(!G(J))return null;let X={},Y=z(J.five_hour),Z=z(J.seven_day);if(Y)X.five_hour=Y;if(Z)X.seven_day=Z;if(Array.isArray(J.scoped)){let $=J.scoped.map((x)=>{if(!G(x))return;let j=z(x);if(!j)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 V=typeof x.modelId==="string"&&x.modelId.trim()?x.modelId.trim():void 0;return{...j,id:x.id.trim(),title:x.title.trim(),...V&&{modelId:V},modelName:x.modelName.trim()}}).filter((x)=>x!=null);X.scoped=$}return Object.keys(X).length?X:null}function F(J){if(!G(J))return{...K};let X={quota:null};if(G(J.main)){let x=J.main;if(X.quota=N(x.quota),typeof x.quotaBackedOff==="boolean")X.quotaBackedOff=x.quotaBackedOff;if(typeof x.quotaBackoffUntil==="number")X.quotaBackoffUntil=x.quotaBackoffUntil;if(typeof x.refreshBackedOff==="boolean")X.refreshBackedOff=x.refreshBackedOff;if(typeof x.refreshBackoffUntil==="number")X.refreshBackoffUntil=x.refreshBackoffUntil}let Y=Array.isArray(J.fallbacks)?J.fallbacks.filter(G).filter((x)=>typeof x.id==="string").map((x)=>({id:x.id,label:typeof x.label==="string"?x.label:void 0,quota:N(x.quota),enabled:typeof x.enabled==="boolean"?x.enabled:!1,needsReauth:typeof x.needsReauth==="boolean"?x.needsReauth:!1})):[],Z=null;if(G(J.relay)){let x=J.relay;if(typeof x.enabled==="boolean"&&typeof x.transport==="string")Z={enabled:x.enabled,transport:x.transport}}let $;if(G(J.cacheKeep)){let x=J.cacheKeep;if(typeof x.enabled==="boolean")$={enabled:x.enabled,window:typeof x.window==="string"?x.window:void 0,trackedSessions:typeof x.trackedSessions==="number"?x.trackedSessions:void 0}}return{main:X,fallbacks:Y,activeId:typeof J.activeId==="string"?J.activeId:void 0,route:typeof J.route==="string"?J.route:K.route,relay:Z,fastMode:typeof J.fastMode==="boolean"?J.fastMode:K.fastMode,cacheKeep:$,lastUpdated:typeof J.lastUpdated==="number"?J.lastUpdated:0}}var W=Promise.resolve();async function P(){try{let J=await M(h(),"utf8");return F(JSON.parse(J))}catch{return K}}async function A(J,X=h()){return W=W.then(async()=>{await q(k(X),{recursive:!0}),await b(X,JSON.stringify(J),"utf8")}).catch(()=>{}),W}async function m(){return W}function v(J){let X=J.activeId;if(X&&X!=="main"){let Y=J.fallbacks?.find((Z)=>Z.enabled&&Z.id===X);if(Y)return{id:Y.id,name:Y.label??Y.id,quota:Y.quota}}return{id:"main",name:"main",quota:J.main?.quota??null}}function U(J){let X=J.replace(/\s+only$/i,"").trim();return/^fable$/i.test(X)?"Fa":X}function y(J){let X=J?.five_hour?.usedPercent??null,Y=J?.seven_day?.usedPercent??null,Z=J?.scoped??[],$=Z.map((V)=>V.usedPercent);if(X==null&&Y==null&&Z.length===0)return{fiveHourUsedPercent:X,sevenDayUsedPercent:Y,scopedUsedPercents:$,text:null};let x=Z.map((V)=>`${U(V.title)}: ${Math.round(V.usedPercent)}%`),j=X==null&&Y==null?[]:[`5h: ${X==null?"—":`${Math.round(X)}%`}`,`7d: ${Y==null?"—":`${Math.round(Y)}%`}`];return{fiveHourUsedPercent:X,sevenDayUsedPercent:Y,scopedUsedPercents:$,text:[...j,...x].join(" ")}}var u=18000000,l=604800000,D=300000,_=0.01,p=1;function c(J,X,Y){if(!J.resetsAt)return null;let Z=new Date(J.resetsAt).getTime();if(!Number.isFinite(Z))return null;let $=Z-X,x=Y-$;if(x<D)return null;if(x<X*_)return null;if(x>=X)return null;let j=J.usedPercent,V=Math.min(Math.max(x/X*100,0),100),B=j-V,C=Math.abs(B)<p?"on-pace":B>0?"deficit":"reserve",O=null;if(j>0){let H=x*100/j,Q=$+H;if(Q<Z)O=new Date(Q).toISOString()}return{pacePercent:V,deltaPercent:B,state:C,runsOutAt:O}}
2
- export{h as Db,K as Eb,F as Fb,P as Gb,A as Hb,m as Ib,v as Jb,U as Kb,y as Lb,u as Mb,l as Nb,c as Ob};