@cortexkit/opencode-anthropic-auth 1.17.0 → 1.19.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.
@@ -0,0 +1,25 @@
1
+ export declare const SERVER_SIDE_FALLBACK_BETA = "server-side-fallback-2026-07-01";
2
+ export declare const SERVER_FALLBACK_MARKER_TEXT = "\u2060";
3
+ export declare const SERVER_FALLBACK_SIGNATURE_PREFIX = "cortexkit-server-fallback-v1:";
4
+ export type ContentFilterFallbackMode = 'server' | 'legacy';
5
+ export type ServerSideFallbackOutcome = {
6
+ requestedModel: string;
7
+ servedModel?: string;
8
+ targetModel?: string;
9
+ fallback: boolean;
10
+ handoff: boolean;
11
+ stopReason: string;
12
+ };
13
+ export declare function resolveContentFilterFallbackMode(value: string | undefined): ContentFilterFallbackMode;
14
+ export declare function applyServerSideFallbackToBody(body: Record<string, unknown>, requested: boolean): {
15
+ enabled: boolean;
16
+ restoredMarkers: number;
17
+ droppedMarkers: number;
18
+ };
19
+ export declare function createServerSideFallbackStreamRewriter(options: {
20
+ requestedModel: string;
21
+ onOutcome?: (outcome: ServerSideFallbackOutcome) => void;
22
+ }): {
23
+ push(text: string): string;
24
+ flush(): string;
25
+ };
@@ -41,9 +41,17 @@ export interface SidebarAccountState {
41
41
  }
42
42
  export interface FableRecoverySidebarState {
43
43
  sessionId: string;
44
- mode: 'opus' | 'fable';
44
+ mode: 'opus' | 'fable' | 'server';
45
45
  remaining: number;
46
46
  changedAt: number;
47
+ /**
48
+ * The model id the user originally requested (e.g. 'claude-fable-5' or
49
+ * 'claude-opus-5'). Optional for backward compatibility with pre-Opus-5
50
+ * state files; older recoveries default to Fable 5 in the summary.
51
+ */
52
+ requestedModelId?: string;
53
+ /** Anthropic-selected target while server-side safety fallback is active. */
54
+ targetModelId?: string;
47
55
  }
