@cortexkit/opencode-openai-auth 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/dist/cli.js +1 -1
- package/dist/codex-http.d.ts +1 -1
- package/dist/commands.d.ts +6 -0
- package/dist/core/accounts.d.ts +6 -1
- package/dist/core/background-quota-refresh.d.ts +46 -0
- package/dist/core/cachekeep.d.ts +4 -0
- package/dist/core/oauth.d.ts +1 -1
- package/dist/core/quota-manager.d.ts +18 -15
- package/dist/core/refresh-all-quota.d.ts +12 -1
- package/dist/core/sticky-routing.d.ts +43 -0
- package/dist/dump.d.ts +1 -0
- package/dist/{index-x1c39tzz.js → index-6rnw2cgs.js} +1 -1
- package/dist/index-89mh4ahn.js +89 -0
- package/dist/index-rfgyxxxq.js +1 -0
- package/dist/index-s5fbqqwx.js +3 -0
- package/dist/index-vrdc90yd.js +6 -0
- package/dist/index-wnxfzjfr.js +2 -0
- package/dist/{index-jpx7h5gc.js → index-wpd7mg3p.js} +1 -1
- package/dist/index-zkzb0twr.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +101 -83
- package/dist/{quota-normalize-02mn21p4.js → quota-normalize-n02dfdx0.js} +1 -1
- package/dist/raw-ws-bun.d.ts +2 -0
- package/dist/raw-ws-node.d.ts +2 -0
- package/dist/raw-ws-upgrade.d.ts +2 -0
- package/dist/rpc/port-file.d.ts +4 -0
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/protocol.d.ts +1 -0
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.d.ts +6 -0
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/rpc/rpc-server.d.ts +2 -0
- package/dist/sidebar-state.d.ts +46 -5
- package/dist/sidebar-state.js +1 -1
- package/dist/{token-dab1ama0.js → token-5hdnazxp.js} +1 -1
- package/dist/token-util-3d2nj45d.js +1 -0
- package/dist/tui-preferences.js +1 -1
- package/dist/tui.d.ts +9 -0
- package/dist/version.d.ts +1 -1
- package/dist/ws-pool.d.ts +2 -11
- package/dist/ws.d.ts +7 -2
- package/package.json +2 -2
- package/src/rpc/port-file.ts +115 -8
- package/src/rpc/protocol.ts +1 -0
- package/src/rpc/rpc-dir.ts +31 -7
- package/src/rpc/rpc-server.ts +18 -2
- package/src/sidebar-state.ts +771 -23
- package/src/tui/command-dialogs.tsx +25 -3
- package/src/tui-compiled/rpc/port-file.ts +115 -8
- package/src/tui-compiled/rpc/protocol.ts +1 -0
- package/src/tui-compiled/rpc/rpc-dir.ts +31 -7
- package/src/tui-compiled/sidebar-state.ts +771 -23
- package/src/tui-compiled/tui/command-dialogs.tsx +17 -4
- package/src/tui-compiled/tui.tsx +50 -15
- package/src/tui.tsx +57 -19
- package/dist/index-72cas5ht.js +0 -7
- package/dist/index-dc7za61x.js +0 -89
- package/dist/index-hjgzqz1c.js +0 -1
- package/dist/index-qnd9x5jh.js +0 -2
- package/dist/index-wpk440dz.js +0 -2
- package/dist/token-util-41n40m0y.js +0 -1
|
@@ -12,6 +12,7 @@ import { openUrl } from "../util/open-url";
|
|
|
12
12
|
export function buildCachekeepDialogOptions(payload) {
|
|
13
13
|
const enabled = payload.knobs.enabled === true;
|
|
14
14
|
const subagents = payload.knobs.subagents === true;
|
|
15
|
+
const sustain = payload.knobs.sustain === true;
|
|
15
16
|
const running = payload.knobs.running === true;
|
|
16
17
|
const tracked = Number(payload.knobs.tracked ?? 0);
|
|
17
18
|
const generatedAt = Number(payload.knobs.generatedAt ?? Date.now());
|
|
@@ -19,11 +20,11 @@ export function buildCachekeepDialogOptions(payload) {
|
|
|
19
20
|
const maxIdleWarmMs = Number(payload.knobs.maxIdleWarmMs ?? 60 * 60 * 1000);
|
|
20
21
|
const maxSubagentIdleMs = Number(payload.knobs.maxSubagentIdleMs ?? 30 * 60 * 1000);
|
|
21
22
|
const windowKnob = payload.knobs.window;
|
|
22
|
-
const windowLabel = windowKnob ? `${String(windowKnob.startHour).padStart(2, '0')}-${String(windowKnob.endHour).padStart(2, '0')}` : 'always';
|
|
23
|
+
const windowLabel = windowKnob ? `${String(windowKnob.startHour).padStart(2, '0')}-${String(windowKnob.endHour).padStart(2, '0')}` : 'always (no window)';
|
|
23
24
|
const lastWarm = lastWarmAt ? `${Math.ceil((generatedAt - lastWarmAt) / 1000)}s ago` : 'none yet';
|
|
24
25
|
const idleWindow = Math.round(maxIdleWarmMs / 60_000);
|
|
25
26
|
const subIdleWindow = Math.round(maxSubagentIdleMs / 60_000);
|
|
26
|
-
const statusParts = [enabled ? '● Enabled' : '○ Disabled', `timer ${running ? 'armed' : 'idle'}`, `${tracked} tracked`, `last warm ${lastWarm}`, `window ${windowLabel}`, `${idleWindow}m idle cap`, `subagent idle ${subIdleWindow}m`].filter(part => part.length > 0);
|
|
27
|
+
const statusParts = [enabled ? '● Enabled' : '○ Disabled', `timer ${running ? 'armed' : 'idle'}`, `${tracked} tracked`, `last warm ${lastWarm}`, `window ${windowLabel}`, `${idleWindow}m idle cap`, `sustain ${sustain ? 'on' : 'off'}`, `subagent idle ${subIdleWindow}m`].filter(part => part.length > 0);
|
|
27
28
|
return [{
|
|
28
29
|
title: statusParts.join(' | '),
|
|
29
30
|
value: 'status',
|
|
@@ -36,6 +37,10 @@ export function buildCachekeepDialogOptions(payload) {
|
|
|
36
37
|
title: subagents ? 'Subagent warming: on' : 'Subagent warming: off',
|
|
37
38
|
value: subagents ? 'subagents off' : 'subagents on',
|
|
38
39
|
description: subagents ? `Warm subagent sessions (${subIdleWindow}m idle cap). Disable to skip subagents.` : `Skip subagent sessions. Enable to warm them too (${subIdleWindow}m idle cap).`
|
|
40
|
+
}, {
|
|
41
|
+
title: sustain ? 'Sustain main sessions: on' : 'Sustain main sessions: off',
|
|
42
|
+
value: sustain ? 'sustain off' : 'sustain on',
|
|
43
|
+
description: 'main-only, idle-cap only; the configured clock window still applies.'
|
|
39
44
|
}, {
|
|
40
45
|
title: windowKnob ? `Warm window: ${windowLabel}` : 'Set warm window…',
|
|
41
46
|
value: 'set_window',
|
|
@@ -117,6 +122,14 @@ export function openCommandDialog(api, payload, apply, sessionId) {
|
|
|
117
122
|
title: 'Fallback first',
|
|
118
123
|
value: 'fallback-first',
|
|
119
124
|
description: 'Prefer fallback accounts, preserve main'
|
|
125
|
+
}, {
|
|
126
|
+
title: 'Sticky balanced',
|
|
127
|
+
value: 'sticky-balanced',
|
|
128
|
+
description: 'Keep each session on one account while balancing new sessions'
|
|
129
|
+
}, {
|
|
130
|
+
title: "Reset this session's pin",
|
|
131
|
+
value: 'reset',
|
|
132
|
+
description: 'Unpin this session; the next request may still choose the same account'
|
|
120
133
|
}],
|
|
121
134
|
onSelect: option => {
|
|
122
135
|
void apply('openai-routing', String(option.value)).then(r => {
|
|
@@ -354,8 +367,8 @@ function openAccountDialog(api, apply, sessionId) {
|
|
|
354
367
|
showAddFlow();
|
|
355
368
|
return;
|
|
356
369
|
}
|
|
357
|
-
// Main has no per-account actions
|
|
358
|
-
//
|
|
370
|
+
// Main has no per-account actions: it is not removable or reorderable,
|
|
371
|
+
// regardless of whether the active session uses mode or sticky routing.
|
|
359
372
|
if (option.value === 'main') return;
|
|
360
373
|
showL2Fallback(option.value);
|
|
361
374
|
}
|
package/src/tui-compiled/tui.tsx
CHANGED
|
@@ -14,14 +14,21 @@ import { fileURLToPath } from "node:url";
|
|
|
14
14
|
import { createEffect, createSignal, For, onCleanup, Show } from "opentui:runtime-module:solid-js";
|
|
15
15
|
import { createLogger } from "./logger.js";
|
|
16
16
|
import { createRpcClient } from "./rpc/rpc-client.js";
|
|
17
|
-
import {
|
|
18
|
-
import { computeQuotaPacing, DEFAULT_SIDEBAR_STATE, getCollapsedQuotaSummary, getPresentQuotaWindows, getSidebarState, resolveActiveAccount, resolveSessionSidebarRouting } from "./sidebar-state.js";
|
|
17
|
+
import { resolveRpcDir } from "./rpc/rpc-dir.js";
|
|
18
|
+
import { computeQuotaPacing, DEFAULT_SIDEBAR_STATE, getCollapsedQuotaSummary, getPresentQuotaWindows, getSidebarState, resolveActiveAccount, resolveSessionSidebarRouting, resolveSessionStickyAccount } from "./sidebar-state.js";
|
|
19
19
|
import { openCommandDialog } from "./tui/command-dialogs.js";
|
|
20
20
|
import { computeEffectiveOrder, DEFAULT_SLOT_ORDER, PLUGIN_KEY, queueTuiPreferenceUpdate, readTuiPreferencesFile, resolveOpenaiAuthPrefs, watchTuiPreferences } from "./tui-preferences.js";
|
|
21
21
|
const RPC_POLL_MS = 500;
|
|
22
22
|
let rpcPollStarted = false;
|
|
23
23
|
const log = createLogger('rpc-tui');
|
|
24
24
|
const ID = 'cortexkit.openai-auth';
|
|
25
|
+
export function buildApplyRequest(command, arguments_, sessionId) {
|
|
26
|
+
return {
|
|
27
|
+
command,
|
|
28
|
+
arguments: arguments_,
|
|
29
|
+
sessionId
|
|
30
|
+
};
|
|
31
|
+
}
|
|
25
32
|
|
|
26
33
|
// Read package metadata from either the raw src/ entry or its generated
|
|
27
34
|
// src/tui-compiled/ counterpart. Avoid a JSON import because package.json sits
|
|
@@ -586,6 +593,27 @@ export async function readStateFromFile() {
|
|
|
586
593
|
export function resolveQuotaDialogActiveId(state, sessionId, now = Date.now()) {
|
|
587
594
|
return sessionId ? resolveSessionSidebarRouting(state, sessionId, now).activeId : state.activeId;
|
|
588
595
|
}
|
|
596
|
+
export function buildRoutingRowsForDisplay(state, sessionId, now = Date.now()) {
|
|
597
|
+
const routing = resolveSessionSidebarRouting(state, sessionId, now);
|
|
598
|
+
const rows = [{
|
|
599
|
+
label: 'Route',
|
|
600
|
+
value: routing.route,
|
|
601
|
+
tone: 'accent'
|
|
602
|
+
}];
|
|
603
|
+
const pinnedAccountId = resolveSessionStickyAccount(state, sessionId, now);
|
|
604
|
+
if (pinnedAccountId) {
|
|
605
|
+
const pinnedAccount = resolveActiveAccount({
|
|
606
|
+
...state,
|
|
607
|
+
activeId: pinnedAccountId
|
|
608
|
+
});
|
|
609
|
+
rows.push({
|
|
610
|
+
label: 'Pin',
|
|
611
|
+
value: pinnedAccount.name,
|
|
612
|
+
tone: 'accent'
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
return rows;
|
|
616
|
+
}
|
|
589
617
|
// The TUI may unmount and remount sidebar_content when the user switches
|
|
590
618
|
// views (e.g. main -> subagent -> main). A remount re-runs the component
|
|
591
619
|
// body, so any signal created inside the component would reset to its
|
|
@@ -927,15 +955,24 @@ function QuotaSidebar(props) {
|
|
|
927
955
|
return theme();
|
|
928
956
|
},
|
|
929
957
|
title: "Routing"
|
|
930
|
-
}), _$createComponent(
|
|
931
|
-
get
|
|
932
|
-
return
|
|
933
|
-
},
|
|
934
|
-
label: "Route",
|
|
935
|
-
get value() {
|
|
936
|
-
return sessionRouting().route;
|
|
958
|
+
}), _$createComponent(For, {
|
|
959
|
+
get each() {
|
|
960
|
+
return buildRoutingRowsForDisplay(state(), props.sessionId);
|
|
937
961
|
},
|
|
938
|
-
|
|
962
|
+
children: row => _$createComponent(StatRow, {
|
|
963
|
+
get theme() {
|
|
964
|
+
return theme();
|
|
965
|
+
},
|
|
966
|
+
get label() {
|
|
967
|
+
return row.label;
|
|
968
|
+
},
|
|
969
|
+
get value() {
|
|
970
|
+
return row.value;
|
|
971
|
+
},
|
|
972
|
+
get tone() {
|
|
973
|
+
return row.tone;
|
|
974
|
+
}
|
|
975
|
+
})
|
|
939
976
|
})];
|
|
940
977
|
}
|
|
941
978
|
}), _$createComponent(For, {
|
|
@@ -1053,7 +1090,8 @@ const tui = async api => {
|
|
|
1053
1090
|
if (!rpcPollStarted) {
|
|
1054
1091
|
rpcPollStarted = true;
|
|
1055
1092
|
const myPid = process.pid;
|
|
1056
|
-
const
|
|
1093
|
+
const rpcDir = await resolveRpcDir(api.state.path.directory ?? '');
|
|
1094
|
+
const rpcClient = createRpcClient(rpcDir.dir, myPid, entry => {
|
|
1057
1095
|
log.debug('rpc tui pid', {
|
|
1058
1096
|
myPid,
|
|
1059
1097
|
matchedPortFilePid: entry?.pid ?? null,
|
|
@@ -1080,10 +1118,7 @@ const tui = async api => {
|
|
|
1080
1118
|
}));
|
|
1081
1119
|
continue;
|
|
1082
1120
|
}
|
|
1083
|
-
openCommandDialog(api, message.payload, (command, args) => rpcClient.apply(
|
|
1084
|
-
command,
|
|
1085
|
-
arguments: args
|
|
1086
|
-
}), sessionId);
|
|
1121
|
+
openCommandDialog(api, message.payload, (command, args) => rpcClient.apply(buildApplyRequest(command, args, sessionId)), sessionId);
|
|
1087
1122
|
}
|
|
1088
1123
|
}).catch(() => {}).finally(() => {
|
|
1089
1124
|
rpcInFlight = false;
|
package/src/tui.tsx
CHANGED
|
@@ -17,8 +17,9 @@ import {
|
|
|
17
17
|
Show,
|
|
18
18
|
} from 'solid-js'
|
|
19
19
|
import { createLogger } from './logger.js'
|
|
20
|
+
import type { ApplyRequest, CommandModalName } from './rpc/protocol.js'
|
|
20
21
|
import { createRpcClient } from './rpc/rpc-client.js'
|
|
21
|
-
import {
|
|
22
|
+
import { resolveRpcDir } from './rpc/rpc-dir.js'
|
|
22
23
|
import {
|
|
23
24
|
type AccountQuota,
|
|
24
25
|
computeQuotaPacing,
|
|
@@ -30,6 +31,7 @@ import {
|
|
|
30
31
|
type QuotaWindow,
|
|
31
32
|
resolveActiveAccount,
|
|
32
33
|
resolveSessionSidebarRouting,
|
|
34
|
+
resolveSessionStickyAccount,
|
|
33
35
|
type SidebarState,
|
|
34
36
|
} from './sidebar-state.js'
|
|
35
37
|
import { openCommandDialog } from './tui/command-dialogs.js'
|
|
@@ -51,6 +53,14 @@ const log = createLogger('rpc-tui')
|
|
|
51
53
|
|
|
52
54
|
const ID = 'cortexkit.openai-auth'
|
|
53
55
|
|
|
56
|
+
export function buildApplyRequest(
|
|
57
|
+
command: CommandModalName,
|
|
58
|
+
arguments_: string,
|
|
59
|
+
sessionId?: string,
|
|
60
|
+
): ApplyRequest {
|
|
61
|
+
return { command, arguments: arguments_, sessionId }
|
|
62
|
+
}
|
|
63
|
+
|
|
54
64
|
// Read package metadata from either the raw src/ entry or its generated
|
|
55
65
|
// src/tui-compiled/ counterpart. Avoid a JSON import because package.json sits
|
|
56
66
|
// outside the declaration build's rootDir.
|
|
@@ -498,6 +508,32 @@ export function resolveQuotaDialogActiveId(
|
|
|
498
508
|
: state.activeId
|
|
499
509
|
}
|
|
500
510
|
|
|
511
|
+
export interface RoutingDisplayRow {
|
|
512
|
+
label: string
|
|
513
|
+
value: string
|
|
514
|
+
tone: Tone
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
export function buildRoutingRowsForDisplay(
|
|
518
|
+
state: SidebarState,
|
|
519
|
+
sessionId: string | undefined,
|
|
520
|
+
now = Date.now(),
|
|
521
|
+
): RoutingDisplayRow[] {
|
|
522
|
+
const routing = resolveSessionSidebarRouting(state, sessionId, now)
|
|
523
|
+
const rows: RoutingDisplayRow[] = [
|
|
524
|
+
{ label: 'Route', value: routing.route, tone: 'accent' },
|
|
525
|
+
]
|
|
526
|
+
const pinnedAccountId = resolveSessionStickyAccount(state, sessionId, now)
|
|
527
|
+
if (pinnedAccountId) {
|
|
528
|
+
const pinnedAccount = resolveActiveAccount({
|
|
529
|
+
...state,
|
|
530
|
+
activeId: pinnedAccountId,
|
|
531
|
+
})
|
|
532
|
+
rows.push({ label: 'Pin', value: pinnedAccount.name, tone: 'accent' })
|
|
533
|
+
}
|
|
534
|
+
return rows
|
|
535
|
+
}
|
|
536
|
+
|
|
501
537
|
interface SidebarController {
|
|
502
538
|
prefs: () => OpenaiAuthTuiPrefs
|
|
503
539
|
collapsed: () => boolean
|
|
@@ -782,12 +818,16 @@ function QuotaSidebar(props: {
|
|
|
782
818
|
{/* Routing */}
|
|
783
819
|
<Show when={prefs().sections.routing}>
|
|
784
820
|
<SectionHeader theme={theme()} title='Routing' />
|
|
785
|
-
<
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
821
|
+
<For each={buildRoutingRowsForDisplay(state(), props.sessionId)}>
|
|
822
|
+
{(row) => (
|
|
823
|
+
<StatRow
|
|
824
|
+
theme={theme()}
|
|
825
|
+
label={row.label}
|
|
826
|
+
value={row.value}
|
|
827
|
+
tone={row.tone}
|
|
828
|
+
/>
|
|
829
|
+
)}
|
|
830
|
+
</For>
|
|
791
831
|
</Show>
|
|
792
832
|
|
|
793
833
|
{/* Plan and credits — whichever are present */}
|
|
@@ -856,17 +896,14 @@ const tui: TuiPlugin = async (api) => {
|
|
|
856
896
|
if (!rpcPollStarted) {
|
|
857
897
|
rpcPollStarted = true
|
|
858
898
|
const myPid = process.pid
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
})
|
|
868
|
-
},
|
|
869
|
-
)
|
|
899
|
+
const rpcDir = await resolveRpcDir(api.state.path.directory ?? '')
|
|
900
|
+
const rpcClient = createRpcClient(rpcDir.dir, myPid, (entry) => {
|
|
901
|
+
log.debug('rpc tui pid', {
|
|
902
|
+
myPid,
|
|
903
|
+
matchedPortFilePid: entry?.pid ?? null,
|
|
904
|
+
rpcPort: entry?.port ?? null,
|
|
905
|
+
})
|
|
906
|
+
})
|
|
870
907
|
let lastNotificationId = 0
|
|
871
908
|
let rpcInFlight = false
|
|
872
909
|
setInterval(() => {
|
|
@@ -897,7 +934,8 @@ const tui: TuiPlugin = async (api) => {
|
|
|
897
934
|
openCommandDialog(
|
|
898
935
|
api,
|
|
899
936
|
message.payload,
|
|
900
|
-
(command, args) =>
|
|
937
|
+
(command, args) =>
|
|
938
|
+
rpcClient.apply(buildApplyRequest(command, args, sessionId)),
|
|
901
939
|
sessionId,
|
|
902
940
|
)
|
|
903
941
|
}
|
package/dist/index-72cas5ht.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{appendFileSync as c,chmodSync as l,existsSync as R,renameSync as m,statSync as i}from"node:fs";import{tmpdir as a}from"node:os";import{join as n}from"node:path";var q={error:0,warn:1,info:2,debug:3,trace:4},t=!1,o=5242880;function h(){return process.env.OPENCODE_OPENAI_AUTH_LOG_FILE??n(a(),"opencode-openai-auth.log")}var S;function _H(H){if(H===void 0||H in q)S=H}function r(){if(S)return S;let H=process.env.OPENCODE_OPENAI_AUTH_LOG_LEVEL;if(H&&H in q)return H;return"info"}var e=/^(authorization|x-api-key|cookie|set-cookie|refresh|access|token)$/i;function HH(H){if(e.test(H))return!0;let J=H.toLowerCase().replace(/[-_]/g,"");if(J==="chatgptaccountid")return!0;if(J.includes("apikey"))return!0;if(J.endsWith("secret")||J.endsWith("password"))return!0;if(J.endsWith("token")&&!J.endsWith("tokens"))return!0;return!1}var JH=/\b(Bearer\s+[\w.-]+|sk-[\w-]+|eyJ[\w.-]+)\b/g;function QH(H){return g(H,new WeakSet)}function g(H,J){if(typeof H==="string")return H.replace(JH,"***REDACTED***");if(Array.isArray(H)){if(J.has(H))return"[Circular]";J.add(H);let Q=H.map((Z)=>g(Z,J));return J.delete(H),Q}if(H&&typeof H==="object"){if(J.has(H))return"[Circular]";J.add(H);let Q={};for(let[Z,B]of Object.entries(H))Q[Z]=HH(Z)?"***REDACTED***":g(B,J);return J.delete(H),Q}return H}var D=[],A,WH=3;function I(H){try{l(H,384)}catch{}}function ZH(){try{let H=h();if(!(R(H)&&i(H).size>o))return;for(let Q=WH-1;Q>=1;Q--)if(R(`${H}.${Q}`)){let Z=`${H}.${Q+1}`;m(`${H}.${Q}`,Z),I(Z)}let J=`${H}.1`;m(H,J),I(J)}catch{}}function O(){if(!D.length)return;let H=D.join("");D=[];try{ZH();let J=h();if(R(J))I(J);c(J,H,{encoding:"utf8",mode:384})}catch{}}function $H(){if(!A)A=setTimeout(()=>{A=void 0,O()},500)}if(!t)process.on("exit",O);function zH(H){try{return` ${JSON.stringify(QH(H))}`}catch{return" [unserializable]"}}function j(H,J,Q,Z){if(q[J]>q[r()])return;let B=`[${new Date().toISOString()}] ${J.toUpperCase()} [${H}] ${Q}`+(Z===void 0?"":zH(Z))+`
|
|
2
|
-
`;if(D.push(B),D.length>=50)O();else $H()}function FH(H){return{error:(J,Q)=>j(H,"error",J,Q),warn:(J,Q)=>j(H,"warn",J,Q),info:(J,Q)=>j(H,"info",J,Q),debug:(J,Q)=>j(H,"debug",J,Q),trace:(J,Q)=>j(H,"trace",J,Q)}}import{randomUUID as T}from"node:crypto";import{mkdir as u,readFile as y,rename as BH,rm as b,stat as v,writeFile as C}from"node:fs/promises";import{homedir as GH}from"node:os";import{dirname as VH,join as N}from"node:path";var XH=globalThis.setTimeout.bind(globalThis),YH=globalThis.clearTimeout.bind(globalThis),KH="openai-auth.json";function xH(){if(process.env.OPENCODE_CONFIG_DIR?.trim())return process.env.OPENCODE_CONFIG_DIR.trim();return N(process.env.XDG_CONFIG_HOME||N(GH(),".config"),"opencode")}function jH(H){let J=H?.code;return J==="ENOENT"||J==="EINVAL"||J==="ENOTDIR"}function DH(){return process.env.OPENCODE_OPENAI_AUTH_FILE?.trim()||N(xH(),KH)}async function gH(H){let Q=`${H.path??DH()}.${H.name}.lock`,Z=N(Q,"owner.json"),B=T(),G=H.now??Date.now,Y=null,_=!1;async function F(){try{return JSON.parse(await y(Q,"utf8"))}catch(W){if(W.code!=="EISDIR")throw W;return JSON.parse(await y(Z,"utf8"))}}async function d(){await C(Q,`${JSON.stringify({ownerId:B,expiresAt:G()+H.ttlMs})}
|
|
3
|
-
`,{encoding:"utf8",mode:384})}async function L(){try{return await C(Q,`${JSON.stringify({ownerId:B,expiresAt:G()+H.ttlMs})}
|
|
4
|
-
`,{encoding:"utf8",mode:384,flag:"wx"}),!0}catch(W){let z=W.code;if(z==="EEXIST"||z==="EISDIR")return!1;if(z==="ENOENT"){await u(VH(Q),{recursive:!0});try{return await C(Q,`${JSON.stringify({ownerId:B,expiresAt:G()+H.ttlMs})}
|
|
5
|
-
`,{encoding:"utf8",mode:384,flag:"wx"}),!0}catch(X){let M=X.code;if(M==="EEXIST"||M==="EISDIR")return!1;throw X}}throw W}}function P(){if(!H.renew||_)return;let W=H.renewIntervalMs??Math.max(1000,Math.floor(H.ttlMs/3));if(Y=XH(()=>{(async()=>{try{let z=await F(),X=G();if(_||z?.ownerId!==B||Number(z?.expiresAt)<=X)return;await d(),P()}catch{}})()},W),"unref"in Y)Y.unref()}let V=await L();if(!V){let W=`${Q}.evicting`,z=N(W,"owner.json"),X=T(),M=5000,bH=8;async function U(){await new Promise(($)=>setTimeout($,Math.floor(Math.random()*4)))}async function E(){try{let $=await F();return Number($?.expiresAt)>G()}catch{try{return(await v(Q)).mtimeMs+H.ttlMs>G()}catch{return!1}}}async function K(){try{return JSON.parse(await y(z,"utf8"))?.ownerId===X}catch{return!1}}async function s(){await u(W);try{await C(z,`${JSON.stringify({ownerId:X,createdAt:G()})}
|
|
6
|
-
`,{encoding:"utf8",mode:384,flag:"wx"})}catch($){if(jH($))return!1;throw await p(),$}return await H.onStep?.("eviction-marker-acquired"),!0}async function p(){if(await K())await b(W,{recursive:!0,force:!0}).catch(()=>{})}for(let $=0;$<8;$++){if(V=await L(),V)break;if(await E())return null;try{if(!await s()){await U();continue}}catch(k){if(k.code!=="EEXIST")throw k;let f;try{f=await v(W)}catch(x){if(x.code==="ENOENT"){await U();continue}throw x}if(f.mtimeMs+5000>G())return null;await H.onStep?.("stale-marker-stat");let w=`${W}.${T()}`;try{await BH(W,w)}catch(x){if(x.code==="ENOENT"){await U();continue}throw x}await H.onStep?.("stale-marker-claimed"),await b(w,{recursive:!0,force:!0}).catch(()=>{}),await U();continue}try{if(await E())return null;if(!await K())return null;if(await H.onStep?.("stale-lock-confirmed"),!await K())return null;if(await b(Q,{recursive:!0,force:!0}).catch(()=>{}),!await K())return null;if(V=await L(),!V)return null;if(!await K())return await b(Q,{recursive:!0,force:!0}).catch(()=>{}),V=!1,null;break}finally{await p()}}}if(!V)return null;return P(),{release:async()=>{if(_=!0,Y)YH(Y),Y=null;try{if((await F())?.ownerId!==B)return}catch{return}await b(Q,{recursive:!0,force:!0}).catch(()=>{})}}}
|
|
7
|
-
export{_H as ja,QH as ka,FH as la,gH as ma};
|
package/dist/index-dc7za61x.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import{la as s,ma as I}from"./index-72cas5ht.js";import{ua as Y2}from"./index-jpx7h5gc.js";import{createHash as p0}from"node:crypto";var l0=86400000,d0=300000,g0=3600000,i0=60000,u0=900000,s0=300000;function t(B){return B instanceof Error?B.message:String(B)}function r0(B){let Z=B?.status;if(typeof Z==="number")return Z===429||Z>=500;if(!(B instanceof Error))return!1;return B.name==="AbortError"||B.name==="TimeoutError"||B.message.includes("fetch failed")||"code"in B&&(B.code==="ECONNRESET"||B.code==="ECONNREFUSED"||B.code==="ETIMEDOUT"||B.code==="UND_ERR_CONNECT_TIMEOUT")}function e(B){let Z=t(B),$=B?.status;if(typeof $==="number")return $===429||$>=500;if(!(B instanceof Error))return!1;let W=B.code;return B.name==="AbortError"||B.name==="TimeoutError"||Z.includes("fetch failed")||W==="ECONNRESET"||W==="ECONNREFUSED"||W==="ETIMEDOUT"||W==="UND_ERR_CONNECT_TIMEOUT"}function Q0(B){return p0("sha256").update(B).digest("hex")}function N0(B){let Z=Q0(B.refreshToken),W=(B.previous?.tokenHash===Z?B.previous.retryCount??0:0)+1,z,X=B.error?.retryAfter;if(typeof X==="number"&&X>0)z=X*1000;else if(r0(B.error))z=Math.min(g0,d0*2**Math.min(W-1,6));else z=l0;return{message:t(B.error),checkedAt:B.now,nextRetryAt:B.now+z,retryCount:W,tokenHash:Z}}function U(B,Z,$){if(!B?.nextRetryAt||B.nextRetryAt<=$)return!1;if(!Z)return!0;return B.tokenHash===Q0(Z)}function d(B,Z){return`Codex OAuth refresh is backed off for ${Math.max(1,Math.ceil(((B.nextRetryAt??Z)-Z)/1000))}s after: ${B.message}`}function f(B){let $=(B.previous?.retryCount??0)+1,W,z=B.error?.retryAfter;if(typeof z==="number"&&z>0)W=z*1000;else if(e(B.error))W=Math.min(u0,i0*2**Math.min($-1,6));else W=s0;return{message:t(B.error),checkedAt:B.now,nextRetryAt:B.now+W,retryCount:$}}function x(B,Z){if(!B?.nextRetryAt||B.nextRetryAt<=Z)return!1;return!0}function B0(B){if(!B)return;let Z=Number(B);if(Number.isFinite(Z)&&Z>0)return Math.ceil(Z);let $=Date.parse(B);if(Number.isFinite($)){let W=Math.ceil(($-Date.now())/1000);return W>0?W:void 0}return}import{createServer as n0}from"node:http";import{setTimeout as c0}from"node:timers/promises";var P0="0.4.2";var u="app_EMoamEEZ73f0CkXaXp7hrann",q="https://auth.openai.com",m=1455,a0=3000,F0=`cortexkit-opencode-openai-auth/${P0}`,O0="main",o0=`"${O0}" is a reserved account id; choose a different label.`;function b0(B){let Z=new Uint8Array(B),$=String.fromCharCode(...Z);return btoa($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function t0(){let Z=Array.from(crypto.getRandomValues(new Uint8Array(43))).map((W)=>"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"[W%66]).join(""),$=b0(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(Z)));return{verifier:Z,challenge:$}}function V0(B){if(B.length>16384)return;let Z=B.split(".");if(Z.length!==3)return;let $=Z[1];if(!$||$.length>8192)return;try{return JSON.parse(Buffer.from($,"base64url").toString())}catch{return}}function L0(B){let Z=B.chatgpt_account_id;if(typeof Z==="string"&&Z.length>0)return Z;let $=B["https://api.openai.com/auth"];if($&&typeof $==="object"&&!Array.isArray($)&&typeof $.chatgpt_account_id==="string"&&$.chatgpt_account_id.length>0)return $.chatgpt_account_id;let W=B.organizations;if(Array.isArray(W)){let z=W[0];if(z&&typeof z==="object"&&!Array.isArray(z)&&typeof z.id==="string"&&z.id.length>0)return z.id}return}function i(B){if(B.id_token){let Z=V0(B.id_token),$=Z&&L0(Z);if($)return $}if(B.access_token){let Z=V0(B.access_token);return Z?L0(Z):void 0}return}function e0(B){return typeof B==="string"&&B.toLowerCase()===O0}function Z0(B){if(e0(B))throw Error(o0);return B}function B2(B,Z,$){let W=new URLSearchParams({response_type:"code",client_id:u,redirect_uri:B,scope:"openid profile email offline_access",code_challenge:Z.challenge,code_challenge_method:"S256",id_token_add_organizations:"true",codex_cli_simplified_flow:"true",state:$,originator:"opencode"});return`${q}/oauth/authorize?${W.toString()}`}async function Z2(B,Z,$){let W=await fetch(`${q}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",code:B,redirect_uri:Z,client_id:u,code_verifier:$.verifier}).toString()});if(!W.ok)throw Error(`Token exchange failed: ${W.status}`);return await W.json()}function $2(B){return B.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}var W2=`<!doctype html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>CortexKit OpenAI Auth - Authorization Successful</title>
|
|
5
|
-
<style>
|
|
6
|
-
body {
|
|
7
|
-
font-family:
|
|
8
|
-
system-ui,
|
|
9
|
-
-apple-system,
|
|
10
|
-
sans-serif;
|
|
11
|
-
display: flex;
|
|
12
|
-
justify-content: center;
|
|
13
|
-
align-items: center;
|
|
14
|
-
height: 100vh;
|
|
15
|
-
margin: 0;
|
|
16
|
-
background: #131010;
|
|
17
|
-
color: #f1ecec;
|
|
18
|
-
}
|
|
19
|
-
.container {
|
|
20
|
-
text-align: center;
|
|
21
|
-
padding: 2rem;
|
|
22
|
-
}
|
|
23
|
-
h1 {
|
|
24
|
-
color: #f1ecec;
|
|
25
|
-
margin-bottom: 1rem;
|
|
26
|
-
}
|
|
27
|
-
p {
|
|
28
|
-
color: #b7b1b1;
|
|
29
|
-
}
|
|
30
|
-
</style>
|
|
31
|
-
</head>
|
|
32
|
-
<body>
|
|
33
|
-
<div class="container">
|
|
34
|
-
<h1>Authorization Successful</h1>
|
|
35
|
-
<p>You can close this window and return to OpenCode.</p>
|
|
36
|
-
</div>
|
|
37
|
-
<script>
|
|
38
|
-
setTimeout(() => window.close(), 2000)
|
|
39
|
-
</script>
|
|
40
|
-
</body>
|
|
41
|
-
</html>`,g=(B)=>`<!doctype html>
|
|
42
|
-
<html>
|
|
43
|
-
<head>
|
|
44
|
-
<title>CortexKit OpenAI Auth - Authorization Failed</title>
|
|
45
|
-
<style>
|
|
46
|
-
body {
|
|
47
|
-
font-family:
|
|
48
|
-
system-ui,
|
|
49
|
-
-apple-system,
|
|
50
|
-
sans-serif;
|
|
51
|
-
display: flex;
|
|
52
|
-
justify-content: center;
|
|
53
|
-
align-items: center;
|
|
54
|
-
height: 100vh;
|
|
55
|
-
margin: 0;
|
|
56
|
-
background: #131010;
|
|
57
|
-
color: #f1ecec;
|
|
58
|
-
}
|
|
59
|
-
.container {
|
|
60
|
-
text-align: center;
|
|
61
|
-
padding: 2rem;
|
|
62
|
-
}
|
|
63
|
-
h1 {
|
|
64
|
-
color: #fc533a;
|
|
65
|
-
margin-bottom: 1rem;
|
|
66
|
-
}
|
|
67
|
-
p {
|
|
68
|
-
color: #b7b1b1;
|
|
69
|
-
}
|
|
70
|
-
.error {
|
|
71
|
-
color: #ff917b;
|
|
72
|
-
font-family: monospace;
|
|
73
|
-
margin-top: 1rem;
|
|
74
|
-
padding: 1rem;
|
|
75
|
-
background: #3c140d;
|
|
76
|
-
border-radius: 0.5rem;
|
|
77
|
-
}
|
|
78
|
-
</style>
|
|
79
|
-
</head>
|
|
80
|
-
<body>
|
|
81
|
-
<div class="container">
|
|
82
|
-
<h1>Authorization Failed</h1>
|
|
83
|
-
<p>An error occurred during authorization.</p>
|
|
84
|
-
<div class="error">${$2(B)}</div>
|
|
85
|
-
</div>
|
|
86
|
-
</body>
|
|
87
|
-
</html>`,k,w,L=new Map;function M(){return L.size}function C(B){if(L.delete(B),M()===0)_()}async function z2(){let B=`http://localhost:${m}/auth/callback`;if(k)return{port:m,redirectUri:B};if(w)return w;w=(async()=>{let Z=n0(($,W)=>{let z=new URL($.url||"/",`http://127.0.0.1:${m}`);if(z.pathname==="/auth/callback"){let X=z.searchParams.get("code"),G=z.searchParams.get("state"),K=z.searchParams.get("error"),Y=z.searchParams.get("error_description");if(K){let j=Y||K;if(G){let Q=L.get(G);if(Q)Q.reject(Error(j)),C(G);else if(M()===0)_()}else if(M()===0)_();W.writeHead(200,{"Content-Type":"text/html"}),W.end(g(j));return}if(!G){if(M()===0)_();W.writeHead(400,{"Content-Type":"text/html"}),W.end(g("Missing state parameter"));return}if(!X){if(M()===0)_();W.writeHead(400,{"Content-Type":"text/html"}),W.end(g("Missing authorization code"));return}let J=L.get(G);if(!J){if(M()===0)_();W.writeHead(400,{"Content-Type":"text/html"}),W.end(g("Unknown state — authorization may have expired"));return}C(G),Z2(X,B,J.pkce).then((j)=>J.resolve(j)).catch((j)=>J.reject(j)),W.writeHead(200,{"Content-Type":"text/html"}),W.end(W2);return}if(z.pathname==="/cancel"){let X=z.searchParams.get("state"),G=X?[X]:[...L.keys()];W.writeHead(200),W.end("Login cancelled");for(let K of G){let Y=L.get(K);if(!Y)continue;Y.reject(Error("Login cancelled")),C(K)}if(M()===0)_();return}W.writeHead(404),W.end("Not found")});return await new Promise(($,W)=>{Z.once("error",W),Z.listen(m,"127.0.0.1",()=>{Z.off("error",W),$()})}),k=Z,{port:m,redirectUri:B}})();try{return await w}finally{w=void 0}}function _(){if(k){let B=k;k=void 0,B.close(()=>{}),B.closeIdleConnections?.(),setTimeout(()=>{B.closeAllConnections?.()},25).unref?.()}}function X2(B,Z,$=300000,W){return new Promise((z,X)=>{if(W?.aborted){C(Z),X(Error("Login cancelled"));return}let G=setTimeout(()=>{if(L.get(Z))C(Z),X(Error("OAuth callback timeout — authorization took too long"))},$),K=()=>{if(clearTimeout(G),L.get(Z))C(Z),X(Error("Login cancelled"))};if(W)W.addEventListener("abort",K);L.set(Z,{pkce:B,state:Z,resolve:(Y)=>{if(clearTimeout(G),W)W.removeEventListener("abort",K);z(Y)},reject:(Y)=>{if(clearTimeout(G),W)W.removeEventListener("abort",K);X(Y)}})})}async function G2(){let B=await fetch(`${q}/api/accounts/deviceauth/usercode`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":F0},body:JSON.stringify({client_id:u})});if(!B.ok)throw Error("Failed to initiate device authorization");let Z=await B.json();return{deviceData:Z,url:`${q}/codex/device`,instructions:`Enter code: ${Z.user_code}`}}async function K2(B,Z){let $=Math.max(parseInt(B.interval,10)||5,1)*1000,W=typeof B.expires_in==="number"?B.expires_in:parseInt(B.expires_in||"",10),z=!Number.isNaN(W)&&W>0?W*1000:900000,X=Date.now();while(!0){if(Z?.aborted)throw Error("Device authorization cancelled");if(Date.now()-X>z)throw Error("Device authorization expired");let G=await fetch(`${q}/api/accounts/deviceauth/token`,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":F0},body:JSON.stringify({device_auth_id:B.device_auth_id,user_code:B.user_code})});if(G.ok){let J=await G.json(),j=await fetch(`${q}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",code:J.authorization_code,redirect_uri:`${q}/deviceauth/callback`,client_id:u,code_verifier:J.code_verifier}).toString()});if(!j.ok)throw Error(`Token exchange failed: ${j.status}`);return await j.json()}if(G.status!==403&&G.status!==404)throw Error(`Device authorization failed: ${G.status}`);let K=z-(Date.now()-X);if(K<=0)throw Error("Device authorization expired");let Y=Math.min($+a0,K);try{await c0(Y,void 0,{signal:Z})}catch(J){if(J instanceof Error&&J.name==="AbortError")throw Error("Device authorization cancelled");throw J}}}function q4(B,Z){let $=-1;if(Z.accountId)$=B.findIndex((W)=>W.accountId&&W.accountId===Z.accountId);if($<0)$=B.findIndex((W)=>W.id===Z.id);if($<0&&Z.label&&!Z.accountId)$=B.findIndex((W)=>W.label===Z.label);if($>=0)return B[$]={...B[$],...Z,addedAt:B[$]?.addedAt??Z.addedAt},$;return B.push(Z),B.length-1}async function C4(B={}){let{label:Z,headless:$=!1,signal:W}=B;if(Z0(Z),$){let{deviceData:J,url:j,instructions:Q}=await G2(),y=(async()=>{let V=await K2(J,W),F=Date.now(),H0=i(V);return{id:Z0(Z||H0||crypto.randomUUID()),label:Z||void 0,type:"oauth",access:V.access_token,refresh:V.refresh_token,expires:F+(V.expires_in??3600)*1000,enabled:!0,addedAt:F,lastUsed:F,lastRefreshedAt:F,accountId:H0}})();return{url:j,instructions:Q,completion:y}}let{redirectUri:z}=await z2(),X=await t0(),G=b0(crypto.getRandomValues(new Uint8Array(32)).buffer),K=B2(z,X,G),Y=(async()=>{try{if(W?.aborted)throw Error("Login cancelled");let J=await X2(X,G,void 0,W),j=Date.now(),Q=i(J);return{id:Z0(Z||Q||crypto.randomUUID()),label:Z||void 0,type:"oauth",access:J.access_token,refresh:J.refresh_token,expires:j+(J.expires_in??3600)*1000,enabled:!0,addedAt:j,lastUsed:j,lastRefreshedAt:j,accountId:Q}}finally{C(G)}})();return{url:K,instructions:"Complete authorization in your browser. This window will close automatically.",completion:Y}}function D0(B){if(B instanceof Error)return B.message;if(typeof B==="string")return B;try{return JSON.stringify(B)}catch{return String(B)}}var J2=s("quota"),$0="primary",W0="secondary",j2="app_EMoamEEZ73f0CkXaXp7hrann",H2="https://auth.openai.com";async function I4(B){let Z=await B.fetchImpl(`${H2}/oauth/token`,{method:"POST",signal:AbortSignal.timeout(15000),headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:B.refreshToken,client_id:j2}).toString()});if(!Z.ok){let W=B0(Z.headers.get("retry-after"));throw Object.assign(Error(`Token refresh failed: ${Z.status}`),{status:Z.status,retryAfter:W,isRefreshError:!0})}let $=await Z.json();if(!$||typeof $.access_token!=="string"||!$.access_token||typeof $.refresh_token!=="string"||!$.refresh_token||typeof $.expires_in!=="number")throw Object.assign(Error("Token refresh failed: malformed response"),{status:Z.status,isRefreshError:!0});return{access:$.access_token,refresh:$.refresh_token,expires:B.now()+$.expires_in*1000,expiresIn:$.expires_in}}var Q2="https://chatgpt.com/backend-api/wham/usage";async function A4(B){let Z=B.logger??J2,$=B.accountKey??"unknown",W=Date.now();Z.debug("wham usage fetch started",{pid:process.pid,accountId:$});try{let z=await B.fetchImpl(Q2,{signal:AbortSignal.timeout(15000),headers:{authorization:`Bearer ${B.accessToken}`,"chatgpt-account-id":B.accountId??"","oai-client-platform":"web","oai-client-version":"0","x-openai-target-path":"/backend-api/wham/usage"}});if(!z.ok){let K=B0(z.headers.get("retry-after"));throw Object.assign(Error(`wham usage check failed: ${z.status}`),{status:z.status,retryAfter:K})}let{normalizeWham:X}=await import("./quota-normalize-02mn21p4.js"),G=X(await z.json());return Z.debug("wham usage fetch succeeded",{pid:process.pid,accountId:$,status:z.status,elapsedMs:Date.now()-W}),G}catch(z){throw Z.warn("wham usage fetch failed",{pid:process.pid,accountId:$,status:typeof z?.status==="number"?z.status:"error",elapsedMs:Date.now()-W,error:D0(z)}),z}}import{createHash as N2}from"node:crypto";var P2=globalThis.setTimeout,V2=5;function h(B){let Z=B?.quota?.checkIntervalMinutes??V2;return Math.max(1,Z)*60000}function L2(B){return B?.quota?.enabled!==!1}function r(B,Z){if(!B?.resetsAt)return!1;let $=Date.parse(B.resetsAt);return Number.isFinite($)&&$<=Z}function h4(B,Z,$,W){let z=Z===$0?B?.primary:Z===W0?B?.secondary:void 0,X=z?.resetsAt?Date.parse(z.resetsAt):NaN;if(Number.isFinite(X)&&X>$)return X;return $+W}function F2(B){let Z=B?.quota?.minimumRemaining||{};return{primary:Z.primary??Z["5h"]??15,secondary:Z.secondary??Z["1w"]??10}}function U0(B,Z,$){if(!L2(Z))return $+h(Z);let W=F2(Z),z=[];for(let X of["primary","secondary"]){let G=B?.[X];if(!G)continue;if(G.remainingPercent>=W[X])continue;let K=G.resetsAt?Date.parse(G.resetsAt):Number.NaN;if(!Number.isFinite(K)||K<=$)return $+h(Z);z.push(K)}if(!z.length)return $+h(Z);return Math.min(...z)+60000}function O2(B){if(!B?.quota?.mainQuota||!B.quota.mainQuotaCheckedAt)return null;return{quota:B.quota.mainQuota,checkedAt:B.quota.mainQuotaCheckedAt,tokenFingerprint:B.quota.mainQuotaToken}}function b2(B){let Z=B?.quota?.refreshEveryNRequests;return typeof Z==="number"&&Number.isFinite(Z)&&Z>0?Math.floor(Z):0}function P(B){return N2("sha256").update(B).digest("hex").slice(0,16)}class O{main=null;mainTokenFp=null;mainQuotaAccountId=null;fallbacks=new Map;fallbackTokenFps=new Map;inflightMain=null;inflightMainFp=null;inflightFallbacks=new Map;mainLastApiError=void 0;fallbackApiErrors=new Map;fallbackErrorTokenFps=new Map;rateLimitedUntilMap=new Map;apiGate=Promise.resolve();lastApiCallAt=0;storage;fetchImpl;now;fetchQuotaFn;onMainQuotaFetched;onApiError;constructor(B){this.storage=B.storage,this.fetchImpl=B.fetchImpl??fetch,this.now=B.now??Date.now,this.fetchQuotaFn=B.fetchQuotaFn,this.onMainQuotaFetched=B.onMainQuotaFetched,this.onApiError=B.onApiError,this.seedMainFromStorage(B.storage),this.seedMainBackoffFromStorage(B.storage)}getMain(B){if(B&&this.main&&this.mainTokenFp&&this.mainTokenFp!==P(B))this.main=null,this.mainTokenFp=null;return this.main}getFallback(B,Z){let $=this.fallbacks.get(B)??null;if(!Z||!$)return $;if(this.fallbackTokenFps.get(B)!==P(Z))return this.fallbacks.delete(B),this.fallbackTokenFps.delete(B),null;return $}getAllFallbacks(){return this.fallbacks}setMain(B,Z,$,W=!1){if(!W&&!M0(Z.quota))return;if(this.mainTokenFp=P(B),$&&this.mainQuotaAccountId&&this.mainQuotaAccountId!==$)this.clearRateLimited("main");if($)this.mainQuotaAccountId=$;if(this.main=Z,z0(Z.quota))this.clearRateLimited("main")}peekMainForPolicy(B){if(B&&this.mainQuotaAccountId&&this.mainQuotaAccountId!==B)return null;return this.main}peekFallbackForPolicy(B){return this.fallbacks.get(B)??null}setFallback(B,Z,$,W=!1){if(!W&&!M0(Z.quota))return;if(this.fallbacks.set(B,Z),$)this.fallbackTokenFps.set(B,P($));else this.fallbackTokenFps.delete(B);if(z0(Z.quota))this.clearRateLimited(B)}markRateLimited(B,Z){let $=this.rateLimitedUntilMap.get(B);if($!==void 0&&$>Z)return;this.rateLimitedUntilMap.set(B,Z)}isRateLimited(B){let Z=this.rateLimitedUntilMap.get(B);return Z!==void 0&&this.now()<Z}rateLimitedUntil(B){return this.rateLimitedUntilMap.get(B)}clearRateLimited(B){this.rateLimitedUntilMap.delete(B)}async refreshMain(B){let Z=P(B);if(this.mainTokenFp&&this.mainTokenFp!==Z)this.main=null,this.mainTokenFp=null;if(this.inflightMain&&this.inflightMainFp===Z)return this.inflightMain;if(this.isBackedOff()){if(this.main)return this.main.quota;throw Error("Quota API rate-limited — try again later")}return this.inflightMainFp=Z,this.inflightMain=this._fetchMain(B),this.inflightMain}async refreshFallback(B,Z){let $=O.fallbackInflightKey(B,Z),W=this.inflightFallbacks.get($);if(W)return W;if(this.isFallbackBackedOff(B,Z)){let X=this.getFallback(B,Z);if(X)return X.quota;throw Error("Quota API rate-limited — try again later")}let z=this._fetchFallback(B,Z);return this.inflightFallbacks.set($,z),z}async refreshAllFallbacks(B){let Z=this.now();for(let $ of B){if($.enabled===!1)continue;if(!$.access)continue;let W=this.getFallback($.id,$.access);if(W&&Z<W.refreshAfter)continue;try{await this.refreshFallback($.id,$.access)}catch{}}}refreshMainInBackground(B){let Z=P(B);if(this.inflightMain&&this.inflightMainFp===Z)return;if(this.isBackedOff())return;this.refreshMain(B).catch(()=>{})}isMainStale(){if(!this.main)return!0;return this.now()>=this.main.refreshAfter}isFallbackStale(B,Z){let $=this.getFallback(B,Z);if(!$)return!0;return this.now()>=$.refreshAfter}shouldRefreshOnRequestCount(B){let Z=b2(this.storage);if(Z<=0)return!1;return B>0&&B%Z===0}needsRefresh(B){return this.isMainStale()||this.shouldRefreshOnRequestCount(B)}updateStorage(B){this.storage=B,this.seedMainFromStorage(B),this.seedMainBackoffFromStorage(B)}seedMainFromStorage(B,Z){let $=O2(B);if(!$)return;let W=Z?P(Z):null;if(W&&$.tokenFingerprint&&$.tokenFingerprint!==W)return;let z={quota:$.quota,refreshAfter:U0($.quota,B,$.checkedAt),checkedAt:$.checkedAt};if(this.main&&this.main.checkedAt>=z.checkedAt&&(!W||!this.mainTokenFp||this.mainTokenFp===W))return;if(this.main=z,this.mainTokenFp=$.tokenFingerprint??null,B?.mainAccountId){if(this.mainQuotaAccountId&&this.mainQuotaAccountId!==B.mainAccountId)this.clearRateLimited("main");this.mainQuotaAccountId=B.mainAccountId}}seedMainBackoffFromStorage(B){let Z=B?.quota?.mainLastQuotaApiError;this.mainLastApiError=Z&&x(Z,this.now())?Z:void 0}seedFallbacksFromAccounts(B){let Z=h(this.storage);for(let $ of B){if($.enabled===!1)continue;if(!$.quota)continue;let W=Math.max($.quota.primary?.checkedAt??0,$.quota.secondary?.checkedAt??0);if(W<=0)continue;let z=this.getFallback($.id,$.access);if(z&&z.checkedAt>=W)continue;this.setFallback($.id,{quota:$.quota,refreshAfter:W+Z,checkedAt:W},$.access)}}isBackedOff(){return x(this.mainLastApiError,this.now())}isFallbackBackedOff(B,Z){if(Z){if(this.fallbackErrorTokenFps.get(B)!==P(Z))return!1}return x(this.fallbackApiErrors.get(B),this.now())}getLastApiError(){return this.mainLastApiError}static API_CALL_GAP_MS=1000;static fallbackInflightKey(B,Z){return JSON.stringify([B,P(Z)])}static quotaLockName(B){return`opencode-fallback-quota-refresh-${B.replace(/[^a-zA-Z0-9._-]+/g,"-")||"account"}`}_enqueueApiFetch(B){let Z=async()=>{let W=this.now()-this.lastApiCallAt;if(W<O.API_CALL_GAP_MS)await new Promise((z)=>{let X=P2(z,O.API_CALL_GAP_MS-W);if(typeof X==="object"&&"unref"in X)X.unref()});return this.lastApiCallAt=this.now(),B()},$=this.apiGate.then(Z,Z);return this.apiGate=$.catch(()=>{}),$}async _fetchMain(B){let Z=P(B);return this._enqueueApiFetch(async()=>{try{if(this.isBackedOff()){if(this.main)return this.main.quota;throw Error("Quota API rate-limited — try again later")}let $=await I({name:"opencode-main-quota-refresh",ttlMs:30000});if(!$){let W=this.main;if(W&&this.now()<W.refreshAfter)return W.quota;throw Error("Quota refresh is already in progress")}try{let W=this.now(),z=await this._fetchQuota(B),X=this.now();if(this.mainTokenFp=P(B),this.main={quota:z,refreshAfter:U0(z,this.storage,X),checkedAt:X},z0(z))this.clearRateLimited("main");return this.mainLastApiError=void 0,this.onMainQuotaFetched?.(z,X,this.mainTokenFp,W),z}catch(W){throw this._handleMainFetchError(W),W}finally{await $.release()}}finally{if(this.inflightMainFp===Z)this.inflightMain=null,this.inflightMainFp=null}})}async _fetchFallback(B,Z){return this._enqueueApiFetch(async()=>{try{if(this.isFallbackBackedOff(B,Z)){let W=this.getFallback(B,Z);if(W)return W.quota;throw Error("Quota API rate-limited — try again later")}let $=await I({name:O.quotaLockName(B),ttlMs:30000});if(!$){let W=this.getFallback(B,Z);if(W&&this.now()<W.refreshAfter)return W.quota;throw Error("Quota refresh is already in progress")}try{let W=await this._fetchQuota(Z),z=this.now();return this.setFallback(B,{quota:W,refreshAfter:z+h(this.storage),checkedAt:z},Z,!0),this.fallbackApiErrors.delete(B),this.fallbackErrorTokenFps.delete(B),W}finally{await $.release()}}catch($){throw this._handleFallbackFetchError(B,Z,$),$}finally{this.inflightFallbacks.delete(O.fallbackInflightKey(B,Z))}})}async _fetchQuota(B){if(!this.fetchQuotaFn)throw Error("Quota fetch not available — no fetchQuotaFn injected (push-only mode)");return this.fetchQuotaFn({accessToken:B,fetchImpl:this.fetchImpl,now:this.now})}static isAuthError(B){return B?.status===401}_handleMainFetchError(B){if(O.isAuthError(B))return;this.mainLastApiError=f({error:B,now:this.now(),previous:this.mainLastApiError}),this.onApiError?.(this.mainLastApiError)}_handleFallbackFetchError(B,Z,$){if(O.isAuthError($))return;let W=P(Z),z=this.fallbackErrorTokenFps.get(B)===W?this.fallbackApiErrors.get(B):void 0;this.fallbackApiErrors.set(B,f({error:$,now:this.now(),previous:z})),this.fallbackErrorTokenFps.set(B,W)}}function M0(B){return Boolean(B.primary||B.secondary)}function z0(B){let{primary:Z,secondary:$}=B;if(!Z&&!$)return!1;if(Z&&Z.usedPercent>=100)return!1;if($&&$.usedPercent>=100)return!1;return!0}import{createHash as E2,randomUUID as S2}from"node:crypto";import{homedir as R2}from"node:os";import{dirname as y2,join as n}from"node:path";import{setTimeout as x2}from"node:timers/promises";import{randomUUID as D2}from"node:crypto";import{mkdir as U2,rename as M2,rm as _2,writeFile as q2}from"node:fs/promises";import{dirname as C2}from"node:path";async function A(B,Z){await U2(C2(B),{recursive:!0});let $=`${B}.${D2()}.tmp`;await q2($,`${JSON.stringify(Z,null,2)}
|
|
88
|
-
`,{encoding:"utf8",mode:384});try{await M2($,B)}catch(W){throw await _2($,{force:!0}).catch(()=>{}),W}}import{readFile as l2}from"node:fs/promises";var E=s("refresh"),_0=1e4,I2=50,x0="openai-auth.json",A2="openai-auth-state.json";function T2(){if(process.env.OPENCODE_CONFIG_DIR?.trim())return process.env.OPENCODE_CONFIG_DIR.trim();return n(process.env.XDG_CONFIG_HOME||n(R2(),".config"),"opencode")}function T(){return process.env.OPENCODE_OPENAI_AUTH_FILE?.trim()||n(T2(),x0)}function o(B=T()){let Z=process.env.OPENCODE_OPENAI_AUTH_STATE_FILE?.trim();if(Z)return Z;return f2(B)}function f2(B){return B.endsWith(x0)?n(y2(B),A2):`${B}.state.json`}function b(B){return B.type==="oauth"}function m2(B){let Z=B?.trim();if(!Z)return!1;try{let $=new URL(Z);return($.protocol==="http:"||$.protocol==="https:")&&!$.username&&!$.password}catch{return!1}}function ZB(B){return B.costZeroing?.enabled!==!1}class c extends Error{code="ACCOUNT_REMOVED_DURING_REFRESH";constructor(B){super(`Fallback account ${B} was removed before refresh`);this.name="AccountRemovedDuringRefreshError"}}var w2=[401,403,429],q0={primary:0,secondary:0},k2=!1,K0={primary:5,secondary:10};function H(B){return B!=null&&typeof B==="object"&&!Array.isArray(B)}function h2(B){return B instanceof c||H(B)&&B.name==="AccountRemovedDuringRefreshError"&&B.code==="ACCOUNT_REMOVED_DURING_REFRESH"}function C0(B){return{id:typeof B.id==="string"&&B.id.trim()?B.id.trim():S2(),label:typeof B.label==="string"?B.label:void 0,enabled:typeof B.enabled==="boolean"?B.enabled:void 0,addedAt:typeof B.addedAt==="number"?B.addedAt:void 0,lastUsed:typeof B.lastUsed==="number"?B.lastUsed:void 0,accountId:typeof B.accountId==="string"?B.accountId:void 0}}function E0(B){if(!H(B))return;if(typeof B.message!=="string")return;let Z=Number(B.checkedAt);if(!Number.isFinite(Z))return;let $=Number(B.nextRetryAt),W=Number(B.retryCount);return{message:B.message,checkedAt:Z,nextRetryAt:Number.isFinite($)?$:void 0,retryCount:Number.isFinite(W)?W:void 0,tokenHash:typeof B.tokenHash==="string"?B.tokenHash:void 0}}function v2(B){if(!H(B))return;let Z={};for(let W of["primary","secondary"]){let z=B[W];if(!H(z))continue;let X=Number(z.usedPercent),G=Number(z.remainingPercent),K=Number(z.checkedAt);if(!Number.isFinite(X)||!Number.isFinite(G)||!Number.isFinite(K))continue;let Y=typeof z.windowMinutes==="number"?z.windowMinutes:Number.NaN;Z[W]={usedPercent:X,remainingPercent:G,checkedAt:K,resetsAt:typeof z.resetsAt==="string"?z.resetsAt:void 0,...Number.isFinite(Y)&&Y>0?{windowMinutes:Y}:{}}}let $=typeof B.resetCreditsAvailable==="number"?B.resetCreditsAvailable:Number.NaN;if(Number.isFinite($)&&$>=0)Z.resetCreditsAvailable=$;return Object.keys(Z).length?Z:void 0}function p2(B){if(!H(B))return null;if(B.type==="api"){let Z=typeof B.baseURL==="string"?B.baseURL.trim():"",$=typeof B.apiKey==="string"?B.apiKey.trim():"";if(!m2(Z))return null;let W=B.authHeader==="x-api-key"?"x-api-key":"authorization-bearer";return{...C0(B),type:"api",apiKey:$||void 0,baseURL:Z,authHeader:W}}if(B.type!=="oauth")return null;if(typeof B.refresh!=="string"||!B.refresh.trim())return null;return{...C0(B),type:"oauth",access:typeof B.access==="string"?B.access:void 0,refresh:B.refresh,expires:typeof B.expires==="number"?B.expires:void 0,lastRefreshedAt:typeof B.lastRefreshedAt==="number"?B.lastRefreshedAt:void 0,lastRefreshError:E0(B.lastRefreshError),lastQuotaRefreshError:E0(B.lastQuotaRefreshError),quota:v2(B.quota)}}function I0(B){if(!H(B)||!Array.isArray(B.accounts))return null;return{version:1,main:{type:"opencode",provider:"openai"},routing:H(B.routing)?B.routing:void 0,fallbackOn:Array.isArray(B.fallbackOn)?B.fallbackOn.filter((Z)=>Number.isInteger(Z)):void 0,refresh:H(B.refresh)?B.refresh:void 0,quota:H(B.quota)?B.quota:void 0,dump:H(B.dump)?B.dump:void 0,costZeroing:H(B.costZeroing)?B.costZeroing:void 0,killswitch:H(B.killswitch)?B.killswitch:void 0,logging:H(B.logging)?B.logging:void 0,cachekeep:H(B.cachekeep)?B.cachekeep:void 0,mainAccountId:typeof B.mainAccountId==="string"?B.mainAccountId:void 0,accounts:B.accounts.map(p2).filter((Z)=>Z!=null)}}async function R(B){try{return{exists:!0,value:JSON.parse(await l2(B,"utf8"))}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,value:null};throw Z}}function D(B){return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0))}async function d2(B){let Z;try{Z=(await R(B)).value}catch{return null}if(!H(Z)||!Array.isArray(Z.accounts))return null;let $=new Set;for(let W of Z.accounts)if(H(W)&&typeof W.id==="string")$.add(W.id);return $}function A0(B,Z){if(!H(B))return B;let $=H(Z)?Z:{},W=H($.main)?$.main:void 0,z=H($.accounts)?$.accounts:{},X=H(B.quota)?B.quota:{},G=H(B.refresh)?B.refresh:{},K=W??X,Y=W??G,j=Array.isArray(B.accounts)?B.accounts.map((Q)=>{if(!H(Q))return Q;let y=typeof Q.id==="string"&&H(z[Q.id])?z[Q.id]:{};return{...Q,...y}}):void 0;return T0({...B,refresh:D({...G,mainLastRefreshError:Y.lastRefreshError,mainRefreshLeaseId:Y.refreshLeaseId,mainRefreshLeaseUntil:Y.refreshLeaseUntil,mainRefreshLeaseTokenHash:Y.refreshLeaseTokenHash}),quota:D({...X,mainQuota:K.quota,mainQuotaCheckedAt:K.quotaCheckedAt,mainQuotaToken:K.quotaToken,mainLastQuotaApiError:K.lastQuotaApiError}),accounts:j})}async function g2(B=T()){let Z=await R(B);if(!Z.exists)return null;let $=await R(o(B));return I0(A0(Z.value,$.value))}function T0(B){return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0))}function i2(B){return D({id:B.id,label:B.label,type:B.type,enabled:B.enabled,addedAt:B.addedAt,accountId:B.accountId,baseURL:B.type==="api"?B.baseURL:void 0,authHeader:B.type==="api"?B.authHeader:void 0})}function f0(B){if(B.type==="api")return D({apiKey:B.apiKey,lastUsed:B.lastUsed});return D({access:B.access,refresh:B.refresh,expires:B.expires,lastUsed:B.lastUsed,lastRefreshedAt:B.lastRefreshedAt,lastRefreshError:B.lastRefreshError,lastQuotaRefreshError:B.lastQuotaRefreshError,quota:B.quota})}function a(B){return Math.max(B?.primary?.checkedAt??0,B?.secondary?.checkedAt??0)}function v(B,Z,$){if($ in Z)B[$]=Z[$];else delete B[$]}function u2(B,Z){return B.access===Z.access&&B.refresh===Z.refresh&&B.expires===Z.expires&&B.lastRefreshedAt===Z.lastRefreshedAt}function s2(B,Z){if(!u2(B,Z))return Z;if(!("lastRefreshError"in Z))return B;if(!("lastRefreshError"in B))return Z;return(Z.lastRefreshError?.checkedAt??0)>(B.lastRefreshError?.checkedAt??0)?Z:B}function r2(B,Z,$){let W=Z.lastRefreshedAt??0,z=$.lastRefreshedAt??0,X=Z.expires??0,G=$.expires??0,K=z>W?$:W>z?Z:G>X?$:X>G?Z:s2(Z,$);v(B,K,"access"),v(B,K,"refresh"),v(B,K,"expires"),v(B,K,"lastRefreshedAt"),v(B,K,"lastRefreshError")}function n2(B,Z){if(!H(B))return Z;let $=B,W=a($.quota),z=a(Z.quota),X=W>z,G=X?{...$,...Z,quota:$.quota,lastQuotaRefreshError:$.lastQuotaRefreshError}:{...$,...Z};if(!X&&!("lastQuotaRefreshError"in Z))delete G.lastQuotaRefreshError;if(!("lastRefreshError"in Z))delete G.lastRefreshError;if(typeof $.lastUsed==="number"&&(typeof Z.lastUsed!=="number"||$.lastUsed>Z.lastUsed))G.lastUsed=$.lastUsed;return r2(G,$,Z),G}function m0(B){let Z=B.refresh?D({enabled:B.refresh.enabled,intervalMinutes:B.refresh.intervalMinutes,refreshBeforeExpiryMinutes:B.refresh.refreshBeforeExpiryMinutes}):void 0,$=B.quota?D({enabled:B.quota.enabled,checkIntervalMinutes:B.quota.checkIntervalMinutes,refreshEveryNRequests:B.quota.refreshEveryNRequests,minimumRemaining:B.quota.minimumRemaining,failClosedOnUnknownQuota:B.quota.failClosedOnUnknownQuota,showToasts:B.quota.showToasts}):void 0;return T0({version:1,main:B.main,routing:B.routing,fallbackOn:B.fallbackOn,refresh:Z,quota:$,dump:B.dump,costZeroing:B.costZeroing,killswitch:B.killswitch,logging:B.logging,cachekeep:B.cachekeep,mainAccountId:B.mainAccountId,accounts:B.accounts.map(i2)})}async function p(B){let Z=Date.now()+_0;while(Date.now()<=Z){let $=await I({name:"save",ttlMs:_0,path:B});if($)return $;let W=Z-Date.now();if(W<=0)break;await x2(Math.min(I2,W))}throw Error(`Timed out acquiring account store lock for ${B}; refusing to overwrite newer account data`)}function w0(B){let Z=Object.fromEntries(B.accounts.map(($)=>[$.id,f0($)]));return{version:1,main:D({quota:B.quota?.mainQuota,quotaCheckedAt:B.quota?.mainQuotaCheckedAt,quotaToken:B.quota?.mainQuotaToken,lastQuotaApiError:B.quota?.mainLastQuotaApiError,lastRefreshError:B.refresh?.mainLastRefreshError,refreshLeaseId:B.refresh?.mainRefreshLeaseId,refreshLeaseUntil:B.refresh?.mainRefreshLeaseUntil,refreshLeaseTokenHash:B.refresh?.mainRefreshLeaseTokenHash}),accounts:Z}}async function WB(B,Z=T()){let $=o(Z),W=await p(Z);try{let z=await p($);try{let X=await R(Z),G=await R($),K=(X.exists?I0(A0(X.value,G.value)):null)??c2(),Y=B(K)??K,j={...H(X.value)?X.value:{},...m0(Y)};return await A(Z,j),await A($,w0(Y)),Y}finally{await z.release()}}finally{await W.release()}}function c2(){return{version:1,main:{type:"opencode",provider:"openai"},accounts:[]}}function a2(B,Z){B.main=B.main??{};let $=typeof B.main.quotaCheckedAt==="number"?B.main.quotaCheckedAt:a(B.main.quota),W=typeof Z.quota?.mainQuotaCheckedAt==="number"?Z.quota.mainQuotaCheckedAt:a(Z.quota?.mainQuota);if($>W)return;B.main.quota=Z.quota?.mainQuota,B.main.quotaCheckedAt=Z.quota?.mainQuotaCheckedAt,B.main.quotaToken=Z.quota?.mainQuotaToken,B.main.lastQuotaApiError=Z.quota?.mainLastQuotaApiError}function o2(B,Z){B.main=B.main??{},B.main.lastRefreshError=Z.refresh?.mainLastRefreshError,B.main.refreshLeaseId=Z.refresh?.mainRefreshLeaseId,B.main.refreshLeaseUntil=Z.refresh?.mainRefreshLeaseUntil,B.main.refreshLeaseTokenHash=Z.refresh?.mainRefreshLeaseTokenHash}function Y0(B){if(Array.isArray(B))return B.map(Y0);if(!H(B))return B;return Object.fromEntries(Object.entries(B).filter(([,Z])=>Z!==void 0).map(([Z,$])=>[Z,Y0($)]))}async function t2(B,Z=T(),$={mainQuota:!0,mainRefresh:!0,accounts:!0}){let W=o(Z),z=await p(W);try{let X=(await R(W)).value,G=H(X)?{...X,version:1}:{version:1};if($.mainQuota)a2(G,B);if($.mainRefresh)o2(G,B);if($.accounts){let K=$.accounts===!0?null:new Set($.accounts),Y=await d2(Z);G.accounts={...H(G.accounts)?G.accounts:{}};for(let J of B.accounts){if(K&&!K.has(J.id))continue;if(Y&&!Y.has(J.id))continue;G.accounts[J.id]=n2(G.accounts[J.id],f0(J))}if(K){for(let J of K)if(!B.accounts.some((j)=>j.id===J))delete G.accounts[J]}if(Y){for(let J of Object.keys(G.accounts))if(!Y.has(J))delete G.accounts[J]}}await A(W,Y0(G))}finally{await z.release()}}function e2(B){return B?.fallbackOn?.length?B.fallbackOn:w2}function zB(B,Z){return e2(Z).includes(B)}function B4(B){let Z=B?.quota?.minimumRemaining||{};return{primary:Z.primary??Z["5h"]??q0.primary,secondary:Z.secondary??Z["1w"]??q0.secondary}}function J0(B){return B?.quota?.enabled!==!1}function l(B){return B?.quota?.failClosedOnUnknownQuota??k2}function k0(B,Z,$=Date.now()){if(!J0(Z))return!0;if(!B)return!l(Z);let W=B4(Z),z=l(Z);for(let X of["primary","secondary"]){let G=B[X];if(!G)continue;if(r(G,$)){if(z)return!1;continue}if(G.remainingPercent<W[X])return!1}return!0}function h0(B){return B?.killswitch?.enabled===!0}function S0(B){return{primary:B?.primary??B?.["5h"]??K0.primary,secondary:B?.secondary??B?.["1w"]??K0.secondary}}function v0(B,Z){if(!B?.killswitch)return K0;if(Z&&B.killswitch.accounts?.[Z])return S0(B.killswitch.accounts[Z]);return S0(B.killswitch.main)}function XB(B,Z,$,W=Date.now()){if(!h0(Z))return!0;if(!B)return!l(Z);let z=v0(Z,$),X=l(Z);for(let G of["primary","secondary"]){let K=B[G];if(!K)continue;if(r(K,W)){if(X)return!1;continue}if(K.remainingPercent<z[G])return!1}return!0}function GB(B,Z,$,W){if(!h0(W))return 300;let z=[],X=[{accountId:void 0,quota:B},...Z];for(let{accountId:K,quota:Y}of X){if(!Y)continue;let J=v0(W,K),j=[],Q=!1;for(let y of["primary","secondary"]){let V=Y[y];if(!V||r(V,$))continue;if(V.remainingPercent>=J[y])continue;let F=V.resetsAt?Date.parse(V.resetsAt):NaN;if(!Number.isFinite(F)||F<=$){Q=!0;break}j.push(F)}if(Q||j.length===0)continue;z.push(Math.max(...j))}if(z.length===0)return 300;let G=Math.min(...z);return Math.max(1,Math.ceil((G-$)/1000))}function Z4(B){return typeof B.version==="number"&&Array.isArray(B.accounts)}async function KB(B,Z=T()){let $=o(Z),W=await p(Z);try{let z=await p($);try{let X=await R(Z);if(X.exists&&H(X.value)){if(Z4(X.value))return}if(!B)return;let G={version:1,main:{type:"opencode",provider:"openai"},accounts:[]};if(B.access){let J=i({id_token:"",access_token:B.access,refresh_token:B.refresh});if(J)G.mainAccountId=J}let Y={...X.exists&&H(X.value)?X.value:{},...m0(G)};await A(Z,Y),await A($,w0(G))}finally{await z.release()}}finally{await W.release()}}function $4(B){return B?.refresh?.enabled!==!1}function W4(B){return(B?.refresh?.refreshBeforeExpiryMinutes??240)*60000}function z4(B){return Math.floor(Math.random()*(B+1))}function S(B,Z,$){return!B.access||!B.expires||B.expires-$<=W4(Z)}function X4(B,Z){return Boolean(B.access&&typeof B.expires==="number"&&B.expires>Z)}function G4(B,Z){return Boolean(B.mainAccountId&&Z.accountId&&Z.accountId===B.mainAccountId)}function N(B,Z){let $=B.accounts.findIndex((W)=>W.id===Z.id);if($!==-1)B.accounts[$]=Z}function X0(B){return B instanceof Error?B.message:String(B)}function j0(B,Z,$){B.lastRefreshError=N0({error:Z,now:$,refreshToken:B.refresh,previous:B.lastRefreshError})}function G0(B,Z,$){if(B.lastQuotaRefreshError=f({error:Z,now:$,previous:B.lastQuotaRefreshError}),Z?.isRefreshError===!0)j0(B,Z,$)}function K4(B){return`fallback-oauth-refresh-${E2("sha256").update(B).digest("base64url").slice(0,16)}`}function R0(B,Z){if(!B)return!1;if(!B.resetsAt)return!0;let $=Date.parse(B.resetsAt);return Number.isFinite($)?$>Z:!0}function Y4(B,Z){if(!B)return!1;return R0(B.primary,Z)||R0(B.secondary,Z)}function J4(B,Z,$){if(!B)return!1;let W=Z?.quota?.checkIntervalMinutes??5,z=Math.max(1,W)*60000,X=Math.max(B.primary?.checkedAt??0,B.secondary?.checkedAt??0);return $-X<z}function y0(B,Z,$){return!J4(B.quota,Z,$)}function j4(B,Z,$,W){return e($)&&k0(B.quota,Z,W)&&Y4(B.quota,W)}function H4(B){let Z=B?.quota?.checkIntervalMinutes??5;return Math.max(1,Z)*60000}var Q4=60000,N4=60000,P4=600000,V4=1e4,L4=100;var YB=globalThis.setTimeout.bind(globalThis),JB=globalThis.clearTimeout.bind(globalThis);class F4{now;fetchImpl;configPath;refreshPromises=new Map;refreshTimer=null;quotaTimer=null;quotaManager;onFallbackStorageChanged;options;constructor(B={}){this.options=B,this.now=B.now??Date.now,this.fetchImpl=B.fetchImpl??fetch,this.configPath=B.configPath??T(),this.quotaManager=B.quotaManager??null,this.onFallbackStorageChanged=B.onFallbackStorageChanged}seedFallbackQuota(B,Z){if(!this.quotaManager)return;if(!B.quota)return;let $=Math.max(B.quota.primary?.checkedAt??0,B.quota.secondary?.checkedAt??0);if($<=0)return;let W=this.quotaManager.getFallback(B.id,B.access);if(W&&W.checkedAt>=$)return;this.quotaManager.setFallback(B.id,{quota:B.quota,refreshAfter:$+H4(Z),checkedAt:$},B.access)}async load(){return g2(this.configPath)}async save(B,Z){await t2(B,this.configPath,{accounts:Z??!0})}startBackgroundRefresh(){let B=async()=>{if(await this.refreshDueAccounts(),this.options.fetchQuotaFn)await this.refreshQuotaForDueAccounts()};if(B().catch(()=>{}),!this.refreshTimer){if(this.refreshTimer=setInterval(()=>{B().catch(()=>{})},Q4+z4(N4)),"unref"in this.refreshTimer)this.refreshTimer.unref()}}stopBackgroundRefresh(){if(this.refreshTimer)clearInterval(this.refreshTimer);if(this.quotaTimer)clearInterval(this.quotaTimer);this.refreshTimer=null,this.quotaTimer=null}async getUsableFallbackAccounts(B){let Z=B!==void 0?B:await this.load();if(!Z)return[];let $=[],W=!1;for(let z of Z.accounts){if(z.enabled===!1||!b(z))continue;if(G4(Z,z))continue;let X=!1,G=z;try{if(S(G,Z,this.now())){let K=G.lastRefreshError;if(K&&U(K,G.refresh,this.now()))throw X=!0,Error(d(K,this.now()));try{G=await this.refreshAccount(G,Z),W=!0}catch(Y){if(h2(Y))continue;X=!0;let J=Z.accounts.find((j)=>j.id===z.id&&b(j));if(J&&!U(J.lastRefreshError,J.refresh,this.now()))j0(J,Y,this.now()),N(Z,J),W=!0;throw Y}}if(this.seedFallbackQuota(G,Z),this.accountPassesQuotaPolicy(this.quotaPolicyAccount(G),Z))$.push(G)}catch(K){let Y=X4(G,this.now());if(X){if(!Y)continue}else if(!Y)continue;if(j4(G,Z,K,this.now()))E.debug("fallback quota using cached quota after refresh error",{pid:process.pid,accountId:G.id,error:X0(K)}),$.push(G);else if(!l(Z))$.push(G)}}if(W)await this.save(Z);return $}async markUsed(B){let Z=await this.load();if(!Z)return;let $=Z.accounts.find((W)=>W.id===B.id);if(!$)return;$.lastUsed=this.now(),await this.save(Z)}accountPassesQuotaPolicy(B,Z){return k0(B.quota,Z,this.now())}quotaPolicyAccount(B){if(!this.quotaManager)return B;let Z=this.quotaManager.getFallback(B.id,B.access)?.quota;return Z?{...B,quota:Z}:B}async refreshDueAccounts(){let B=await this.load();if(!B||!$4(B))return;let Z=!1;for(let $ of B.accounts){if($.enabled===!1||!b($))continue;if(!S($,B,this.now()))continue;if(U($.lastRefreshError,$.refresh,this.now()))continue;try{E.debug("fallback oauth background due",{pid:process.pid,accountId:$.id,expiresInMs:$.expires?$.expires-this.now():void 0}),await this.refreshAccount($,B),Z=!0}catch(W){E.warn("fallback oauth background failed",{pid:process.pid,accountId:$.id,error:X0(W)}),j0($,W,this.now()),N(B,$),Z=!0}}if(Z)await this.save(B)}async refreshQuotaForDueAccounts(){let B=await this.load();if(!B||!J0(B))return;if(!this.options.fetchQuotaFn)return;let Z=!1;for(let $ of B.accounts){if($.enabled===!1||!b($))continue;let W=$;try{if(S(W,B,this.now())){if(U(W.lastRefreshError,W.refresh,this.now()))continue;W=await this.refreshAccount(W,B),Z=!0}if(x(W.lastQuotaRefreshError,this.now()))continue;if(this.seedFallbackQuota(W,B),!(this.quotaManager?this.quotaManager.isFallbackStale(W.id,W.access):y0(W,B,this.now())))continue;await this.refreshAccountQuota(W,B),Z=!0}catch(z){G0($,z,this.now()),N(B,$),Z=!0}}if(Z)await this.save(B),this.onFallbackStorageChanged?.()}async refreshQuotaForAllAccounts(B={}){let Z=await this.load(),$=[];if(!Z||!J0(Z))return{storage:Z,errors:$};if(!this.options.fetchQuotaFn)return{storage:Z,errors:$};let W=B.force??!1,z=!1;for(let X of Z.accounts){if(X.enabled===!1||!b(X))continue;let G=X;try{if(S(G,Z,this.now())){let K=G.lastRefreshError;if(K&&U(K,G.refresh,this.now()))throw Error(d(K,this.now()));G=await this.refreshAccount(G,Z),z=!0}if(!W&&!y0(G,Z,this.now())){if(G.lastQuotaRefreshError)G.lastQuotaRefreshError=void 0,N(Z,G),z=!0;continue}await this.refreshAccountQuota(G,Z),z=!0}catch(K){G0(X,K,this.now()),N(Z,X),z=!0,$.push({accountId:X.id,message:X0(K)})}}if(z)await this.save(Z);return{storage:Z,errors:$}}async refreshAccount(B,Z,$={}){let W=this.refreshPromises.get(B.id);if(W){let G=await W;return N(Z,G),G}let z=this.refreshAccountNow(B,Z,$).finally(()=>{this.refreshPromises.delete(B.id)});this.refreshPromises.set(B.id,z);let X=await z;return N(Z,X),X}async waitForConcurrentFallbackRefresh(B,Z,$,W){let z=Date.now()+V4;while(Date.now()<z){await new Promise((J)=>setTimeout(J,L4));let X=await this.load(),G=X?.accounts.find((J)=>J.id===B.id&&b(J));if(!G)continue;if((G.access!==$.access||G.refresh!==$.refresh||(G.expires??0)>($.expires??0)+60000)&&(W.force||!S(G,X,this.now())))return N(Z,G),E.debug("fallback oauth joined concurrent refresh",{pid:process.pid,accountId:G.id,expiresInMs:G.expires?G.expires-this.now():void 0}),G;let Y=G.lastRefreshError;if(Y&&U(Y,G.refresh,this.now()))throw N(Z,G),Error(d(Y,this.now()))}return null}async refreshAccountNow(B,Z,$){let W=await this.load(),z=W?.accounts.find((K)=>K.id===B.id&&b(K));if(z&&!$.force&&!S(z,W,this.now()))return N(Z,z),z;let X=z??B,G=await I({name:K4(X.id),ttlMs:P4,path:this.configPath,now:this.now,renew:!0});if(!G){E.debug("fallback oauth refresh skipped file lock",{pid:process.pid,accountId:X.id});let K=await this.waitForConcurrentFallbackRefresh(B,Z,X,$);if(K)return K;throw Error("Fallback OAuth refresh is already in progress")}try{if(W=await this.load(),z=W?.accounts.find((j)=>j.id===B.id&&b(j)),z&&!$.force&&!S(z,W,this.now()))return N(Z,z),z;if(!z)throw new c(B.id);X=z;let K=this.options.refreshFn??(async()=>{throw Error("No refreshFn injected into FallbackAccountManager")});E.debug("fallback oauth refresh request start",{pid:process.pid,accountId:X.id,force:$.force===!0,expiresInMs:X.expires?X.expires-this.now():void 0});let Y=await K({refreshToken:X.refresh,fetchImpl:this.fetchImpl,now:this.now});if(X.access=Y.access,X.refresh=Y.refresh,X.expires=Y.expires,X.lastRefreshedAt=Y.expires-Y.expiresIn*1000,X.lastRefreshError=void 0,N(Z,X),await this.save(Z),!(await this.load())?.accounts.some((j)=>j.id===B.id))throw new c(B.id);return E.debug("fallback oauth refresh succeeded",{pid:process.pid,accountId:X.id,expiresInMs:X.expires?X.expires-this.now():void 0}),X}finally{await G.release()}}async refreshAccountQuota(B,Z){let $=B;if(!$.access)throw Error(`Fallback account ${B.id} has no access token`);if(!this.options.fetchQuotaFn)throw Error("No fetchQuotaFn injected — wham/usage supplement is disabled");let W=this.options.fetchQuotaFn??(async()=>{throw Error("No fetchQuotaFn injected — wham/usage supplement is disabled")}),z=(X)=>this.quotaManager?this.quotaManager.refreshFallback($.id,X):W({accessToken:X,fetchImpl:this.fetchImpl,now:this.now});try{if(!$.access)throw Error(`Fallback account ${B.id} has no access token`);let X=await z($.access);$.quota=X,$.lastQuotaRefreshError=void 0,N(Z,$),await this.save(Z)}catch(X){throw G0(B,X,this.now()),N(Z,B),X}}}
|
|
89
|
-
export{Q0 as h,N0 as i,U as j,d as k,F0 as l,b0 as m,t0 as n,V0 as o,L0 as p,i as q,Z0 as r,B2 as s,C as t,z2 as u,X2 as v,G2 as w,K2 as x,q4 as y,C4 as z,D0 as A,I4 as B,A4 as C,h4 as D,O as E,T as F,b as G,ZB as H,K0 as I,g2 as J,WB as K,zB as L,h0 as M,XB as N,GB as O,KB as P,F4 as Q};
|
package/dist/index-hjgzqz1c.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createHash as z}from"node:crypto";import{homedir as A,tmpdir as K}from"node:os";import{join as q,resolve as B}from"node:path";var F="OPENCODE_OPENAI_AUTH_RPC_DIR";function M(f){let k=process.env[F]?.trim();if(k)return B(f,k);let w=z("sha256").update(f).digest("hex").slice(0,16),x=process.env.XDG_STATE_HOME||q(A(),".local","state");return q(x,"cortexkit","openai-auth","rpc",w)}export{K as pa,M as qa};
|
package/dist/index-qnd9x5jh.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{mkdir as u,readdir as l,readFile as c,rename as p,unlink as m,writeFile as d}from"node:fs/promises";import{join as a}from"node:path";function f(t){try{return process.kill(t,0),!0}catch(r){return r.code==="EPERM"}}async function b(t,r){await u(t,{recursive:!0});let s={...r,startedAt:Date.now()},e=a(t,`port-${r.pid}.json`),i=`${e}.${process.pid}.tmp`;return await d(i,JSON.stringify(s),{encoding:"utf8",mode:384}),await p(i,e),e}async function h(t,r){let s;try{s=await l(t)}catch{return null}let e=[];for(let n of s){if(!n.startsWith("port-")||!n.endsWith(".json"))continue;try{let o=JSON.parse(await c(a(t,n),"utf8"));if(Number.isFinite(o.port))if(f(o.pid))e.push(o);else m(a(t,n)).catch(()=>{})}catch{}}if(e.length===0)return null;let i=r!==void 0&&r>=1?e.filter((n)=>n.pid===r):[];return(i.length>0?i:e).sort((n,o)=>o.startedAt-n.startedAt)[0]??null}
|
|
2
|
-
export{b as na,h as oa};
|
package/dist/index-wpk440dz.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{la as U,ma as F}from"./index-72cas5ht.js";import{randomUUID as E}from"node:crypto";import{mkdir as R,readFile as g,rename as f,rm as m,writeFile as S}from"node:fs/promises";import{tmpdir as c}from"node:os";import{dirname as y,join as v}from"node:path";var _=["primary","secondary"],k={primary:300,secondary:10080};function N(H){return Number.isInteger(H)?String(H):String(Math.round(H*10)/10)}function p(H,J){let Z=H!==void 0&&Number.isFinite(H)&&H>0?H:k[J];if(Z<60)return`${N(Z)}m`;if(Z<1440)return`${N(Z/60)}h`;return`${N(Z/1440)}d`}function A(H){if(!H)return[];let J=[];for(let Z of _){let $=H[Z];if(!$)continue;let x=$.windowMinutes,Q=x!==void 0&&Number.isFinite(x)&&x>0?x:k[Z];J.push({key:Z,label:p(Q,Z),window:$,windowMs:Q*60000})}return J}var w=U("sidebar"),u="OPENCODE_OPENAI_AUTH_SIDEBAR_STATE_FILE",d=v(c(),"opencode-openai-auth"),l=v(d,"sidebar-state.json");function o(H){return typeof H==="number"&&Number.isFinite(H)&&H>=0?H:void 0}function W(H){let J=o(H);return J!==void 0?{resetCredits:J}:{}}function s(H){if(H===null||typeof H!=="object"||Array.isArray(H))return;let J={};for(let[Z,$]of Object.entries(H)){if($===null||typeof $!=="object"||Array.isArray($))continue;let x=$;if(typeof x.activeId!=="string"||typeof x.route!=="string"||typeof x.updatedAt!=="number"||!Number.isFinite(x.updatedAt))continue;J[Z]={activeId:x.activeId,route:x.route,updatedAt:x.updatedAt}}return Object.keys(J).length>0?J:void 0}function z(){return process.env[u]||l}var K={main:{quota:null,killed:!1},fallbacks:[],activeId:void 0,route:"main",lastUpdated:0};function M(H){if(H===null||typeof H!=="object"||Array.isArray(H))return K;let J=H,Z=J.main,$;if(Z!==null&&typeof Z==="object"&&!Array.isArray(Z)){let j=Z;$={quota:"quota"in j?j.quota:null,killed:typeof j.killed==="boolean"?j.killed:!1,...typeof j.quotaBackedOff==="boolean"?{quotaBackedOff:j.quotaBackedOff}:{},...typeof j.quotaBackoffUntil==="number"?{quotaBackoffUntil:j.quotaBackoffUntil}:{},...typeof j.refreshBackedOff==="boolean"?{refreshBackedOff:j.refreshBackedOff}:{},...typeof j.refreshBackoffUntil==="number"?{refreshBackoffUntil:j.refreshBackoffUntil}:{},...W(j.resetCredits)}}else $={quota:null,killed:!1};let x=J.fallbacks,Q=Array.isArray(x)?x.filter((j)=>j!==null&&typeof j==="object"&&!Array.isArray(j)&&typeof j.id==="string").map((j)=>({id:j.id,label:typeof j.label==="string"?j.label:void 0,quota:"quota"in j?j.quota:null,killed:typeof j.killed==="boolean"?j.killed:!1,enabled:typeof j.enabled==="boolean"?j.enabled:!0,...W(j.resetCredits)})):[],Y=typeof J.activeId==="string"?J.activeId:void 0,V=typeof J.route==="string"?J.route:K.route,X=typeof J.lastUpdated==="number"?J.lastUpdated:0,O=typeof J.planType==="string"?J.planType:void 0,G=typeof J.credits==="number"?J.credits:void 0,q=s(J.activeRouting);return{main:$,fallbacks:Q,activeId:Y,route:V,lastUpdated:X,...q!==void 0?{activeRouting:q}:{},...O!==void 0?{planType:O}:{},...G!==void 0?{credits:G}:{}}}async function XH(){try{let H=await g(z(),"utf8");return M(JSON.parse(H))}catch{return K}}var r=3600000,D=128;function I(H,J,Z=Date.now()){if(!(H.updatedAt>=Z-r&&H.updatedAt<=Z))return!1;return H.activeId==="main"||J.some((x)=>x.enabled!==!1&&x.id===H.activeId)}function KH(H,J,Z=Date.now()){if(!J)return{activeId:H.activeId??"main",route:H.route};let $=J?H.activeRouting?.[J]:void 0;if($&&I($,H.fallbacks,Z))return{activeId:$.activeId,route:$.route};let x=H.fallbacks.find((Q)=>Q.enabled&&!Q.killed);return{activeId:H.route==="fallback-first"&&x?x.id:"main",route:H.route}}function T(H,J,Z=Date.now(),$){if(!H)return;let x=Object.entries(H).filter(([Y,V])=>Y!==$&&I(V,J,Z)),Q=x.length<=D?x:x.sort((Y,V)=>V[1].updatedAt-Y[1].updatedAt).slice(0,D);return Q.length>0?Object.fromEntries(Q):void 0}var P=Promise.resolve(),n=3,i=1e4,a=15000;function B(H){let J=P.then(H);return P=J.catch(()=>{}),J}function zH(H,J=z()){return B(()=>L(H,J))}async function t(H){try{return b(await h(H))}catch{return K}}async function h(H){try{return await g(H,"utf8")}catch(J){if(J.code==="ENOENT")return"";throw J}}function b(H){if(H==="")return K;try{return M(JSON.parse(H))}catch{return K}}async function e(H){await R(y(H),{recursive:!0});let J=Date.now()+a;while(Date.now()<=J){let Z=await F({name:"sidebar-write",path:H,ttlMs:i,renew:!0});if(Z)return Z;await new Promise(($)=>setTimeout($,10))}throw Error("Timed out waiting for the sidebar state write lock")}async function C(H,J,Z){let $=await e(H);try{for(let Q=0;Q<n;Q+=1){let Y=await h(H),V=J(b(Y));if(Q===0)await Z?.beforeRecheck?.();if(await h(H)!==Y)continue;await L(V,H);return}let x=await t(H);await L(J(x),H)}finally{await $.release()}}function GH(H,J=z(),Z){return B(async()=>{await C(J,($)=>({...$,...H,activeId:$.activeId,activeRouting:$.activeRouting,lastUpdated:Math.max(Date.now(),$.lastUpdated+1)}),Z)})}function BH(H,J,Z=z(),$){return B(async()=>{await C(Z,(x)=>{let Q=T({...x.activeRouting,[H.sessionId]:{activeId:H.activeId,route:H.route,updatedAt:H.updatedAt}},J,Date.now());return{...x,activeId:H.activeId,route:H.route,activeRouting:Q,lastUpdated:Math.max(Date.now(),x.lastUpdated+1)}},$)})}function OH(H,J=z()){return B(async()=>{await C(J,(Z)=>({...Z,activeId:H.activeId,route:H.route,lastUpdated:Math.max(Date.now(),Z.lastUpdated+1)}))})}function qH(H,J,Z=z(),$){return B(async()=>{await C(Z,(x)=>{let Q=Date.now(),Y=T(x.activeRouting,J,Q,H);return{...x,activeRouting:Y,lastUpdated:Math.max(Date.now(),x.lastUpdated+1)}},$)})}async function L(H,J){let Z=`${J}.${E()}.tmp`;try{await R(y(J),{recursive:!0}),await S(Z,JSON.stringify(H),"utf8"),await f(Z,J)}catch($){throw await m(Z,{force:!0}).catch(()=>{}),w.warn("sidebar write failed",{pid:process.pid,error:$ instanceof Error?$.message:String($)}),$}}function CH(){return P}function NH(H){let J=H.activeId;if(J&&J!=="main"){let Z=H.fallbacks.find(($)=>$.enabled&&$.id===J);if(Z)return{id:Z.id,name:Z.label??Z.id,quota:Z.quota,killed:Z.killed}}return{id:"main",name:"main",quota:H.main.quota,killed:H.main.killed}}function PH(H){let J=H?.primary?.usedPercent??null,Z=H?.secondary?.usedPercent??null,$=A(H);return{primaryUsedPercent:J,secondaryUsedPercent:Z,text:$.length===0?null:$.map(({label:x,window:Q})=>`${x}: ${Math.round(Q.usedPercent)}%`).join(" ")}}var HH=300000,JH=0.01,ZH=1;function hH(H,J,Z){if(!H.resetsAt)return null;let $=new Date(H.resetsAt).getTime();if(!Number.isFinite($))return null;let x=$-J,Q=Z-x;if(Q<HH)return null;if(Q<J*JH)return null;if(Q>=J)return null;let Y=H.usedPercent,V=Math.min(Math.max(Q/J*100,0),100),X=Y-V,O=Math.abs(X)<ZH?"on-pace":X>0?"deficit":"reserve",G=null;if(Y>0){let q=Q*100/Y,j=x+q;if(j<$)G=new Date(j).toISOString()}return{pacePercent:V,deltaPercent:X,state:O,runsOutAt:G}}
|
|
2
|
-
export{p as R,A as S,z as T,K as U,M as V,XH as W,r as X,D as Y,I as Z,KH as _,T as $,zH as aa,GH as ba,BH as ca,OH as da,qH as ea,CH as fa,NH as ga,PH as ha,hH as ia};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as a}from"./index-x1c39tzz.js";import"./index-jpx7h5gc.js";export default a();
|