@cortexkit/opencode-openai-auth 1.0.5 → 1.1.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/dist/bin.js +9 -8
- package/dist/{pool-lifecycle-C_6YRmsh.d.ts → codex-request-BXDXToyt.d.ts} +158 -27
- package/dist/index-0yh85bwb.js +69 -0
- package/dist/{index-826s1yxa.js → index-4c8yw54k.js} +2 -2
- package/dist/{index-y4gxyxqd.js → index-7c6sxtd6.js} +2 -2
- package/dist/index-7eb3dw37.js +90 -0
- package/dist/index-8re8rprk.js +2 -0
- package/dist/{index-66asrje2.js → index-csky2xpg.js} +1 -1
- package/dist/index-edbdscy7.js +65 -0
- package/dist/{index-pg305s90.js → index-f2fmb596.js} +1 -1
- package/dist/{index-fsxbncpw.js → index-j8v2xwq6.js} +1 -1
- package/dist/{index-fsky1rsh.js → index-k6cydkgt.js} +2 -2
- package/dist/{index-116q849r.js → index-m5qmvr6c.js} +2 -2
- package/dist/index-msx2m78k.js +8 -0
- package/dist/{index-nx2qh047.js → index-zpm95mt5.js} +1 -1
- package/dist/index.d.ts +15 -7
- package/dist/index.js +1 -1
- package/dist/{map-m6f5a_IA.d.ts → map-Buq-GW7l.d.ts} +1 -1
- package/dist/{protocol-DctqemRI.d.ts → model-YRg7Uowo.d.ts} +67 -25
- package/dist/{port-file-ZPlxXB4G.d.ts → port-file-CxEpgSHY.d.ts} +1 -1
- package/dist/protocol-CDV1Pc6h.d.ts +29 -0
- package/dist/rpc/port-file.d.ts +1 -1
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/protocol.d.ts +1 -1
- package/dist/rpc/protocol.js +1 -1
- package/dist/rpc/rpc-client.d.ts +3 -3
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/{sidebar-state-z_M7Trnd.d.ts → sidebar-state-DjTWUbmf.d.ts} +15 -9
- package/dist/sidebar-state.d.ts +1 -1
- package/dist/sidebar-state.js +1 -1
- package/dist/{token-bzhkgc29.js → token-rz4t3ay6.js} +1 -1
- package/dist/token-util-tpy2c7h6.js +1 -0
- package/dist/tui-preferences.js +1 -1
- package/dist/tui.d.ts +20 -2
- package/dist/v2/server.d.ts +73 -1
- package/dist/v2/server.js +3 -3
- package/package.json +2 -2
- package/src/tui-compiled/raw/shared/0332701351b3eeec-format.js +13 -8
- package/src/tui-compiled/raw/shared/0f77ebc3c914c9c6-custody.js +354 -0
- package/src/tui-compiled/raw/shared/134b008900698fe0-backoff.js +92 -0
- package/src/tui-compiled/raw/shared/169b2b4bf30909bc-consumer.js +393 -0
- package/src/tui-compiled/raw/shared/2577ec69f9973ae9-quota-normalize.js +154 -0
- package/src/tui-compiled/raw/shared/2dce6e9613993329-quota-manager.js +473 -0
- package/src/tui-compiled/raw/shared/30f5bc480f31f51c-roster.js +566 -0
- package/src/tui-compiled/raw/shared/43fc9e6b994519c7-refresh-lock.js +0 -1
- package/src/tui-compiled/raw/shared/4593a4d71edf69fd-tombstone.js +25 -0
- package/src/tui-compiled/raw/shared/4d05c2d7a531aece-oauth.js +500 -0
- package/src/tui-compiled/raw/shared/6371b24a0573d79e-any-signal.js +42 -0
- package/src/tui-compiled/raw/shared/7c140680fc81be92-interlock.js +29 -0
- package/src/tui-compiled/raw/shared/85512cc5263ba259-provider.js +87 -0
- package/src/tui-compiled/raw/shared/abd062d633e29fd2-pool-routing.js +192 -0
- package/src/tui-compiled/raw/shared/b9588ad4725c1d10-enrollment.js +806 -0
- package/src/tui-compiled/raw/shared/bfbdd0f9aae56b47-pool-quota.js +85 -0
- package/src/tui-compiled/raw/shared/c852a15cfe489d12-pool.js +0 -1
- package/src/tui-compiled/raw/shared/ca0fccaba1d87af4-errors.js +8 -0
- package/src/tui-compiled/raw/shared/d0f0b6be200311af-insula.js +152 -0
- package/src/tui-compiled/raw/shared/d9d2892a4c371301-host-slot.js +72 -0
- package/src/tui-compiled/raw/shared/dbc61cd405941828-accounts.js +1470 -0
- package/src/tui-compiled/raw/shared/e8cd4929507508d8-refresh-file-lock.js +26 -12
- package/src/tui-compiled/raw/shared/e8d3c8da776ef9cd-index.js +24 -0
- package/src/tui-compiled/raw/sidebar-state.js +41 -14
- package/src/tui-compiled/raw/tui/command-dialogs.tsx +3 -34
- package/src/tui-compiled/raw/tui/section-text.js +21 -0
- package/src/tui-compiled/raw/tui/v2-dialog.js +137 -0
- package/src/tui-compiled/raw/tui/v2.tsx +133 -0
- package/src/tui-compiled/raw/tui.tsx +146 -40
- package/src/tui-compiled/runtime/shared/0332701351b3eeec-format.js +13 -8
- package/src/tui-compiled/runtime/shared/0f77ebc3c914c9c6-custody.js +354 -0
- package/src/tui-compiled/runtime/shared/134b008900698fe0-backoff.js +92 -0
- package/src/tui-compiled/runtime/shared/169b2b4bf30909bc-consumer.js +393 -0
- package/src/tui-compiled/runtime/shared/2577ec69f9973ae9-quota-normalize.js +154 -0
- package/src/tui-compiled/runtime/shared/2dce6e9613993329-quota-manager.js +473 -0
- package/src/tui-compiled/runtime/shared/30f5bc480f31f51c-roster.js +566 -0
- package/src/tui-compiled/runtime/shared/43fc9e6b994519c7-refresh-lock.js +0 -1
- package/src/tui-compiled/runtime/shared/4593a4d71edf69fd-tombstone.js +25 -0
- package/src/tui-compiled/runtime/shared/4d05c2d7a531aece-oauth.js +500 -0
- package/src/tui-compiled/runtime/shared/6371b24a0573d79e-any-signal.js +42 -0
- package/src/tui-compiled/runtime/shared/7c140680fc81be92-interlock.js +29 -0
- package/src/tui-compiled/runtime/shared/85512cc5263ba259-provider.js +87 -0
- package/src/tui-compiled/runtime/shared/abd062d633e29fd2-pool-routing.js +192 -0
- package/src/tui-compiled/runtime/shared/b9588ad4725c1d10-enrollment.js +806 -0
- package/src/tui-compiled/runtime/shared/bfbdd0f9aae56b47-pool-quota.js +85 -0
- package/src/tui-compiled/runtime/shared/c852a15cfe489d12-pool.js +0 -1
- package/src/tui-compiled/runtime/shared/ca0fccaba1d87af4-errors.js +8 -0
- package/src/tui-compiled/runtime/shared/d0f0b6be200311af-insula.js +152 -0
- package/src/tui-compiled/runtime/shared/d9d2892a4c371301-host-slot.js +72 -0
- package/src/tui-compiled/runtime/shared/dbc61cd405941828-accounts.js +1470 -0
- package/src/tui-compiled/runtime/shared/e8cd4929507508d8-refresh-file-lock.js +26 -12
- package/src/tui-compiled/runtime/shared/e8d3c8da776ef9cd-index.js +24 -0
- package/src/tui-compiled/runtime/sidebar-state.js +41 -14
- package/src/tui-compiled/runtime/tui/command-dialogs.js +3 -15
- package/src/tui-compiled/runtime/tui/section-text.js +21 -0
- package/src/tui-compiled/runtime/tui/v2-dialog.js +137 -0
- package/src/tui-compiled/runtime/tui/v2.js +95 -0
- package/src/tui-compiled/runtime/tui.js +255 -163
- package/dist/index-4fnghj9e.js +0 -65
- package/dist/index-a69gr76b.js +0 -2
- package/dist/index-h263aftt.js +0 -157
- package/dist/index-ssj7m2rd.js +0 -8
- package/dist/index-ydz3hbhc.js +0 -2
- package/dist/token-util-4a2xxnpg.js +0 -1
package/dist/tui.d.ts
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { S as SpendControlReading, b as SidebarState, l as QuotaPacing, r as AccountQuota, u as QuotaWindow } from "./sidebar-state-DjTWUbmf.js";
|
|
2
|
+
import { i as OpenDialogPayload, n as ApplyResult, t as ApplyRequest } from "./protocol-CDV1Pc6h.js";
|
|
3
|
+
import { Plugin } from "@opencode/plugin/tui";
|
|
3
4
|
import { TuiPluginModule } from "@opencode-ai/plugin/tui";
|
|
5
|
+
import { JSX } from "solid-js";
|
|
6
|
+
//#region src/tui/v2.d.ts
|
|
7
|
+
interface TuiTransportOptions {
|
|
8
|
+
/** Test-only label for proving that the host can render a sidebar component. */
|
|
9
|
+
sidebarText?: string;
|
|
10
|
+
sidebar?: {
|
|
11
|
+
render(input: {
|
|
12
|
+
sessionID: string;
|
|
13
|
+
}): JSX.Element;
|
|
14
|
+
dispose(): void;
|
|
15
|
+
};
|
|
16
|
+
openDialog?: (payload: OpenDialogPayload, apply: (request: Omit<ApplyRequest, 'sessionId'>) => Promise<ApplyResult>) => Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
4
19
|
//#region src/tui.d.ts
|
|
5
20
|
/** One drawer action as the RPC apply request carries it, with its session. */
|
|
6
21
|
export declare function buildApplyRequest(request: Omit<ApplyRequest, 'sessionId'>, sessionId?: string): ApplyRequest;
|
|
@@ -11,6 +26,7 @@ export interface QuotaDisplayRow {
|
|
|
11
26
|
label: string;
|
|
12
27
|
labelWidth: number;
|
|
13
28
|
text: string;
|
|
29
|
+
resetText?: string;
|
|
14
30
|
window: QuotaWindow;
|
|
15
31
|
pacing: QuotaPacing | null;
|
|
16
32
|
}
|
|
@@ -56,8 +72,10 @@ export interface RoutingDisplayRow {
|
|
|
56
72
|
tone: Tone;
|
|
57
73
|
}
|
|
58
74
|
export declare function buildRoutingRowsForDisplay(state: SidebarState, sessionId: string | undefined, now?: number): RoutingDisplayRow[];
|
|
75
|
+
declare function setup(context: Plugin.Context, options?: TuiTransportOptions): Promise<() => void>;
|
|
59
76
|
declare const plugin: TuiPluginModule & {
|
|
60
77
|
id: string;
|
|
78
|
+
setup: typeof setup;
|
|
61
79
|
};
|
|
62
80
|
//#endregion
|
|
63
81
|
export { plugin as default };
|
package/dist/v2/server.d.ts
CHANGED
|
@@ -1,8 +1,63 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { h as BeginAccountLoginResult, i as CodexSessionMetadata, m as BeginAccountLoginOptions, o as PoolLifecycleDeps, p as OpenAiVaultOptions, r as CodexRequestRuntime, s as HostSlotAdapter, x as AccountPaths } from "../codex-request-BXDXToyt.js";
|
|
2
|
+
import { i as OpenDialogPayload, n as ApplyResult } from "../protocol-CDV1Pc6h.js";
|
|
2
3
|
import { Plugin } from "@opencode/plugin";
|
|
3
4
|
import "@opencode/plugin/promise/session";
|
|
4
5
|
import "@opencode/plugin/promise/integration";
|
|
5
6
|
import "@opencode/plugin/promise/registration";
|
|
7
|
+
//#region src/v2/codex-sessions.d.ts
|
|
8
|
+
interface CodexSessionStoreOptions {
|
|
9
|
+
/** Mints the turn ids of loaded sessions; UUIDv7 by default. */
|
|
10
|
+
uuid?: () => string;
|
|
11
|
+
/** Test seam: runs while the lock is held, after the file was re-read. */
|
|
12
|
+
afterRead?: () => Promise<void>;
|
|
13
|
+
/** Test seam: the lock wait; `LOCK_WAIT_MS` by default. */
|
|
14
|
+
lockWaitMs?: number;
|
|
15
|
+
}
|
|
16
|
+
declare class CodexSessionStore {
|
|
17
|
+
#private;
|
|
18
|
+
readonly path: string;
|
|
19
|
+
readonly options: CodexSessionStoreOptions;
|
|
20
|
+
readonly sessions: Map<string, CodexSessionMetadata>;
|
|
21
|
+
constructor(path: string, options?: CodexSessionStoreOptions);
|
|
22
|
+
/** The session's metadata; a new session gets a new thread id and is saved. */
|
|
23
|
+
get(sessionID: string, uuid?: () => string): CodexSessionMetadata;
|
|
24
|
+
/** Forgets a deleted host session here and, on the next save, in the file. */
|
|
25
|
+
delete(sessionID: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Saves this process's changes. Saves run one at a time; changes made while
|
|
28
|
+
* one runs go in the next. Never rejects: a lock timeout or write failure
|
|
29
|
+
* keeps the changes for the next save.
|
|
30
|
+
*/
|
|
31
|
+
save(): Promise<void>;
|
|
32
|
+
/** Resolves once every save started so far has finished. */
|
|
33
|
+
settled(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/v2/codex-wire.d.ts
|
|
37
|
+
/**
|
|
38
|
+
* HTTP requests and WebSocket cache keys share each host session's thread
|
|
39
|
+
* identity. With a store, sessions are the store's process-wide map and new
|
|
40
|
+
* or deleted sessions are saved to its file; without one they live only in
|
|
41
|
+
* this object.
|
|
42
|
+
*/
|
|
43
|
+
declare class CodexHttpState {
|
|
44
|
+
readonly runtime?: CodexRequestRuntime | undefined;
|
|
45
|
+
readonly store?: CodexSessionStore | undefined;
|
|
46
|
+
readonly sessions: Map<string, CodexSessionMetadata>;
|
|
47
|
+
readonly installationID: string;
|
|
48
|
+
constructor(runtime?: CodexRequestRuntime | undefined, installationID?: string, store?: CodexSessionStore | undefined);
|
|
49
|
+
get(sessionID: string): CodexSessionMetadata;
|
|
50
|
+
/** Drops a deleted host session; a later request with its id starts a new thread. */
|
|
51
|
+
forget(sessionID: string): void;
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/v2/control-plane.d.ts
|
|
55
|
+
/** Server-owned menu callbacks shared by command dispatch and loopback RPC. */
|
|
56
|
+
interface ControlPlaneMenu {
|
|
57
|
+
open(sessionId: string): Promise<OpenDialogPayload>;
|
|
58
|
+
apply(request: unknown): Promise<ApplyResult>;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
6
61
|
//#region src/v2/login.d.ts
|
|
7
62
|
type BeginLogin = (options: BeginAccountLoginOptions) => Promise<BeginAccountLoginResult>;
|
|
8
63
|
//#endregion
|
|
@@ -14,6 +69,18 @@ type BeginLogin = (options: BeginAccountLoginOptions) => Promise<BeginAccountLog
|
|
|
14
69
|
export declare const OPENAI_AUTH_PLUGIN_ID = "cortexkit-openai-auth";
|
|
15
70
|
/** Test and embedding seams; every field has a production default. */
|
|
16
71
|
interface OpenAIAuthV2Options {
|
|
72
|
+
/** Overrides HTTP identity and clock sources for deterministic wire fixtures. */
|
|
73
|
+
codex?: CodexHttpState;
|
|
74
|
+
/** Binds this location's sidebar output; defaults to the shared sidebar state file. */
|
|
75
|
+
sidebarStateFile?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Test-only interval in milliseconds for checking settings/enrollment file
|
|
78
|
+
* metadata and cached vault rosters. Tests can shorten the 2,000 ms default
|
|
79
|
+
* to observe changes quickly.
|
|
80
|
+
*/
|
|
81
|
+
sidebarObservationIntervalMs?: number;
|
|
82
|
+
/** Overrides the production menu for transport fixtures. */
|
|
83
|
+
controlPlane?: ControlPlaneMenu;
|
|
17
84
|
/** The account config and state files; read on every use. */
|
|
18
85
|
paths?: () => AccountPaths;
|
|
19
86
|
/** OpenCode 1's login slot the migration reads; its `auth.json` by default. */
|
|
@@ -22,6 +89,11 @@ interface OpenAIAuthV2Options {
|
|
|
22
89
|
version?: string;
|
|
23
90
|
/** Used for token refreshes and quota polls. */
|
|
24
91
|
fetch?: typeof fetch;
|
|
92
|
+
/**
|
|
93
|
+
* The clock for token refreshes, quota polls and the readings they record,
|
|
94
|
+
* rate-limit marks, and reset credits; `Date.now` by default.
|
|
95
|
+
*/
|
|
96
|
+
now?: () => number;
|
|
25
97
|
/** Starts one ChatGPT login (`beginAccountLogin`). */
|
|
26
98
|
beginLogin?: BeginLogin;
|
|
27
99
|
/** The migration's version fence; `migrationFenceOpen` for `version` by default. */
|
package/dist/v2/server.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{c as
|
|
2
|
-
`)}:{event:
|
|
3
|
-
`)}}function L2($,K){let J=new TextDecoder,X="",j=(R)=>{let T=P$(R);if(!T)return;try{$(T)}catch(O){K(O)}},B=()=>{for(;;){let R=/\r?\n\r?\n/.exec(X);if(!R)return;let T=X.slice(0,R.index);X=X.slice(R.index+R[0].length),j(T)}};return new TransformStream({transform(R,T){T.enqueue(R),X+=J.decode(R,{stream:!0}),B()},flush(){if(X+=J.decode(),B(),X.trim()!=="")j(X);X=""}})}var i2=512,Y2="x-common-auth-attempt",e=($,K)=>JSON.stringify([$,K]),o=($)=>({providerID:$.model.providerID,modelID:$.model.id,sessionID:$.sessionID,agent:$.agent,kind:$.kind});function T$($){let K=$.headers;return typeof K==="object"&&K!==null}function M$($,K){let J=$.getReader();return new ReadableStream({async pull(X){let j;try{j=await J.read()}catch(B){K({reason:"failed",message:B instanceof Error?B.message:String(B)}),X.error(B);return}if(j.done)K(),X.close();else X.enqueue(j.value)},async cancel(X){K({reason:"cancelled",...X===void 0?{}:{message:String(X)}}),await J.cancel(X)}})}function _2($,K){for(let[J,X]of Object.entries(K)){let j=J.toLowerCase();for(let B of Object.keys($))if(B.toLowerCase()===j)delete $[B];if(X!==null)$[J]=X}}function L$($,K){for(let[J,X]of Object.entries(K))if(X===null)$.delete(J);else $.set(J,X)}async function q2($,K,J={}){let{providerID:X}=K,j=J.gateOnPlaceholder,B=(Y)=>j===void 0||j.credential(Y)===s(X),R=J.logger,T=Math.max(1,J.maxRecords??i2),O=[...J.hostCredentials??[s(X)],...j?[s(X)]:[]].filter((Y)=>Y!==""),H=new Map,W=new WeakMap,y=new Map,b=new Set,E=new Map,v=!1,f=!1,d=new Map,I=0,u=!1,g=new Map,h=(Y,Z)=>{try{R?.warn(Y,Z)}catch{}},z=(Y)=>Y instanceof Error?Y.message:String(Y),V=async(Y,Z)=>{let G=d.get(Y);if(!G||G.size===0)return;await Promise.all([...G].map(async(Q)=>{try{await Q(Z)}catch(M){h("opencode2 auth listener threw; the request is unaffected",{event:Y,error:z(M)})}}))},F=async(Y,Z)=>{try{await K.onAttemptEnd?.(Y,Z)}catch(G){h("opencode2 auth onAttemptEnd threw; the request is unaffected",{attemptId:Y.attemptId,error:z(G)})}},C=(Y,Z)=>{if(Y.ended||!Y.attempt)return;let G={...Y.status===void 0?{}:{status:Y.status},outputStarted:Y.outputStarted,...Y.limit?{limit:Y.limit.signal}:{},...Z?{error:Z}:{}};if(Z)Y.endError=Z;Y.ended=F(Y.attempt,G)},A=(Y,Z)=>C(Y,{reason:"abandoned",message:Z}),P=(Y)=>[...H.values()].filter((Z)=>Z.key===Y),D=(Y)=>P(Y).at(-1),k=(Y)=>{if(H.delete(Y.id),!P(Y.key).length)y.delete(Y.key)},q=(Y)=>{H.set(Y.id,Y);while(H.size>T){let Z=H.values().next().value;if(Z===void 0)break;A(Z,"dropped to keep the record bound"),k(Z)}},m=(Y)=>Y.accountId===void 0?void 0:{...Y.scope,accountId:Y.accountId},i=(Y,Z)=>new c({kind:"no-account",providerID:X,sessionID:Y.sessionID,requestKind:Y.kind,...Z===void 0?{}:{message:Z}}),l=(Y)=>{g.get(Y)?.clear(),g.delete(Y)},p=async(Y,Z)=>{let G=()=>i(Y,`${X} ${Y.kind} request has no account: its auth selection was revoked by session forgetting or installation disposal`);if(u)throw G();let Q=g.get(Y.sessionID);if(!Q)Q=new Set,g.set(Y.sessionID,Q);let M={};Q.add(M);let x=()=>{if(!Q.has(M))throw G()};try{return await Z(x)}finally{if(Q.delete(M),Q.size===0&&g.get(Y.sessionID)===Q)g.delete(Y.sessionID)}},U=(Y,Z)=>{for(let[G,Q]of Z)if(O.some((M)=>Q.includes(M)))throw new c({kind:"host-credential-on-wire",providerID:X,sessionID:Y.sessionID,requestKind:Y.kind,message:`${X} ${Y.kind} request still carries the host's placeholder credential in ${G}; the adapter's account headers must replace it`})},L=(Y)=>{for(let Z of P(Y))if(Z.ended||!Z.attempt)k(Z);else if(Z.transport==="ws"||Z.judged)A(Z,"a newer attempt of its session and kind began"),k(Z)},S=async(Y,Z,G,Q)=>{let M=e(Y.sessionID,Y.kind),x=y.get(M);y.delete(M);let N=x?.accountId??D(M)?.accountId;L(M);let _={...Y,...N===void 0?{}:{previousAccountId:N},...x?.rerouteFrom===void 0?{}:{rerouteFrom:x.rerouteFrom}},w=await K.chooseAccount(_);G();let a={},p2;if(w!==void 0){let Q2=await K.accountHeaders({...Y,accountId:w});if(G(),T$(Q2))a=Q2.headers,p2=Q2.attempt;else a=Q2}let l2=`attempt-${++I}`,z2={id:l2,key:M,scope:Y,accountId:w,headers:a,attempt:w===void 0?void 0:{...Y,accountId:w,attemptId:l2,transport:Q,data:p2},...Q===void 0?{}:{transport:Q},outputStarted:!1};if(q(z2),z2.attempt)V("select",{...Y,accountId:z2.attempt.accountId,hook:Z,..._.previousAccountId===void 0?{}:{previousAccountId:_.previousAccountId},..._.rerouteFrom===void 0?{}:{rerouteFrom:_.rerouteFrom},handle:z2.attempt});return z2},Z2=async(Y,Z,G,Q,M)=>{let x=e(Y.sessionID,Y.kind),N=Q===void 0?void 0:H.get(Q);if(N?.key!==x)N=void 0;if(!N){if(N=D(x),P(x).filter((w)=>w.transport===void 0&&!w.ended).length>1&&!f)f=!0,h("opencode2 auth tied a send without its attempt mark to the newest of several waiting attempts",{sessionID:Y.sessionID,kind:Y.kind})}if(!N||N.transport!==void 0||N.ended)N=await S(Y,Z,M,G);else if(N.transport=G,N.attempt)N.attempt.transport=G;if(G==="ws"){for(let _ of P(x))if(_!==N&&_.transport==="ws")A(_,"a newer attempt of its session and kind went out over WebSocket")}return N},$2=async(Y,Z)=>{try{return await Z()}catch(G){throw C(Y,{reason:"failed",message:z(G)}),G}},h2=(Y,Z)=>{let G=P(e(Y,Z)).filter((Q)=>Q.transport==="ws").at(-1);return G?.attempt!==void 0&&!G.ended?G:void 0},P2=(Y,Z,G)=>{let Q=m(Y);if(!Q||!Y.attempt||Y.limit)return;Y.limit={signal:Z,delivered:V("limit",{...Q,via:G,limit:Z,outputStarted:Y.outputStarted,handle:Y.attempt})}},v2=(Y,Z,G,Q)=>{let M=m(Y);if(!M||!Y.attempt)return;V("quota",{...M,transport:Z,...Q===void 0?{}:{status:Q},quota:G,handle:Y.attempt})},m2=(Y,Z,G,Q)=>{let M=Y.attempt;if(!M)return;let x=K.inspectEvent?.(Q===void 0?{transport:Z,data:G,attempt:M}:{transport:Z,data:G,event:Q,attempt:M});if(!x)return;if(x.quota!==void 0)v2(Y,Z,x.quota);if(x.outputStarted)Y.outputStarted=!0;if(x.limit)P2(Y,x.limit,Z);if(x.error!==void 0)C(Y,{reason:"failed",message:x.error});else if(x.done)C(Y)},C$=(Y,Z)=>{let G=Y.attempt;if(!G||Z.accountId===Y.accountId)return;if(G.reboundFrom??=G.accountId,G.accountId=Z.accountId,"data"in Z)G.data=Z.data;Y.accountId=Z.accountId},N$=(Y)=>!Y.attempt||Y.endError!==void 0||Y.status!==void 0&&Y.status>=400,F$=(Y)=>{let Z=[...H.values()].filter((_)=>_.scope.sessionID===Y),G=Z.filter((_)=>_.limit&&!_.rerouted).at(-1);if(G)return G;let Q=Z.filter((_)=>_.scope.kind==="primary"),M=Q.length>0?Q:Z;if(M.length<=1)return M[0];let x=M.filter((_)=>!_.judged&&N$(_)).at(-1);if(x)return x;let N=M.filter((_)=>_.attempt&&!_.ended);if(N.length>1)return"ambiguous";return N[0]??M.at(-1)},t={providerID:X},r=[];r.push(await $.session.hook("model.request",(Y)=>{if(j)return;return p(o(Y),async(Z)=>{let G=await S(o(Y),"model.request",Z);if(Z(),G.accountId===void 0)throw i(G.scope);_2(Y.headers,{...G.headers,[Y2]:G.id})})},t)),r.push(await $.session.hook("http.request",(Y)=>{if(j){let Z=B(Y.request.headers);if(E.set(Y.sessionID,Z),!Z)return}return p(o(Y),async(Z)=>{let G=Y.request.headers.get(Y2)??void 0,Q=j?await S(o(Y),"http.request",Z,"http"):await Z2(o(Y),"http.request","http",G,Z);Z();let M=m(Q),x=Q.attempt;if(!M||!x)throw i(Q.scope);await $2(Q,async()=>{let N=Y.request;if(K.rewriteRequest){if(G!==void 0){let a=new Headers(N.headers);a.delete(Y2),N=new Request(N,{headers:a})}N=await K.rewriteRequest({...M,request:N,attempt:x})??N,Z()}let _=new Headers(N.headers);_.delete(Y2),L$(_,Q.headers),U(Q.scope,_.entries());let w=new Request(N,{headers:_});W.set(w,Q),Y.request=w})})},t)),r.push(await $.session.hook("http.response",async(Y)=>{let Z=W.get(Y.request);if(!Z){if(j)return;if(!v)v=!0,h("opencode2 auth dropped an http.response whose request it did not produce",{sessionID:Y.sessionID,kind:Y.kind});return}let G=Y.response;if(K.answeredBy&&Z.attempt){let _=Z.attempt,w=await $2(Z,async()=>K.answeredBy?.({request:Y.request,response:G,attempt:_}));if(w)C$(Z,w)}let Q=m(Z),M=Z.attempt;if(!Q||!M)return;Z.status=G.status;let x=K.quotaFromHeaders?.(G.headers,G.status,M);if(x!==void 0)v2(Z,"http",x,G.status);if(!G.ok&&K.limitFromResponse){let _=await K.limitFromResponse({status:G.status,headers:G.headers,body:()=>G.clone().text(),attempt:M});if(_)P2(Z,_,"http")}if(!G.ok||!G.body)C(Z);let N=G;if(G.body&&(K.inspectEvent||K.onAttemptEnd)){let _=G.body;if(K.inspectEvent)_=_.pipeThrough(L2((w)=>m2(Z,"http",w.data,w.event),(w)=>h("opencode2 auth event inspection threw",{error:z(w)})));N=new Response(M$(_,(w)=>C(Z,w)),{status:G.status,statusText:G.statusText,headers:G.headers})}if(K.rewriteResponse)N=await K.rewriteResponse({...Q,request:Y.request,response:N,attempt:M})??N;if(N!==G)Y.response=N},t)),r.push(await $.session.hook("experimental.ws.handshake",(Y)=>{if(j){let Z=B(new Headers(Y.headers)),G=e(Y.sessionID,Y.kind);if(E.set(Y.sessionID,Z),b.delete(G),!Z)return}return p(o(Y),async(Z)=>{let G;for(let N of Object.keys(Y.headers)){if(N.toLowerCase()!==Y2)continue;G??=Y.headers[N],delete Y.headers[N]}let Q=j?await S(o(Y),"experimental.ws.handshake",Z,"ws"):await Z2(o(Y),"experimental.ws.handshake","ws",G,Z);Z();let M=m(Q),x=Q.attempt;if(!M||!x)throw i(Q.scope);await $2(Q,async()=>{_2(Y.headers,Q.headers);let N=K.rewriteHandshakeURL?.({...M,url:Y.url,attempt:x});if(N!==void 0)Y.url=N;if(U(Q.scope,Object.entries(Y.headers)),j)b.add(Q.key)})})},t));let f2=K.rewriteWebSocketFrame?.bind(K);if(f2)r.push(await $.session.hook("experimental.ws.send",async(Y)=>{let Z=o(Y);if(j&&!b.has(e(Z.sessionID,Z.kind)))return;let G=h2(Z.sessionID,Z.kind),Q=await f2({...Z,attempt:G?.attempt,frame:Y.frame});if(Q!==void 0)Y.frame=Q},t));r.push(await $.session.hook("experimental.ws.receive",(Y)=>{if(j&&!b.has(e(Y.sessionID,Y.kind)))return;let Z=h2(Y.sessionID,Y.kind);if(!Z)return;try{m2(Z,"ws",Y.frame)}catch(G){h("opencode2 auth frame inspection threw",{error:z(G)})}},t)),r.push(await $.session.hook("retry",async(Y)=>{if(j&&E.get(Y.sessionID)!==!0)return;let Z=F$(Y.sessionID);if(!Z)return;let G=Y.decision;if(Z==="ambiguous"){await V("retry",{sessionID:Y.sessionID,attempt:Y.attempt,reason:"host-decides",hostDecision:G,decision:G});return}let Q=Z;await p(Q.scope,async(M)=>{Q.judged=!0;let x=G,N,_,w=Q.attempt;if(Q.accountId===void 0||!w)x={retry:!1},N="no-account";else if(Q.outputStarted)x={retry:!1},N="output-started";else{if(!Q.limit){let a=K.limitFromError?.(Y.error,w);if(a)P2(Q,a,"error")}if(Q.ended)await Q.ended,M();if(Q.limit)await Q.limit.delivered,M(),Q.rerouted=!0,_={accountId:Q.accountId,limit:Q.limit.signal},x={retry:!0,delay:0},N="reroute";else N="host-decides"}if(Y.decision=x,x.retry&&Q.accountId!==void 0)y.set(Q.key,{sessionID:Q.scope.sessionID,accountId:Q.accountId,..._===void 0?{}:{rerouteFrom:_}});await V("retry",{sessionID:Y.sessionID,...Q.accountId===void 0?{}:{accountId:Q.accountId},kind:Q.scope.kind,attempt:Y.attempt,reason:N,hostDecision:G,decision:x,...w===void 0?{}:{handle:w}})})},t));let g2=(Y)=>{l(Y),E.delete(Y);for(let Z of b)if(JSON.parse(Z)[0]===Y)b.delete(Z);for(let Z of[...H.values()]){if(Z.scope.sessionID!==Y)continue;A(Z,"its session was forgotten"),H.delete(Z.id)}for(let[Z,G]of y)if(G.sessionID===Y)y.delete(Z)},T2=new AbortController,u2=$.event;if(u2)(async()=>{try{for await(let Y of u2.subscribe({signal:T2.signal}))if(Y.type==="session.deleted")g2(Y.data.sessionID)}catch(Y){if(!T2.signal.aborted)h("opencode2 auth stopped listening for session deletion",{error:z(Y)})}})();return{on(Y,Z){let G=d.get(Y);if(!G)G=new Set,d.set(Y,G);let Q=Z;return G.add(Q),()=>{G.delete(Q)}},accountFor(Y,Z){return D(e(Y,Z))?.accountId},forgetSession:g2,get size(){return H.size},async dispose(){if(u)return;u=!0;for(let Y of g.keys())l(Y);T2.abort();for(let Y of H.values())A(Y,"the installation was disposed");H.clear(),y.clear(),b.clear(),E.clear(),d.clear(),await Promise.all(r.map(async(Y)=>{try{await Y.dispose()}catch(Z){h("opencode2 auth hook did not dispose cleanly",{error:z(Z)})}}))}}}var x2={version:a2,"user-agent":s2,originator:"codex_exec"},_$="x-openai-internal-codex-responses-lite",q$=1024,x$=/(?:^|\/)gpt-6-(?:astra|sol|luna)$/i,B2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($),E$=($)=>B2($)&&($.type==="message"||("role"in $))&&$.role==="user",S$=($)=>B2($)&&$.type==="configuration_update";class E2{#$=new Map;apply($,K,J){if(K.kind!=="primary")return!1;let X=typeof $.model==="string"?$.model:"";if(!o2.has(X))return!1;if(x$.test(X))return!1;let j=B2($.reasoning)?$.reasoning:void 0,B=typeof j?.effort==="string"?j.effort:void 0;if(!B)return!1;let R=this.#$.get(K.sessionID);if(R===void 0)return this.#Y(K.sessionID,B),!1;if(B===R)return!1;let T=Array.isArray($.input)?$.input:void 0;if(!T||T.length===0)return!1;let O=T.findLastIndex(E$);if(O<0){if(J==="http")return!1;return $.reasoning={...j,effort:R},!0}if($.reasoning={...j,effort:R},!S$(T[O-1]))T.splice(O,0,{type:"configuration_update",reasoning:{effort:B}});return!0}forget($){this.#$.delete($)}#Y($,K){this.#$.set($,K);while(this.#$.size>q$){let J=this.#$.keys().next().value;if(J===void 0)break;this.#$.delete(J)}}}function R$($){if(typeof $.model!=="string"||!n2.has($.model))return!1;return r2($),!0}function t2($){try{let K=JSON.parse($);return B2(K)?K:void 0}catch{return}}async function e2($,K,J,X){if($.method.toUpperCase()!=="POST"||$.body===null)return;if(!/\/responses\/?$/.test(new URL($.url).pathname))return;let j=t2(await $.clone().text());if(!j)return;let B="max_output_tokens"in j;delete j.max_output_tokens;let R=J.apply(j,K,"http"),T=X&&R$(j);if(!B&&!R&&!T)return;let O=new Headers($.headers);if(O.delete("content-length"),T)O.set(_$,"true");return new Request($,{headers:O,body:JSON.stringify(j)})}function $1($,K,J){let X=t2($);if(X?.type!=="response.create")return;let j="max_output_tokens"in X;delete X.max_output_tokens;let B=J.apply(X,K,"ws");return j||B?JSON.stringify(X):void 0}function A$($){return $.replace(/\/responses\/?$/,"").replace(/\/$/,"")}function S2($,K){let J=new URL($);if(J.origin!=="https://api.openai.com"&&J.origin!=="wss://api.openai.com"||!/\/responses\/?$/.test(J.pathname))return $;let X=new URL(`${A$(K)}/responses`);if(X.search=J.search,J.protocol==="ws:"||J.protocol==="wss:")X.protocol=X.protocol==="https:"?"wss:":"ws:";return X.href}var n="openai",D$=60000,Y1=1,O$="request refused: no account with a usable credential",b$=1024,K2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($);function A2($){try{return JSON.parse($)}catch{return}}function K1($){let K=H2($);return K?U2(K):void 0}var y$=new Set(["usage_limit_reached","rate_limit_exceeded"]);function D2($,K,J){return{reason:$.window,...J!==void 0?{status:J}:{},...$.resetAt!==void 0?{retryAfterMs:Math.max(0,$.resetAt-K)}:{}}}function k$($,K){let J=W2($);if(J){let B=typeof $.status==="number"?$.status:void 0;return D2(J,K,B)}if($.type!=="response.failed"||!K2($.response))return;let X=$.response.failed;if(K2(X)&&typeof X.rate_limit_reached_type==="string")return{reason:X.rate_limit_reached_type};let j=$.response.error;if(K2(j)){let B=typeof j.code==="string"?j.code:typeof j.type==="string"?j.type:void 0;if(B&&y$.has(B))return{reason:B}}return}function w$($,K){let J=A2($);if(!K2(J))return;let X=typeof J.type==="string"?J.type:void 0;if(X==="codex.rate_limits")return{quota:{snapshot:X1(J),complete:!0}};let j=k$(J,K);if(j)return{limit:j};if(X===void 0||X==="error")return;return L1(X)?void 0:{outputStarted:!0}}function I$($){let K=!1;for(let J of $.keys())if(J.toLowerCase().startsWith("x-codex-")){K=!0;break}if(!K)return;return{snapshot:z1($),complete:J1($)}}function h$($){let K=$.get("retry-after");if(K===null)return;let J=Number(K);return Number.isFinite(J)&&J>=0?J*1000:void 0}function _1($){let{source:K,pins:J}=$,X=$.now??Date.now,j=$.log,B=$.vault,R=new E2,T=new Map,O=(z)=>`${z.sessionID}\x00${z.kind}\x00${z.accountId}`,H=new Map,W=new Map,y=(z,V)=>{W.delete(z),W.set(z,V);while(W.size>b$){let F=W.keys().next().value;if(F===void 0)break;W.delete(F)}},b=(z,V,F)=>{let C=F?[]:M1(K.peek().rows,z,V,B?.identities()??new Set),A=(B?.routes()??[]).filter((P)=>P.kind==="oauth"&&G1(V2(P.quota),z,V));return[...C.map((P)=>({id:P.id,...P.identity!==void 0?{identity:P.identity}:{},quota:P.quota,row:P})),...A.map((P)=>({id:P.id,...P.identity!==void 0?{identity:P.identity}:{},quota:P.quota}))]},E=(z,V,F)=>{let C=new Map;if(Q1(V))for(let q of z)C.set(q.id,V1(V2(q.quota),V,q.id===R2?void 0:q.id,F));let A=z.map((q)=>({id:q.id,kind:"oauth",...Z1(q.quota)?{quota:q.quota}:{}})),P=z.flatMap((q)=>q.row?[q.row]:[]),D=new Set(z.filter((q)=>!q.row).map((q)=>q.id)),k=K.rateLimitMarks(P);for(let q of D){let m=H.get(q);if(m===void 0)continue;if(m<=F)H.delete(q);else k.set(q,m)}return{rows:A,now:F,rateLimitMarks:k,refreshBackoff:K.refreshBackoffFor(P),killswitch:C,requestPull:(q)=>D.has(q)?B?.requestReading(q):K.requestReading(q)}},v=(z,V,F,C)=>{let A=N1({...z,placement:U1(V)});if(A.kind==="block"){j?.debug("pool admission refused the request",{reason:A.block.reason});return}let P=A.order.filter((D)=>!F.has(D));if(C!==void 0&&P.includes(C))return C;return P[0]},f=(z,V,F,C,A,P)=>{let D={requestBytes:Y1,reservePercent:(U)=>B1(F,U===R2?void 0:U),resetCredits:()=>{return}},k=F1(z),q=(U,L)=>J.place({sessionId:C,requestBytes:Y1,validPinnedAccountIds:z.rows.map((S)=>S.id).filter((S)=>!k.excluded.has(S)),excludeAccountIds:U,quotaCheckedAtByAccount:Object.fromEntries(z.rows.map((S)=>[S.id,k.projections.get(S.id)?.checkedAt])),wireAccountIdByAccount:Object.fromEntries(V.map((S)=>[S.id,S.identity])),select:(S)=>P1(z,D,new Set(U),S),persist:L}),m=[...A],i=q(m,P);if(!i)return;let l=i.accountId,p=T1(z,D,l);if(p.kind==="none")return;if(p.kind==="move"){let U=q([...m,l],P);if(U)return U.accountId;return p.reason==="killswitch"?void 0:l}if(p.kind==="detour")return q([...m,l],!1)?.accountId;return l},u={providerID:n,chooseAccount:async(z)=>{let V=await B?.authority(),F=await $.storage(),C=V!==void 0&&V!=="local",A=()=>{throw new c({kind:"no-account",providerID:n,sessionID:z.sessionID,requestKind:z.kind,message:C2})};if(C)await $.awaitVaultRoster?.();else{if(!(await K.current()).active){if(await $.slotPlaceholderWithoutMain?.())A();j?.warn("the account pool does not serve requests yet; refusing the request",{kind:z.kind});return}await K.prepareTokens(K.peek().rows,F)}let P=X(),D=b(F,P,C),k=C1(E(D.filter((S)=>S.id!==z.rerouteFrom?.accountId),F,P));if(k)await k,P=X(),D=b(F,P,C);let q=new Map(D.map((S)=>[S.id,S])),m=E(D,F,P),i=new Set(z.rerouteFrom?[z.rerouteFrom.accountId]:[]),l=F?.routing?.mode??"main-first",p=z.kind==="primary",U=new Set,L;for(;;){let S=new Set([...i,...U]);if(L=void 0,l==="sticky-balanced")L=f(m,D,F,z.sessionID,S,p&&U.size===0);if(L??=v(m,l,S,p?void 0:W.get(z.sessionID)),L===void 0||U.has(L)){L=void 0;break}let Z2=q.get(L)?.row;if(Z2){if(K.usableToken(Z2)!==void 0)break;j?.debug("pool row holds no usable token; choosing again",{accountId:L})}else{if(!B)break;let $2=await B.authorize(L);if($2){T.set(O({...z,accountId:L}),$2);break}j?.debug("the vault refused to serve an account; choosing again",{accountId:L})}U.add(L)}if(L===void 0&&!C&&D.length===0&&await $.slotPlaceholderWithoutMain?.())A();if(L===void 0&&C&&B&&(D.length===0||U.size>0)){let S=U.size>0?"vault-refused":H1(B);throw j?.warn("vault mode: no vault account can serve; refusing the request",{cause:S}),new c({kind:"no-account",providerID:n,sessionID:z.sessionID,requestKind:z.kind,message:W1[S]})}if(L!==void 0&&p)y(z.sessionID,L);return j?.debug("pool account chosen",{kind:z.kind,accountId:L,mode:l,...z.rerouteFrom?{rerouteFrom:z.rerouteFrom.accountId}:{}}),L},accountHeaders:async(z)=>{let{accountId:V}=z,F=()=>new c({kind:"no-account",providerID:n,sessionID:z.sessionID,requestKind:z.kind,message:O$}),C=B&&await B.authority()!=="local"?void 0:K.peek().rows.find((D)=>D.id===V);if(!C&&B){let D=O(z),k=T.get(D)??await B.authorize(V);if(T.delete(D),!k)throw j?.warn("the vault refused to serve an account; refusing the request",{accountId:V}),F();return{headers:{...x2,"session-id":z.sessionID,authorization:`Bearer ${k.accessToken}`,"chatgpt-account-id":k.accountIdentity??K1(k.accessToken)??null},attempt:{kind:"vault",routeId:V,receipt:k}}}let A=C?K.usableToken(C):void 0;if(!C||!A)throw j?.warn("pool row holds no usable token; refusing the request",{accountId:V}),F();let P=C.identity??K1(A);return{headers:{...x2,"session-id":z.sessionID,authorization:`Bearer ${A}`,"chatgpt-account-id":P??null},attempt:{kind:"pool",token:A,credentialEpoch:C.credentialEpoch}}},async rewriteRequest({request:z,sessionID:V,kind:F}){let C=$.codexEndpoint?S2(z.url,$.codexEndpoint()):z.url,A=C===z.url?z:new Request(C,z);return await e2(A,{sessionID:V,kind:F},R,$.responsesLite?.()??!1)??A},rewriteHandshakeURL:({url:z})=>$.codexEndpoint?S2(z,$.codexEndpoint()):void 0,rewriteWebSocketFrame:({frame:z,sessionID:V,kind:F})=>$1(z,{sessionID:V,kind:F},R),quotaFromHeaders:(z)=>I$(z),async limitFromResponse({status:z,headers:V,body:F}){if(z<400)return;let C=A2(await F().catch(()=>"")),A=W2({...K2(C)?C:{},status:z});if(!A)return;let P=X(),D=D2(A,P,z);if(D.retryAfterMs!==void 0)return D;let k=h$(V);return k===void 0?D:{...D,retryAfterMs:k}},inspectEvent:({data:z})=>w$(z,X()),limitFromError(z){let V=A2(z.message),F=W2({...K2(V)?V:{},...z.status!==void 0?{status:z.status}:{}})??(z.message.includes("usage_limit_reached")?{window:"usage_limit_reached"}:void 0);return F?D2(F,X(),z.status):void 0},async onAttemptEnd(z,V){let F=z.data;if(F?.kind!=="vault"||V.status!==401)return;j?.warn("a vault account answered 401; reporting it to the vault",{accountId:z.accountId}),await B?.reportFailure(F.receipt,401)}},g=(z,V,F)=>{let C=F.data;if(C?.kind==="vault"){B?.recordSnapshot(z,V.snapshot,V.complete,C.receipt);return}if(C?.kind!=="pool")return;if(K.peek().rows.find((P)=>P.id===z)?.credentialEpoch!==C.credentialEpoch){j?.debug("quota reading dropped: the row holds another credential",{accountId:z});return}K.recordSnapshot(z,V.snapshot,C.token,V.complete)},h=(z,V,F)=>{let C=X(),A=F.data?.kind==="vault",P=A?B?.routes().find((q)=>q.id===z)?.quota:K.peek().rows.find((q)=>q.id===z)?.quota,D=j1(V2(P),V.reason,C,D$,V.retryAfterMs!==void 0?C+V.retryAfterMs:void 0);if(!A){K.markRateLimited(z,D);return}let k=H.get(z);if(k===void 0||k<D)H.set(z,D)};return{adapter:u,attach(z){z.on("quota",(V)=>g(V.accountId,V.quota,V.handle)),z.on("limit",(V)=>{h(V.accountId,V.limit,V.handle),j?.debug("pool row refused the request",{accountId:V.accountId,via:V.via,reason:V.limit.reason,outputStarted:V.outputStarted})})},forgetSession(z){J.forget(z),W.delete(z),R.forget(z)}}}var v$="openai-auth-pool-browser",m$="openai-auth-pool-headless",f$="openai-auth-vault",g$="Vault login requires this OpenCode host to be enrolled in the Claustrum vault. Connect to the vault or disconnect this host before trying again.";async function X2($){if(await $.authority()!=="local")throw Error("This host is connected to the credential vault or its enrollment is unreadable; the login was not stored. Disconnect this host from the vault to add a local login.")}function A1($){return{method:{id:f$,type:"oauth",label:"ChatGPT accounts in the vault"},async activate(){if(await q1($.paths,$.name)!=="vault")throw Error(g$)}}}function D1($){let K=(J,X,j)=>({method:{id:J,type:"oauth",label:X},async authorize(){if($.vault)await X2($.vault);let B=await $.beginLogin({version:$.version,headless:j});return{url:B.url,instructions:B.instructions,mode:"auto",callback:B.completion}}});return[K(v$,"ChatGPT (openai-auth pool, browser)",!1),K(m$,"ChatGPT (openai-auth pool, headless)",!0)]}function O2($){let K=(J)=>typeof J==="string"?J:"";return J2({type:"oauth",access:K($.access),refresh:K($.refresh)})||$.refresh===S1||x1($)}function u$($){if($.accountId)return $.accountId;let K=$.access?H2($.access):void 0;return K?U2(K):void 0}async function O1($,K,J,X={}){if(X.vault)await X2(X.vault);if(O2(J))throw Error("the credential is not a ChatGPT login (a placeholder or a tombstone); it was not stored");let j=E1($,{rowLocks:(E)=>R1(K,E)}),B=await j.read();if(B.status!=="ready")throw Error(`the account pool cannot be read (${B.status}); the login was not stored`);let R={type:"oauth",refresh:J.refresh,...J.access!==void 0?{access:J.access}:{},...J.expires!==void 0?{expires:J.expires}:{}},T=u$(J);if(X.vault)await X2(X.vault);let O=T!==void 0?{identity:T}:{};if(X.origin==="import"){let E=B.rows.find((v)=>T!==void 0&&v.identity===T||v.credential?.type==="oauth"&&v.credential.refresh===J.refresh);if(E)return{id:E.id,operation:"kept"}}let H=B.rows.filter((E)=>E.type==="oauth"&&!E.invalid),W=T?H.find((E)=>E.identity===T):void 0,y=B.rows.find((E)=>E.id===N2);if(W)return{id:(await j.replace(W.id,R,O)).id,operation:"replaced"};if(!y){let E=await j.add({id:N2,credential:R,...O,...J.label!==void 0?{label:J.label}:{}});return{id:E.id,operation:E.outcome==="added-disabled"?"added-disabled":"added"}}if(!y.invalid&&!y.credential)return{id:(await j.replace(N2,R,O)).id,operation:"replaced"};let b=await j.add({id:J.id,credential:R,...O,...J.label!==void 0?{label:J.label}:{}});return{id:b.id,operation:b.outcome==="added-disabled"?"added-disabled":b.outcome==="rotated"?"replaced":"added"}}function p$($){if(!b1($.modelID??$.id)){$.enabled=!1;return}let K=y1($.id);if(K)$.limit={...K}}function k1($){return $.model.transform((K)=>{for(let J of K.list(n))K.update(n,String(J.id),(X)=>p$(X))})}import{resolve as I1}from"node:path";var l$=1024;class b2{pins=new Map;limit;constructor($=l$){this.limit=Math.max(1,$)}get($){return this.pins.get($)?.accountId}forget($){this.pins.delete($)}get size(){return this.pins.size}set($,K){this.pins.delete($),this.pins.set($,K);while(this.pins.size>this.limit){let J=this.pins.keys().next().value;if(J===void 0)break;this.pins.delete(J)}}place($){return w1(this.pins,$,(K,J)=>this.set(K,J))}}var h1=Symbol.for("@cortexkit/openai-auth/opencode2-pins"),v1=globalThis,y2=v1[h1]??new Map;v1[h1]=y2;function m1($){let K=JSON.stringify([I1($.configPath),I1($.statePath)]),J=y2.get(K);if(!J)J=new b2,y2.set(K,J);return J}var F2="cortexkit-openai-auth",c$=5000;async function f1($,K,J){let X=new Map,j=new Map,B=(H)=>{j.delete(H);for(let W of X.keys())if(W.startsWith(`${H}:`))X.delete(W)},T=await q2({session:{hook:(H,W,y)=>$.session.hook(H,async(b)=>{let E=H==="http.request"?b:void 0,v=H==="experimental.ws.handshake"?b:void 0,d=(E?E.request.headers:v?new Headers(v.headers):void 0)?.get("authorization")===`Bearer ${s(K.providerID)}`;try{await W(b)}catch(I){if(d&&!(I instanceof c))throw o1(I);throw I}if(E||v){let I=E??v;if(!I)return;let g=(E?E.request.headers:new Headers(I.headers)).get("authorization")?.replace(/^Bearer /,"");if(d&&g)j.set(I.sessionID,g);else j.delete(I.sessionID);if(v){let h=`${v.sessionID}:${v.kind}`;if(d&&g)X.set(h,g);else X.delete(h)}if(j.size>512){let h=j.keys().next().value;if(h)j.delete(h)}if(X.size>512){let h=X.keys().next().value;if(h)X.delete(h)}}else if(H==="experimental.ws.receive"){let I=b,u=X.get(`${I.sessionID}:${I.kind}`);if(u)I.frame=r1(I.frame,u)}else if(H==="retry"){let I=b,u=j.get(I.sessionID);if(u)Object.assign(I.error,{message:s1(I.error.message,u)})}},y)},event:{subscribe:(H)=>async function*(){for await(let W of $.event.subscribe(H)){if(W.type==="session.deleted")B(W.data.sessionID);yield W}}()}},{...K,rewriteResponse:async(H)=>{let W=await K.rewriteResponse?.(H)??H.response;return t1(W,H.request.headers.get("authorization")?.replace(/^Bearer /,""),"event-stream")}},{gateOnPlaceholder:{credential:(H)=>{let W=H.get("authorization");return W?.startsWith("Bearer ")?W.slice(7):void 0}},logger:{warn:(H,W)=>J.warn(H,{data:W})}}),O=T.dispose;return{...T,dispose:async()=>{j.clear(),X.clear(),await O()}}}function I2($={}){return{id:F2,setup:(K)=>d$(K,$)}}async function d$($,K={}){let m=[];try{let J=j2("opencode2");let X=j2("quota");let j=K.paths??(()=>$$(e1()));let B=K.fetch??fetch;let R=K.version??J$;let T=K.poolMigration??W$;if(!T&&!G2(j().configPath)){J.info("openai-auth stands aside on OpenCode 2: this install has not moved into the account pool and the migration is switched off, so OpenCode 2 serves its own ChatGPT login");let U=(S)=>{throw new c({kind:"no-account",providerID:n,sessionID:S.sessionID,requestKind:S.kind,message:C2})},L=await f1($,{providerID:n,chooseAccount:U,accountHeaders:U},J);return()=>L.dispose()}let O=K.vault?.firstRosterWaitMs??j$;let H=V$({host:"opencode",stateDir:K.vault?.stateDir??a1(j().statePath),reservedRouteIds:()=>f.peek().rows.map((U)=>U.id),...K.vault?.connectionFile?{connectionFile:K.vault.connectionFile}:{},...K.vault?.connectScoped?{connectScoped:K.vault.connectScoped}:{},...K.vault?.connectEnrollment?{connectEnrollment:K.vault.connectEnrollment}:{},...K.vault?.pollIntervalMs!==void 0?{pollIntervalMs:K.vault.pollIntervalMs}:{},fetchImpl:()=>B},j());let W=H.vault;let y=!1;let b=!1;const E=g1(m,{[Symbol.dispose](){if(!y)H.release()}},0);await W.authority();let v=H.firstRoster;let f=new G$({paths:j,refreshProvider:async(U)=>{let L=await c1({refreshToken:U.refresh,fetchImpl:B,now:Date.now}),S=p1({id_token:"",access_token:L.access,refresh_token:L.refresh});return{...L,...S?{identity:S}:{}}},pullQuota:async(U)=>{let L=U.credential;if(L.type!=="oauth"||!L.access)throw Error("the row holds no access token to poll with");let S=await d1({accessToken:L.access,fetchImpl:B,now:Date.now,...U.identity?{accountId:U.identity}:{},accountKey:U.id,logger:X});return n1(S,Date.now(),!0)},vaultIdentities:()=>W.identities(),vaultMode:()=>W.enrolled(),vaultAuthority:()=>W.authority(),vaultFirstRoster:v,vaultFirstRosterBackgroundWaitMs:O,log:j2("pool")});await f.load();let d=K.heartbeat===!1?void 0:await B$({version:R,logger:j2("heartbeat")});let I=K.fence??(()=>z$({currentVersion:R}));let u=K.slot??H$();let g=async()=>Y$(j(),await u.get({path:{id:"openai"}}));let h=!1;let z=T?Q$({paths:j,slot:u,version:R,fence:I,runDeps:{vaultServes:()=>W.serves()},paused:async()=>await W.authority()!=="local",migrate:async(U)=>{let L=await K$(U);if(h=L.status==="refused",!b)await f.load();return L},adopt:async(U)=>{if(b)return{status:"retry",reason:"unsettled"};if(!await w2(v,O))return{status:"retry",reason:"vault-roster-pending"};if(b)return{status:"retry",reason:"unsettled"};let L=await Z$(U);if(!b)await f.load();return L}}):void 0;z?.start();H.start();let V=m1(j());let F=_1({source:f,slotPlaceholderWithoutMain:g,storage:()=>i1(j()),pins:V,vault:W,awaitVaultRoster:async()=>{await w2(W.awaitRequestRoster(),X$)},responsesLite:()=>k2().responsesLite,codexEndpoint:()=>k2().codexApiEndpoint,log:J});let C=await f1($,F.adapter,J);F.attach(C);let A=async(U)=>{if(await X2(W),G2(j().configPath))return;if(await z?.idle(),G2(j().configPath))return;if(h&&!O2(U)&&(await I()).open){await f.poolStore().initialize();return}throw Error("OpenAI accounts move to the shared account pool once every OpenCode process on this machine runs this version of openai-auth; the login was not stored. Update or close the older processes and sign in again.")};let P=async(U)=>{await A(U);let L=await O1(f.poolStore(),j(),U,{vault:W});if(!G2(j().configPath))await z?.requestAdoption();await f.load(),J.info("ChatGPT login stored in the account pool",L)};let D=await M2($,{integrationID:n,methods:D1({beginLogin:K.beginLogin??l1,version:R,vault:W}),onLogin:(U)=>P(U),label:"ChatGPT (openai-auth account pool)",vault:A1(W)});let k=await k1($);let q=new AbortController;(async()=>{try{for await(let U of $.event.subscribe({signal:q.signal}))if(U.type==="session.deleted")F.forgetSession(U.data.sessionID)}catch(U){if(!q.signal.aborted)J.warn("stopped listening for session deletion",{error:U instanceof Error?U.message:String(U)})}})();y=!0;return async()=>{b=!0,q.abort(),z?.dispose(),f.dispose(),await Promise.allSettled([C.dispose(),D.dispose(),k.dispose()]);let U;try{await Promise.race([Promise.all([z?.idle(),f.settled()]),new Promise((L)=>{U=setTimeout(L,c$),U.unref?.()})])}finally{clearTimeout(U),H.release(),await d?.release()}}}catch(i){var l=i,p=1}finally{u1(m,l,p)}}var i$=I2(),jK={id:F2,setup:i$.setup,server:U$.server};export{jK as default,I2 as createOpenAIAuthPlugin,F2 as OPENAI_AUTH_PLUGIN_ID};
|
|
1
|
+
import{c as BZ}from"../index-j8v2xwq6.js";import{A as o2,B as XZ,C as GZ,D as I1,E as y$,F as w$,G as YZ,H as jZ,I as e1,J as $$,K as E2,L as f1,O as H$,P as K$,X as C$,Y as T$,aa as QZ,d as m1,e as s$,f as P2,g as B2,ga as V1,h as A2,ha as W1,i as $Z,j as ZZ,k as S2,ka as VZ,l as H2,n as j1,o as Q1,p as B1,q as g1,r as l1,s as u1,t as o1,u as r1,v as t1,w as V$,x as W$,y as JZ,z as zZ}from"../index-edbdscy7.js";import{$a as D2,Ka as X$,Ra as L$,ab as i$,bb as n$,cb as a$,eb as o$,fb as G$,ob as r$,pb as t$,qb as e$,ra as d$,rb as Y$,sa as R1,ta as O1}from"../index-0yh85bwb.js";import{$b as k$,Fb as S$,Ub as D$,Vb as q$,Xb as b$}from"../index-8re8rprk.js";import{$c as J$,Ad as E1,Gd as x2,Ic as R2,Jc as O2,Kc as p$,Nd as P$,Od as N2,Pd as A1,Qd as x1,Rc as s2,Rd as S1,Sc as C1,Tc as T1,Td as D1,Uc as M1,Ud as q1,Vd as b1,Wd as k1,Xd as y1,Yd as w1,fd as z$,hd as c$,id as F$,jd as _1,mc as P1,sd as z2,xd as L1}from"../index-7eb3dw37.js";import{ce as v1}from"../index-msx2m78k.js";import{le as a1}from"../index-4c8yw54k.js";import"../index-k6cydkgt.js";import{ve as u$,xe as j2}from"../index-7c6sxtd6.js";import"../index-m5qmvr6c.js";import{Te as s1}from"../index-f2fmb596.js";import{Xe as a2,Ye as l$}from"../index-csky2xpg.js";import{AsyncLocalStorage as tZ}from"node:async_hooks";import{randomUUID as eZ}from"node:crypto";class a extends Error{kind;providerID;sessionID;requestKind;constructor($){super($.message??`${$.providerID} ${$.requestKind} request refused (${$.kind})`);this.name="OpenCode2AuthError",this.kind=$.kind,this.providerID=$.providerID,this.sessionID=$.sessionID,this.requestKind=$.requestKind}}function e($){return`common-auth-placeholder.${$}`}function z1($){let Z=e($.integrationID);return{type:"oauth",methodID:$.methodID,access:Z,refresh:Z,expires:$.now+31536000000,metadata:{["commonAuthPlaceholder"]:!0}}}function U2($,Z){if($?.type!=="oauth")return!1;let z=Z===void 0?void 0:e(Z),X=(G)=>z===void 0?G.startsWith("common-auth-placeholder."):G===z;return X($.access)&&X($.refresh)}var X1="No browser sign-in: this connects the plugin to the accounts in its vault.";async function k2($,Z){let z=Z.now??Date.now,{integrationID:X}=Z,G=(K)=>z1({integrationID:X,methodID:K,now:z()}),Q=async(K,L)=>{return await Z.onLogin(K,{integrationID:X,methodID:L}),G(L)},F=(K)=>async(L)=>{let N=K.method.id,H=await K.authorize(L),A={url:H.url,instructions:H.instructions,...H.expiresAt===void 0?{}:{expiresAt:H.expiresAt}};if(H.mode==="auto")return{...A,mode:"auto",callback:H.callback.then((W)=>Q(W,N))};let P=H.callback;return{...A,mode:"code",callback:async(W)=>Q(await P(W),N)}};return $.integration.transform((K)=>{let L=Z.label===void 0?{}:{label:()=>Z.label};for(let A of Z.methods)K.method.update({integrationID:X,method:A.method,authorize:F(A),refresh:async(P)=>{if(!U2(P,X))throw Error("This login method refreshes only its pool placeholder; sign in again with the plugin's login method.");return G(P.methodID)},...L});let N=Z.vault;if(N===void 0)return;let H=N.method.id;K.method.update({integrationID:X,method:N.method,authorize:async()=>({url:"",instructions:N.instructions??X1,mode:"auto",callback:Promise.resolve().then(()=>N.activate({integrationID:X,methodID:H})).then(()=>G(H))}),refresh:async(A)=>{if(!U2(A,X)||A.methodID!==H)throw Error("This login method refreshes only its vault placeholder; choose the plugin's vault login method again.");return G(H)},...L})})}function UZ($){let Z=[],z;for(let X of $.split(/\r?\n/))if(X.startsWith("data:"))Z.push(X.slice(5).replace(/^ /,""));else if(X.startsWith("event:"))z=X.slice(6).trim();if(Z.length===0)return;return z===void 0?{data:Z.join(`
|
|
2
|
+
`)}:{event:z,data:Z.join(`
|
|
3
|
+
`)}}function y2($,Z){let z=new TextDecoder,X="",G=(F)=>{let K=UZ(F);if(!K)return;try{$(K)}catch(L){Z(L)}},Q=()=>{for(;;){let F=/\r?\n\r?\n/.exec(X);if(!F)return;let K=X.slice(0,F.index);X=X.slice(F.index+F[0].length),G(K)}};return new TransformStream({transform(F,K){K.enqueue(F),X+=z.decode(F,{stream:!0}),Q()},flush(){if(X+=z.decode(),Q(),X.trim()!=="")G(X);X=""}})}var G1=512,Q2="x-common-auth-attempt",Y2=($,Z)=>JSON.stringify([$,Z]),$2=($)=>({providerID:$.model.providerID,modelID:$.model.id,sessionID:$.sessionID,agent:$.agent,kind:$.kind});function HZ($){let Z=$.headers;return typeof Z==="object"&&Z!==null}function KZ($,Z){let z=$.getReader();return new ReadableStream({async pull(X){let G;try{G=await z.read()}catch(Q){Z({reason:"failed",message:Q instanceof Error?Q.message:String(Q)}),X.error(Q);return}if(G.done)Z(),X.close();else X.enqueue(G.value)},async cancel(X){Z({reason:"cancelled",...X===void 0?{}:{message:String(X)}}),await z.cancel(X)}})}function w2($,Z){for(let[z,X]of Object.entries(Z)){let G=z.toLowerCase();for(let Q of Object.keys($))if(Q.toLowerCase()===G)delete $[Q];if(X!==null)$[z]=X}}function NZ($,Z){for(let[z,X]of Object.entries(Z))if(X===null)$.delete(z);else $.set(z,X)}async function I2($,Z,z={}){let{providerID:X}=Z,G=z.gateOnPlaceholder,Q=(J)=>G===void 0||G.credential(J)===e(X),F=z.logger,K=Math.max(1,z.maxRecords??G1),L=[...z.hostCredentials??[e(X)],...G?[e(X)]:[]].filter((J)=>J!==""),N=new Map,H=new WeakMap,A=new Map,P=new Set,W=new Map,g=!1,p=!1,l=new Map,m=0,r=!1,k=new Map,f=(J,j)=>{try{F?.warn(J,j)}catch{}},Y=(J)=>J instanceof Error?J.message:String(J),U=async(J,j)=>{let B=l.get(J);if(!B||B.size===0)return;await Promise.all([...B].map(async(V)=>{try{await V(j)}catch(R){f("opencode2 auth listener threw; the request is unaffected",{event:J,error:Y(R)})}}))},M=async(J,j)=>{try{await Z.onAttemptEnd?.(J,j)}catch(B){f("opencode2 auth onAttemptEnd threw; the request is unaffected",{attemptId:J.attemptId,error:Y(B)})}},C=(J,j)=>{if(J.ended||!J.attempt)return;let B={...J.status===void 0?{}:{status:J.status},outputStarted:J.outputStarted,...J.limit?{limit:J.limit.signal}:{},...j?{error:j}:{}};if(j)J.endError=j;J.ended=M(J.attempt,B)},q=(J,j)=>C(J,{reason:"abandoned",message:j}),T=(J)=>[...N.values()].filter((j)=>j.key===J),x=(J)=>T(J).at(-1),y=(J)=>{if(N.delete(J.id),!T(J.key).length)A.delete(J.key)},b=(J)=>{N.set(J.id,J);while(N.size>K){let j=N.values().next().value;if(j===void 0)break;q(j,"dropped to keep the record bound"),y(j)}},h=(J)=>J.accountId===void 0?void 0:{...J.scope,accountId:J.accountId},i=(J,j)=>new a({kind:"no-account",providerID:X,sessionID:J.sessionID,requestKind:J.kind,...j===void 0?{}:{message:j}}),n=(J)=>{k.get(J)?.clear(),k.delete(J)},c=async(J,j)=>{let B=()=>i(J,`${X} ${J.kind} request has no account: its auth selection was revoked by session forgetting or installation disposal`);if(r)throw B();let V=k.get(J.sessionID);if(!V)V=new Set,k.set(J.sessionID,V);let R={};V.add(R);let S=()=>{if(!V.has(R))throw B()};try{return await j(S)}finally{if(V.delete(R),V.size===0&&k.get(J.sessionID)===V)k.delete(J.sessionID)}},d=(J,j)=>{for(let[B,V]of j)if(L.some((R)=>V.includes(R)))throw new a({kind:"host-credential-on-wire",providerID:X,sessionID:J.sessionID,requestKind:J.kind,message:`${X} ${J.kind} request still carries the host's placeholder credential in ${B}; the adapter's account headers must replace it`})},D=(J)=>{for(let j of T(J))if(j.ended||!j.attempt)y(j);else if(j.transport==="ws"||j.judged)q(j,"a newer attempt of its session and kind began"),y(j)},v=async(J,j,B,V)=>{let R=Y2(J.sessionID,J.kind),S=A.get(R);A.delete(R);let _=S?.accountId??x(R)?.accountId;D(R);let O={...J,..._===void 0?{}:{previousAccountId:_},...S?.rerouteFrom===void 0?{}:{rerouteFrom:S.rerouteFrom}},w=await Z.chooseAccount(O);B();let t={},Z1;if(w!==void 0){let _2=await Z.accountHeaders({...J,accountId:w});if(B(),HZ(_2))t=_2.headers,Z1=_2.attempt;else t=_2}let J1=`attempt-${++m}`,W2={id:J1,key:R,scope:J,accountId:w,headers:t,attempt:w===void 0?void 0:{...J,accountId:w,attemptId:J1,transport:V,data:Z1},...V===void 0?{}:{transport:V},outputStarted:!1};if(b(W2),W2.attempt)U("select",{...J,accountId:W2.attempt.accountId,hook:j,...O.previousAccountId===void 0?{}:{previousAccountId:O.previousAccountId},...O.rerouteFrom===void 0?{}:{rerouteFrom:O.rerouteFrom},handle:W2.attempt});return W2},I=async(J,j,B,V,R)=>{let S=Y2(J.sessionID,J.kind),_=V===void 0?void 0:N.get(V);if(_?.key!==S)_=void 0;if(!_){if(_=x(S),T(S).filter((w)=>w.transport===void 0&&!w.ended).length>1&&!p)p=!0,f("opencode2 auth tied a send without its attempt mark to the newest of several waiting attempts",{sessionID:J.sessionID,kind:J.kind})}if(!_||_.transport!==void 0||_.ended)_=await v(J,j,R,B);else if(_.transport=B,_.attempt)_.attempt.transport=B;if(B==="ws"){for(let O of T(S))if(O!==_&&O.transport==="ws")q(O,"a newer attempt of its session and kind went out over WebSocket")}return _},o=async(J,j)=>{try{return await j()}catch(B){throw C(J,{reason:"failed",message:Y(B)}),B}},T2=(J,j)=>{let B=T(Y2(J,j)).filter((V)=>V.transport==="ws").at(-1);return B?.attempt!==void 0&&!B.ended?B:void 0},V2=(J,j,B)=>{let V=h(J);if(!V||!J.attempt||J.limit)return;J.limit={signal:j,delivered:U("limit",{...V,via:B,limit:j,outputStarted:J.outputStarted,handle:J.attempt})}},M2=(J,j,B,V)=>{let R=h(J);if(!R||!J.attempt)return;U("quota",{...R,transport:j,...V===void 0?{}:{status:V},quota:B,handle:J.attempt})},E=(J,j,B,V)=>{let R=J.attempt;if(!R)return;let S=Z.inspectEvent?.(V===void 0?{transport:j,data:B,attempt:R}:{transport:j,data:B,event:V,attempt:R});if(!S)return;if(S.quota!==void 0)M2(J,j,S.quota);if(S.outputStarted)J.outputStarted=!0;if(S.limit)V2(J,S.limit,j);if(S.error!==void 0)C(J,{reason:"failed",message:S.error});else if(S.done)C(J)},u=(J,j)=>{let B=J.attempt;if(!B||j.accountId===J.accountId)return;if(B.reboundFrom??=B.accountId,B.accountId=j.accountId,"data"in j)B.data=j.data;J.accountId=j.accountId},X2=(J)=>!J.attempt||J.endError!==void 0||J.status!==void 0&&J.status>=400,WZ=(J)=>{let j=[...N.values()].filter((O)=>O.scope.sessionID===J),B=j.filter((O)=>O.limit&&!O.rerouted).at(-1);if(B)return B;let V=j.filter((O)=>O.scope.kind==="primary"),R=V.length>0?V:j;if(R.length<=1)return R[0];let S=R.filter((O)=>!O.judged&&X2(O)).at(-1);if(S)return S;let _=R.filter((O)=>O.attempt&&!O.ended);if(_.length>1)return"ambiguous";return _[0]??R.at(-1)},G2={providerID:X},J2=[];J2.push(await $.session.hook("model.request",(J)=>{if(G)return;return c($2(J),async(j)=>{let B=await v($2(J),"model.request",j);if(j(),B.accountId===void 0)throw i(B.scope);w2(J.headers,{...B.headers,[Q2]:B.id})})},G2)),J2.push(await $.session.hook("http.request",(J)=>{if(G){let j=Q(J.request.headers);if(W.set(J.sessionID,j),!j)return}return c($2(J),async(j)=>{let B=J.request.headers.get(Q2)??void 0,V=G?await v($2(J),"http.request",j,"http"):await I($2(J),"http.request","http",B,j);j();let R=h(V),S=V.attempt;if(!R||!S)throw i(V.scope);await o(V,async()=>{let _=J.request;if(Z.rewriteRequest){if(B!==void 0){let t=new Headers(_.headers);t.delete(Q2),_=new Request(_,{headers:t})}_=await Z.rewriteRequest({...R,request:_,attempt:S})??_,j()}let O=new Headers(_.headers);O.delete(Q2),NZ(O,V.headers),d(V.scope,O.entries());let w=new Request(_,{headers:O});H.set(w,V),J.request=w})})},G2)),J2.push(await $.session.hook("http.response",async(J)=>{let j=H.get(J.request);if(!j){if(G)return;if(!g)g=!0,f("opencode2 auth dropped an http.response whose request it did not produce",{sessionID:J.sessionID,kind:J.kind});return}let B=J.response;if(Z.answeredBy&&j.attempt){let O=j.attempt,w=await o(j,async()=>Z.answeredBy?.({request:J.request,response:B,attempt:O}));if(w)u(j,w)}let V=h(j),R=j.attempt;if(!V||!R)return;j.status=B.status;let S=Z.quotaFromHeaders?.(B.headers,B.status,R);if(S!==void 0)M2(j,"http",S,B.status);if(!B.ok&&Z.limitFromResponse){let O=await Z.limitFromResponse({status:B.status,headers:B.headers,body:()=>B.clone().text(),attempt:R});if(O)V2(j,O,"http")}if(!B.ok||!B.body)C(j);let _=B;if(B.body&&(Z.inspectEvent||Z.onAttemptEnd)){let O=B.body;if(Z.inspectEvent)O=O.pipeThrough(y2((w)=>E(j,"http",w.data,w.event),(w)=>f("opencode2 auth event inspection threw",{error:Y(w)})));_=new Response(KZ(O,(w)=>C(j,w)),{status:B.status,statusText:B.statusText,headers:B.headers})}if(Z.rewriteResponse)_=await Z.rewriteResponse({...V,request:J.request,response:_,attempt:R})??_;if(_!==B)J.response=_},G2)),J2.push(await $.session.hook("experimental.ws.handshake",(J)=>{if(G){let j=Q(new Headers(J.headers)),B=Y2(J.sessionID,J.kind);if(W.set(J.sessionID,j),P.delete(B),!j)return}return c($2(J),async(j)=>{let B;for(let _ of Object.keys(J.headers)){if(_.toLowerCase()!==Q2)continue;B??=J.headers[_],delete J.headers[_]}let V=G?await v($2(J),"experimental.ws.handshake",j,"ws"):await I($2(J),"experimental.ws.handshake","ws",B,j);j();let R=h(V),S=V.attempt;if(!R||!S)throw i(V.scope);await o(V,async()=>{w2(J.headers,V.headers);let _=Z.rewriteHandshakeURL?.({...R,url:J.url,attempt:S});if(_!==void 0)J.url=_;if(d(V.scope,Object.entries(J.headers)),G)P.add(V.key)})})},G2));let t2=Z.rewriteWebSocketFrame?.bind(Z);if(t2)J2.push(await $.session.hook("experimental.ws.send",async(J)=>{let j=$2(J);if(G&&!P.has(Y2(j.sessionID,j.kind)))return;let B=T2(j.sessionID,j.kind),V=await t2({...j,attempt:B?.attempt,frame:J.frame});if(V!==void 0)J.frame=V},G2));J2.push(await $.session.hook("experimental.ws.receive",(J)=>{if(G&&!P.has(Y2(J.sessionID,J.kind)))return;let j=T2(J.sessionID,J.kind);if(!j)return;try{E(j,"ws",J.frame)}catch(B){f("opencode2 auth frame inspection threw",{error:Y(B)})}},G2)),J2.push(await $.session.hook("retry",async(J)=>{if(G&&W.get(J.sessionID)!==!0)return;let j=WZ(J.sessionID);if(!j)return;let B=J.decision;if(j==="ambiguous"){await U("retry",{sessionID:J.sessionID,attempt:J.attempt,reason:"host-decides",hostDecision:B,decision:B});return}let V=j;await c(V.scope,async(R)=>{V.judged=!0;let S=B,_,O,w=V.attempt;if(V.accountId===void 0||!w)S={retry:!1},_="no-account";else if(V.outputStarted)S={retry:!1},_="output-started";else{if(!V.limit){let t=Z.limitFromError?.(J.error,w);if(t)V2(V,t,"error")}if(V.ended)await V.ended,R();if(V.limit)await V.limit.delivered,R(),V.rerouted=!0,O={accountId:V.accountId,limit:V.limit.signal},S={retry:!0,delay:0},_="reroute";else _="host-decides"}if(J.decision=S,S.retry&&V.accountId!==void 0)A.set(V.key,{sessionID:V.scope.sessionID,accountId:V.accountId,...O===void 0?{}:{rerouteFrom:O}});await U("retry",{sessionID:J.sessionID,...V.accountId===void 0?{}:{accountId:V.accountId},kind:V.scope.kind,attempt:J.attempt,reason:_,hostDecision:B,decision:S,...w===void 0?{}:{handle:w}})})},G2));let e2=(J)=>{n(J),W.delete(J);for(let j of P)if(JSON.parse(j)[0]===J)P.delete(j);for(let j of[...N.values()]){if(j.scope.sessionID!==J)continue;q(j,"its session was forgotten"),N.delete(j.id)}for(let[j,B]of A)if(B.sessionID===J)A.delete(j)},b2=new AbortController,$1=$.event;if($1)(async()=>{try{for await(let J of $1.subscribe({signal:b2.signal}))if(J.type==="session.deleted")e2(J.data.sessionID)}catch(J){if(!b2.signal.aborted)f("opencode2 auth stopped listening for session deletion",{error:Y(J)})}})();return{on(J,j){let B=l.get(J);if(!B)B=new Set,l.set(J,B);let V=j;return B.add(V),()=>{B.delete(V)}},accountFor(J,j){return x(Y2(J,j))?.accountId},forgetSession:e2,get size(){return N.size},async dispose(){if(r)return;r=!0;for(let J of k.keys())n(J);b2.abort();for(let J of N.values())q(J,"the installation was disposed");N.clear(),A.clear(),P.clear(),W.clear(),l.clear(),await Promise.all(J2.map(async(J)=>{try{await J.dispose()}catch(j){f("opencode2 auth hook did not dispose cleanly",{error:Y(j)})}}))}}}var Y1=Symbol.for("@cortexkit/openai-auth/opencode2/codex-installation");function FZ(){let $=globalThis;return $[Y1]??=crypto.randomUUID(),$[Y1]}class K2{runtime;store;sessions;installationID;constructor($,Z,z){this.runtime=$;this.store=z;this.installationID=Z??FZ(),this.sessions=z?.sessions??new Map}get($){let Z=this.runtime?.uuid??H2;if(this.store)return this.store.get($,Z);let z=this.sessions.get($);if(!z){let X=Z();z={threadID:X,turnID:Z(),windowID:`${X}:0`},this.sessions.set($,z)}return z}forget($){if(this.store)this.store.delete($);else this.sessions.delete($)}}var f2={version:j1,"user-agent":Q1,originator:"codex_exec"};var PZ=1024,CZ=/(?:^|\/)gpt-6-(?:astra|sol|luna)$/i,L2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($),TZ=($)=>L2($)&&($.type==="message"||("role"in $))&&$.role==="user",MZ=($)=>L2($)&&$.type==="configuration_update";class h2{http;#$=new Map;constructor($=new K2){this.http=$}apply($,Z,z){if(Z.kind!=="primary")return!1;let X=typeof $.model==="string"?$.model:"";if(!V1.has(X))return!1;if(CZ.test(X))return!1;let G=L2($.reasoning)?$.reasoning:void 0,Q=typeof G?.effort==="string"?G.effort:void 0;if(!Q)return!1;let F=this.#$.get(Z.sessionID);if(F===void 0)return this.#Z(Z.sessionID,Q),!1;if(Q===F)return!1;let K=Array.isArray($.input)?$.input:void 0;if(!K||K.length===0)return!1;let L=K.findLastIndex(TZ);if(L<0){if(z==="http")return!1;return $.reasoning={...G,effort:F},!0}if($.reasoning={...G,effort:F},!MZ(K[L-1]))K.splice(L,0,{type:"configuration_update",reasoning:{effort:Q}});return!0}forget($){this.#$.delete($),this.http.forget($)}#Z($,Z){this.#$.set($,Z);while(this.#$.size>PZ){let z=this.#$.keys().next().value;if(z===void 0)break;this.#$.delete(z)}}}function U1($){try{let Z=JSON.parse($);return L2(Z)?Z:void 0}catch{return}}async function H1($,Z,z,X,G=z.http){if($.method.toUpperCase()!=="POST")return;if(!/\/responses\/?$/.test(new URL($.url).pathname))return;let Q=await $.clone().text(),F=U1(Q);if(F)delete F.max_output_tokens;let K=new Headers($.headers),L=B1({rewriteLite:W1,init:{body:F?JSON.stringify(F):$.body===null?void 0:Q},headers:K,metadata:G.get(Z.sessionID),installationID:G.installationID,runtime:G.runtime,websocket:!1,responsesLite:X,applyEffort:(N)=>{z.apply(N,Z,"http")}});return new Request($,{headers:K,body:L.init?.body})}function K1($,Z,z){let X=U1($);if(X?.type!=="response.create")return;let G="max_output_tokens"in X;delete X.max_output_tokens;let Q=z.http.get(Z.sessionID).threadID,F=X.prompt_cache_key!==Q;X.prompt_cache_key=Q;let K=z.apply(X,Z,"ws");return G||F||K?JSON.stringify(X):void 0}function _Z($){return $.replace(/\/responses\/?$/,"").replace(/\/$/,"")}function v2($,Z){let z=new URL($);if(z.origin!=="https://api.openai.com"&&z.origin!=="wss://api.openai.com"||!/\/responses\/?$/.test(z.pathname))return $;let X=new URL(`${_Z(Z)}/responses`);if(X.search=z.search,z.protocol==="ws:"||z.protocol==="wss:")X.protocol=X.protocol==="https:"?"wss:":"ws:";return X.href}var s="openai",LZ=60000,N1=1,EZ="request refused: no account with a usable credential",RZ=1024,Z2=($)=>typeof $==="object"&&$!==null&&!Array.isArray($);function OZ($){let Z=Z2($)?$.counters:void 0,z=Z2(Z)?Z.resetCredits:void 0,X=Z2(z)?z.value:void 0;return typeof X==="number"&&Number.isFinite(X)?X:void 0}function m2($){try{return JSON.parse($)}catch{return}}function F1($){let Z=R2($);return Z?O2(Z):void 0}var AZ=new Set(["usage_limit_reached","rate_limit_exceeded"]);function g2($,Z,z){return{reason:$.window,...z!==void 0?{status:z}:{},...$.resetAt!==void 0?{retryAfterMs:Math.max(0,$.resetAt-Z)}:{}}}function xZ($,Z){let z=E2($);if(z){let Q=typeof $.status==="number"?$.status:void 0;return g2(z,Z,Q)}if($.type!=="response.failed"||!Z2($.response))return;let X=$.response.failed;if(Z2(X)&&typeof X.rate_limit_reached_type==="string")return{reason:X.rate_limit_reached_type};let G=$.response.error;if(Z2(G)){let Q=typeof G.code==="string"?G.code:typeof G.type==="string"?G.type:void 0;if(Q&&AZ.has(Q))return{reason:Q}}return}function SZ($,Z){let z=m2($);if(!Z2(z))return;let X=typeof z.type==="string"?z.type:void 0;if(X==="codex.rate_limits")return{quota:{snapshot:M1(z),complete:!0}};let G=xZ(z,Z);if(G)return{limit:G};if(X===void 0||X==="error")return;return f1(X)?void 0:{outputStarted:!0}}function DZ($){let Z=!1;for(let z of $.keys())if(z.toLowerCase().startsWith("x-codex-")){Z=!0;break}if(!Z)return;return{snapshot:C1($),complete:T1($)}}function qZ($){let Z=$.get("retry-after");if(Z===null)return;let z=Number(Z);return Number.isFinite(z)&&z>=0?z*1000:void 0}function h1($){let{source:Z,pins:z}=$,X=$.now??Date.now,G=$.log,Q=$.vault,F=new h2($.codex),K=new Map,L=(Y)=>`${Y.sessionID}\x00${Y.kind}\x00${Y.accountId}`,N=new Map,H=new Map,A=(Y,U)=>{H.delete(Y),H.set(Y,U);while(H.size>RZ){let M=H.keys().next().value;if(M===void 0)break;H.delete(M)}},P=(Y,U,M)=>{let C=M?[]:I1(Z.peek().rows,Y,U,Q?.identities()??new Set),q=(Q?.routes()??[]).filter((T)=>T.kind==="oauth"&&L1(N2(T.quota),Y,U));return[...C.map((T)=>({id:T.id,...T.identity!==void 0?{identity:T.identity}:{},quota:T.quota,row:T})),...q.map((T)=>({id:T.id,...T.identity!==void 0?{identity:T.identity}:{},quota:T.quota}))]},W=(Y,U,M)=>{let C=S1(Y,U,M),q=Y.map((b)=>({id:b.id,kind:"oauth",...P1(b.quota)?{quota:b.quota}:{}})),T=Y.flatMap((b)=>b.row?[b.row]:[]),x=new Set(Y.filter((b)=>!b.row).map((b)=>b.id)),y=Z.rateLimitMarks(T);for(let b of x){let h=N.get(b);if(h===void 0)continue;if(h<=M)N.delete(b);else y.set(b,h)}return{rows:q,now:M,rateLimitMarks:y,refreshBackoff:Z.refreshBackoffFor(T),killswitch:C,requestPull:(b)=>x.has(b)?Q?.requestReading(b):Z.requestReading(b)}},g=(Y,U,M,C,q)=>{let T=b1({...Y,placement:D1(U),mainId:q});if(T.kind==="block"){G?.debug("pool admission refused the request",{reason:T.block.reason});return}let x=T.order.filter((y)=>!M.has(y));if(C!==void 0&&x.includes(C))return C;return x[0]},p=(Y,U,M,C,q,T)=>{let x=new Map(U.map((D)=>[D.id,D.quota])),y={requestBytes:N1,reservePercent:(D)=>E1(M,D===A1?void 0:D),resetCredits:(D)=>OZ(x.get(D))},b=k1(Y),h=(D,v)=>z.place({sessionId:C,requestBytes:N1,validPinnedAccountIds:Y.rows.map((I)=>I.id).filter((I)=>!b.excluded.has(I)),excludeAccountIds:D,quotaCheckedAtByAccount:Object.fromEntries(Y.rows.map((I)=>[I.id,b.projections.get(I.id)?.checkedAt])),wireAccountIdByAccount:Object.fromEntries(U.map((I)=>[I.id,I.identity])),select:(I)=>y1(Y,y,new Set(D),I),persist:v}),i=[...q],n=h(i,T);if(!n)return;let c=n.accountId,d=w1(Y,y,c);if(d.kind==="none")return;if(d.kind==="move"){let D=h([...i,c],T);if(D)return D.accountId;return d.reason==="killswitch"?void 0:c}if(d.kind==="detour")return h([...i,c],!1)?.accountId;return c},r={providerID:s,chooseAccount:async(Y)=>{let U=await Q?.authority(),M=await $.storage(),C=U!==void 0&&U!=="local",q=()=>{throw new a({kind:"no-account",providerID:s,sessionID:Y.sessionID,requestKind:Y.kind,message:A2})};if(C)await $.awaitVaultRoster?.();else{if(!(await Z.current()).active){if(await $.slotPlaceholderWithoutMain?.())q();G?.warn("the account pool does not serve requests yet; refusing the request",{kind:Y.kind});return}await Z.prepareTokens(Z.peek().rows,M)}let T=X(),x=P(M,T,C),y=q1(W(x.filter((v)=>v.id!==Y.rerouteFrom?.accountId),M,T));if(y)await y,T=X(),x=P(M,T,C);let b=new Map(x.map((v)=>[v.id,v])),h=W(x,M,T),i=new Set(Y.rerouteFrom?[Y.rerouteFrom.accountId]:[]),n=M?.routing?.mode??"main-first",c=Y.kind==="primary",d=new Set,D;for(;;){let v=new Set([...i,...d]);if(D=void 0,n==="sticky-balanced")D=p(h,x,M,Y.sessionID,v,c&&d.size===0);if(D??=g(h,n,v,c?void 0:H.get(Y.sessionID),C?n==="sticky-balanced"?null:x1(Q?.routes()??[]):void 0),D===void 0||d.has(D)){D=void 0;break}let I=b.get(D)?.row;if(I){if(Z.usableToken(I)!==void 0)break;G?.debug("pool row holds no usable token; choosing again",{accountId:D})}else{if(!Q)break;let o=await Q.authorize(D);if(o){K.set(L({...Y,accountId:D}),o);break}G?.debug("the vault refused to serve an account; choosing again",{accountId:D})}d.add(D)}if(D===void 0&&!C&&x.length===0&&await $.slotPlaceholderWithoutMain?.())q();if(D===void 0&&C&&Q&&(x.length===0||d.size>0)){let v=d.size>0?"vault-refused":O1(Q);throw G?.warn("vault mode: no vault account can serve; refusing the request",{cause:v}),new a({kind:"no-account",providerID:s,sessionID:Y.sessionID,requestKind:Y.kind,message:R1[v]})}if(D!==void 0&&c)A(Y.sessionID,D),$.onRoute?.(Y.sessionID,D,n);return G?.debug("pool account chosen",{kind:Y.kind,accountId:D,mode:n,...Y.rerouteFrom?{rerouteFrom:Y.rerouteFrom.accountId}:{}}),D},accountHeaders:async(Y)=>{let{accountId:U}=Y,M=()=>new a({kind:"no-account",providerID:s,sessionID:Y.sessionID,requestKind:Y.kind,message:EZ}),C=Q&&await Q.authority()!=="local"?void 0:Z.peek().rows.find((x)=>x.id===U);if(!C&&Q){let x=L(Y),y=K.get(x)??await Q.authorize(U);if(K.delete(x),!y)throw G?.warn("the vault refused to serve an account; refusing the request",{accountId:U}),M();return{headers:{...f2,"session-id":Y.sessionID,authorization:`Bearer ${y.accessToken}`,"chatgpt-account-id":y.accountIdentity??F1(y.accessToken)??null},attempt:{kind:"vault",routeId:U,receipt:y}}}let q=C?Z.usableToken(C):void 0;if(!C||!q)throw G?.warn("pool row holds no usable token; refusing the request",{accountId:U}),M();let T=C.identity??F1(q);return{headers:{...f2,"session-id":Y.sessionID,authorization:`Bearer ${q}`,"chatgpt-account-id":T??null},attempt:{kind:"pool",token:q,credentialEpoch:C.credentialEpoch}}},async rewriteRequest({request:Y,sessionID:U,kind:M}){let C=$.codexEndpoint?v2(Y.url,$.codexEndpoint()):Y.url,q=C===Y.url?Y:new Request(C,Y);return await H1(q,{sessionID:U,kind:M},F,$.responsesLite?.()??!1)??q},rewriteHandshakeURL:({url:Y})=>$.codexEndpoint?v2(Y,$.codexEndpoint()):void 0,rewriteWebSocketFrame:({frame:Y,sessionID:U,kind:M})=>K1(Y,{sessionID:U,kind:M},F),quotaFromHeaders:(Y)=>DZ(Y),async limitFromResponse({status:Y,headers:U,body:M}){if(Y<400)return;let C=m2(await M().catch(()=>"")),q=E2({...Z2(C)?C:{},status:Y});if(!q)return;let T=X(),x=g2(q,T,Y);if(x.retryAfterMs!==void 0)return x;let y=qZ(U);return y===void 0?x:{...x,retryAfterMs:y}},inspectEvent:({data:Y})=>SZ(Y,X()),limitFromError(Y){let U=m2(Y.message),M=E2({...Z2(U)?U:{},...Y.status!==void 0?{status:Y.status}:{}})??(Y.message.includes("usage_limit_reached")?{window:"usage_limit_reached"}:void 0);return M?g2(M,X(),Y.status):void 0},async onAttemptEnd(Y,U){let M=Y.data;if(M?.kind!=="vault"||U.status!==401)return;G?.warn("a vault account answered 401; reporting it to the vault",{accountId:Y.accountId}),await Q?.reportFailure(M.receipt,401)}},k=(Y,U,M)=>{let C=M.data;if(C?.kind==="vault"){Q?.recordSnapshot(Y,U.snapshot,U.complete,C.receipt);return}if(C?.kind!=="pool")return;if(Z.peek().rows.find((T)=>T.id===Y)?.credentialEpoch!==C.credentialEpoch){G?.debug("quota reading dropped: the row holds another credential",{accountId:Y});return}Z.recordSnapshot(Y,U.snapshot,C.token,U.complete)},f=(Y,U,M)=>{let C=X(),q=M.data?.kind==="vault",T=q?Q?.routes().find((b)=>b.id===Y)?.quota:Z.peek().rows.find((b)=>b.id===Y)?.quota,x=_1(N2(T),U.reason,C,LZ,U.retryAfterMs!==void 0?C+U.retryAfterMs:void 0);if(!q){Z.markRateLimited(Y,x);return}let y=N.get(Y);if(y===void 0||y<x)N.set(Y,x)};return{adapter:r,attach(Y){Y.on("quota",(U)=>k(U.accountId,U.quota,U.handle)),Y.on("limit",(U)=>{f(U.accountId,U.limit,U.handle),G?.debug("pool row refused the request",{accountId:U.accountId,via:U.via,reason:U.limit.reason,outputStarted:U.outputStarted})})},forgetSession(Y){z.forget(Y),H.delete(Y),F.forget(Y)}}}import{mkdirSync as bZ}from"node:fs";import{dirname as kZ,join as yZ,resolve as wZ}from"node:path";var IZ="openai-auth-sessions-opencode2.json";function fZ(){return yZ(m1(),IZ)}var hZ="sessions",vZ=1e4,mZ=5000,gZ=25;class p1{path;options;sessions;#$=new Set;#Z=new Set;#J=Promise.resolve();#z=!1;constructor($,Z={}){this.path=$;this.options=Z;this.sessions=l1($,Z.uuid??H2)}get($,Z=H2){let z=this.sessions.get($);if(!z){let X=Z();z={threadID:X,turnID:Z(),windowID:`${X}:0`},this.sessions.set($,z),this.#Z.delete($),this.#$.add($),this.save()}return z}delete($){this.sessions.delete($),this.#$.delete($),this.#Z.add($),this.save()}save(){if(!this.#z)this.#z=!0,this.#J=this.#J.then(()=>{return this.#z=!1,this.#X()});return this.#J}settled(){return this.#J}async#X(){if(this.#$.size===0&&this.#Z.size===0)return;let $=[...this.#$].flatMap((X)=>{let G=this.sessions.get(X);return G?[[X,G]]:[]}),Z=[...this.#Z],z=null;try{if(bZ(kZ(this.path),{recursive:!0}),z=await this.#G(),!z)return;let X;try{X=g1(this.path)}catch{X=new Map}await this.options.afterRead?.();for(let G of Z)X.delete(G);for(let[G,Q]of $)X.set(G,Q.threadID);u1(this.path,X)}catch{return}finally{await z?.release().catch(()=>{})}for(let[X,G]of $)if(this.sessions.get(X)===G)this.#$.delete(X);for(let X of Z)if(!this.sessions.has(X))this.#Z.delete(X)}async#G(){let $=performance.now()+(this.options.lockWaitMs??mZ);for(;;){let Z=await v1({name:hZ,path:this.path,ttlMs:vZ});if(Z||performance.now()>=$)return Z;await new Promise((z)=>setTimeout(z,gZ))}}}var c1=Symbol.for("@cortexkit/openai-auth/opencode2-codex-sessions"),d1=globalThis,l2=d1[c1]??new Map;d1[c1]=l2;function i1($=fZ()){let Z=wZ($),z=l2.get(Z);if(!z)z=new p1(Z),l2.set(Z,z);return z}var n1=Symbol.for("cortexkit.openai-auth.v2.commands");function lZ(){let $=globalThis;return $[n1]??={locations:new Map},$[n1]}async function Z$($,Z){let z=lZ(),X=$.location.directory,G={menu:Z,session:$.session},Q=await s1(X),F=await a1(e1,Q.dir,()=>$$({...Q,drain:r1,apply:(H)=>{let A=z.locations.get(X);if(!A)throw Error("The OpenAI menu location was closed");return A.menu.apply(H)}})),K=z.locations.get(X);z.locations.set(X,G),await K?.registration?.dispose(),z.command??={name:"openai",description:"OpenAI account menu",async execute(H){let A=z.locations.values().next().value?.session;if(!A)return;let P=await A.get({sessionID:H.sessionID}),W=z.locations.get(P.location.directory);if(!W||!t1(H.sessionID))return;let g=await W.menu.open(H.sessionID);o1(g,H.sessionID)}};let L=z.command;try{G.registration=await $.command.transform((H)=>{H.add(L)})}catch(H){if(z.locations.get(X)===G)z.locations.delete(X);throw await F.release(),H}let N=!1;return async()=>{if(N)return;if(N=!0,z.locations.get(X)===G)z.locations.delete(X);await F.release(),await G.registration?.dispose()}}var uZ="openai-auth-pool-browser",pZ="openai-auth-pool-headless",cZ="openai-auth-vault",dZ="Vault login requires this OpenCode host to be enrolled in the Claustrum vault. Connect to the vault or disconnect this host before trying again.";async function F2($){if(await $.authority()!=="local")throw Error("This host is connected to the credential vault or its enrollment is unreadable; the login was not stored. Disconnect this host from the vault to add a local login.")}function j$($){return{method:{id:cZ,type:"oauth",label:"ChatGPT accounts in the vault"},async activate(){if(await J$($.paths,$.name)!=="vault")throw Error(dZ)}}}function Q$($){let Z=(z,X,G)=>({method:{id:z,type:"oauth",label:X},async authorize(){if($.vault)await F2($.vault);let Q=await $.beginLogin({version:$.version,headless:G});return{url:Q.url,instructions:Q.instructions,mode:"auto",callback:Q.completion}}});return[Z(uZ,"ChatGPT (openai-auth pool, browser)",!1),Z(pZ,"ChatGPT (openai-auth pool, headless)",!0)]}function u2($){let Z=(z)=>typeof z==="string"?z:"";return U2({type:"oauth",access:Z($.access),refresh:Z($.refresh)})||$.refresh===G$||z$($)}function iZ($){if($.accountId)return $.accountId;let Z=$.access?R2($.access):void 0;return Z?O2(Z):void 0}async function B$($,Z,z,X={}){if(X.vault)await F2(X.vault);if(u2(z))throw Error("the credential is not a ChatGPT login (a placeholder or a tombstone); it was not stored");let G=X$($,{rowLocks:(W)=>Y$(Z,W)}),Q=await G.read();if(Q.status!=="ready")throw Error(`the account pool cannot be read (${Q.status}); the login was not stored`);let F={type:"oauth",refresh:z.refresh,...z.access!==void 0?{access:z.access}:{},...z.expires!==void 0?{expires:z.expires}:{}},K=iZ(z);if(X.vault)await F2(X.vault);let L=K!==void 0?{identity:K}:{};if(X.origin==="import"){let W=Q.rows.find((g)=>K!==void 0&&g.identity===K||g.credential?.type==="oauth"&&g.credential.refresh===z.refresh);if(W)return{id:W.id,operation:"kept"}}let N=Q.rows.filter((W)=>W.type==="oauth"&&!W.invalid),H=K?N.find((W)=>W.identity===K):void 0,A=Q.rows.find((W)=>W.id===x2);if(H)return{id:(await G.replace(H.id,F,L)).id,operation:"replaced"};if(!A){let W=await G.add({id:x2,credential:F,...L,...z.label!==void 0?{label:z.label}:{}});return{id:W.id,operation:W.outcome==="added-disabled"?"added-disabled":"added"}}if(!A.invalid&&!A.credential)return{id:(await G.replace(x2,F,L)).id,operation:"replaced"};let P=await G.add({id:z.id,credential:F,...L,...z.label!==void 0?{label:z.label}:{}});return{id:P.id,operation:P.outcome==="added-disabled"?"added-disabled":P.outcome==="rotated"?"replaced":"added"}}function nZ($){let Z=$.itemId!==void 0;switch($.sectionId){case"accounts":return Z?["enable","disable","remove","move"].includes($.actionId):$.actionId==="add";case"routing":return!Z&&["order","mode"].includes($.actionId);case"quota":return $.actionId==="check";case"limits":return Z?$.actionId==="floors":$.actionId==="killswitch";case"session":return!Z&&$.actionId==="clear-pin";case"diagnostics":return!Z&&["logging","dump"].includes($.actionId);case"reset":return Z&&["preview","spend","retry"].includes($.actionId);default:return!1}}function U$($){let Z={...$,allowAction:nZ,unavailableSections:["cache"]};return{open:(z)=>V$(Z,z),apply:(z)=>{let X=z!==null&&typeof z==="object"?z:{},G=X.values&&typeof X.values==="object"&&!Array.isArray(X.values)?Object.fromEntries(Object.entries(X.values).filter(([,Q])=>Q===null||["string","number","boolean"].includes(typeof Q))):void 0;return W$(Z,{command:"openai",sectionId:typeof X.sectionId==="string"?X.sectionId:"",actionId:typeof X.actionId==="string"?X.actionId:"",...G?{values:G}:{},...X.confirmed===!0?{confirmed:!0}:{},...typeof X.itemId==="string"?{itemId:X.itemId}:{},...typeof X.sessionId==="string"?{sessionId:X.sessionId}:{}})}}}function aZ($){if(!H$($.modelID??$.id)){$.enabled=!1;return}let Z=K$($.id);if(Z)$.limit={...Z}}function N$($){return $.model.transform((Z)=>{for(let z of Z.list(s))Z.update(s,String(z.id),(X)=>aZ(X))})}class p2{log;pending=new Map;requests=new Map;writing=new Set;constructor($){this.log=$}async safely($){let Z=(async()=>{try{await $()}catch{this.log.warn("request dump failed")}})();this.writing.add(Z);try{await Z}finally{this.writing.delete(Z)}}async captureHttp($,Z){await this.safely(async()=>{if(!P2().dump)return;let z={sessionID:Z.sessionID,accountId:Z.accountId,transport:"http",phase:"http",url:$.url,method:$.method,headers:new Headers($.headers),bodyText:await $.clone().text()};if(this.pending.set($,{attemptId:Z.attemptId,input:z}),this.requests.set(Z.attemptId,$),this.pending.size>512){let X=this.pending.keys().next().value;if(X)this.take(X)}})}take($){let Z=this.pending.get($);if(Z)this.pending.delete($),this.requests.delete(Z.attemptId);return Z?.input}async response($,Z){let z=this.take($);if(z)await this.safely(()=>S2({...z,status:Z}))}async end($,Z){if(Z.status!==void 0||!Z.error)return;let z=this.requests.get($.attemptId),X=z&&this.take(z);if(!X)return;let{reason:G,message:Q}=Z.error,F=Q?`${G}: ${Q}`:G;await this.safely(()=>S2({...X,error:D2(F,z?.headers.get("authorization")?.replace(/^Bearer /,""))}))}async frame($,Z){await this.safely(()=>S2({sessionID:Z.sessionID,accountId:Z.accountId,transport:"websocket",phase:"observed",bodyText:$}))}clear(){this.pending.clear(),this.requests.clear()}async settle(){await Promise.all(this.writing)}}class c2{counts=new Map;record($,Z){let z=Z.resetCreditsApplicable;this.counts.set($.id,{credentialEpoch:$.credentialEpoch,identity:$.identity,applicable:typeof z==="number"&&Number.isFinite(z)?z:void 0})}applicable($){let Z=this.counts.get($.id);if(!Z||Z.credentialEpoch!==$.credentialEpoch||Z.identity!==$.identity)return;return Z.applicable}}function M$($){return async(Z)=>{let z=Z.credential;if(z.type!=="oauth"||!z.access)throw Error("the row holds no access token to poll with");let X=await F$({accessToken:z.access,fetchImpl:$.fetchImpl,now:$.now,...Z.identity?{accountId:Z.identity}:{},accountKey:Z.id,...$.logger?{logger:$.logger}:{}});return $.counts.record(Z,X),P$(X,$.now(),!0)}}function _$($){let{source:Z,counts:z,now:X}=$,G=async(N)=>{let H=await Z.rowAccess(N,await $.storage());if(!H?.row)throw new C$("unknown_account",`${N==="main"?"Main":"Fallback"} account ${N} was not found.`);return T$(N,H)},Q=async(N)=>{if($.authority&&await $.authority()!=="local")return{account:N,ok:!1,error:"local accounts are not polled while this host is connected to the vault"};let[H]=await Z.pollRows(await $.storage(),{ids:[N]});if(!H)return{account:N,ok:!1,error:"targeted quota refresh returned no result"};return{account:H.id,ok:H.ok,...H.error!==void 0?{error:H.error}:{}}},F=(N)=>Z.peek().rows.find((H)=>H.id===N),K=(N)=>{let H=F(N);if(!H)return null;let A=N2(H.quota)??{},P=z.applicable(H),W=Math.max(0,...[A.primary?.checkedAt,A.secondary?.checkedAt].filter((g)=>typeof g==="number"));return{quota:{...A,...P!==void 0?{resetCreditsApplicable:P}:{}},checkedAt:W,refreshAfter:W,...H.identity!==void 0?{accountId:H.identity}:{}}};return{resolveResetTarget:G,refreshResetTargetQuota:Q,quotaManager:{isRateLimited:(N)=>{let H=F(N);if(!H)return!1;let A=Z.rateLimitMarks([H]).get(H.id);return A!==void 0&&A>X()},getMain:()=>K("main"),getFallback:(N)=>K(N)}}}import{resolve as E$}from"node:path";var sZ=1024;class d2{pins=new Map;listeners=new Set;limit;constructor($=sZ){this.limit=Math.max(1,$)}get($){return this.pins.get($)?.accountId}forget($){this.pins.delete($);for(let Z of this.listeners)Z($)}subscribe($){return this.listeners.add($),()=>{this.listeners.delete($)}}snapshot(){return new Map(this.pins)}get size(){return this.pins.size}set($,Z){this.pins.delete($),this.pins.set($,Z);for(let z of this.listeners)z($,Z);while(this.pins.size>this.limit){let z=this.pins.keys().next().value;if(z===void 0)break;this.forget(z)}}place($){return L$(this.pins,$,(Z,z)=>this.set(Z,z))}}var R$=Symbol.for("@cortexkit/openai-auth/opencode2-pins"),O$=globalThis,i2=O$[R$]??new Map;O$[R$]=i2;function A$($){let Z=JSON.stringify([E$($.configPath),E$($.statePath)]),z=i2.get(Z);if(!z)z=new d2,i2.set(Z,z);return z}import{statSync as oZ}from"node:fs";import{resolve as rZ}from"node:path";function I$($){return $.map((Z)=>{try{let z=oZ(Z);return`${z.ino}:${z.size}:${z.mtimeMs}:${z.ctimeMs}`}catch{return"?"}}).join("|")}function n2($){return I$([$.vault.paths.tokenPath,$.vault.paths.statePath])}function x$($){return I$([$.paths.configPath,$.paths.statePath,$.vault.paths.rosterPath])+n2($)}class f${file;observationIntervalMs;producers=new Set;subscriptions=new Map;observations=new Map;chain=Promise.resolve();timer;constructor($,Z){this.file=$;this.observationIntervalMs=Z}add($){this.producers.add($),this.observations.set($,{stamp:x$($),roster:$.vault.snapshot()});let Z=$.source.subscribe(()=>{this.publish($)}),z=this.subscriptions.get($.pins);if(!z){let X=new Set;z={producers:X,stop:$.pins.subscribe((G,Q)=>{let F=X.values().next().value;if(F)this.publish(F,{sessionId:G,pin:Q,accountId:Q?.accountId,route:"sticky-balanced"})})},this.subscriptions.set($.pins,z)}return z.producers.add($),this.timer??=setInterval(()=>{for(let X of this.producers){let G={stamp:x$(X),roster:X.vault.snapshot()},Q=this.observations.get(X);if(G.stamp!==Q?.stamp||G.roster!==Q?.roster)this.observations.set(X,G),this.publish(X)}},this.observationIntervalMs),this.timer.unref?.(),()=>{if(Z(),this.producers.delete($),this.observations.delete($),z.producers.delete($),!z.producers.size)z.stop(),this.subscriptions.delete($.pins);if(!this.producers.size)clearInterval(this.timer),this.timer=void 0}}publish($,Z){return this.chain=this.chain.then(async()=>{if(!this.producers.has($))return;let X=await $.vault.authority()!=="local",G=n2($),Q=()=>this.producers.has($)&&$.vault.enrolled()===X&&n2($)===G,F=await z2($.paths),K=X?y$($.vault.snapshot()?.rows??[],new Set($.vault.routes().map((N)=>N.id)),F,Date.now()):w$((await $.source.sidebarView()).rows,F,Date.now());if(await D$(K,this.file,{canWrite:Q}),!Q()||!Z)return;let L=K.vaultAccounts??K.fallbacks;if(Z.accountId===void 0){await b$(Z.sessionId,L,this.file,{canWrite:Q});return}if(Z.pin){let N=Date.now();await k$({sessionId:Z.sessionId,assignment:{accountId:Z.pin.accountId,wireAccountId:Z.pin.wireIdentity,inputBytes:Z.pin.inputBytes??0,quotaCheckedAt:Z.pin.quotaCheckedAt,assignedAt:N,lastSeenAt:N},validPinnedAccountIds:[...X?[]:["main"],...L.filter((H)=>H.enabled).map((H)=>H.id)]},this.file)}await q$({sessionId:Z.sessionId,activeId:Z.accountId,route:Z.route??K.route,updatedAt:Date.now()},L,this.file,{canWrite:Q})}).catch(()=>{j2("opencode2").warn("sidebar publication failed")}),this.chain}settled(){return this.chain}get empty(){return this.producers.size===0}}var h$=Symbol.for("@cortexkit/openai-auth/opencode2-sidebar-publishers"),v$=globalThis,C2=v$[h$]??new Map;v$[h$]=C2;function m$($,Z=S$(),z=2000){let X=rZ(Z),G=C2.get(X);if(!G)G=new f$(X,z),C2.set(X,G);let Q=G,F=Q.add($),K=!1;for(let[L,N]of $.pins.snapshot())Q.publish($,{sessionId:L,pin:N,accountId:N.accountId,route:"sticky-balanced"});return{publish:()=>Q.publish($),route:(L,N,H)=>{Q.publish($,{sessionId:L,accountId:N,route:H})},async release(){if(K)return;if(K=!0,F(),await Q.settled(),Q.empty&&C2.get(X)===Q)C2.delete(X)}}}var q2="cortexkit-openai-auth",$0=5000;async function g$($,Z,z,X=new K2){let G=new p2(z),Q=new tZ,F=new Map,K=new Map,L=(P)=>{K.delete(P);for(let W of F.keys())if(W.startsWith(`${P}:`))F.delete(W)},H=await I2({session:{hook:(P,W,g)=>$.session.hook(P,async(p)=>{let l=P==="http.request"?p:void 0,m=P==="experimental.ws.handshake"?p:void 0,k=(l?l.request.headers:m?new Headers(m.headers):void 0)?.get("authorization")===`Bearer ${e(Z.providerID)}`,f={};if(m)F.delete(`${m.sessionID}:${m.kind}`);try{await Q.run(f,()=>W(p))}catch(Y){if(k&&!(Y instanceof a))throw i$(Y);throw Y}if(l&&k&&f.attempt){let Y=l.request.headers.get("thread-id");if(Y)l.request.headers.set("session-id",Y)}if(l&&k&&f.attempt)await G.captureHttp(l.request,f.attempt);if(m&&k&&f.attempt)m.headers["session-id"]=X.get(m.sessionID).threadID;if(P==="experimental.ws.send"){let Y=p,U=F.get(`${Y.sessionID}:${Y.kind}`);if(U)await G.frame(Y.frame,U.attempt)}if(l||m){let Y=l??m;if(!Y)return;let M=(l?l.request.headers:new Headers(Y.headers)).get("authorization")?.replace(/^Bearer /,"");if(k&&M)K.set(Y.sessionID,M);else K.delete(Y.sessionID);if(m){let C=`${m.sessionID}:${m.kind}`;if(k&&M&&f.attempt)F.set(C,{bearer:M,attempt:f.attempt});else F.delete(C)}if(K.size>512){let C=K.keys().next().value;if(C)K.delete(C)}if(F.size>512){let C=F.keys().next().value;if(C)F.delete(C)}}else if(P==="experimental.ws.receive"){let Y=p,U=F.get(`${Y.sessionID}:${Y.kind}`);if(U)Y.frame=n$(Y.frame,U.bearer)}else if(P==="retry"){let Y=p,U=K.get(Y.sessionID);if(U)Object.assign(Y.error,{message:D2(Y.error.message,U)})}},g)},event:{subscribe:(P)=>async function*(){for await(let W of $.event.subscribe(P)){if(W.type==="session.deleted")L(W.data.sessionID);yield W}}()}},{...Z,rewriteRequest:async(P)=>{let W=Q.getStore();if(W)W.attempt=P.attempt;return Z.rewriteRequest?.(P)},rewriteHandshakeURL:(P)=>{let W=Q.getStore();if(W)W.attempt=P.attempt;return Z.rewriteHandshakeURL?.(P)},onAttemptEnd:async(P,W)=>{await G.end(P,W),await Z.onAttemptEnd?.(P,W)},rewriteResponse:async(P)=>{await G.response(P.request,P.response.status);let W=await Z.rewriteResponse?.(P)??P.response;return a$(W,P.request.headers.get("authorization")?.replace(/^Bearer /,""),"event-stream")}},{gateOnPlaceholder:{credential:(P)=>{let W=P.get("authorization");return W?.startsWith("Bearer ")?W.slice(7):void 0}},logger:{warn:(P,W)=>z.warn(P,{data:W})}}),A=H.dispose;return{...H,dispose:async()=>{K.clear(),F.clear(),await A(),await G.settle(),G.clear()}}}function r2($={}){return{id:q2,setup:(Z)=>Z0(Z,$)}}async function Z0($,Z={}){let o=[];try{let z=j2("opencode2");let X=j2("quota");let G=Z.paths??(()=>o$(s$()));let Q=await z2(G());let F=Q?.logging?.level;if(F&&typeof F==="string")u$(F);let K=Z.fetch??fetch;let L=Z.now??Date.now;let N=Z.version??ZZ;let H=Z.poolMigration??QZ;if(!H&&!B2(G().configPath)){z.info("openai-auth stands aside on OpenCode 2: this install has not moved into the account pool and the migration is switched off, so OpenCode 2 serves its own ChatGPT login");let E=(X2)=>{throw new a({kind:"no-account",providerID:s,sessionID:X2.sessionID,requestKind:X2.kind,message:A2})},u=await g$($,{providerID:s,chooseAccount:E,accountHeaders:E},z);return()=>u.dispose()}let A=Z.vault?.firstRosterWaitMs??zZ;let P=jZ({host:"opencode",stateDir:Z.vault?.stateDir??d$(G().statePath),reservedRouteIds:()=>k.peek().rows.map((E)=>E.id),...Z.vault?.connectionFile?{connectionFile:Z.vault.connectionFile}:{},...Z.vault?.connectScoped?{connectScoped:Z.vault.connectScoped}:{},...Z.vault?.connectEnrollment?{connectEnrollment:Z.vault.connectEnrollment}:{},...Z.vault?.pollIntervalMs!==void 0?{pollIntervalMs:Z.vault.pollIntervalMs}:{},fetchImpl:()=>K},G());let W=P.vault;let g=!1;let p=!1;const l=a2(o,{[Symbol.dispose](){if(!g)P.release()}},0);await W.authority();let m=P.firstRoster;let r=new c2;let k=new XZ({paths:G,refreshProvider:async(E)=>{let u=await c$({refreshToken:E.refresh,fetchImpl:K,now:L}),X2=p$({id_token:"",access_token:u.access,refresh_token:u.refresh});return{...u,...X2?{identity:X2}:{}}},pullQuota:M$({fetchImpl:K,now:L,counts:r,logger:X}),now:L,vaultIdentities:()=>W.identities(),vaultMode:()=>W.enrolled(),vaultAuthority:()=>W.authority(),vaultFirstRoster:m,vaultFirstRosterBackgroundWaitMs:A,log:j2("pool")});await k.load();let f=Z.heartbeat===!1?void 0:await YZ({version:N,logger:j2("heartbeat")});let Y=Z.fence??(()=>$Z({currentVersion:N}));let U=Z.slot??BZ();let M=async()=>r$(G(),await U.get({path:{id:"openai"}}));let C=!1;let q=H?GZ({paths:G,slot:U,version:N,fence:Y,runDeps:{vaultServes:()=>W.serves()},paused:async()=>await W.authority()!=="local",migrate:async(E)=>{let u=await t$(E);if(C=u.status==="refused",!p)await k.load();return u},adopt:async(E)=>{if(p)return{status:"retry",reason:"unsettled"};if(!await o2(m,A))return{status:"retry",reason:"vault-roster-pending"};if(p)return{status:"retry",reason:"unsettled"};let u=await e$(E);if(!p)await k.load();return u}}):void 0;q?.start();P.start();let T=A$(G());let x=m$({paths:G(),source:k,pins:T,vault:W},Z.sidebarStateFile,Z.sidebarObservationIntervalMs);const y=a2(o,{[Symbol.dispose](){if(!g)x.release()}},0);x.publish();let b=Z.codex??new K2(void 0,void 0,i1());let h=h1({codex:b,onRoute:x.route,source:k,slotPlaceholderWithoutMain:M,storage:()=>z2(G()),pins:T,vault:W,awaitVaultRoster:async()=>{await o2(W.awaitRequestRoster(),JZ)},responsesLite:()=>P2().responsesLite,codexEndpoint:()=>P2().codexApiEndpoint,now:L,log:z});let i=await g$($,h.adapter,z,b);h.attach(i);let n=async(E)=>{if(await F2(W),B2(G().configPath))return;if(await q?.idle(),B2(G().configPath))return;if(C&&!u2(E)&&(await Y()).open){await k.poolStore().initialize();return}throw Error("OpenAI accounts move to the shared account pool once every OpenCode process on this machine runs this version of openai-auth; the login was not stored. Update or close the older processes and sign in again.")};let c=async(E)=>{await n(E);let u=await B$(k.poolStore(),G(),E,{vault:W});if(!B2(G().configPath))await q?.requestAdoption();await k.load(),z.info("ChatGPT login stored in the account pool",u)};let d=await k2($,{integrationID:s,methods:Q$({beginLogin:Z.beginLogin??s2,version:N,vault:W}),onLogin:(E)=>c(E),label:"ChatGPT (openai-auth account pool)",vault:j$(W)});let D=await N$($);if(Z.controlPlane&&(!$.command||!$.location))throw Error("OpenCode 2 control plane requires command and location APIs");let v=$.command&&$.location?await Z$({session:$.session,command:$.command,location:$.location},Z.controlPlane??U$({..._$({source:k,storage:()=>z2(G()),counts:r,now:L,authority:()=>W.authority()}),fetchImpl:K,now:L,randomUUID:eZ,accountStoragePath:G().configPath,accountStatePath:G().statePath,packageVersion:N,loadAccounts:z2,store:()=>k.poolStore(),migration:async()=>{if(B2(G().configPath))return{migrated:!0};let E=await Y();return{migrated:!1,blockers:E.open?[]:E.blockers}},beginAccountLogin:Z.beginLogin??s2,refreshAllQuota:async()=>(await k.pollRows(await z2(G()))).map((E)=>({...E,account:E.id})),getStickyRouting:async(E)=>T.get(E),afterWrite:()=>k.load(),refreshSidebar:()=>x.publish(),clearStickyRouting:async(E)=>{let u=T.get(E)!==void 0;return T.forget(E),u},vault:W})):void 0;let I=new AbortController;(async()=>{try{for await(let E of $.event.subscribe({signal:I.signal}))if(E.type==="session.deleted")h.forgetSession(E.data.sessionID)}catch(E){if(!I.signal.aborted)z.warn("stopped listening for session deletion",{error:E instanceof Error?E.message:String(E)})}})();g=!0;return async()=>{p=!0,I.abort(),await v?.(),q?.dispose(),k.dispose(),await x.release(),await Promise.allSettled([i.dispose(),d.dispose(),D.dispose()]);let E;try{await Promise.race([Promise.all([q?.idle(),k.settled(),b.store?.settled()]),new Promise((u)=>{E=setTimeout(u,$0),E.unref?.()})])}finally{clearTimeout(E),P.release(),await f?.release()}}}catch(T2){var V2=T2,M2=1}finally{l$(o,V2,M2)}}var J0=r2(),z5={id:q2,setup:J0.setup,server:VZ.server};export{z5 as default,r2 as createOpenAIAuthPlugin,q2 as OPENAI_AUTH_PLUGIN_ID};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/opencode-openai-auth",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@ai-sdk/openai": "3.0.88",
|
|
69
|
-
"@cortexkit/common-auth": "^0.
|
|
69
|
+
"@cortexkit/common-auth": "^0.18.0",
|
|
70
70
|
"@cortexkit/openai-auth-core": "workspace:*",
|
|
71
71
|
"@opencode/plugin": "2.0.27"
|
|
72
72
|
},
|
|
@@ -22,18 +22,23 @@ export const NO_QUOTA_READING = 'no quota reading yet';
|
|
|
22
22
|
*/
|
|
23
23
|
export const NO_LIMITS_REPORTED = 'no limits reported';
|
|
24
24
|
/**
|
|
25
|
-
* A
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* A time span in at most its two largest units: `45m`, `2h29m`, `5h`, `3d23h`,
|
|
26
|
+
* `7d`. Every unit is rounded down, so a reset is never shown later than it is;
|
|
27
|
+
* the one exception is a span under a minute, which reads `1m` rather than
|
|
28
|
+
* zero. A zero second unit is left out.
|
|
28
29
|
*/
|
|
29
30
|
function shortSpan(ms) {
|
|
30
|
-
const minutes = Math.max(1, Math.
|
|
31
|
+
const minutes = Math.max(1, Math.floor(ms / 60_000));
|
|
31
32
|
if (minutes < 60)
|
|
32
33
|
return `${minutes}m`;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
if (minutes < 1440) {
|
|
35
|
+
const hours = Math.floor(minutes / 60);
|
|
36
|
+
const rest = minutes % 60;
|
|
37
|
+
return rest === 0 ? `${hours}h` : `${hours}h${rest}m`;
|
|
38
|
+
}
|
|
39
|
+
const days = Math.floor(minutes / 1440);
|
|
40
|
+
const hours = Math.floor((minutes % 1440) / 60);
|
|
41
|
+
return hours === 0 ? `${days}d` : `${days}d${hours}h`;
|
|
37
42
|
}
|
|
38
43
|
/** A stored window length in minutes as its exact name: `5h`, `7d`, `90m`. */
|
|
39
44
|
function lengthName(minutes) {
|