48
56
  export interface SidebarState {
49
57
  main: {
@@ -112,6 +120,12 @@ export declare function resolveActiveAccount(state: SidebarState): {
112
120
  quota: AccountQuota | null;
113
121
  };
114
122
  export declare function formatScopedQuotaLabel(title: string): string;
123
+ /**
124
+ * Pretty label for a recoverable-refusal source model (Fable 5 or Opus 5).
125
+ * Falls back to the raw id for unrecognized ids so the sidebar never goes
126
+ * blank on a future model that has not yet been cataloged here.
127
+ */
128
+ export declare function formatFallbackModelLabel(modelId: string | undefined): string;
115
129
  export declare function getFableRecoverySummary(state: SidebarState, sessionId: string): string | undefined;
116
130
  export declare function getCollapsedQuotaSummary(quota: AccountQuota | null): {
117
131
  fiveHourUsedPercent: number | null;
@@ -1 +1 @@
1
- import{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q}from"./index-gj7emmj5.js";import"./index-xvfesm3w.js";import"./index-y2n9h7p6.js";import"./index-f5r96vyv.js";export{i as setSidebarState,k as resolveActiveAccount,c as normalizeSidebarState,a as getSidebarStateFile,h as getSidebarState,f as getInitialSidebarRoutingTestHooks,m as getFableRecoverySummary,n as getCollapsedQuotaSummary,l as formatScopedQuotaLabel,j as drainSidebarWrites,q as computeQuotaPacing,d as __setSidebarStateWriteTestHooks,e as __setInitialSidebarRoutingTestHooks,g as __acquireSidebarStateLockForTest,p as SEVEN_DAY_MS,o as FIVE_HOUR_MS,b as DEFAULT_SIDEBAR_STATE};
1
+ import{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r}from"./index-szybnfvk.js";import"./index-h0pmqm96.js";import"./index-1ets4bf8.js";import"./index-9aeag0wm.js";export{i as setSidebarState,k as resolveActiveAccount,c as normalizeSidebarState,a as getSidebarStateFile,h as getSidebarState,f as getInitialSidebarRoutingTestHooks,n as getFableRecoverySummary,o as getCollapsedQuotaSummary,l as formatScopedQuotaLabel,m as formatFallbackModelLabel,j as drainSidebarWrites,r as computeQuotaPacing,d as __setSidebarStateWriteTestHooks,e as __setInitialSidebarRoutingTestHooks,g as __acquireSidebarStateLockForTest,q as SEVEN_DAY_MS,p as FIVE_HOUR_MS,b as DEFAULT_SIDEBAR_STATE};
@@ -1,4 +1,5 @@
1
1
  import { type Cache1hMode, type ClaudeCodeIdentity } from '@cortexkit/anthropic-auth-core';
2
+ import { type ServerSideFallbackOutcome } from './server-fallback';
2
3
  export type FetchInput = string | URL | Request;
3
4
  /**
4
5
  * Merge headers from a Request object and/or a RequestInit headers value
@@ -84,6 +85,7 @@ export declare function rewriteRequestBody(body: string, options?: {
84
85
  identity?: ClaudeCodeIdentity;
85
86
  perf?: RewritePerfCallback;
86
87
  hybridStandbyAnchor?: HybridMessageCacheAnchor;
88
+ serverSideFallbackEnabled?: boolean;
87
89
  }): Promise<string>;
88
90
  /**
89
91
  * Create a streaming response that strips the tool prefix from tool names.
@@ -92,5 +94,8 @@ export declare function createStrippedStream(response: Response, options?: {
92
94
  perf?: RewritePerfCallback;
93
95
  onContentFilter?: () => boolean | undefined;
94
96
  onComplete?: (finishReason: string) => void;
97
+ contentFilterModel?: unknown;
98
+ serverSideFallbackModel?: string;
99
+ onServerSideFallbackOutcome?: (outcome: ServerSideFallbackOutcome) => void;
95
100
  }): Response;
96
101
  export {};
@@ -1,4 +1,4 @@
1
- import{pc as c,qc as C,rc as h}from"./index-f5r96vyv.js";var m=C((v,k)=>{(function(Q){if(typeof k==="object"&&typeof k.exports==="object"){var J=Q(h,v);if(J!==void 0)k.exports=J}else if(typeof define==="function"&&define.amd)define(["require","exports","./impl/format","./impl/edit","./impl/scanner","./impl/parser"],Q)})(function(Q,J){Object.defineProperty(J,"__esModule",{value:!0}),J.applyEdits=J.modify=J.format=J.printParseErrorCode=J.ParseErrorCode=J.stripComments=J.visit=J.getNodeValue=J.getNodePath=J.findNodeAtOffset=J.findNodeAtLocation=J.parseTree=J.parse=J.getLocation=J.SyntaxKind=J.ScanError=J.createScanner=void 0;let X=Q("./impl/format"),Z=Q("./impl/edit"),$=Q("./impl/scanner"),G=Q("./impl/parser");J.createScanner=$.createScanner;var V;(function(z){z[z.None=0]="None",z[z.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",z[z.UnexpectedEndOfString=2]="UnexpectedEndOfString",z[z.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",z[z.InvalidUnicode=4]="InvalidUnicode",z[z.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",z[z.InvalidCharacter=6]="InvalidCharacter"})(V||(J.ScanError=V={}));var Y;(function(z){z[z.OpenBraceToken=1]="OpenBraceToken",z[z.CloseBraceToken=2]="CloseBraceToken",z[z.OpenBracketToken=3]="OpenBracketToken",z[z.CloseBracketToken=4]="CloseBracketToken",z[z.CommaToken=5]="CommaToken",z[z.ColonToken=6]="ColonToken",z[z.NullKeyword=7]="NullKeyword",z[z.TrueKeyword=8]="TrueKeyword",z[z.FalseKeyword=9]="FalseKeyword",z[z.StringLiteral=10]="StringLiteral",z[z.NumericLiteral=11]="NumericLiteral",z[z.LineCommentTrivia=12]="LineCommentTrivia",z[z.BlockCommentTrivia=13]="BlockCommentTrivia",z[z.LineBreakTrivia=14]="LineBreakTrivia",z[z.Trivia=15]="Trivia",z[z.Unknown=16]="Unknown",z[z.EOF=17]="EOF"})(Y||(J.SyntaxKind=Y={})),J.getLocation=G.getLocation,J.parse=G.parse,J.parseTree=G.parseTree,J.findNodeAtLocation=G.findNodeAtLocation,J.findNodeAtOffset=G.findNodeAtOffset,J.getNodePath=G.getNodePath,J.getNodeValue=G.getNodeValue,J.visit=G.visit,J.stripComments=G.stripComments;var L;(function(z){z[z.InvalidSymbol=1]="InvalidSymbol",z[z.InvalidNumberFormat=2]="InvalidNumberFormat",z[z.PropertyNameExpected=3]="PropertyNameExpected",z[z.ValueExpected=4]="ValueExpected",z[z.ColonExpected=5]="ColonExpected",z[z.CommaExpected=6]="CommaExpected",z[z.CloseBraceExpected=7]="CloseBraceExpected",z[z.CloseBracketExpected=8]="CloseBracketExpected",z[z.EndOfFileExpected=9]="EndOfFileExpected",z[z.InvalidCommentToken=10]="InvalidCommentToken",z[z.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",z[z.UnexpectedEndOfString=12]="UnexpectedEndOfString",z[z.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",z[z.InvalidUnicode=14]="InvalidUnicode",z[z.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",z[z.InvalidCharacter=16]="InvalidCharacter"})(L||(J.ParseErrorCode=L={}));function B(z){switch(z){case 1:return"InvalidSymbol";case 2:return"InvalidNumberFormat";case 3:return"PropertyNameExpected";case 4:return"ValueExpected";case 5:return"ColonExpected";case 6:return"CommaExpected";case 7:return"CloseBraceExpected";case 8:return"CloseBracketExpected";case 9:return"EndOfFileExpected";case 10:return"InvalidCommentToken";case 11:return"UnexpectedEndOfComment";case 12:return"UnexpectedEndOfString";case 13:return"UnexpectedEndOfNumber";case 14:return"InvalidUnicode";case 15:return"InvalidEscapeCharacter";case 16:return"InvalidCharacter"}return"<unknown ParseErrorCode>"}J.printParseErrorCode=B;function j(z,H,N){return X.format(z,H,N)}J.format=j;function A(z,H,N,R){return Z.setProperty(z,H,N,R)}J.modify=A;function O(z,H){let N=H.slice(0).sort((U,D)=>{let T=U.offset-D.offset;if(T===0)return U.length-D.length;return T}),R=z.length;for(let U=N.length-1;U>=0;U--){let D=N[U];if(D.offset+D.length<=R)z=Z.applyEdit(z,D);else throw Error("Overlapping edit");R=D.offset}return z}J.applyEdits=O})});var q=c(m(),1);import{watch as y}from"node:fs";import{mkdir as S,readFile as w,rename as E,writeFile as p}from"node:fs/promises";import{homedir as l}from"node:os";import{basename as x,dirname as P,join as _}from"node:path";import{clearTimeout as F,setTimeout as f}from"node:timers";var i="OPENCODE_TUI_PREFERENCES_FILE",s="tui-preferences.jsonc";function b(){let Q=process.env[i];if(Q)return Q;let J=process.env.OPENCODE_CONFIG_DIR||_(process.env.XDG_CONFIG_HOME||_(l(),".config"),"opencode");return _(J,s)}function I(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}async function Vz(){try{let Q=await w(b(),"utf8"),J=[],X=q.parse(Q,J,{allowTrailingComma:!0});if(J.length>0)return{};return I(X)?X:{}}catch{return{}}}var d="anthropic-auth",n=160,u={forceToTop:!1,order:n,startCollapsed:!1,rememberCollapsed:!0,collapsed:null,pollMs:1500,refreshDebounceMs:200,header:{label:"CLAUDE",showVersion:!0},sections:{quota:!0,fallbackAccounts:!0,routing:!0,cache:!0,health:!0,pacing:!0},appearance:{barWidth:10,barFilledChar:"█",barEmptyChar:"░",warnThreshold:50,errorThreshold:80}};function W(Q,J){return typeof Q==="boolean"?Q:J}function M(Q,J,X,Z){if(typeof Q!=="number"||!Number.isFinite(Q))return J;return Math.min(Math.max(Math.round(Q),X),Z)}function a(Q,J,X){if(typeof Q!=="string"||Q.length===0)return J;return Q.slice(0,X)}function K(Q,J){if(typeof Q!=="string")return J;return[...Q][0]??J}function Yz(Q){let J=Q[d];if(!I(J))return structuredClone(u);let X=u,Z=I(J.header)?J.header:{},$=I(J.sections)?J.sections:{},G=I(J.appearance)?J.appearance:{},V=M(G.warnThreshold,X.appearance.warnThreshold,0,99),Y=Math.max(M(G.errorThreshold,X.appearance.errorThreshold,0,100),Math.min(V+1,100));return{forceToTop:W(J.forceToTop,X.forceToTop),order:M(J.order,X.order,-1e4,1e4),startCollapsed:W(J.startCollapsed,X.startCollapsed),rememberCollapsed:W(J.rememberCollapsed,X.rememberCollapsed),collapsed:typeof J.collapsed==="boolean"?J.collapsed:null,pollMs:M(J.pollMs,X.pollMs,500,30000),refreshDebounceMs:M(J.refreshDebounceMs,X.refreshDebounceMs,50,5000),header:{label:a(Z.label,X.header.label,20),showVersion:W(Z.showVersion,X.header.showVersion)},sections:{quota:W($.quota,X.sections.quota),fallbackAccounts:W($.fallbackAccounts,X.sections.fallbackAccounts),routing:W($.routing,X.sections.routing),cache:W($.cache,X.sections.cache),health:W($.health,X.sections.health),pacing:W($.pacing,X.sections.pacing)},appearance:{barWidth:M(G.barWidth,X.appearance.barWidth,4,40),barFilledChar:K(G.barFilledChar,X.appearance.barFilledChar),barEmptyChar:K(G.barEmptyChar,X.appearance.barEmptyChar),warnThreshold:V,errorThreshold:Y}}}var t=-1e5;function Hz(Q,J,X){let Z=Q[J];if(!I(Z))return X;if(Z.forceToTop===!0)return t+Object.keys(Q).indexOf(J);return M(Z.order,X,-1e4,1e4)}var o=`// Shared preferences for opencode TUI plugins.
1
+ import{sc as c,tc as C,uc as h}from"./index-9aeag0wm.js";var m=C((v,k)=>{(function(Q){if(typeof k==="object"&&typeof k.exports==="object"){var J=Q(h,v);if(J!==void 0)k.exports=J}else if(typeof define==="function"&&define.amd)define(["require","exports","./impl/format","./impl/edit","./impl/scanner","./impl/parser"],Q)})(function(Q,J){Object.defineProperty(J,"__esModule",{value:!0}),J.applyEdits=J.modify=J.format=J.printParseErrorCode=J.ParseErrorCode=J.stripComments=J.visit=J.getNodeValue=J.getNodePath=J.findNodeAtOffset=J.findNodeAtLocation=J.parseTree=J.parse=J.getLocation=J.SyntaxKind=J.ScanError=J.createScanner=void 0;let X=Q("./impl/format"),Z=Q("./impl/edit"),$=Q("./impl/scanner"),G=Q("./impl/parser");J.createScanner=$.createScanner;var V;(function(z){z[z.None=0]="None",z[z.UnexpectedEndOfComment=1]="UnexpectedEndOfComment",z[z.UnexpectedEndOfString=2]="UnexpectedEndOfString",z[z.UnexpectedEndOfNumber=3]="UnexpectedEndOfNumber",z[z.InvalidUnicode=4]="InvalidUnicode",z[z.InvalidEscapeCharacter=5]="InvalidEscapeCharacter",z[z.InvalidCharacter=6]="InvalidCharacter"})(V||(J.ScanError=V={}));var Y;(function(z){z[z.OpenBraceToken=1]="OpenBraceToken",z[z.CloseBraceToken=2]="CloseBraceToken",z[z.OpenBracketToken=3]="OpenBracketToken",z[z.CloseBracketToken=4]="CloseBracketToken",z[z.CommaToken=5]="CommaToken",z[z.ColonToken=6]="ColonToken",z[z.NullKeyword=7]="NullKeyword",z[z.TrueKeyword=8]="TrueKeyword",z[z.FalseKeyword=9]="FalseKeyword",z[z.StringLiteral=10]="StringLiteral",z[z.NumericLiteral=11]="NumericLiteral",z[z.LineCommentTrivia=12]="LineCommentTrivia",z[z.BlockCommentTrivia=13]="BlockCommentTrivia",z[z.LineBreakTrivia=14]="LineBreakTrivia",z[z.Trivia=15]="Trivia",z[z.Unknown=16]="Unknown",z[z.EOF=17]="EOF"})(Y||(J.SyntaxKind=Y={})),J.getLocation=G.getLocation,J.parse=G.parse,J.parseTree=G.parseTree,J.findNodeAtLocation=G.findNodeAtLocation,J.findNodeAtOffset=G.findNodeAtOffset,J.getNodePath=G.getNodePath,J.getNodeValue=G.getNodeValue,J.visit=G.visit,J.stripComments=G.stripComments;var L;(function(z){z[z.InvalidSymbol=1]="InvalidSymbol",z[z.InvalidNumberFormat=2]="InvalidNumberFormat",z[z.PropertyNameExpected=3]="PropertyNameExpected",z[z.ValueExpected=4]="ValueExpected",z[z.ColonExpected=5]="ColonExpected",z[z.CommaExpected=6]="CommaExpected",z[z.CloseBraceExpected=7]="CloseBraceExpected",z[z.CloseBracketExpected=8]="CloseBracketExpected",z[z.EndOfFileExpected=9]="EndOfFileExpected",z[z.InvalidCommentToken=10]="InvalidCommentToken",z[z.UnexpectedEndOfComment=11]="UnexpectedEndOfComment",z[z.UnexpectedEndOfString=12]="UnexpectedEndOfString",z[z.UnexpectedEndOfNumber=13]="UnexpectedEndOfNumber",z[z.InvalidUnicode=14]="InvalidUnicode",z[z.InvalidEscapeCharacter=15]="InvalidEscapeCharacter",z[z.InvalidCharacter=16]="InvalidCharacter"})(L||(J.ParseErrorCode=L={}));function B(z){switch(z){case 1:return"InvalidSymbol";case 2:return"InvalidNumberFormat";case 3:return"PropertyNameExpected";case 4:return"ValueExpected";case 5:return"ColonExpected";case 6:return"CommaExpected";case 7:return"CloseBraceExpected";case 8:return"CloseBracketExpected";case 9:return"EndOfFileExpected";case 10:return"InvalidCommentToken";case 11:return"UnexpectedEndOfComment";case 12:return"UnexpectedEndOfString";case 13:return"UnexpectedEndOfNumber";case 14:return"InvalidUnicode";case 15:return"InvalidEscapeCharacter";case 16:return"InvalidCharacter"}return"<unknown ParseErrorCode>"}J.printParseErrorCode=B;function j(z,H,N){return X.format(z,H,N)}J.format=j;function A(z,H,N,R){return Z.setProperty(z,H,N,R)}J.modify=A;function O(z,H){let N=H.slice(0).sort((U,D)=>{let T=U.offset-D.offset;if(T===0)return U.length-D.length;return T}),R=z.length;for(let U=N.length-1;U>=0;U--){let D=N[U];if(D.offset+D.length<=R)z=Z.applyEdit(z,D);else throw Error("Overlapping edit");R=D.offset}return z}J.applyEdits=O})});var q=c(m(),1);import{watch as y}from"node:fs";import{mkdir as S,readFile as w,rename as E,writeFile as p}from"node:fs/promises";import{homedir as l}from"node:os";import{basename as x,dirname as P,join as _}from"node:path";import{clearTimeout as F,setTimeout as f}from"node:timers";var i="OPENCODE_TUI_PREFERENCES_FILE",s="tui-preferences.jsonc";function b(){let Q=process.env[i];if(Q)return Q;let J=process.env.OPENCODE_CONFIG_DIR||_(process.env.XDG_CONFIG_HOME||_(l(),".config"),"opencode");return _(J,s)}function I(Q){return typeof Q==="object"&&Q!==null&&!Array.isArray(Q)}async function Vz(){try{let Q=await w(b(),"utf8"),J=[],X=q.parse(Q,J,{allowTrailingComma:!0});if(J.length>0)return{};return I(X)?X:{}}catch{return{}}}var d="anthropic-auth",n=160,u={forceToTop:!1,order:n,startCollapsed:!1,rememberCollapsed:!0,collapsed:null,pollMs:1500,refreshDebounceMs:200,header:{label:"CLAUDE",showVersion:!0},sections:{quota:!0,fallbackAccounts:!0,routing:!0,cache:!0,health:!0,pacing:!0},appearance:{barWidth:10,barFilledChar:"█",barEmptyChar:"░",warnThreshold:50,errorThreshold:80}};function W(Q,J){return typeof Q==="boolean"?Q:J}function M(Q,J,X,Z){if(typeof Q!=="number"||!Number.isFinite(Q))return J;return Math.min(Math.max(Math.round(Q),X),Z)}function a(Q,J,X){if(typeof Q!=="string"||Q.length===0)return J;return Q.slice(0,X)}function K(Q,J){if(typeof Q!=="string")return J;return[...Q][0]??J}function Yz(Q){let J=Q[d];if(!I(J))return structuredClone(u);let X=u,Z=I(J.header)?J.header:{},$=I(J.sections)?J.sections:{},G=I(J.appearance)?J.appearance:{},V=M(G.warnThreshold,X.appearance.warnThreshold,0,99),Y=Math.max(M(G.errorThreshold,X.appearance.errorThreshold,0,100),Math.min(V+1,100));return{forceToTop:W(J.forceToTop,X.forceToTop),order:M(J.order,X.order,-1e4,1e4),startCollapsed:W(J.startCollapsed,X.startCollapsed),rememberCollapsed:W(J.rememberCollapsed,X.rememberCollapsed),collapsed:typeof J.collapsed==="boolean"?J.collapsed:null,pollMs:M(J.pollMs,X.pollMs,500,30000),refreshDebounceMs:M(J.refreshDebounceMs,X.refreshDebounceMs,50,5000),header:{label:a(Z.label,X.header.label,20),showVersion:W(Z.showVersion,X.header.showVersion)},sections:{quota:W($.quota,X.sections.quota),fallbackAccounts:W($.fallbackAccounts,X.sections.fallbackAccounts),routing:W($.routing,X.sections.routing),cache:W($.cache,X.sections.cache),health:W($.health,X.sections.health),pacing:W($.pacing,X.sections.pacing)},appearance:{barWidth:M(G.barWidth,X.appearance.barWidth,4,40),barFilledChar:K(G.barFilledChar,X.appearance.barFilledChar),barEmptyChar:K(G.barEmptyChar,X.appearance.barEmptyChar),warnThreshold:V,errorThreshold:Y}}}var t=-1e5;function Hz(Q,J,X){let Z=Q[J];if(!I(Z))return X;if(Z.forceToTop===!0)return t+Object.keys(Q).indexOf(J);return M(Z.order,X,-1e4,1e4)}var o=`// Shared preferences for opencode TUI plugins.
2
2
  // One top-level key per plugin (short name). See each plugin's README for
3
3
  // its supported settings. This file is safe to hand-edit; plugins update
4
4
  // individual keys in place and preserve comments.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-anthropic-auth",
3
- "version": "1.17.0",
3
+ "version": "1.19.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -61,7 +61,7 @@
61
61
  "@opencode-ai/plugin": "*"
62
62
  },
63
63
  "dependencies": {
64
- "@cortexkit/anthropic-auth-core": "1.17.0",
64
+ "@cortexkit/anthropic-auth-core": "1.19.0",
65
65
  "@opentui/core": "0.4.3",
66
66
  "@opentui/solid": "0.4.3",
67
67
  "jsonc-parser": "^3.3.1",
@@ -39,9 +39,17 @@ export interface SidebarAccountState {
39
39
 
40
40
  export interface FableRecoverySidebarState {
41
41
  sessionId: string
42
- mode: 'opus' | 'fable'
42
+ mode: 'opus' | 'fable' | 'server'
43
43
  remaining: number
44
44
  changedAt: number
45
+ /**
46
+ * The model id the user originally requested (e.g. 'claude-fable-5' or
47
+ * 'claude-opus-5'). Optional for backward compatibility with pre-Opus-5
48
+ * state files; older recoveries default to Fable 5 in the summary.
49
+ */
50
+ requestedModelId?: string
51
+ /** Anthropic-selected target while server-side safety fallback is active. */
52
+ targetModelId?: string
45
53
  }
46
54
 
47
55
  export interface SidebarState {
@@ -274,7 +282,9 @@ export function normalizeSidebarState(raw: unknown): SidebarState {
274
282
  .flatMap((recovery): FableRecoverySidebarState[] => {
275
283
  if (
276
284
  typeof recovery.sessionId !== 'string' ||
277
- (recovery.mode !== 'opus' && recovery.mode !== 'fable') ||
285
+ (recovery.mode !== 'opus' &&
286
+ recovery.mode !== 'fable' &&
287
+ recovery.mode !== 'server') ||
278
288
  typeof recovery.remaining !== 'number' ||
279
289
  !Number.isFinite(recovery.remaining) ||
280
290
  typeof recovery.changedAt !== 'number' ||
@@ -287,6 +297,14 @@ export function normalizeSidebarState(raw: unknown): SidebarState {
287
297
  mode: recovery.mode,
288
298
  remaining: Math.max(0, Math.floor(recovery.remaining)),
289
299
  changedAt: recovery.changedAt,
300
+ requestedModelId:
301
+ typeof recovery.requestedModelId === 'string'
302
+ ? recovery.requestedModelId
303
+ : undefined,
304
+ targetModelId:
305
+ typeof recovery.targetModelId === 'string'
306
+ ? recovery.targetModelId
307
+ : undefined,
290
308
  },
291
309
  ]
292
310
  })
@@ -677,6 +695,21 @@ export function formatScopedQuotaLabel(title: string) {
677
695
  return /^fable$/i.test(label) ? 'Fa' : label
678
696
  }
679
697
 
698
+ /**
699
+ * Pretty label for a recoverable-refusal source model (Fable 5 or Opus 5).
700
+ * Falls back to the raw id for unrecognized ids so the sidebar never goes
701
+ * blank on a future model that has not yet been cataloged here.
702
+ */
703
+ export function formatFallbackModelLabel(modelId: string | undefined): string {
704
+ if (modelId === 'claude-fable-5' || modelId?.startsWith('claude-fable-5-'))
705
+ return 'Fable 5'
706
+ if (modelId === 'claude-opus-5' || modelId?.startsWith('claude-opus-5-'))
707
+ return 'Opus 5'
708
+ if (modelId === 'claude-opus-4-8' || modelId?.startsWith('claude-opus-4-8-'))
709
+ return 'Opus 4.8'
710
+ return modelId ?? 'Fable 5'
711
+ }
712
+
680
713
  export function getFableRecoverySummary(
681
714
  state: SidebarState,
682
715
  sessionId: string,
@@ -685,7 +718,12 @@ export function getFableRecoverySummary(
685
718
  (candidate) => candidate.sessionId === sessionId,
686
719
  )
687
720
  if (!recovery) return undefined
688
- if (recovery.mode === 'fable') return 'Fable 5 · restored'
721
+ if (recovery.mode === 'fable') {
722
+ return `${formatFallbackModelLabel(recovery.requestedModelId)} · restored`
723
+ }
724
+ if (recovery.mode === 'server') {
725
+ return `${formatFallbackModelLabel(recovery.requestedModelId)}→${formatFallbackModelLabel(recovery.targetModelId)} · safety`
726
+ }
689
727
  return `Opus 4.8 · ${recovery.remaining} left`
690
728
  }
691
729
 
@@ -39,9 +39,17 @@ export interface SidebarAccountState {
39
39
 
40
40
  export interface FableRecoverySidebarState {
41
41
  sessionId: string
42
- mode: 'opus' | 'fable'
42
+ mode: 'opus' | 'fable' | 'server'
43
43
  remaining: number
44
44
  changedAt: number
45
+ /**
46
+ * The model id the user originally requested (e.g. 'claude-fable-5' or
47
+ * 'claude-opus-5'). Optional for backward compatibility with pre-Opus-5
48
+ * state files; older recoveries default to Fable 5 in the summary.
49
+ */
50
+ requestedModelId?: string
51
+ /** Anthropic-selected target while server-side safety fallback is active. */
52
+ targetModelId?: string
45
53
  }
46
54
 
47
55
  export interface SidebarState {
@@ -274,7 +282,9 @@ export function normalizeSidebarState(raw: unknown): SidebarState {
274
282
  .flatMap((recovery): FableRecoverySidebarState[] => {
275
283
  if (
276
284
  typeof recovery.sessionId !== 'string' ||
277
- (recovery.mode !== 'opus' && recovery.mode !== 'fable') ||
285
+ (recovery.mode !== 'opus' &&
286
+ recovery.mode !== 'fable' &&
287
+ recovery.mode !== 'server') ||
278
288
  typeof recovery.remaining !== 'number' ||
279
289
  !Number.isFinite(recovery.remaining) ||
280
290
  typeof recovery.changedAt !== 'number' ||
@@ -287,6 +297,14 @@ export function normalizeSidebarState(raw: unknown): SidebarState {
287
297
  mode: recovery.mode,
288
298
  remaining: Math.max(0, Math.floor(recovery.remaining)),
289
299
  changedAt: recovery.changedAt,
300
+ requestedModelId:
301
+ typeof recovery.requestedModelId === 'string'
302
+ ? recovery.requestedModelId
303
+ : undefined,
304
+ targetModelId:
305
+ typeof recovery.targetModelId === 'string'
306
+ ? recovery.targetModelId
307
+ : undefined,
290
308
  },
291
309
  ]
292
310
  })
@@ -677,6 +695,21 @@ export function formatScopedQuotaLabel(title: string) {
677
695
  return /^fable$/i.test(label) ? 'Fa' : label
678
696
  }
679
697
 
698
+ /**
699
+ * Pretty label for a recoverable-refusal source model (Fable 5 or Opus 5).
700
+ * Falls back to the raw id for unrecognized ids so the sidebar never goes
701
+ * blank on a future model that has not yet been cataloged here.
702
+ */
703
+ export function formatFallbackModelLabel(modelId: string | undefined): string {
704
+ if (modelId === 'claude-fable-5' || modelId?.startsWith('claude-fable-5-'))
705
+ return 'Fable 5'
706
+ if (modelId === 'claude-opus-5' || modelId?.startsWith('claude-opus-5-'))
707
+ return 'Opus 5'
708
+ if (modelId === 'claude-opus-4-8' || modelId?.startsWith('claude-opus-4-8-'))
709
+ return 'Opus 4.8'
710
+ return modelId ?? 'Fable 5'
711
+ }
712
+
680
713
  export function getFableRecoverySummary(
681
714
  state: SidebarState,
682
715
  sessionId: string,
@@ -685,7 +718,12 @@ export function getFableRecoverySummary(
685
718
  (candidate) => candidate.sessionId === sessionId,
686
719
  )
687
720
  if (!recovery) return undefined
688
- if (recovery.mode === 'fable') return 'Fable 5 · restored'
721
+ if (recovery.mode === 'fable') {
722
+ return `${formatFallbackModelLabel(recovery.requestedModelId)} · restored`
723
+ }
724
+ if (recovery.mode === 'server') {
725
+ return `${formatFallbackModelLabel(recovery.requestedModelId)}→${formatFallbackModelLabel(recovery.targetModelId)} · safety`
726
+ }
689
727
  return `Opus 4.8 · ${recovery.remaining} left`
690
728
  }
691
729
 
@@ -682,7 +682,7 @@ function QuotaSidebar(props) {
682
682
  const needsReauth = () => enabledFallbacks().some(f => f.needsReauth);
683
683
  const degraded = () => quotaBackedOff() || refreshBackedOff() || needsReauth();
684
684
  const fableRecoverySummary = () => getFableRecoverySummary(state(), props.sessionId);
685
- const fableRecoveryTone = () => state().fableRecoveries?.find(recovery => recovery.sessionId === props.sessionId)?.mode === 'opus' ? 'warn' : 'ok';
685
+ const fableRecoveryTone = () => state().fableRecoveries?.find(recovery => recovery.sessionId === props.sessionId)?.mode === 'fable' ? 'ok' : 'warn';
686
686
  const cacheKeep = () => state().cacheKeep;
687
687
  const showCache = () => prefs().sections.cache && cacheKeep() != null && cacheKeep()?.window != null;
688
688
  const relayValue = () => {
package/src/tui.tsx CHANGED
@@ -644,9 +644,9 @@ function QuotaSidebar(props: {
644
644
  const fableRecoveryTone = (): Tone =>
645
645
  state().fableRecoveries?.find(
646
646
  (recovery) => recovery.sessionId === props.sessionId,
647
- )?.mode === 'opus'
648
- ? 'warn'
649
- : 'ok'
647
+ )?.mode === 'fable'
648
+ ? 'ok'
649
+ : 'warn'
650
650
  const cacheKeep = () => state().cacheKeep
651
651
  const showCache = () =>
652
652
  prefs().sections.cache && cacheKeep() != null && cacheKeep()?.window != null
@@ -1,2 +0,0 @@
1
- import{ic as Q}from"./index-y2n9h7p6.js";import{randomUUID as f}from"node:crypto";import{mkdir as P,readFile as D,rename as b,rm as O,rmdir as T,stat as U,unlink as p,writeFile as E}from"node:fs/promises";import{tmpdir as k}from"node:os";import{dirname as S,join as W}from"node:path";var F="OPENCODE_ANTHROPIC_AUTH_SIDEBAR_STATE_FILE",m=W(k(),"opencode-anthropic-auth"),y=W(m,"sidebar-state.json");function R(){return process.env[F]||y}var C={main:{quota:null},fallbacks:[],activeId:void 0,route:"main",relay:null,fastMode:!1,lastUpdated:0};function N(J){return J!==null&&typeof J==="object"&&!Array.isArray(J)}function q(J){if(!N(J))return;let $=Number(J.usedPercent),V=Number(J.remainingPercent);if(!Number.isFinite($)||!Number.isFinite(V))return;return{usedPercent:$,remainingPercent:V,resetsAt:typeof J.resetsAt==="string"?J.resetsAt:void 0}}function I(J){if(!N(J))return null;let $={},V=q(J.five_hour),x=q(J.seven_day);if(V)$.five_hour=V;if(x)$.seven_day=x;if(Array.isArray(J.scoped)){let G=J.scoped.map((X)=>{if(!N(X))return;let Z=q(X);if(!Z)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{...Z,id:X.id.trim(),title:X.title.trim(),...j&&{modelId:j},modelName:X.modelName.trim()}}).filter((X)=>X!=null);$.scoped=G}if(N(J.extraUsage)){let G=L(J.extraUsage.used),X=L(J.extraUsage.limit);if(G&&X&&typeof J.extraUsage.exhausted==="boolean")$.extraUsage={used:G,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())$.bindingWindow=J.bindingWindow.trim();if(typeof J.fallbackAdvised==="boolean")$.fallbackAdvised=J.fallbackAdvised;return Object.keys($).length?$:null}function L(J){if(!N(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 w(J){if(!N(J))return{...C};let $={quota:null};if(N(J.main)){let Z=J.main;if($.quota=I(Z.quota),typeof Z.tierLabel==="string"&&Z.tierLabel.trim())$.tierLabel=Z.tierLabel.trim();if(typeof Z.quotaBackedOff==="boolean")$.quotaBackedOff=Z.quotaBackedOff;if(typeof Z.quotaBackoffUntil==="number")$.quotaBackoffUntil=Z.quotaBackoffUntil;if(typeof Z.refreshBackedOff==="boolean")$.refreshBackedOff=Z.refreshBackedOff;if(typeof Z.refreshBackoffUntil==="number")$.refreshBackoffUntil=Z.refreshBackoffUntil}let V=Array.isArray(J.fallbacks)?J.fallbacks.filter(N).filter((Z)=>typeof Z.id==="string").map((Z)=>({id:Z.id,label:typeof Z.label==="string"?Z.label:void 0,quota:I(Z.quota),enabled:typeof Z.enabled==="boolean"?Z.enabled:!1,needsReauth:typeof Z.needsReauth==="boolean"?Z.needsReauth:!1,tierLabel:typeof Z.tierLabel==="string"&&Z.tierLabel.trim()?Z.tierLabel.trim():void 0})):[],x=null;if(N(J.relay)){let Z=J.relay;if(typeof Z.enabled==="boolean"&&typeof Z.transport==="string")x={enabled:Z.enabled,transport:Z.transport}}let G;if(N(J.cacheKeep)){let Z=J.cacheKeep;if(typeof Z.enabled==="boolean")G={enabled:Z.enabled,window:typeof Z.window==="string"?Z.window:void 0,trackedSessions:typeof Z.trackedSessions==="number"?Z.trackedSessions:void 0}}let X=Array.isArray(J.fableRecoveries)?J.fableRecoveries.filter(N).flatMap((Z)=>{if(typeof Z.sessionId!=="string"||Z.mode!=="opus"&&Z.mode!=="fable"||typeof Z.remaining!=="number"||!Number.isFinite(Z.remaining)||typeof Z.changedAt!=="number"||!Number.isFinite(Z.changedAt))return[];return[{sessionId:Z.sessionId,mode:Z.mode,remaining:Math.max(0,Math.floor(Z.remaining)),changedAt:Z.changedAt}]}):[];return{main:$,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:G,fableRecoveries:X.length>0?X:void 0,lastUpdated:typeof J.lastUpdated==="number"?J.lastUpdated:0}}var h=Promise.resolve(),v=1000,d=2000,c=5,u=15,z=null;function $J(J){z=J}var _=null;function VJ(J){_=J}function XJ(){return _}function l(J){return new Promise(($)=>setTimeout($,J))}async function A(J){let $=`${J}.lock`,V=z?.lockBudgetMs??v,x=z?.lockRetryMinMs??c,G=z?.lockRetryMaxMs??u,X=Date.now()+V;while(!0){try{await P($);let Y=f(),K=W($,Y);return await E(K,"",{encoding:"utf8",mode:384,flag:"wx"}),await z?.onLockAcquired?.($),{ownsLock:async()=>{try{return await U(K),!0}catch{return!1}},release:async()=>{try{await p(K)}catch{return}await z?.beforeReleaseDirectoryRemoval?.($),await T($).catch(()=>{})}}}catch(Y){if(Y.code!=="EEXIST")return Q.trace("sidebar","state lock unavailable; write skipped",{stateFile:J,error:Y instanceof Error?Y.message:String(Y)}),null}try{let Y=await U($);if(Date.now()-Y.mtimeMs>d){await z?.afterStaleLockStat?.($);let K=`${$}.evict-${process.pid}-${f()}`;try{await b($,K)}catch(B){if(B.code==="ENOENT")continue;throw B}await z?.onStaleLockClaimed?.($),await O(K,{recursive:!0,force:!0}).catch(()=>{});continue}}catch(Y){if(Y.code==="ENOENT")continue;return Q.trace("sidebar","state lock inspection failed; write skipped",{stateFile:J,error:Y instanceof Error?Y.message:String(Y)}),null}let Z=X-Date.now();if(Z<=0)return Q.warn("sidebar","lock budget exhausted, write skipped",{stateFile:J,budgetMs:V}),null;let j=x+Math.floor(Math.random()*(G-x+1));await l(Math.min(j,Z))}}async function xJ(J){return(await A(J))?.release??null}async function n(J,$,V){let x=`${J}.${process.pid}.${f()}.tmp`;await E(x,JSON.stringify($),{encoding:"utf8",mode:384});try{if(!await V())return Q.trace("sidebar","state lock lost before rename; write aborted",{stateFile:J}),await O(x,{force:!0}).catch(()=>{}),"lock-lost-before-rename";if(await z?.beforeRename?.(J,x),!await V())return Q.trace("sidebar","state lock lost before rename; write aborted",{stateFile:J}),await O(x,{force:!0}).catch(()=>{}),"lock-lost-before-rename";if(await b(x,J),await z?.afterRename?.(J),!await V())return"lock-lost-after-rename";return"written"}catch(G){throw await O(x,{force:!0}).catch(()=>{}),G}}async function M(J=R()){try{let $=await D(J,"utf8");return w(JSON.parse($))}catch{return C}}async function YJ(J,$=R(),V={}){return h=h.then(async()=>{await P(S($),{recursive:!0});for(let x=0;x<2;x++){let G=x===1,X=await A($);if(!X){if(G)Q.warn("sidebar","post-rename repair lock unavailable; write skipped",{stateFile:$});return}let Z=J,j;try{if(V.routingAuthoritative===!1){let Y=await M($),K=await V.resolvePreservedRouting?.(Y);if(K){let B=K.state??J;Z={...B,activeId:K.activeId,route:K.route,lastUpdated:Math.max(B.lastUpdated,Y.lastUpdated)}}await z?.afterMergeRead?.($)}else if(G){let Y=await M($);Z={...Y,activeId:J.activeId,route:J.route,relay:J.relay,fastMode:J.fastMode,cacheKeep:J.cacheKeep,lastUpdated:Math.max(Y.lastUpdated,J.lastUpdated)}}j=await n($,Z,X.ownsLock)}finally{await X.release()}if(j==="lock-lost-after-rename"){if(G){Q.warn("sidebar","post-rename repair lost lock; write skipped",{stateFile:$});return}Q.warn("sidebar","state lock lost after rename; repairing write",{stateFile:$});continue}if(j==="lock-lost-before-rename")return;V.onRoutingResolved?.({activeId:Z.activeId,route:Z.route});return}}).catch(()=>{}),h}async function GJ(){return h}function jJ(J){let $=J.activeId;if($&&$!=="main"){let V=J.fallbacks?.find((x)=>x.enabled&&x.id===$);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 i(J){let $=J.replace(/\s+only$/i,"").trim();return/^fable$/i.test($)?"Fa":$}function KJ(J,$){let V=J.fableRecoveries?.find((x)=>x.sessionId===$);if(!V)return;if(V.mode==="fable")return"Fable 5 · restored";return`Opus 4.8 · ${V.remaining} left`}function zJ(J){let $=J?.five_hour?.usedPercent??null,V=J?.seven_day?.usedPercent??null,x=J?.scoped??[],G=x.map((j)=>j.usedPercent);if($==null&&V==null&&x.length===0)return{fiveHourUsedPercent:$,sevenDayUsedPercent:V,scopedUsedPercents:G,text:null};let X=x.map((j)=>`${i(j.title)}: ${Math.round(j.usedPercent)}%`),Z=$==null&&V==null?[]:[`5h: ${$==null?"—":`${Math.round($)}%`}`,`7d: ${V==null?"—":`${Math.round(V)}%`}`];return{fiveHourUsedPercent:$,sevenDayUsedPercent:V,scopedUsedPercents:G,text:[...Z,...X].join(" ")}}var NJ=18000000,QJ=604800000,s=300000,o=0.01,a=1;function BJ(J,$,V){if(!J.resetsAt)return null;let x=new Date(J.resetsAt).getTime();if(!Number.isFinite(x))return null;let G=x-$,X=V-G;if(X<s)return null;if(X<$*o)return null;if(X>=$)return null;let Z=J.usedPercent,j=Math.min(Math.max(X/$*100,0),100),Y=Z-j,K=Math.abs(Y)<a?"on-pace":Y>0?"deficit":"reserve",B=null;if(Z>0){let g=X*100/Z,H=G+g;if(H<x)B=new Date(H).toISOString()}return{pacePercent:j,deltaPercent:Y,state:K,runsOutAt:B}}
2
- export{R as a,C as b,w as c,$J as d,VJ as e,XJ as f,xJ as g,M as h,YJ as i,GJ as j,jJ as k,i as l,KJ as m,zJ as n,NJ as o,QJ as p,BJ as q};