@cortexkit/opencode-anthropic-auth 1.12.2 → 1.13.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 +8 -5
- package/dist/cli.js +5 -5
- package/dist/{index-ptdkq8gx.js → index-1gc9eney.js} +1 -1
- package/dist/index-9053h96k.js +417 -0
- package/dist/{index-9rxvhx0b.js → index-97vmbv5w.js} +1 -1
- package/dist/index-bk5avdcz.js +2 -0
- package/dist/{index-ggyzz0xr.js → index-ha0gz07d.js} +1 -1
- package/dist/{index-z86v5q5a.js → index-se4sd5kz.js} +1 -1
- package/dist/index.d.ts +37 -0
- package/dist/index.js +11 -11
- package/dist/{logger-59cepv7b.js → logger-sg9wxpvj.js} +1 -1
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/sidebar-state.d.ts +9 -0
- package/dist/sidebar-state.js +1 -1
- package/dist/tui/command-dialogs.d.ts +6 -0
- package/dist/tui-preferences.js +1 -1
- package/package.json +2 -2
- package/src/sidebar-state.ts +92 -5
- package/src/tui/command-dialogs.tsx +29 -19
- package/src/tui.tsx +26 -1
- package/dist/index-67j80sm1.js +0 -417
- package/dist/index-erkja50x.js +0 -2
package/README.md
CHANGED
|
@@ -179,7 +179,7 @@ Example:
|
|
|
179
179
|
},
|
|
180
180
|
"killswitch": {
|
|
181
181
|
"enabled": false,
|
|
182
|
-
"main": { "five_hour": 5, "seven_day": 10 },
|
|
182
|
+
"main": { "five_hour": 5, "seven_day": 10, "scoped": 0 },
|
|
183
183
|
"accounts": {}
|
|
184
184
|
},
|
|
185
185
|
"claudeCache": {
|
|
@@ -294,18 +294,20 @@ Add a `killswitch` block to the sidecar config:
|
|
|
294
294
|
"enabled": true,
|
|
295
295
|
"main": {
|
|
296
296
|
"five_hour": 5,
|
|
297
|
-
"seven_day": 10
|
|
297
|
+
"seven_day": 10,
|
|
298
|
+
"scoped": 0
|
|
298
299
|
},
|
|
299
300
|
"accounts": {
|
|
300
301
|
"work-alt": {
|
|
301
302
|
"five_hour": 10,
|
|
302
|
-
"seven_day": 20
|
|
303
|
+
"seven_day": 20,
|
|
304
|
+
"scoped": 0
|
|
303
305
|
}
|
|
304
306
|
}
|
|
305
307
|
}
|
|
306
308
|
```
|
|
307
309
|
|
|
308
|
-
Thresholds are remaining-percent values. With `five_hour: 5`, the account is killed when less than 5% of the 5-hour quota window remains. Accounts without an entry in `accounts` fall back to the `main` thresholds. The aliases `5h` and `1w` are also accepted.
|
|
310
|
+
Thresholds are remaining-percent values. With `five_hour: 5`, the account is killed when less than 5% of the 5-hour quota window remains. The optional `scoped` threshold applies to matching model-scoped quota windows (for example Fable weekly quota) and blocks when the scoped remaining percent is at or below the threshold. Accounts without an entry in `accounts` fall back to the `main` thresholds. The aliases `5h` and `1w` are also accepted.
|
|
309
311
|
|
|
310
312
|
Behavior:
|
|
311
313
|
|
|
@@ -321,7 +323,8 @@ Manage the killswitch from inside OpenCode:
|
|
|
321
323
|
/claude-killswitch on — enable with current or default thresholds
|
|
322
324
|
/claude-killswitch off — disable
|
|
323
325
|
/claude-killswitch set all:5,10 — set all accounts to 5h≥5%, 1w≥10%
|
|
324
|
-
/claude-killswitch set main:3,8
|
|
326
|
+
/claude-killswitch set main:3,8,0 — set main to 5h≥3%, 1w≥8%, scoped≤0%
|
|
327
|
+
/claude-killswitch set main:3,8,0 work-alt:5,10,0 — per-account thresholds
|
|
325
328
|
```
|
|
326
329
|
|
|
327
330
|
Changes made with `/claude-killswitch` are persisted to the sidecar config.
|
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
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-9053h96k.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:
|
|
3
3
|
opencode-anthropic-auth login [label]
|
|
4
4
|
opencode-anthropic-auth api add [label]
|
|
5
5
|
opencode-anthropic-auth list
|
|
6
6
|
opencode-anthropic-auth relay setup
|
|
7
7
|
|
|
8
8
|
Fallback accounts are stored in:
|
|
9
|
-
${D()}`)}function W(j,G){let F=j?.trim();if(!F)throw Error(`${G} is required`);return F}async function K(j){let F=await(j.fetchImpl??fetch)(`https://api.cloudflare.com/client/v4${j.path}`,{method:j.method,headers:{authorization:`Bearer ${j.token}`,...j.body instanceof FormData?{}:{"content-type":"application/json"},...j.headers},body:j.body}),M=await F.text(),J;try{J=JSON.parse(M)}catch{throw Error(`Cloudflare API returned ${F.status}: ${M}`)}if(!F.ok||J.success===!1){let X=J.errors?.map((Q)=>Q.message).filter(Boolean).join("; ");throw Error(X||`Cloudflare API returned ${F.status}`)}return J.result}async function A(j,G,F,M){return K({token:j,method:"POST",path:`/accounts/${G}/storage/kv/namespaces`,body:JSON.stringify({title:F}),fetchImpl:M})}async function h(j){let G={main_module:"worker.js",compatibility_date:"2026-04-28",bindings:[{type:"kv_namespace",name:"RELAY_STATE",namespace_id:j.kvNamespaceId},{type:"secret_text",name:"RELAY_TOKEN",text:j.relayToken}]},F=new FormData;return F.set("metadata",JSON.stringify(G)),F.set("worker.js",new Blob([x],{type:"application/javascript+module"}),"worker.js"),K({token:j.token,method:"PUT",path:`/accounts/${j.accountId}/workers/scripts/${j.scriptName}`,body:F,fetchImpl:j.fetchImpl})}async function k(j,G,F,M){await K({token:j,method:"POST",path:`/accounts/${G}/workers/scripts/${F}/subdomain`,body:JSON.stringify({enabled:!0,previews_enabled:!1}),fetchImpl:M})}async function I(j,G,F){return K({token:j,method:"GET",path:`/accounts/${G}/workers/subdomain`,fetchImpl:F}).catch(()=>null)}async function f(j={}){let G=j.fetchImpl??fetch,F=j.prompt??V,M=await C()??
|
|
9
|
+
${D()}`)}function W(j,G){let F=j?.trim();if(!F)throw Error(`${G} is required`);return F}async function K(j){let F=await(j.fetchImpl??fetch)(`https://api.cloudflare.com/client/v4${j.path}`,{method:j.method,headers:{authorization:`Bearer ${j.token}`,...j.body instanceof FormData?{}:{"content-type":"application/json"},...j.headers},body:j.body}),M=await F.text(),J;try{J=JSON.parse(M)}catch{throw Error(`Cloudflare API returned ${F.status}: ${M}`)}if(!F.ok||J.success===!1){let X=J.errors?.map((Q)=>Q.message).filter(Boolean).join("; ");throw Error(X||`Cloudflare API returned ${F.status}`)}return J.result}async function A(j,G,F,M){return K({token:j,method:"POST",path:`/accounts/${G}/storage/kv/namespaces`,body:JSON.stringify({title:F}),fetchImpl:M})}async function h(j){let G={main_module:"worker.js",compatibility_date:"2026-04-28",bindings:[{type:"kv_namespace",name:"RELAY_STATE",namespace_id:j.kvNamespaceId},{type:"secret_text",name:"RELAY_TOKEN",text:j.relayToken}]},F=new FormData;return F.set("metadata",JSON.stringify(G)),F.set("worker.js",new Blob([x],{type:"application/javascript+module"}),"worker.js"),K({token:j.token,method:"PUT",path:`/accounts/${j.accountId}/workers/scripts/${j.scriptName}`,body:F,fetchImpl:j.fetchImpl})}async function k(j,G,F,M){await K({token:j,method:"POST",path:`/accounts/${G}/workers/scripts/${F}/subdomain`,body:JSON.stringify({enabled:!0,previews_enabled:!1}),fetchImpl:M})}async function I(j,G,F){return K({token:j,method:"GET",path:`/accounts/${G}/workers/subdomain`,fetchImpl:F}).catch(()=>null)}async function f(j={}){let G=j.fetchImpl??fetch,F=j.prompt??V,M=await C()??P(),J=W(process.env.CLOUDFLARE_API_TOKEN?.trim()||await F("Cloudflare API token: "),"Cloudflare API token"),X=W(process.env.CLOUDFLARE_ACCOUNT_ID||await F("Cloudflare account ID: "),"Cloudflare account ID"),Q=await F("Worker name [opencode-anthropic-relay]: ")||"opencode-anthropic-relay",Y=`${Q}-state`,$=S();console.log("Creating Cloudflare KV namespace...");let Z=await A(J,X,Y,G);console.log("Uploading relay Worker..."),await h({token:J,accountId:X,scriptName:Q,kvNamespaceId:Z.id,relayToken:$,fetchImpl:G}),await k(J,X,Q,G).catch((U)=>{console.warn(`Could not enable workers.dev automatically: ${U instanceof Error?U.message:String(U)}`)});let B=await I(J,X,G),_=(B?.subdomain?`https://${Q}.${B.subdomain}.workers.dev`:"")||W(await V("Relay Worker URL: "),"Relay Worker URL");M.relay={enabled:!0,url:_,token:$,fallbackToDirect:!0,transport:"http"},await H(M),console.log(`Relay enabled at ${_}`),console.log(`Config saved to ${D()}.`)}var E=null;async function V(j){return E??=R({input:y,output:v}),(await E.question(j)).trim()}function b(){E?.close(),E=null}async function g(j,G={}){let F=G.prompt??V,M=G.authorize??N,J=G.exchange??L,X=await C()??P(),Q=j?.trim()||await F("Fallback account label (optional): "),Y=await M("max");console.log(`
|
|
10
10
|
Open this URL in your browser and complete Claude sign-in:
|
|
11
11
|
`),console.log(`${Y.url}
|
|
12
|
-
`);let $=await F("Paste the full callback URL or authorization code here: "),Z=await J($,Y.verifier,Y.redirectUri,Y.state);if(Z.type==="failed")throw Error("Authentication failed");let B=Date.now();
|
|
13
|
-
Saved fallback account${Q?` "${Q}"`:""}.`)}async function d(j,G={}){let F=G.prompt??V,M=await C()??
|
|
14
|
-
Saved API fallback route${J?` "${J}"`:""} (${X}).`)}async function m(){let j=await C();if(!j?.accounts.length){console.log(`No fallback accounts found at ${D()}.`);return}for(let[G,F]of j.accounts.entries()){let M=F.label||F.id,J=F.enabled===!1?"disabled":"enabled";if(!T(F)){console.log(`${G+1}. ${M} (${J}) — API route ${F.baseURL}`);continue}let X=F.quota?.five_hour?.remainingPercent,Q=F.quota?.seven_day?.remainingPercent,Y=X===void 0&&Q===void 0?"quota unknown":`5h ${X??"?"}%, 1w ${Q??"?"}% remaining`;console.log(`${G+1}. ${M} (${J}) — ${Y}`)}}async function i(){let[j,G,F]=process.argv.slice(2);if(!j||j==="help"||j==="--help"||j==="-h"){
|
|
12
|
+
`);let $=await F("Paste the full callback URL or authorization code here: "),Z=await J($,Y.verifier,Y.redirectUri,Y.state);if(Z.type==="failed")throw Error("Authentication failed");let B=Date.now();O(X,{id:Q||crypto.randomUUID(),label:Q||void 0,type:"oauth",access:Z.access,refresh:Z.refresh,expires:Z.expires,enabled:!0,addedAt:B,lastUsed:B,lastRefreshedAt:B}),await H(X),console.log(`
|
|
13
|
+
Saved fallback account${Q?` "${Q}"`:""}.`)}async function d(j,G={}){let F=G.prompt??V,M=await C()??P(),J=j?.trim()||await F("API fallback label (optional): "),X=process.env.OPENCODE_ANTHROPIC_AUTH_API_BASE_URL?.trim()||(await F("Anthropic-compatible base URL [https://api.kie.ai/claude]: ")).trim()||"https://api.kie.ai/claude";if(!q(X))throw Error("API fallback base URL must be an http(s) URL without embedded credentials");let Q=process.env.OPENCODE_ANTHROPIC_AUTH_API_KEY?.trim()||await F("API key: ");if(!Q.trim())throw Error("API key is required");let $=(process.env.OPENCODE_ANTHROPIC_AUTH_API_AUTH_HEADER?.trim()||await F("Auth header [authorization-bearer|x-api-key] (default authorization-bearer): ")).trim().toLowerCase()==="x-api-key"?"x-api-key":"authorization-bearer",Z=Date.now();O(M,{id:J||crypto.randomUUID(),label:J||void 0,type:"api",apiKey:Q.trim(),baseURL:X,authHeader:$,enabled:!0,addedAt:Z,lastUsed:Z}),await H(M),console.log(`
|
|
14
|
+
Saved API fallback route${J?` "${J}"`:""} (${X}).`)}async function m(){let j=await C();if(!j?.accounts.length){console.log(`No fallback accounts found at ${D()}.`);return}for(let[G,F]of j.accounts.entries()){let M=F.label||F.id,J=F.enabled===!1?"disabled":"enabled";if(!T(F)){console.log(`${G+1}. ${M} (${J}) — API route ${F.baseURL}`);continue}let X=F.quota?.five_hour?.remainingPercent,Q=F.quota?.seven_day?.remainingPercent,Y=X===void 0&&Q===void 0?"quota unknown":`5h ${X??"?"}%, 1w ${Q??"?"}% remaining`;console.log(`${G+1}. ${M} (${J}) — ${Y}`)}}async function i(){let[j,G,F]=process.argv.slice(2);if(!j||j==="help"||j==="--help"||j==="-h"){w();return}if(j==="login"){await g(G);return}if(j==="api"&&G==="add"){await d(F);return}if(j==="list"){await m();return}if(j==="relay"&&G==="setup"){await f();return}w(),process.exitCode=1}if(z.main==z.module)try{await i()}catch(j){console.error(j instanceof Error?j.message:String(j)),process.exitCode=1}finally{b()}export{f as relaySetup,g as login,d as addApiRoute};
|
|
@@ -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
|
|
2
|
+
export{r as Tb,s as Ub,u as Vb};
|