@cortexkit/opencode-openai-auth 0.11.0 → 1.0.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 +15 -26
- package/dist/index-766sfrh5.js +1 -0
- package/dist/index-8kj7sa1p.js +12 -0
- package/dist/index-8rqfbhfw.js +221 -0
- package/dist/index-b3q3j39x.js +2 -0
- package/dist/index-bmd7x5aq.js +2 -0
- package/dist/index-eqh53k8v.js +2 -0
- package/dist/{index-sdt2d2ra.js → index-hy9030jh.js} +1 -1
- package/dist/index-jyr8y8k4.js +7 -0
- package/dist/index-rv08jmd4.js +2 -0
- package/dist/index.d.ts +578 -145
- package/dist/index.js +1 -110
- package/dist/pool-lifecycle-DbDmgabd.d.ts +2430 -0
- package/dist/port-file-Do3lQIEk.d.ts +29 -0
- package/dist/protocol-BOBdkqqm.d.ts +198 -0
- package/dist/rpc/port-file.d.ts +4 -17
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/protocol.d.ts +2 -2
- package/dist/rpc/protocol.js +1 -0
- package/dist/rpc/rpc-client.d.ts +5 -4
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.d.ts +2 -0
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/sidebar-state-D6cUKgkm.d.ts +385 -0
- package/dist/sidebar-state.d.ts +2 -2
- package/dist/sidebar-state.js +1 -1
- package/dist/token-util-wdza526f.js +1 -0
- package/dist/{token-9823y0pc.js → token-ypk61xj0.js} +1 -1
- package/dist/tui-preferences.js +5 -2
- package/dist/tui.d.ts +9 -4
- package/dist/v2/server.d.ts +54 -0
- package/dist/v2/server.js +4 -0
- package/package.json +21 -9
- package/src/tui/entry.mjs +26 -25
- package/src/tui-compiled/raw/logger.js +24 -0
- package/src/tui-compiled/raw/rpc/protocol.js +3 -0
- package/src/tui-compiled/raw/rpc/rpc-client.js +7 -0
- package/src/tui-compiled/raw/rpc/rpc-dir.js +27 -0
- package/src/tui-compiled/raw/selector.js +21 -0
- package/src/tui-compiled/raw/shared/0332701351b3eeec-format.js +138 -0
- package/src/tui-compiled/raw/shared/04a6357627de5ed0-errors.js +38 -0
- package/src/tui-compiled/raw/shared/053cc17b5419261e-codec.js +12 -0
- package/src/tui-compiled/raw/shared/0766d78c6f481f18-watcher.js +157 -0
- package/src/tui-compiled/raw/shared/08eef45626a94992-reserved.js +13 -0
- package/src/tui-compiled/raw/shared/39c3cb05738fcf6d-projection.js +134 -0
- package/src/tui-compiled/raw/shared/3c2d4169d00f907e-tui-support.js +5 -0
- package/src/tui-compiled/raw/shared/3e7d45a77c6ad4d5-index.js +4 -0
- package/src/tui-compiled/raw/shared/415792e85d80819e-capture-sink.js +13 -0
- package/src/tui-compiled/raw/shared/42ae93ab554fcec2-open-url.js +28 -0
- package/src/tui-compiled/raw/shared/43fc9e6b994519c7-refresh-lock.js +136 -0
- package/src/tui-compiled/raw/shared/458b934e92490331-mutate.js +500 -0
- package/src/tui-compiled/raw/shared/45bf5343bbbf9add-admission.js +142 -0
- package/src/tui-compiled/raw/shared/46f3dff1266160e8-client.js +2 -0
- package/src/tui-compiled/raw/shared/4825e03209d6ae3e-with-lock.js +48 -0
- package/src/tui-compiled/raw/shared/4f36d333d081d040-merge.js +162 -0
- package/src/tui-compiled/raw/shared/54eba94fd64c8c3c-index.js +7 -0
- package/src/tui-compiled/raw/shared/7211cfec06a298bc-atomic-write.js +80 -0
- package/src/tui-compiled/raw/shared/754d6017f8e419cf-builtins.js +534 -0
- package/src/tui-compiled/raw/shared/75bd8c3bd63b315f-identity.js +79 -0
- package/src/tui-compiled/raw/shared/7a91bb630e6f4804-index.js +1 -0
- package/src/tui-compiled/raw/shared/826342a4b6a8b89b-model.js +16 -0
- package/src/tui-compiled/raw/shared/83068c0dbe8a6f13-publication.js +304 -0
- package/src/tui-compiled/raw/shared/836fc615de6afbd9-settings.js +120 -0
- package/src/tui-compiled/raw/shared/83bc3ba9d0fe2761-runtime.js +68 -0
- package/src/tui-compiled/raw/shared/8a18abe4fa2977c8-menu.js +300 -0
- package/src/tui-compiled/raw/shared/901e149c5a0dbbff-sticky.js +339 -0
- package/src/tui-compiled/raw/shared/9020c407ce64f672-ordered.js +58 -0
- package/src/tui-compiled/raw/shared/905bffc0220f43d0-map.js +105 -0
- package/src/tui-compiled/raw/shared/94820e324f2b4c09-seam.js +301 -0
- package/src/tui-compiled/raw/shared/97484d9bb98c705b-provider-state.js +226 -0
- package/src/tui-compiled/raw/shared/9968e3cade6969a1-index.js +2 -0
- package/src/tui-compiled/raw/shared/9b4da614c45f9cd0-lock-constants.js +14 -0
- package/src/tui-compiled/raw/shared/9d3fc9e37456504e-refresh.js +225 -0
- package/src/tui-compiled/raw/shared/9deae3c4da4fd63b-hooks.js +34 -0
- package/src/tui-compiled/raw/shared/a09b6a533c11858f-tui-preferences.js +77 -0
- package/src/tui-compiled/raw/shared/a62a27a204266acd-attribution.js +60 -0
- package/src/tui-compiled/raw/shared/a910277ac43a8626-pull.js +143 -0
- package/src/tui-compiled/raw/shared/b85c5301fddcb98a-paths.js +5 -0
- package/src/tui-compiled/raw/shared/c14988621dc60a75-port-file.js +217 -0
- package/src/tui-compiled/raw/shared/c64d7afbc14ca125-sidebar-file.js +157 -0
- package/src/tui-compiled/raw/shared/c6b176708c446d6d-pins.js +34 -0
- package/src/tui-compiled/raw/shared/c7d252bedee01600-pi.js +206 -0
- package/src/tui-compiled/raw/shared/c852a15cfe489d12-pool.js +120 -0
- package/src/tui-compiled/raw/shared/cc9e0702a752cea7-index.js +3 -0
- package/src/tui-compiled/raw/shared/cd94316a888b0a8e-schema.js +754 -0
- package/src/tui-compiled/raw/shared/d319517e3ea6ad70-redact.js +83 -0
- package/src/tui-compiled/raw/shared/d5a8f1061ee2f114-index.js +5 -0
- package/src/tui-compiled/raw/shared/d669d72c40e9e116-logger.js +19 -0
- package/src/tui-compiled/raw/shared/d7dcba96fea1685c-engine.js +246 -0
- package/src/tui-compiled/raw/shared/dbef697d1df1cd84-index.js +5 -0
- package/src/tui-compiled/raw/shared/e4acc4cb713f300c-protocol.js +3 -0
- package/src/tui-compiled/raw/shared/e8cd4929507508d8-refresh-file-lock.js +501 -0
- package/src/tui-compiled/raw/shared/ec971142548df90e-index.js +6 -0
- package/src/tui-compiled/raw/shared/f37fcefc7aedbf25-error.js +11 -0
- package/src/tui-compiled/raw/shared/fbcdcd0f925e74c0-rpc-client.js +253 -0
- package/src/tui-compiled/raw/shared/fd45e82f2f9c0a0d-torn.js +294 -0
- package/src/tui-compiled/raw/shared/fe02abeadc535f77-rows.js +1258 -0
- package/src/tui-compiled/raw/sidebar-state.js +960 -0
- package/src/tui-compiled/raw/tui/command-dialogs.tsx +424 -0
- package/src/tui-compiled/raw/tui-preferences.js +135 -0
- package/src/tui-compiled/raw/tui.tsx +135 -143
- package/src/tui-compiled/runtime/logger.js +24 -0
- package/src/tui-compiled/runtime/rpc/protocol.js +3 -0
- package/src/tui-compiled/runtime/rpc/rpc-client.js +7 -0
- package/src/tui-compiled/runtime/rpc/rpc-dir.js +27 -0
- package/src/tui-compiled/runtime/selector.js +21 -0
- package/src/tui-compiled/runtime/shared/0332701351b3eeec-format.js +138 -0
- package/src/tui-compiled/runtime/shared/04a6357627de5ed0-errors.js +38 -0
- package/src/tui-compiled/runtime/shared/053cc17b5419261e-codec.js +12 -0
- package/src/tui-compiled/runtime/shared/0766d78c6f481f18-watcher.js +157 -0
- package/src/tui-compiled/runtime/shared/08eef45626a94992-reserved.js +13 -0
- package/src/tui-compiled/runtime/shared/39c3cb05738fcf6d-projection.js +134 -0
- package/src/tui-compiled/runtime/shared/3c2d4169d00f907e-tui-support.js +5 -0
- package/src/tui-compiled/runtime/shared/3e7d45a77c6ad4d5-index.js +4 -0
- package/src/tui-compiled/runtime/shared/415792e85d80819e-capture-sink.js +13 -0
- package/src/tui-compiled/runtime/shared/42ae93ab554fcec2-open-url.js +28 -0
- package/src/tui-compiled/runtime/shared/43fc9e6b994519c7-refresh-lock.js +136 -0
- package/src/tui-compiled/runtime/shared/458b934e92490331-mutate.js +500 -0
- package/src/tui-compiled/runtime/shared/45bf5343bbbf9add-admission.js +142 -0
- package/src/tui-compiled/runtime/shared/46f3dff1266160e8-client.js +2 -0
- package/src/tui-compiled/runtime/shared/4825e03209d6ae3e-with-lock.js +48 -0
- package/src/tui-compiled/runtime/shared/4f36d333d081d040-merge.js +162 -0
- package/src/tui-compiled/runtime/shared/54eba94fd64c8c3c-index.js +7 -0
- package/src/tui-compiled/runtime/shared/7211cfec06a298bc-atomic-write.js +80 -0
- package/src/tui-compiled/runtime/shared/754d6017f8e419cf-builtins.js +534 -0
- package/src/tui-compiled/runtime/shared/75bd8c3bd63b315f-identity.js +79 -0
- package/src/tui-compiled/runtime/shared/7a91bb630e6f4804-index.js +1 -0
- package/src/tui-compiled/runtime/shared/826342a4b6a8b89b-model.js +16 -0
- package/src/tui-compiled/runtime/shared/83068c0dbe8a6f13-publication.js +304 -0
- package/src/tui-compiled/runtime/shared/836fc615de6afbd9-settings.js +120 -0
- package/src/tui-compiled/runtime/shared/83bc3ba9d0fe2761-runtime.js +68 -0
- package/src/tui-compiled/runtime/shared/8a18abe4fa2977c8-menu.js +300 -0
- package/src/tui-compiled/runtime/shared/901e149c5a0dbbff-sticky.js +339 -0
- package/src/tui-compiled/runtime/shared/9020c407ce64f672-ordered.js +58 -0
- package/src/tui-compiled/runtime/shared/905bffc0220f43d0-map.js +105 -0
- package/src/tui-compiled/runtime/shared/94820e324f2b4c09-seam.js +301 -0
- package/src/tui-compiled/runtime/shared/97484d9bb98c705b-provider-state.js +226 -0
- package/src/tui-compiled/runtime/shared/9968e3cade6969a1-index.js +2 -0
- package/src/tui-compiled/runtime/shared/9b4da614c45f9cd0-lock-constants.js +14 -0
- package/src/tui-compiled/runtime/shared/9d3fc9e37456504e-refresh.js +225 -0
- package/src/tui-compiled/runtime/shared/9deae3c4da4fd63b-hooks.js +34 -0
- package/src/tui-compiled/runtime/shared/a09b6a533c11858f-tui-preferences.js +77 -0
- package/src/tui-compiled/runtime/shared/a62a27a204266acd-attribution.js +60 -0
- package/src/tui-compiled/runtime/shared/a910277ac43a8626-pull.js +143 -0
- package/src/tui-compiled/runtime/shared/b85c5301fddcb98a-paths.js +5 -0
- package/src/tui-compiled/runtime/shared/c14988621dc60a75-port-file.js +217 -0
- package/src/tui-compiled/runtime/shared/c64d7afbc14ca125-sidebar-file.js +157 -0
- package/src/tui-compiled/runtime/shared/c6b176708c446d6d-pins.js +34 -0
- package/src/tui-compiled/runtime/shared/c7d252bedee01600-pi.js +206 -0
- package/src/tui-compiled/runtime/shared/c852a15cfe489d12-pool.js +120 -0
- package/src/tui-compiled/runtime/shared/cc9e0702a752cea7-index.js +3 -0
- package/src/tui-compiled/runtime/shared/cd94316a888b0a8e-schema.js +754 -0
- package/src/tui-compiled/runtime/shared/d319517e3ea6ad70-redact.js +83 -0
- package/src/tui-compiled/runtime/shared/d5a8f1061ee2f114-index.js +5 -0
- package/src/tui-compiled/runtime/shared/d669d72c40e9e116-logger.js +19 -0
- package/src/tui-compiled/runtime/shared/d7dcba96fea1685c-engine.js +246 -0
- package/src/tui-compiled/runtime/shared/dbef697d1df1cd84-index.js +5 -0
- package/src/tui-compiled/runtime/shared/e4acc4cb713f300c-protocol.js +3 -0
- package/src/tui-compiled/runtime/shared/e8cd4929507508d8-refresh-file-lock.js +501 -0
- package/src/tui-compiled/runtime/shared/ec971142548df90e-index.js +6 -0
- package/src/tui-compiled/runtime/shared/f37fcefc7aedbf25-error.js +11 -0
- package/src/tui-compiled/runtime/shared/fbcdcd0f925e74c0-rpc-client.js +253 -0
- package/src/tui-compiled/runtime/shared/fd45e82f2f9c0a0d-torn.js +294 -0
- package/src/tui-compiled/runtime/shared/fe02abeadc535f77-rows.js +1258 -0
- package/src/tui-compiled/runtime/sidebar-state.js +960 -0
- package/src/tui-compiled/runtime/tui/command-dialogs.js +378 -0
- package/src/tui-compiled/runtime/tui-preferences.js +135 -0
- package/src/tui-compiled/runtime/{tui.tsx → tui.js} +288 -316
- package/dist/index-4effjmr6.js +0 -2
- package/dist/index-9ehhb051.js +0 -2
- package/dist/index-g3hsdjh4.js +0 -2
- package/dist/index-hh52v8sb.js +0 -2
- package/dist/index-jwn4r3sw.js +0 -1
- package/dist/index-sq36b120.js +0 -211
- package/dist/internal-BTndPmW2.d.ts +0 -914
- package/dist/quota-normalize-08hpp51v.js +0 -1
- package/dist/sidebar-state-CoKYKcLn.d.ts +0 -220
- package/dist/token-util-ypgz7rge.js +0 -1
- package/src/tui-compiled/raw/core-account-paths.ts +0 -114
- package/src/tui-compiled/raw/core-custody-state.ts +0 -243
- package/src/tui-compiled/raw/logger.ts +0 -53
- package/src/tui-compiled/raw/rpc-port-file.ts +0 -177
- package/src/tui-compiled/raw/rpc-protocol.ts +0 -12
- package/src/tui-compiled/raw/rpc-rpc-client.ts +0 -82
- package/src/tui-compiled/raw/rpc-rpc-dir.ts +0 -46
- package/src/tui-compiled/raw/sidebar-state.ts +0 -1659
- package/src/tui-compiled/raw/tui-command-dialogs.tsx +0 -1096
- package/src/tui-compiled/raw/tui-preferences.ts +0 -328
- package/src/tui-compiled/runtime/core-account-paths.ts +0 -114
- package/src/tui-compiled/runtime/core-custody-state.ts +0 -243
- package/src/tui-compiled/runtime/logger.ts +0 -53
- package/src/tui-compiled/runtime/rpc-port-file.ts +0 -177
- package/src/tui-compiled/runtime/rpc-protocol.ts +0 -12
- package/src/tui-compiled/runtime/rpc-rpc-client.ts +0 -82
- package/src/tui-compiled/runtime/rpc-rpc-dir.ts +0 -46
- package/src/tui-compiled/runtime/sidebar-state.ts +0 -1659
- package/src/tui-compiled/runtime/tui-command-dialogs.tsx +0 -855
- package/src/tui-compiled/runtime/tui-preferences.ts +0 -328
- package/src/tui-compiled/shared/internal.ts +0 -6
- package/src/tui-compiled/shared/logger.ts +0 -264
- package/src/tui-compiled/shared/paths.ts +0 -33
- package/src/tui-compiled/shared/refresh-file-lock.ts +0 -384
- package/src/tui-compiled/shared/util/error.ts +0 -9
- package/src/tui-compiled/shared/util/open-url.ts +0 -30
|
@@ -1,914 +0,0 @@
|
|
|
1
|
-
import { Endpoint } from "@cortexkit/subc-client";
|
|
2
|
-
//#region ../../node_modules/.bun/@cortexkit+claustrum-client@0.3.0/node_modules/@cortexkit/claustrum-client/dist/detect.d.ts
|
|
3
|
-
type ClaustrumEndpoint = Endpoint;
|
|
4
|
-
type ClaustrumDetection = {
|
|
5
|
-
status: 'available';
|
|
6
|
-
schema: number;
|
|
7
|
-
wireVersion: number;
|
|
8
|
-
endpoints: ClaustrumEndpoint[];
|
|
9
|
-
} | {
|
|
10
|
-
status: 'absent';
|
|
11
|
-
path: string;
|
|
12
|
-
} | {
|
|
13
|
-
status: 'malformed';
|
|
14
|
-
path: string;
|
|
15
|
-
reason: string;
|
|
16
|
-
};
|
|
17
|
-
declare function detectClaustrumConnection(explicitPath?: string): Promise<ClaustrumDetection>;
|
|
18
|
-
//#endregion
|
|
19
|
-
//#region ../../node_modules/.bun/@cortexkit+claustrum-client@0.3.0/node_modules/@cortexkit/claustrum-client/dist/handles.d.ts
|
|
20
|
-
type HandleAccount = {
|
|
21
|
-
label: string;
|
|
22
|
-
handle: string;
|
|
23
|
-
credential_id: string;
|
|
24
|
-
superseded?: string[];
|
|
25
|
-
minTtlMs?: number;
|
|
26
|
-
};
|
|
27
|
-
type HandleProvider = {
|
|
28
|
-
provider: string;
|
|
29
|
-
shape: 'api' | 'oauth';
|
|
30
|
-
serve: string;
|
|
31
|
-
accounts: HandleAccount[];
|
|
32
|
-
};
|
|
33
|
-
type OpenCodeHandleFileV1 = {
|
|
34
|
-
version: 1;
|
|
35
|
-
providers: HandleProvider[];
|
|
36
|
-
};
|
|
37
|
-
//#endregion
|
|
38
|
-
//#region ../../node_modules/.bun/@cortexkit+claustrum-client@0.3.0/node_modules/@cortexkit/claustrum-client/dist/manifest-lock.d.ts
|
|
39
|
-
type ManifestHandleFile = OpenCodeHandleFileV1;
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region ../core/dist/provider.d.ts
|
|
42
|
-
type QuotaWindowName = string;
|
|
43
|
-
type ProviderQuotaFn = (input: {
|
|
44
|
-
accessToken: string;
|
|
45
|
-
fetchImpl: typeof fetch;
|
|
46
|
-
now: () => number;
|
|
47
|
-
}) => Promise<OAuthQuotaSnapshot>;
|
|
48
|
-
//#endregion
|
|
49
|
-
//#region ../core/dist/quota-manager.d.ts
|
|
50
|
-
type QuotaEntry = {
|
|
51
|
-
quota: OAuthQuotaSnapshot;
|
|
52
|
-
refreshAfter: number;
|
|
53
|
-
checkedAt: number;
|
|
54
|
-
accountId?: string;
|
|
55
|
-
};
|
|
56
|
-
type QuotaManagerOptions = {
|
|
57
|
-
storage: AccountStorage | null;
|
|
58
|
-
fetchImpl?: typeof fetch;
|
|
59
|
-
/**
|
|
60
|
-
* Account config file this manager's cross-process refresh locks are named
|
|
61
|
-
* after. Host-resolved and required, so two hosts pointing at different
|
|
62
|
-
* stores never contend on one another's lock.
|
|
63
|
-
*/
|
|
64
|
-
configPath: string;
|
|
65
|
-
now?: () => number;
|
|
66
|
-
/** Injected quota-fetch function — replaces the hard-imported Anthropic fetchOAuthQuotaSnapshot */
|
|
67
|
-
fetchQuotaFn?: ProviderQuotaFn;
|
|
68
|
-
onMainQuotaFetched?: (quota: OAuthQuotaSnapshot, checkedAt: number, fingerprint: string, fetchStartedAt: number) => void;
|
|
69
|
-
onApiError?: (error: AccountOperationError) => void;
|
|
70
|
-
};
|
|
71
|
-
declare class QuotaManager {
|
|
72
|
-
private main;
|
|
73
|
-
private mainTokenFp;
|
|
74
|
-
private mainQuotaAccountId;
|
|
75
|
-
private fallbacks;
|
|
76
|
-
private fallbackTokenFps;
|
|
77
|
-
private inflightMain;
|
|
78
|
-
private inflightMainFp;
|
|
79
|
-
private inflightFallbacks;
|
|
80
|
-
private mainLastApiError;
|
|
81
|
-
private fallbackApiErrors;
|
|
82
|
-
private fallbackErrorTokenFps;
|
|
83
|
-
private rateLimitedUntilMap;
|
|
84
|
-
private apiGate;
|
|
85
|
-
private lastApiCallAt;
|
|
86
|
-
private storage;
|
|
87
|
-
private readonly fetchImpl;
|
|
88
|
-
private readonly now;
|
|
89
|
-
private readonly fetchQuotaFn;
|
|
90
|
-
private readonly onMainQuotaFetched;
|
|
91
|
-
private readonly onApiError;
|
|
92
|
-
private readonly configPath;
|
|
93
|
-
constructor(opts: QuotaManagerOptions);
|
|
94
|
-
/**
|
|
95
|
-
* Cached main quota entry. Pass the live access token to enforce token
|
|
96
|
-
* binding: if the cached entry was produced by a different token (main
|
|
97
|
-
* account switched), it is dropped and null is returned so the caller
|
|
98
|
-
* refetches for the current account. Called without a token (e.g. for
|
|
99
|
-
* display) it returns whatever is cached.
|
|
100
|
-
*/
|
|
101
|
-
getMain(accessToken?: string): QuotaEntry | null;
|
|
102
|
-
/**
|
|
103
|
-
* Cached fallback quota entry. Pass the live access token to enforce token
|
|
104
|
-
* binding: if the entry was produced by a different token (account re-login),
|
|
105
|
-
* it is dropped and null is returned so the caller refetches.
|
|
106
|
-
*/
|
|
107
|
-
getFallback(accountId: string, accessToken?: string): QuotaEntry | null;
|
|
108
|
-
getAllFallbacks(): Map<string, QuotaEntry>;
|
|
109
|
-
setMain(accessToken: string, entry: QuotaEntry, accountId?: string, completeSnapshot?: boolean): void;
|
|
110
|
-
/**
|
|
111
|
-
* Non-invalidating read of the cached main quota for POLICY decisions
|
|
112
|
-
* (killswitch). Unlike getMain(token), a token mismatch does NOT drop the
|
|
113
|
-
* cache — an access-token refresh is a same-account event and must not turn a
|
|
114
|
-
* known-exhausted account into "unknown" (which would fail open and spend).
|
|
115
|
-
*
|
|
116
|
-
* Pass the live ChatGPT accountId to still drop on a genuine account SWITCH:
|
|
117
|
-
* if the cached entry's account identity is known and differs, return null so
|
|
118
|
-
* the killswitch treats it as unknown rather than judging account A by account
|
|
119
|
-
* B's quota. When identity is unknown on either side, the cached snapshot is
|
|
120
|
-
* returned (best-effort) — the same fail-open-on-unknown stance as elsewhere.
|
|
121
|
-
*/
|
|
122
|
-
peekMainForPolicy(accountId?: string): QuotaEntry | null;
|
|
123
|
-
/**
|
|
124
|
-
* Non-invalidating read of a cached fallback quota for POLICY decisions
|
|
125
|
-
* (killswitch, admission). Keyed by the stable internal account id, so a
|
|
126
|
-
* token refresh for the same account does not drop it (getFallback(id, token)
|
|
127
|
-
* would).
|
|
128
|
-
*
|
|
129
|
-
* Pass the live ChatGPT identity to still drop on a genuine re-login: if the
|
|
130
|
-
* cached entry's identity is known and differs, return null so the previous
|
|
131
|
-
* identity's (possibly exhausted) quota is never judged against its
|
|
132
|
-
* replacement. Unknown on either side fails open, matching peekMainForPolicy.
|
|
133
|
-
*/
|
|
134
|
-
peekFallbackForPolicy(accountId: string, identity?: string): QuotaEntry | null;
|
|
135
|
-
setFallback(accountId: string, entry: QuotaEntry, accessToken?: string, completeSnapshot?: boolean, identity?: string): void;
|
|
136
|
-
/**
|
|
137
|
-
* Mark accountId ('main' or a fallback id) rate-limited until resetAtMs.
|
|
138
|
-
* Keeps the LATER reset: skips only when an existing mark is strictly
|
|
139
|
-
* later than resetAtMs, so an equal-reset re-mark still applies (idempotent)
|
|
140
|
-
* instead of being silently dropped by a stale `>=` comparison.
|
|
141
|
-
*/
|
|
142
|
-
markRateLimited(accountId: string, resetAtMs: number): void;
|
|
143
|
-
/** True iff accountId has a mark whose reset has not yet passed. */
|
|
144
|
-
isRateLimited(accountId: string): boolean;
|
|
145
|
-
/**
|
|
146
|
-
* Raw stored reset for accountId's mark, or undefined if none. Unlike
|
|
147
|
-
* isRateLimited, this does NOT apply read-time expiry — callers on the
|
|
148
|
-
* block path already know the mark is live (isRateLimited just returned
|
|
149
|
-
* true) and want its exact reset estimate for a Retry-After computation.
|
|
150
|
-
*/
|
|
151
|
-
rateLimitedUntil(accountId: string): number | undefined;
|
|
152
|
-
/** Explicit early clear — read-time expiry in isRateLimited is primary. */
|
|
153
|
-
clearRateLimited(accountId: string): void;
|
|
154
|
-
refreshMain(accessToken: string): Promise<OAuthQuotaSnapshot>;
|
|
155
|
-
refreshFallback(accountId: string, accessToken: string): Promise<OAuthQuotaSnapshot>;
|
|
156
|
-
refreshAllFallbacks(accounts: OAuthAccount[]): Promise<void>;
|
|
157
|
-
/**
|
|
158
|
-
* Fire-and-forget refresh. Does not await, swallows errors.
|
|
159
|
-
*/
|
|
160
|
-
refreshMainInBackground(accessToken: string): void;
|
|
161
|
-
isMainStale(): boolean;
|
|
162
|
-
isFallbackStale(accountId: string, accessToken?: string): boolean;
|
|
163
|
-
shouldRefreshOnRequestCount(requestCount: number): boolean;
|
|
164
|
-
/**
|
|
165
|
-
* Combined check: should a refresh happen right now?
|
|
166
|
-
* True if main is stale by time OR triggered by request count.
|
|
167
|
-
*/
|
|
168
|
-
needsRefresh(requestCount: number): boolean;
|
|
169
|
-
updateStorage(storage: AccountStorage | null): void;
|
|
170
|
-
/**
|
|
171
|
-
* Seed/update the main quota cache from persisted state. This is deliberately
|
|
172
|
-
* callable after every disk load so another plugin process's fresh quota write
|
|
173
|
-
* can stop this process from showing "checking…" or making a redundant quota
|
|
174
|
-
* API call.
|
|
175
|
-
*/
|
|
176
|
-
seedMainFromStorage(storage: AccountStorage | null, accessToken?: string): void;
|
|
177
|
-
private seedMainBackoffFromStorage;
|
|
178
|
-
/**
|
|
179
|
-
* Seed fallback cache entries from persisted account.quota data.
|
|
180
|
-
* Updates older in-memory entries so a fresh quota write from another plugin
|
|
181
|
-
* process prevents redundant checks and stale sidebar writes.
|
|
182
|
-
*/
|
|
183
|
-
seedFallbacksFromAccounts(accounts: OAuthAccount[]): void;
|
|
184
|
-
/**
|
|
185
|
-
* Whether the MAIN quota API is currently in backoff. Scoped to the main
|
|
186
|
-
* account — a fallback account's 429 never reports here.
|
|
187
|
-
*/
|
|
188
|
-
isBackedOff(): boolean;
|
|
189
|
-
/**
|
|
190
|
-
* Whether a specific fallback account's quota API is in backoff.
|
|
191
|
-
*/
|
|
192
|
-
isFallbackBackedOff(accountId: string, accessToken?: string): boolean;
|
|
193
|
-
getLastApiError(): AccountOperationError | undefined;
|
|
194
|
-
/** Minimum gap between consecutive quota API calls (ms). */
|
|
195
|
-
private static readonly API_CALL_GAP_MS;
|
|
196
|
-
private static fallbackInflightKey;
|
|
197
|
-
private static quotaLockName;
|
|
198
|
-
/**
|
|
199
|
-
* Serialize API calls through a shared gate so only one
|
|
200
|
-
* quota API request runs at a time, with a minimum gap
|
|
201
|
-
* between calls. Prevents concurrent and rapid-fire calls
|
|
202
|
-
* from triggering rate limits.
|
|
203
|
-
*/
|
|
204
|
-
private _enqueueApiFetch;
|
|
205
|
-
private _fetchMain;
|
|
206
|
-
private _fetchFallback;
|
|
207
|
-
/** Route through injected fetchQuotaFn, or throw if unset. */
|
|
208
|
-
private _fetchQuota;
|
|
209
|
-
private static isAuthError;
|
|
210
|
-
/** Main quota failure: arms main-only backoff and persists via onApiError. */
|
|
211
|
-
private _handleMainFetchError;
|
|
212
|
-
/**
|
|
213
|
-
* Fallback quota failure: arms backoff for THIS account only. Never touches
|
|
214
|
-
* main backoff state and never calls onApiError (which persists the main
|
|
215
|
-
* quota error) — the per-account error is recorded by the caller via the
|
|
216
|
-
* account's lastQuotaRefreshError.
|
|
217
|
-
*/
|
|
218
|
-
private _handleFallbackFetchError;
|
|
219
|
-
}
|
|
220
|
-
//#endregion
|
|
221
|
-
//#region ../core/dist/custody-manifest.d.ts
|
|
222
|
-
type CustodyManifestReadResult = {
|
|
223
|
-
ok: true;
|
|
224
|
-
value: ManifestHandleFile;
|
|
225
|
-
revision: string;
|
|
226
|
-
} | {
|
|
227
|
-
ok: false;
|
|
228
|
-
reason: 'absent';
|
|
229
|
-
} | {
|
|
230
|
-
ok: false;
|
|
231
|
-
reason: 'tooLarge';
|
|
232
|
-
message: string;
|
|
233
|
-
} | {
|
|
234
|
-
ok: false;
|
|
235
|
-
reason: 'permissions' | 'unsafeParent' | 'notRegular' | 'symlink';
|
|
236
|
-
message: string;
|
|
237
|
-
} | {
|
|
238
|
-
ok: false;
|
|
239
|
-
reason: 'invalid';
|
|
240
|
-
message: string;
|
|
241
|
-
} | {
|
|
242
|
-
ok: false;
|
|
243
|
-
reason: 'unreadable';
|
|
244
|
-
message: string;
|
|
245
|
-
};
|
|
246
|
-
type CustodyManifestIo = {
|
|
247
|
-
lstat?: (path: string) => Promise<CustodyStat>;
|
|
248
|
-
stat?: (path: string) => Promise<CustodyStat>;
|
|
249
|
-
readFile?: (path: string, encoding: 'utf8') => Promise<string>;
|
|
250
|
-
open?: (path: string) => Promise<CustodyDescriptor>;
|
|
251
|
-
currentUid?: () => number | undefined;
|
|
252
|
-
};
|
|
253
|
-
type CustodyStat = {
|
|
254
|
-
isFile(): boolean;
|
|
255
|
-
isDirectory?(): boolean;
|
|
256
|
-
isSymbolicLink?(): boolean;
|
|
257
|
-
mode: number;
|
|
258
|
-
size?: number;
|
|
259
|
-
uid?: number;
|
|
260
|
-
mtimeMs?: number;
|
|
261
|
-
};
|
|
262
|
-
type CustodyDescriptor = {
|
|
263
|
-
stat(): Promise<CustodyStat>;
|
|
264
|
-
read(options: {
|
|
265
|
-
buffer: Buffer;
|
|
266
|
-
offset: number;
|
|
267
|
-
length: number;
|
|
268
|
-
position: number;
|
|
269
|
-
}): Promise<{
|
|
270
|
-
bytesRead: number;
|
|
271
|
-
}>;
|
|
272
|
-
close(): Promise<void>;
|
|
273
|
-
};
|
|
274
|
-
//#endregion
|
|
275
|
-
//#region ../core/dist/refresh-file-lock.d.ts
|
|
276
|
-
declare function acquireRefreshFileLock(options: {
|
|
277
|
-
name: string;
|
|
278
|
-
ttlMs: number;
|
|
279
|
-
/**
|
|
280
|
-
* File the lock is named after. Required: the lock and the write it guards
|
|
281
|
-
* must target the same file, and a default resolved in here could only ever
|
|
282
|
-
* be one host's path.
|
|
283
|
-
*/
|
|
284
|
-
path: string;
|
|
285
|
-
now?: () => number;
|
|
286
|
-
renew?: boolean;
|
|
287
|
-
renewIntervalMs?: number;
|
|
288
|
-
onStep?: (step: 'stale-marker-stat' | 'stale-marker-claimed' | 'stale-lock-confirmed' | 'eviction-marker-acquired' | 'renewal-owner-confirmed' | 'renewal-marker-unavailable' | 'renewal-write-fenced' | 'renewal-write-ready' | 'relinquish-read' | 'renewal-finished' | 'release-owner-confirmed') => void | Promise<void>;
|
|
289
|
-
}): Promise<{
|
|
290
|
-
release: () => Promise<void>;
|
|
291
|
-
} | null>;
|
|
292
|
-
//#endregion
|
|
293
|
-
//#region ../core/dist/custody.d.ts
|
|
294
|
-
type ClaustrumMode = 'local' | 'claustrum';
|
|
295
|
-
type CustodyTransitionState = {
|
|
296
|
-
manifestRevision: string;
|
|
297
|
-
storeGeneration: string;
|
|
298
|
-
fingerprints: {
|
|
299
|
-
main?: string;
|
|
300
|
-
fallbacks: Record<string, string>;
|
|
301
|
-
};
|
|
302
|
-
};
|
|
303
|
-
declare const CUSTODY_REFUSE: unique symbol;
|
|
304
|
-
declare const CUSTODY_EXCLUDED: unique symbol;
|
|
305
|
-
type VaultProvenance = {
|
|
306
|
-
handle: string;
|
|
307
|
-
recordVersion: number;
|
|
308
|
-
};
|
|
309
|
-
type FallbackAccessResolution = {
|
|
310
|
-
token: string;
|
|
311
|
-
provenance: 'local';
|
|
312
|
-
} | {
|
|
313
|
-
token: string;
|
|
314
|
-
provenance: VaultProvenance;
|
|
315
|
-
};
|
|
316
|
-
type ResolveFallbackAccessOptions = {
|
|
317
|
-
cache?: ClaustrumCredentialCache;
|
|
318
|
-
manifestHandle?: string;
|
|
319
|
-
completeEnrollmentDeps?: CompleteEnrollmentDeps;
|
|
320
|
-
refreshBeforeExpiryMs?: number;
|
|
321
|
-
now?: () => number;
|
|
322
|
-
requestPath?: boolean;
|
|
323
|
-
};
|
|
324
|
-
declare function resolveFallbackAccess(account: OAuthAccount, storage: Pick<AccountStorage, 'claustrum'>, manifest?: CustodyManifestReadResult, options?: ResolveFallbackAccessOptions): Promise<FallbackAccessResolution | typeof CUSTODY_REFUSE | typeof CUSTODY_EXCLUDED>;
|
|
325
|
-
type ClaustrumCredentialCacheOptions = {
|
|
326
|
-
connector: (options: {
|
|
327
|
-
connectionFile: string;
|
|
328
|
-
handshakeTimeoutMs?: number;
|
|
329
|
-
}) => Promise<ClaustrumCacheTransport>;
|
|
330
|
-
now?: () => number;
|
|
331
|
-
};
|
|
332
|
-
type ClaustrumCacheTransport = {
|
|
333
|
-
getCredential(handle: string, minTtlMs?: number): Promise<{
|
|
334
|
-
material: string;
|
|
335
|
-
recordVersion: number;
|
|
336
|
-
expiresAtMs: number | null;
|
|
337
|
-
accountId?: string;
|
|
338
|
-
}>;
|
|
339
|
-
statusCredential(handle: string): Promise<{
|
|
340
|
-
ready: boolean;
|
|
341
|
-
lastErrorCode: string | null;
|
|
342
|
-
leaseHeld: boolean;
|
|
343
|
-
recordVersion: number;
|
|
344
|
-
}>;
|
|
345
|
-
reportAuthFailure(params: {
|
|
346
|
-
handle: string;
|
|
347
|
-
providerStatus: number;
|
|
348
|
-
recordVersion: number;
|
|
349
|
-
reporterSource: 'direct' | 'relay_status_field' | 'relay_message_parse';
|
|
350
|
-
}): Promise<void>;
|
|
351
|
-
close(): void;
|
|
352
|
-
};
|
|
353
|
-
type ResidentRecord = {
|
|
354
|
-
payload: {
|
|
355
|
-
access: string;
|
|
356
|
-
};
|
|
357
|
-
recordVersion: number;
|
|
358
|
-
expiresAtMs: number;
|
|
359
|
-
servedAccountId?: string;
|
|
360
|
-
};
|
|
361
|
-
declare class ClaustrumCredentialCache {
|
|
362
|
-
#private;
|
|
363
|
-
constructor(options: ClaustrumCredentialCacheOptions);
|
|
364
|
-
/**
|
|
365
|
-
* Peek the resident record without I/O. Returns `undefined` if absent,
|
|
366
|
-
* including the case where the record was invalidated by `reportAuthFailure`.
|
|
367
|
-
*/
|
|
368
|
-
peek(handle: string): Promise<ResidentRecord | undefined>;
|
|
369
|
-
/**
|
|
370
|
-
* Public read-only view of a peek result. Exposes only the version and
|
|
371
|
-
* expiry — never the credential material — so a projection layer can
|
|
372
|
-
* surface a vault `recordVersion` without ever seeing a token.
|
|
373
|
-
*/
|
|
374
|
-
peekMetadata(handle: string): Promise<{
|
|
375
|
-
recordVersion: number;
|
|
376
|
-
expiresAtMs: number;
|
|
377
|
-
} | undefined>;
|
|
378
|
-
/**
|
|
379
|
-
* True iff a recent auth failure on this handle has been reported to the
|
|
380
|
-
* daemon. The blocked set is informational; the resolver still attempts a
|
|
381
|
-
* fetch on `get`, which clears the flag on success.
|
|
382
|
-
*/
|
|
383
|
-
isBlocked(handle: string): boolean;
|
|
384
|
-
/**
|
|
385
|
-
* True iff the bound-and-reauth fence has fired for this handle and the
|
|
386
|
-
* reauth window has not yet elapsed. Callers that project "needs reauth"
|
|
387
|
-
* UI should gate on this. The fence clears after a proven 2xx vault request
|
|
388
|
-
* or when the reauth window expires.
|
|
389
|
-
*/
|
|
390
|
-
isReauth(handle: string, now?: number): boolean;
|
|
391
|
-
markVaultSuccess(handle: string): void;
|
|
392
|
-
/**
|
|
393
|
-
* Get the live resident record. If a live record exists and the caller
|
|
394
|
-
* did not pass `force:true`, it returns immediately (no daemon I/O).
|
|
395
|
-
* Otherwise it issues a single-flight `getCredential` call.
|
|
396
|
-
*
|
|
397
|
-
* `force:true` ALWAYS issues a new daemon call (it bypasses both the
|
|
398
|
-
* resident record and any pending in-flight that originated from a
|
|
399
|
-
* non-force caller). Two concurrent force:true calls share the same
|
|
400
|
-
* new in-flight promise, so the second and subsequent force:true verifies
|
|
401
|
-
* collapse onto the first one. A non-force caller issued while a
|
|
402
|
-
* force:true fetch is pending still joins that force-fetch in-flight —
|
|
403
|
-
* the cache never races two parallel daemon calls for the same handle.
|
|
404
|
-
*/
|
|
405
|
-
get(handle: string, minTtlMs?: number, options?: {
|
|
406
|
-
force?: boolean;
|
|
407
|
-
}): Promise<ResidentRecord>;
|
|
408
|
-
/**
|
|
409
|
-
* Report an upstream auth failure on a served record. The report is
|
|
410
|
-
* version-fenced (one report per handle per recordVersion), and after
|
|
411
|
-
* two reports on the same version a one-hour bound fires — the third
|
|
412
|
-
* and subsequent reports on the same version are suppressed, and the
|
|
413
|
-
* handle is moved into the `reauth` set for an hour. A proven 2xx vault
|
|
414
|
-
* request or expiry of that window clears the bound and reauth entry.
|
|
415
|
-
*
|
|
416
|
-
* The reported version is invalidated from the resident record in
|
|
417
|
-
* `finally`, so a follow-up `get` cannot accidentally serve the same
|
|
418
|
-
* version the daemon already rejected.
|
|
419
|
-
*/
|
|
420
|
-
reportAuthFailure(params: {
|
|
421
|
-
handle: string;
|
|
422
|
-
providerStatus: number;
|
|
423
|
-
recordVersion: number;
|
|
424
|
-
}): Promise<void>;
|
|
425
|
-
close(): void;
|
|
426
|
-
}
|
|
427
|
-
type CompleteEnrollmentDeps = {
|
|
428
|
-
loadAccounts: typeof loadAccounts;
|
|
429
|
-
readCustodyManifest: (path?: string) => Promise<CustodyManifestReadResult>;
|
|
430
|
-
acquireRefreshFileLock: typeof acquireRefreshFileLock;
|
|
431
|
-
configPath: string;
|
|
432
|
-
paths: AccountPaths;
|
|
433
|
-
manifestPath?: string;
|
|
434
|
-
cache: ClaustrumCredentialCache;
|
|
435
|
-
/** Minimum TTL (ms) handed to the vault for the verify-get. */
|
|
436
|
-
minTtlMs: number;
|
|
437
|
-
/**
|
|
438
|
-
* Read-modify-write the account store. The sweep calls this once on a
|
|
439
|
-
* successful verify, setting empty `access`, sentinel `refresh`, and
|
|
440
|
-
* `expires = 0` — that single write is the only durable effect.
|
|
441
|
-
*/
|
|
442
|
-
mutateAccounts: typeof mutateAccounts;
|
|
443
|
-
/** Provider name; defaults to the owning provider (openai). */
|
|
444
|
-
provider?: string;
|
|
445
|
-
/** Caller-supplied clock so tests can drive the boot/hour log dedupe. */
|
|
446
|
-
now?: () => number;
|
|
447
|
-
};
|
|
448
|
-
//#endregion
|
|
449
|
-
//#region ../core/dist/paths.d.ts
|
|
450
|
-
/**
|
|
451
|
-
* The config file and the runtime-state file a store operation reads and writes.
|
|
452
|
-
*
|
|
453
|
-
* Both are required. A store function never derives one from the other, because
|
|
454
|
-
* a host may point its state file somewhere the derivation would not reach and
|
|
455
|
-
* a silently derived path would lock one file while writing another.
|
|
456
|
-
*/
|
|
457
|
-
interface AccountPaths {
|
|
458
|
-
configPath: string;
|
|
459
|
-
statePath: string;
|
|
460
|
-
}
|
|
461
|
-
//#endregion
|
|
462
|
-
//#region ../core/dist/accounts.d.ts
|
|
463
|
-
type AccountQuotaWindow = {
|
|
464
|
-
usedPercent: number;
|
|
465
|
-
remainingPercent: number;
|
|
466
|
-
resetsAt?: string;
|
|
467
|
-
checkedAt: number;
|
|
468
|
-
windowMinutes?: number;
|
|
469
|
-
};
|
|
470
|
-
interface OAuthQuotaSnapshot {
|
|
471
|
-
primary?: AccountQuotaWindow;
|
|
472
|
-
secondary?: AccountQuotaWindow;
|
|
473
|
-
resetCreditsAvailable?: number;
|
|
474
|
-
resetCreditsApplicable?: number;
|
|
475
|
-
spendControl?: OAuthSpendControlReading;
|
|
476
|
-
/**
|
|
477
|
-
* Set when the source explicitly reported that the account has no credit
|
|
478
|
-
* budget (wham's `spend_control` or `individual_limit` is null). An absent
|
|
479
|
-
* `spendControl` alone only means the source did not carry the field: header
|
|
480
|
-
* and WebSocket pushes never do, so merges keep the previous budget for them.
|
|
481
|
-
* This marker is what lets a merge drop a budget that no longer exists.
|
|
482
|
-
*/
|
|
483
|
-
spendControlCleared?: true;
|
|
484
|
-
credits?: OAuthCredits;
|
|
485
|
-
}
|
|
486
|
-
interface OAuthSpendControlReading {
|
|
487
|
-
limit: number;
|
|
488
|
-
used: number;
|
|
489
|
-
remaining: number;
|
|
490
|
-
usedPercent: number;
|
|
491
|
-
remainingPercent: number;
|
|
492
|
-
resetsAt?: string;
|
|
493
|
-
unit?: string;
|
|
494
|
-
source?: string;
|
|
495
|
-
reached: boolean;
|
|
496
|
-
}
|
|
497
|
-
interface OAuthCredits {
|
|
498
|
-
hasCredits: boolean;
|
|
499
|
-
unlimited: boolean;
|
|
500
|
-
overageLimitReached: boolean;
|
|
501
|
-
balance?: number;
|
|
502
|
-
}
|
|
503
|
-
type AccountBase = {
|
|
504
|
-
id: string;
|
|
505
|
-
label?: string;
|
|
506
|
-
enabled?: boolean;
|
|
507
|
-
addedAt?: number;
|
|
508
|
-
lastUsed?: number;
|
|
509
|
-
/** Stable ChatGPT account identifier extracted from the OAuth token claims. */
|
|
510
|
-
accountId?: string;
|
|
511
|
-
};
|
|
512
|
-
type AccountOperationError = {
|
|
513
|
-
message: string;
|
|
514
|
-
checkedAt: number;
|
|
515
|
-
nextRetryAt?: number;
|
|
516
|
-
retryCount?: number;
|
|
517
|
-
tokenHash?: string;
|
|
518
|
-
};
|
|
519
|
-
type OAuthAccount = AccountBase & {
|
|
520
|
-
type: 'oauth';
|
|
521
|
-
corrupt?: false;
|
|
522
|
-
access?: string;
|
|
523
|
-
refresh: string;
|
|
524
|
-
expires?: number;
|
|
525
|
-
lastRefreshedAt?: number;
|
|
526
|
-
lastRefreshError?: AccountOperationError;
|
|
527
|
-
lastQuotaRefreshError?: AccountOperationError;
|
|
528
|
-
quota?: OAuthQuotaSnapshot;
|
|
529
|
-
};
|
|
530
|
-
type CorruptOAuthAccount = AccountBase & {
|
|
531
|
-
type: 'oauth';
|
|
532
|
-
corrupt: true;
|
|
533
|
-
access?: undefined;
|
|
534
|
-
refresh?: undefined;
|
|
535
|
-
expires?: undefined;
|
|
536
|
-
lastRefreshedAt?: undefined;
|
|
537
|
-
lastRefreshError?: undefined;
|
|
538
|
-
lastQuotaRefreshError?: undefined;
|
|
539
|
-
quota?: undefined;
|
|
540
|
-
};
|
|
541
|
-
type ApiKeyAccount = AccountBase & {
|
|
542
|
-
type: 'api';
|
|
543
|
-
apiKey?: string;
|
|
544
|
-
baseURL: string;
|
|
545
|
-
authHeader?: 'authorization-bearer' | 'x-api-key';
|
|
546
|
-
};
|
|
547
|
-
type FallbackAccount = OAuthAccount | CorruptOAuthAccount | ApiKeyAccount;
|
|
548
|
-
type RoutingMode = 'main-first' | 'fallback-first' | 'sticky-balanced';
|
|
549
|
-
type KillswitchThresholds = Partial<Record<QuotaWindowName | '5h' | '1w', number>>;
|
|
550
|
-
type KillswitchConfig = {
|
|
551
|
-
enabled?: boolean;
|
|
552
|
-
main?: KillswitchThresholds;
|
|
553
|
-
accounts?: Record<string, KillswitchThresholds>;
|
|
554
|
-
};
|
|
555
|
-
interface ResetInFlight {
|
|
556
|
-
redeemRequestId: string;
|
|
557
|
-
creditId: string;
|
|
558
|
-
startedAt: number;
|
|
559
|
-
}
|
|
560
|
-
interface ResetLastOutcome {
|
|
561
|
-
code: string;
|
|
562
|
-
at: number;
|
|
563
|
-
previousOutcome?: {
|
|
564
|
-
code: string;
|
|
565
|
-
at: number;
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
interface ResetAccountState {
|
|
569
|
-
inFlight?: ResetInFlight | Record<string, unknown>;
|
|
570
|
-
lastOutcome?: ResetLastOutcome;
|
|
571
|
-
cooldownUntil?: number;
|
|
572
|
-
}
|
|
573
|
-
type ResetStateByAccount = Record<string, ResetAccountState>;
|
|
574
|
-
type AccountStorage = {
|
|
575
|
-
version: 1;
|
|
576
|
-
main?: {
|
|
577
|
-
type: 'opencode';
|
|
578
|
-
provider: 'openai';
|
|
579
|
-
};
|
|
580
|
-
routing?: {
|
|
581
|
-
mode?: RoutingMode;
|
|
582
|
-
};
|
|
583
|
-
fallbackOn?: number[];
|
|
584
|
-
refresh?: {
|
|
585
|
-
enabled?: boolean;
|
|
586
|
-
refreshBeforeExpiryMinutes?: number;
|
|
587
|
-
mainLastRefreshError?: AccountOperationError;
|
|
588
|
-
mainRefreshLeaseId?: string;
|
|
589
|
-
mainRefreshLeaseUntil?: number;
|
|
590
|
-
mainRefreshLeaseTokenHash?: string;
|
|
591
|
-
};
|
|
592
|
-
quota?: {
|
|
593
|
-
enabled?: boolean;
|
|
594
|
-
checkIntervalMinutes?: number;
|
|
595
|
-
refreshEveryNRequests?: number;
|
|
596
|
-
minimumRemaining?: Partial<Record<QuotaWindowName | '5h' | '1w', number>>;
|
|
597
|
-
failClosedOnUnknownQuota?: boolean;
|
|
598
|
-
mainQuota?: OAuthQuotaSnapshot;
|
|
599
|
-
mainQuotaCheckedAt?: number;
|
|
600
|
-
mainQuotaToken?: string;
|
|
601
|
-
mainLastQuotaApiError?: AccountOperationError;
|
|
602
|
-
};
|
|
603
|
-
reset?: ResetStateByAccount;
|
|
604
|
-
dump?: {
|
|
605
|
-
enabled?: boolean;
|
|
606
|
-
};
|
|
607
|
-
costZeroing?: {
|
|
608
|
-
enabled?: boolean;
|
|
609
|
-
};
|
|
610
|
-
killswitch?: KillswitchConfig;
|
|
611
|
-
logging?: {
|
|
612
|
-
level?: string;
|
|
613
|
-
};
|
|
614
|
-
cachekeep?: {
|
|
615
|
-
enabled?: boolean;
|
|
616
|
-
subagents?: boolean;
|
|
617
|
-
sustain?: boolean;
|
|
618
|
-
/** Clock-hour window start (0-23, inclusive) — keeps cachekeep idle warming
|
|
619
|
-
* inside `[startHour, endHour)` local hours. Omit to warm unconditionally. */
|
|
620
|
-
startHour?: number;
|
|
621
|
-
/** Clock-hour window end (0-23, exclusive) — must differ from startHour
|
|
622
|
-
* to be honored; an unset or equal hour falls back to "always warm". */
|
|
623
|
-
endHour?: number;
|
|
624
|
-
};
|
|
625
|
-
/** Stable ChatGPT account identifier of the main account (extracted from OAuth token). */
|
|
626
|
-
mainAccountId?: string;
|
|
627
|
-
claustrum?: {
|
|
628
|
-
mode?: ClaustrumMode;
|
|
629
|
-
transition?: CustodyTransitionState;
|
|
630
|
-
rowHistory?: string[];
|
|
631
|
-
};
|
|
632
|
-
accounts: FallbackAccount[];
|
|
633
|
-
};
|
|
634
|
-
declare function loadAccounts(paths: AccountPaths): Promise<AccountStorage | null>;
|
|
635
|
-
type AccountStoreTransaction = {
|
|
636
|
-
read(): Promise<AccountStorage>;
|
|
637
|
-
write(storage: AccountStorage): Promise<void>;
|
|
638
|
-
writeMode(mode: ClaustrumMode, transition?: CustodyTransitionState): Promise<void>;
|
|
639
|
-
};
|
|
640
|
-
declare function withAccountStoreTransaction<T>(action: (transaction: AccountStoreTransaction) => Promise<T>, paths: AccountPaths): Promise<T>;
|
|
641
|
-
/**
|
|
642
|
-
* Read-modify-write the account store atomically under the save lock.
|
|
643
|
-
*
|
|
644
|
-
* Unlike saveAccounts (which UNION-merges the incoming accounts with the latest
|
|
645
|
-
* on-disk set so concurrent ADDS from another process are never lost), this
|
|
646
|
-
* reads the freshest state under the lock and writes the mutator's result
|
|
647
|
-
* AUTHORITATIVELY — no union. That is required for structural edits (remove,
|
|
648
|
-
* reorder): a union cannot express a deletion (the removed id reappears from
|
|
649
|
-
* `latest`) or a reordering (the union is seeded latest-first). Because the
|
|
650
|
-
* mutator runs against freshly-read state under the lock, an add committed by a
|
|
651
|
-
* concurrent process is still visible to it and preserved.
|
|
652
|
-
*
|
|
653
|
-
* The mutator may edit `current` in place and return it, or return a new
|
|
654
|
-
* storage object. Returning undefined means "no change" and still rewrites the
|
|
655
|
-
* freshly-read state (a harmless idempotent write).
|
|
656
|
-
*
|
|
657
|
-
* Load-time drop preservation: if normalizeAccount (called inside
|
|
658
|
-
* normalizeStorage) rejects an account whose id IS in the raw config roster,
|
|
659
|
-
* the previous behavior would erase that id silently on the next write. This
|
|
660
|
-
* function now carries the dropped raw entry through to the written config
|
|
661
|
-
* verbatim, so the on-disk state always matches the operator's intent (an
|
|
662
|
-
* account they added, even if temporarily un-loadable, stays in their list
|
|
663
|
-
* until they deliberately remove it).
|
|
664
|
-
*
|
|
665
|
-
* Removal seam: when the caller knows they are removing an id (e.g. the CLI
|
|
666
|
-
* `remove` command) and that id may be load-dropped — in which case the
|
|
667
|
-
* mutator cannot find it in `current.accounts` to splice it — the caller can
|
|
668
|
-
* pass `options.allowDrop: [id]`. Ids in `allowDrop` are NOT preserved; the
|
|
669
|
-
* mutator's splice still no-ops on a dropped id, but the absence of
|
|
670
|
-
* preservation completes the removal end-to-end.
|
|
671
|
-
*/
|
|
672
|
-
interface MutateAccountsContext {
|
|
673
|
-
/** Valid string ids read from the raw config while both store locks are held. */
|
|
674
|
-
rawRosterIds: readonly string[];
|
|
675
|
-
/** Ids retained after normalization and validation, before the mutator ran. */
|
|
676
|
-
loadedRosterIds: readonly string[];
|
|
677
|
-
}
|
|
678
|
-
declare function mutateAccounts(mutate: (current: AccountStorage, context?: MutateAccountsContext) => AccountStorage | undefined, paths: AccountPaths, options?: {
|
|
679
|
-
allowDrop?: readonly string[];
|
|
680
|
-
}): Promise<AccountStorage>;
|
|
681
|
-
//#endregion
|
|
682
|
-
//#region ../core/dist/oauth.d.ts
|
|
683
|
-
interface IdTokenClaims {
|
|
684
|
-
chatgpt_account_id?: string;
|
|
685
|
-
email?: string;
|
|
686
|
-
organizations?: Array<{
|
|
687
|
-
id: string;
|
|
688
|
-
}>;
|
|
689
|
-
'https://api.openai.com/auth'?: {
|
|
690
|
-
chatgpt_account_id?: string;
|
|
691
|
-
};
|
|
692
|
-
}
|
|
693
|
-
declare function parseJwtClaims(token: string): IdTokenClaims | undefined;
|
|
694
|
-
declare function extractAccountIdFromClaims(claims: IdTokenClaims): string | undefined;
|
|
695
|
-
interface TokenResponse {
|
|
696
|
-
id_token: string;
|
|
697
|
-
access_token: string;
|
|
698
|
-
refresh_token: string;
|
|
699
|
-
expires_in?: number;
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* Minimal shape of a fallback OAuth account for ingestion. Matches the
|
|
703
|
-
* fields used by upsertAccount and beginAccountLogin, compatible with
|
|
704
|
-
* the full OAuthAccount type in accounts.ts.
|
|
705
|
-
*/
|
|
706
|
-
interface IngestAccount {
|
|
707
|
-
id: string;
|
|
708
|
-
label?: string;
|
|
709
|
-
type: 'oauth';
|
|
710
|
-
access?: string;
|
|
711
|
-
refresh: string;
|
|
712
|
-
expires?: number;
|
|
713
|
-
enabled: boolean;
|
|
714
|
-
addedAt: number;
|
|
715
|
-
lastUsed: number;
|
|
716
|
-
/**
|
|
717
|
-
* When the token was obtained. Stamped at login so a freshly added account
|
|
718
|
-
* carries a refresh marker — without it, the runtime-state merge cannot tell a
|
|
719
|
-
* rotated token from a stale one (both default to 0) and a concurrent stale
|
|
720
|
-
* save could roll the token back.
|
|
721
|
-
*/
|
|
722
|
-
lastRefreshedAt?: number;
|
|
723
|
-
/** Stable ChatGPT account identifier from the OAuth token claims. */
|
|
724
|
-
accountId?: string;
|
|
725
|
-
}
|
|
726
|
-
interface BeginAccountLoginOptions {
|
|
727
|
-
label?: string;
|
|
728
|
-
headless?: boolean;
|
|
729
|
-
signal?: AbortSignal;
|
|
730
|
-
/** Host package version, sent as the version half of the `User-Agent`. */
|
|
731
|
-
version: string;
|
|
732
|
-
}
|
|
733
|
-
interface BeginAccountLoginResult {
|
|
734
|
-
url: string;
|
|
735
|
-
instructions: string;
|
|
736
|
-
/** Resolves after the user completes the OAuth flow with a ready-to-ingest account. */
|
|
737
|
-
completion: Promise<IngestAccount>;
|
|
738
|
-
}
|
|
739
|
-
/**
|
|
740
|
-
* Split-return OAuth flow entry point.
|
|
741
|
-
*
|
|
742
|
-
* Browser flow (default):
|
|
743
|
-
* 1. Start OAuth server, generate PKCE, build authorize URL
|
|
744
|
-
* 2. Return { url, instructions, completion } — url is ready immediately
|
|
745
|
-
* 3. completion resolves after browser callback + token exchange
|
|
746
|
-
*
|
|
747
|
-
* Headless flow:
|
|
748
|
-
* 1. Begin device auth
|
|
749
|
-
* 2. Return { url, instructions, completion }
|
|
750
|
-
* 3. completion polls device endpoint + exchanges for tokens
|
|
751
|
-
*
|
|
752
|
-
* The split return allows the TUI command to show the URL before the
|
|
753
|
-
* (potentially 30-60s) wait, avoiding a deadlock.
|
|
754
|
-
*/
|
|
755
|
-
declare function beginAccountLogin(opts: BeginAccountLoginOptions): Promise<BeginAccountLoginResult>;
|
|
756
|
-
//#endregion
|
|
757
|
-
//#region ../core/dist/protocol.d.ts
|
|
758
|
-
type CommandModalName = 'openai-quota' | 'openai-account' | 'openai-routing' | 'openai-killswitch' | 'openai-dump' | 'openai-logging' | 'openai-cachekeep' | 'openai-reset';
|
|
759
|
-
interface OpenDialogPayload {
|
|
760
|
-
command: CommandModalName;
|
|
761
|
-
text: string;
|
|
762
|
-
knobs: Record<string, unknown>;
|
|
763
|
-
}
|
|
764
|
-
interface RpcNotification {
|
|
765
|
-
id: number;
|
|
766
|
-
type: 'open-dialog';
|
|
767
|
-
payload: OpenDialogPayload;
|
|
768
|
-
sessionId?: string;
|
|
769
|
-
}
|
|
770
|
-
interface ApplyRequest {
|
|
771
|
-
command: CommandModalName;
|
|
772
|
-
arguments: string;
|
|
773
|
-
sessionId?: string;
|
|
774
|
-
}
|
|
775
|
-
interface ApplyResult {
|
|
776
|
-
text: string;
|
|
777
|
-
knobs: Record<string, unknown>;
|
|
778
|
-
}
|
|
779
|
-
//#endregion
|
|
780
|
-
//#region ../core/dist/refresh-all-quota.d.ts
|
|
781
|
-
interface RefreshAllQuotaResult {
|
|
782
|
-
account: string;
|
|
783
|
-
ok: boolean;
|
|
784
|
-
error?: string;
|
|
785
|
-
/**
|
|
786
|
-
* The account cannot recover on its own: the provider has rejected its
|
|
787
|
-
* credentials, so no amount of retrying will help until the operator re-adds
|
|
788
|
-
* it.
|
|
789
|
-
*
|
|
790
|
-
* Carried as a flag rather than left for the caller to infer from `error`,
|
|
791
|
-
* because sniffing an error string for a user-facing decision breaks the
|
|
792
|
-
* moment the wording changes.
|
|
793
|
-
*/
|
|
794
|
-
permanent?: boolean;
|
|
795
|
-
}
|
|
796
|
-
//#endregion
|
|
797
|
-
//#region ../core/dist/commands.d.ts
|
|
798
|
-
/**
|
|
799
|
-
* The prompt-cache manager, as the commands use it.
|
|
800
|
-
*
|
|
801
|
-
* Declared structurally rather than imported: the manager itself is tied to one
|
|
802
|
-
* host's live request loader and stays there. Only the members reached through
|
|
803
|
-
* this field appear here — a status snapshot, the two lifecycle calls the
|
|
804
|
-
* cachekeep command makes, and the per-session drop the host performs when a
|
|
805
|
-
* session ends.
|
|
806
|
-
*/
|
|
807
|
-
interface CacheKeepManager {
|
|
808
|
-
status(): {
|
|
809
|
-
running: boolean;
|
|
810
|
-
sustain: boolean;
|
|
811
|
-
window?: {
|
|
812
|
-
startHour: number;
|
|
813
|
-
endHour: number;
|
|
814
|
-
} | undefined;
|
|
815
|
-
tracked: number;
|
|
816
|
-
generatedAt: number;
|
|
817
|
-
ttlMs: number;
|
|
818
|
-
leadMs: number;
|
|
819
|
-
maxIdleWarmMs: number;
|
|
820
|
-
maxSubagentIdleMs: number;
|
|
821
|
-
targets: ReadonlyArray<{
|
|
822
|
-
sessionKey: string;
|
|
823
|
-
accountId?: string;
|
|
824
|
-
cacheExpiresAt: number;
|
|
825
|
-
lastWarmedAt?: number;
|
|
826
|
-
backoffUntil?: number;
|
|
827
|
-
}>;
|
|
828
|
-
};
|
|
829
|
-
start(): void;
|
|
830
|
-
stop(): void;
|
|
831
|
-
remove(sessionKey: string): void;
|
|
832
|
-
}
|
|
833
|
-
interface CommandContext {
|
|
834
|
-
accountStoragePath: string;
|
|
835
|
-
/**
|
|
836
|
-
* Runtime-state file that goes with `accountStoragePath`. Required, and
|
|
837
|
-
* resolved by the host: nothing here derives one path from the other.
|
|
838
|
-
*/
|
|
839
|
-
accountStatePath: string;
|
|
840
|
-
/** Host package version, sent as the version half of the OAuth `User-Agent`. */
|
|
841
|
-
packageVersion: string;
|
|
842
|
-
quotaManager: QuotaManager;
|
|
843
|
-
loadAccounts: typeof loadAccounts;
|
|
844
|
-
client: {
|
|
845
|
-
auth: {
|
|
846
|
-
set: (input: {
|
|
847
|
-
path: {
|
|
848
|
-
id: string;
|
|
849
|
-
};
|
|
850
|
-
body: {
|
|
851
|
-
type: string;
|
|
852
|
-
access?: string;
|
|
853
|
-
refresh: string;
|
|
854
|
-
expires?: number;
|
|
855
|
-
};
|
|
856
|
-
}) => Promise<unknown>;
|
|
857
|
-
};
|
|
858
|
-
};
|
|
859
|
-
/** Session ID for pushNotification delivery. */
|
|
860
|
-
sessionId?: string;
|
|
861
|
-
/** If set, pushNotification is wired up and can deliver feedback to the user. */
|
|
862
|
-
notify?: (payload: OpenDialogPayload) => void;
|
|
863
|
-
/** Refresh the sidebar-state file so the TUI modal shows current data. */
|
|
864
|
-
refreshSidebar?: () => Promise<void>;
|
|
865
|
-
/** Actively poll wham/usage for all accounts (main + fallbacks). */
|
|
866
|
-
refreshAllQuota?: () => Promise<RefreshAllQuotaResult[]>;
|
|
867
|
-
/** Prompt-cache cachekeep manager. Set when the command is wired. */
|
|
868
|
-
cacheKeepManager?: CacheKeepManager | null;
|
|
869
|
-
/** Updates the live loader's persisted-enabled cachekeep gate. */
|
|
870
|
-
setCacheKeepEnabled?: (enabled: boolean) => void;
|
|
871
|
-
/** Updates the live loader's persisted-subagent cachekeep gate. */
|
|
872
|
-
setCacheKeepSubagents?: (enabled: boolean) => void;
|
|
873
|
-
/** Updates the live loader's main-agent idle-cap bypass gate. */
|
|
874
|
-
setCacheKeepSustain?: (enabled: boolean) => void;
|
|
875
|
-
/** Updates the live loader's clock-hour warm window. undefined = no window. */
|
|
876
|
-
setCacheKeepWindow?: (window: {
|
|
877
|
-
startHour: number;
|
|
878
|
-
endHour: number;
|
|
879
|
-
} | undefined) => void;
|
|
880
|
-
/** Clears only the sticky account assignment for one OpenCode session. */
|
|
881
|
-
clearStickyRouting?: (sessionId: string) => Promise<boolean>;
|
|
882
|
-
/** Resolves the current session's usable sticky account, if one exists. */
|
|
883
|
-
getStickyRouting?: (sessionId: string) => Promise<string | undefined>;
|
|
884
|
-
resolveResetTarget?: (accountKey: string) => Promise<ResetTargetIdentity>;
|
|
885
|
-
fetchImpl?: typeof fetch;
|
|
886
|
-
now?: () => number;
|
|
887
|
-
randomUUID?: () => string;
|
|
888
|
-
/** Starts an OAuth account-add flow; injected by the runtime boundary. */
|
|
889
|
-
beginAccountLogin?: typeof beginAccountLogin;
|
|
890
|
-
refreshResetTargetQuota?: (accountKey: string) => Promise<RefreshAllQuotaResult>;
|
|
891
|
-
enterClaustrumMode?: () => Promise<{
|
|
892
|
-
status: 'completed' | 'incomplete' | 'aborted';
|
|
893
|
-
outcomes: Record<string, string>;
|
|
894
|
-
reason?: string;
|
|
895
|
-
}>;
|
|
896
|
-
leaveClaustrumMode?: () => Promise<void>;
|
|
897
|
-
withFallbackAccountLock?: <T>(accountId: string, action: () => Promise<T>) => Promise<T>;
|
|
898
|
-
checkUsableCustodyBinding?: (account: OAuthAccount) => Promise<{
|
|
899
|
-
ready: true;
|
|
900
|
-
accountId: string;
|
|
901
|
-
} | {
|
|
902
|
-
ready: false;
|
|
903
|
-
reason: string;
|
|
904
|
-
}>;
|
|
905
|
-
}
|
|
906
|
-
interface ResetTargetIdentity {
|
|
907
|
-
accountKey: string;
|
|
908
|
-
label: string;
|
|
909
|
-
accessToken: string;
|
|
910
|
-
chatgptAccountId?: string;
|
|
911
|
-
onAuthFailure?: (status: number) => Promise<void>;
|
|
912
|
-
}
|
|
913
|
-
//#endregion
|
|
914
|
-
export { CustodyManifestIo as C, detectClaustrumConnection as E, acquireRefreshFileLock as S, QuotaManager as T, loadAccounts as _, CommandModalName as a, ClaustrumCredentialCache as b, IdTokenClaims as c, parseJwtClaims as d, AccountStorage as f, OAuthQuotaSnapshot as g, OAuthAccount as h, ApplyResult as i, TokenResponse as l, FallbackAccount as m, ResetTargetIdentity as n, OpenDialogPayload as o, AccountStoreTransaction as p, ApplyRequest as r, RpcNotification as s, CommandContext as t, extractAccountIdFromClaims as u, mutateAccounts as v, CustodyManifestReadResult as w, resolveFallbackAccess as x, withAccountStoreTransaction as y };
|