@eddyskywalker/dsh-chatgpt-subscription 0.8.5 → 0.9.2
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/CHANGELOG.md +44 -0
- package/README.md +94 -38
- package/lib/client.js +2126 -1693
- package/lib/client.js.map +1 -1
- package/lib/index.js +7935 -2956
- package/lib/types/client/claude/ClaudeComposerQuota.d.ts +33 -0
- package/lib/types/client/claude/ClaudeComposerQuota.d.ts.map +1 -0
- package/lib/types/client/{zhipu/ZhipuSection.d.ts → claude/ClaudeSection.d.ts} +2 -2
- package/lib/types/client/claude/ClaudeSection.d.ts.map +1 -0
- package/lib/types/client/claude/locales.d.ts +444 -0
- package/lib/types/client/claude/locales.d.ts.map +1 -0
- package/lib/types/client/claude/styles.d.ts +15 -0
- package/lib/types/client/claude/styles.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/host/claude/__probe-assert.d.ts +2 -0
- package/lib/types/host/claude/__probe-assert.d.ts.map +1 -0
- package/lib/types/host/claude/account-pool.d.ts +580 -0
- package/lib/types/host/claude/account-pool.d.ts.map +1 -0
- package/lib/types/host/claude/adapter.d.ts +267 -0
- package/lib/types/host/claude/adapter.d.ts.map +1 -0
- package/lib/types/host/claude/adopt.d.ts +292 -0
- package/lib/types/host/claude/adopt.d.ts.map +1 -0
- package/lib/types/host/claude/client.d.ts +513 -0
- package/lib/types/host/claude/client.d.ts.map +1 -0
- package/lib/types/host/claude/mapper.d.ts +510 -0
- package/lib/types/host/claude/mapper.d.ts.map +1 -0
- package/lib/types/host/claude/model-catalog.d.ts +365 -0
- package/lib/types/host/claude/model-catalog.d.ts.map +1 -0
- package/lib/types/host/claude/oauth.d.ts +393 -0
- package/lib/types/host/claude/oauth.d.ts.map +1 -0
- package/lib/types/host/claude/routes.d.ts +128 -0
- package/lib/types/host/claude/routes.d.ts.map +1 -0
- package/lib/types/host/claude/token-store.d.ts +312 -0
- package/lib/types/host/claude/token-store.d.ts.map +1 -0
- package/lib/types/host/claude/types.d.ts +237 -0
- package/lib/types/host/claude/types.d.ts.map +1 -0
- package/lib/types/host/common/account-pool.d.ts +40 -0
- package/lib/types/host/common/account-pool.d.ts.map +1 -1
- package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
- package/lib/types/host/kimi-code/client.d.ts +28 -0
- package/lib/types/host/kimi-code/client.d.ts.map +1 -1
- package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
- package/lib/types/index.d.ts +10 -7
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/__probe-claude-import.d.ts +2 -0
- package/lib/types/shared/__probe-claude-import.d.ts.map +1 -0
- package/lib/types/shared/claude-contracts.d.ts +337 -0
- package/lib/types/shared/claude-contracts.d.ts.map +1 -0
- package/package.json +1 -1
- package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts +0 -26
- package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts.map +0 -1
- package/lib/types/client/zhipu/ZhipuSection.d.ts.map +0 -1
- package/lib/types/client/zhipu/locales.d.ts +0 -275
- package/lib/types/client/zhipu/locales.d.ts.map +0 -1
- package/lib/types/client/zhipu/styles.d.ts +0 -12
- package/lib/types/client/zhipu/styles.d.ts.map +0 -1
- package/lib/types/host/zhipu/account-pool.d.ts +0 -43
- package/lib/types/host/zhipu/account-pool.d.ts.map +0 -1
- package/lib/types/host/zhipu/adapter.d.ts +0 -93
- package/lib/types/host/zhipu/adapter.d.ts.map +0 -1
- package/lib/types/host/zhipu/client.d.ts +0 -153
- package/lib/types/host/zhipu/client.d.ts.map +0 -1
- package/lib/types/host/zhipu/mapper.d.ts +0 -111
- package/lib/types/host/zhipu/mapper.d.ts.map +0 -1
- package/lib/types/host/zhipu/model-catalog.d.ts +0 -73
- package/lib/types/host/zhipu/model-catalog.d.ts.map +0 -1
- package/lib/types/host/zhipu/routes.d.ts +0 -33
- package/lib/types/host/zhipu/routes.d.ts.map +0 -1
- package/lib/types/host/zhipu/token-store.d.ts +0 -112
- package/lib/types/host/zhipu/token-store.d.ts.map +0 -1
- package/lib/types/host/zhipu/types.d.ts +0 -125
- package/lib/types/host/zhipu/types.d.ts.map +0 -1
- package/lib/types/shared/zhipu-contracts.d.ts +0 -164
- package/lib/types/shared/zhipu-contracts.d.ts.map +0 -1
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude subscription OAuth sign-in.
|
|
3
|
+
*
|
|
4
|
+
* WHO THIS FILE IS FOR, AND WHAT IT ASSUMES ABOUT UPSTREAM.
|
|
5
|
+
*
|
|
6
|
+
* This module drives the browser sign-in that turns a Claude Pro/Max account
|
|
7
|
+
* into a credential this provider can call /v1/messages with. The wire facts it
|
|
8
|
+
* relies on — authorization endpoint, token endpoint, client id, scope set, the
|
|
9
|
+
* manual-paste redirect URI, the default callback port, the login timeout — all
|
|
10
|
+
* live in the frozen sibling 'types.ts' and are imported from there rather than
|
|
11
|
+
* restated here: one fact, one home.
|
|
12
|
+
*
|
|
13
|
+
* Everything this module could NOT verify is called out inline and collected
|
|
14
|
+
* again in the ASSUMPTIONS block at the bottom of this comment. Treat each one
|
|
15
|
+
* as a claim a later reviewer may need to re-check against the live
|
|
16
|
+
* authorization host: a locally installed reference implementation is an
|
|
17
|
+
* artifact, not a specification.
|
|
18
|
+
*
|
|
19
|
+
* ---------------------------------------------------------------------------
|
|
20
|
+
* WHY THIS IS NOT A COPY OF THE REFERENCE
|
|
21
|
+
* ---------------------------------------------------------------------------
|
|
22
|
+
*
|
|
23
|
+
* The locally installed reference ('@earendil-works/pi-ai',
|
|
24
|
+
* dist/auth/oauth/anthropic.js line 209) sets 'state: verifier' — it reuses the
|
|
25
|
+
* PKCE code verifier AS the OAuth state. That puts the verifier in a URL (the
|
|
26
|
+
* authorize URL, the address bar, browser history, and in the manual flow the
|
|
27
|
+
* clipboard) while the verifier is the one value that is supposed to stay
|
|
28
|
+
* inside this process: PKCE's whole security argument is that an attacker who
|
|
29
|
+
* can READ the authorization request still cannot redeem the code without the
|
|
30
|
+
* verifier. A leaked verifier plus a leaked code is a complete exchange, so
|
|
31
|
+
* this module draws the two values independently and never encodes the
|
|
32
|
+
* verifier anywhere a URL can carry it. 'test/claude-oauth.test.ts' asserts
|
|
33
|
+
* that property directly on the produced URL.
|
|
34
|
+
*
|
|
35
|
+
* ---------------------------------------------------------------------------
|
|
36
|
+
* WHY THE TWO MODES ARE TWO FLOWS
|
|
37
|
+
* ---------------------------------------------------------------------------
|
|
38
|
+
*
|
|
39
|
+
* An authorization code is bound to the redirect_uri of the request that issued
|
|
40
|
+
* it: the token endpoint compares the redirect_uri sent with the exchange
|
|
41
|
+
* against the one recorded with the code and rejects the request when they
|
|
42
|
+
* differ. "Which redirect URI is in the UI right now" is therefore not a value
|
|
43
|
+
* the exchange may read — it has to be the value recorded on the flow that
|
|
44
|
+
* produced the code. So each sign-in is a LoginFlow carrying its own
|
|
45
|
+
* { flowId, mode, redirectUri, verifier, state }, the mode is immutable for
|
|
46
|
+
* that flow's lifetime, and switching mode abandons the flow and starts a new
|
|
47
|
+
* one with fresh secrets. The exchange reads flow.redirectUri and nothing else,
|
|
48
|
+
* which is also what lets a test prove the two modes never share one request.
|
|
49
|
+
*
|
|
50
|
+
* ---------------------------------------------------------------------------
|
|
51
|
+
* ASSUMPTIONS (each one unverifiable from here)
|
|
52
|
+
* ---------------------------------------------------------------------------
|
|
53
|
+
*
|
|
54
|
+
* - A1. "The client registration permits arbitrary ports." The loopback flow
|
|
55
|
+
* hands the authorization host a redirect URI built from whatever port the
|
|
56
|
+
* probe resolves, on the theory that a public client registered for a
|
|
57
|
+
* loopback redirect accepts any port (RFC 8252 section 7.3 says it should,
|
|
58
|
+
* which is why the port of a loopback redirect is normally ignored). THIS IS
|
|
59
|
+
* AN ASSUMPTION, NOT A VERIFIED FACT: the registration belongs to Anthropic
|
|
60
|
+
* and nothing in this repository can read it. If it is false, the browser
|
|
61
|
+
* callback fails for every port except an exactly registered one — and the
|
|
62
|
+
* failure is recoverable, because the manual flow exists, the probe already
|
|
63
|
+
* degrades to it, and the card tells the user why.
|
|
64
|
+
* - A2. The token endpoint accepts the two JSON bodies written below, including
|
|
65
|
+
* 'state' in the authorization_code exchange. Both shapes are transcribed
|
|
66
|
+
* from the reference implementation; neither was exercised against a live
|
|
67
|
+
* account from here.
|
|
68
|
+
* - A3. A token response that omits 'refresh_token' means "keep the one you
|
|
69
|
+
* have" rather than "there is no refresh token". The reference stores the
|
|
70
|
+
* field unconditionally, which would overwrite a working refresh token with
|
|
71
|
+
* undefined; this module prefers the stored value. The two readings differ
|
|
72
|
+
* only in the case where one of them destroys the credential, and losing a
|
|
73
|
+
* rotating credential is unrecoverable without a fresh sign-in.
|
|
74
|
+
* - A4. 'expires_in' is seconds and the server keeps it inside
|
|
75
|
+
* [300, 31536000]. That clamp is the reference's own guard, transcribed; a
|
|
76
|
+
* response outside it is treated as malformed rather than trusted. The
|
|
77
|
+
* observable consequence of a grant narrower than reported is exactly what
|
|
78
|
+
* this module already handles: a 401 that forces a refresh, or a final
|
|
79
|
+
* verdict that forces a new sign-in.
|
|
80
|
+
* - A5. The account endpoint shape for 'account' ({uuid, email_address}) is the
|
|
81
|
+
* reference's; the fields are parsed defensively and are purely cosmetic.
|
|
82
|
+
* - A6. A browser that resolves 'localhost' to ::1 first will still reach a
|
|
83
|
+
* listener bound only to 127.0.0.1, because every mainstream browser falls
|
|
84
|
+
* back across address families (Happy Eyeballs, RFC 8305) when the first
|
|
85
|
+
* attempt is refused. The redirect URI comes from types.ts's
|
|
86
|
+
* loopbackRedirectUri(), which spells the authority 'localhost', while the
|
|
87
|
+
* listener is bound to the 127.0.0.1 literal — binding the wildcard address
|
|
88
|
+
* instead would expose a one-time authorization code to every interface on
|
|
89
|
+
* the machine, which is the worse failure.
|
|
90
|
+
*
|
|
91
|
+
* Corroborated rather than merely assumed: the reference implementation ships
|
|
92
|
+
* exactly this pairing — `CALLBACK_HOST = "127.0.0.1"` (anthropic.js:16) with
|
|
93
|
+
* `REDIRECT_URI = \`http://localhost:\${CALLBACK_PORT}\${CALLBACK_PATH}\`` (line 19).
|
|
94
|
+
* So 'localhost' in the advertised URI with a v4-literal bind is the combination
|
|
95
|
+
* a working client actually uses, and that is why this module keeps it instead
|
|
96
|
+
* of "fixing" the spelling to 127.0.0.1: the authority is also what the client
|
|
97
|
+
* is registered for, so changing it is the riskier edit, not the safer one.
|
|
98
|
+
* If a browser without the cross-family fallback ever matters, the fix belongs
|
|
99
|
+
* in types.ts and must be weighed against that registration.
|
|
100
|
+
*
|
|
101
|
+
* ---------------------------------------------------------------------------
|
|
102
|
+
* SECRET HYGIENE
|
|
103
|
+
* ---------------------------------------------------------------------------
|
|
104
|
+
*
|
|
105
|
+
* The authorization code, both tokens and the PKCE verifier never enter a
|
|
106
|
+
* status object, an error message, or a log line. Every error raised here names
|
|
107
|
+
* the CLASS of failure (and at most the HTTP status); none interpolates a
|
|
108
|
+
* credential. Tests assert this by searching the serialized status payload and
|
|
109
|
+
* the thrown messages for the secret material.
|
|
110
|
+
*/
|
|
111
|
+
import { type Server } from 'node:http';
|
|
112
|
+
/**
|
|
113
|
+
* The stored credential is OWNED by the sibling token-store module.
|
|
114
|
+
*
|
|
115
|
+
* Imported as a type and never re-declared here. That direction of dependency is
|
|
116
|
+
* the point: a second structural copy of this shape would drift, and the drift
|
|
117
|
+
* would be silent in the worst direction — the store refuses (or, worse,
|
|
118
|
+
* narrows) a credential this module wrote, so the sign-in succeeds and the very
|
|
119
|
+
* next call reports "not signed in". The concrete trap this avoids:
|
|
120
|
+
* 'token-store.ts' records the granted scopes as a 'scopes' ARRAY and requires
|
|
121
|
+
* 'user:inference' in it, so a credential written with a space-delimited
|
|
122
|
+
* 'scope' string would parse to zero scopes and be refused as "not a
|
|
123
|
+
* subscription credential".
|
|
124
|
+
*/
|
|
125
|
+
import type { ClaudeAccountInfo, ClaudeCredentials } from './token-store.ts';
|
|
126
|
+
export type { ClaudeCredentials };
|
|
127
|
+
/**
|
|
128
|
+
* The only store interface this module needs.
|
|
129
|
+
*
|
|
130
|
+
* Deliberately two methods and no class: 'read' returning null means "not
|
|
131
|
+
* signed in", which is a state rather than an error. This module never learns
|
|
132
|
+
* how the bytes reach the disk, so the real store's document layout, its
|
|
133
|
+
* account records and its preference settings are all outside its concern —
|
|
134
|
+
* the caller passes a two-method adapter over whichever of those it holds.
|
|
135
|
+
*/
|
|
136
|
+
export interface ClaudeTokenStore {
|
|
137
|
+
read(): Promise<ClaudeCredentials | null>;
|
|
138
|
+
write(credentials: ClaudeCredentials): Promise<void>;
|
|
139
|
+
}
|
|
140
|
+
/** The one interface the loopback listener is ever bound to. */
|
|
141
|
+
export declare const LOOPBACK_HOST = "127.0.0.1";
|
|
142
|
+
/** Raised when the credential is dead and only a new sign-in can fix it. */
|
|
143
|
+
export declare class ClaudeUnauthorizedError extends Error {
|
|
144
|
+
constructor(message: string);
|
|
145
|
+
}
|
|
146
|
+
/** Raised when a transient failure outlived its retry budget. */
|
|
147
|
+
export declare class ClaudeRetryableError extends Error {
|
|
148
|
+
readonly cause?: unknown | undefined;
|
|
149
|
+
constructor(message: string, cause?: unknown | undefined);
|
|
150
|
+
}
|
|
151
|
+
/** The secrets one authorize request is built from. */
|
|
152
|
+
export interface PkceMaterial {
|
|
153
|
+
/** SECRET. Never placed in a URL, a log, or an error. */
|
|
154
|
+
verifier: string;
|
|
155
|
+
/** The only half of the pair that belongs in the authorize URL. */
|
|
156
|
+
challenge: string;
|
|
157
|
+
/** Independent anti-forgery value; NOT derived from the verifier. */
|
|
158
|
+
state: string;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Generate one flow's PKCE material and state.
|
|
162
|
+
*
|
|
163
|
+
* The verifier is 32 random bytes — the RFC 7636 ceiling for entropy — encoded
|
|
164
|
+
* as base64url, and the challenge is its SHA-256 in the same encoding. The
|
|
165
|
+
* state is a SEPARATE 24-byte draw. Deriving it from the verifier, or reusing
|
|
166
|
+
* the verifier as the reference does, would make the two values one secret and
|
|
167
|
+
* put the verifier in the URL. 24 bytes is comfortably above the 16-byte floor
|
|
168
|
+
* this line requires, and the two are the same length so nothing about their
|
|
169
|
+
* shapes can be used to tell them apart.
|
|
170
|
+
*/
|
|
171
|
+
export declare function generatePkceMaterial(): PkceMaterial;
|
|
172
|
+
/** Account facts a token response may name, in the sibling store's own spelling. */
|
|
173
|
+
export type TokenAccount = ClaudeAccountInfo;
|
|
174
|
+
/** One parsed token response, in the shape the credential store consumes. */
|
|
175
|
+
export interface OAuthTokenResult {
|
|
176
|
+
accessToken: string;
|
|
177
|
+
/** Empty string when the endpoint did not report one; see A3. */
|
|
178
|
+
refreshToken: string;
|
|
179
|
+
expiresAt: number;
|
|
180
|
+
expiresIn: number;
|
|
181
|
+
/** Empty when the endpoint reported no scope at all. */
|
|
182
|
+
scopes: string[];
|
|
183
|
+
account: TokenAccount;
|
|
184
|
+
}
|
|
185
|
+
interface TokenRequestOptions {
|
|
186
|
+
fetchFn?: typeof fetch;
|
|
187
|
+
signal?: AbortSignal;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Exchange an authorization code for a token pair (RFC 6749 section 4.1.3).
|
|
191
|
+
*
|
|
192
|
+
* 'redirectUri' is passed in rather than resolved here: it must be the value
|
|
193
|
+
* recorded on the flow that issued the code, never a "current UI" value, or the
|
|
194
|
+
* endpoint rejects the exchange.
|
|
195
|
+
*/
|
|
196
|
+
export declare function exchangeAuthorizationCode(params: {
|
|
197
|
+
code: string;
|
|
198
|
+
state: string;
|
|
199
|
+
verifier: string;
|
|
200
|
+
redirectUri: string;
|
|
201
|
+
}, options?: TokenRequestOptions): Promise<OAuthTokenResult>;
|
|
202
|
+
/**
|
|
203
|
+
* Refresh an access token, with a bounded retry over transient failures.
|
|
204
|
+
*
|
|
205
|
+
* Only a transient status or a transport failure is retried. A final verdict —
|
|
206
|
+
* ClaudeUnauthorizedError — stops immediately and propagates, because every
|
|
207
|
+
* further attempt would be a guaranteed rejection and, on a rotation endpoint,
|
|
208
|
+
* one more chance to spend the refresh token.
|
|
209
|
+
*
|
|
210
|
+
* The returned 'refreshToken' is empty when the endpoint named none; the caller
|
|
211
|
+
* merges that case by keeping the stored value (A3).
|
|
212
|
+
*/
|
|
213
|
+
export declare function refreshAccessToken(refreshToken: string, options?: TokenRequestOptions): Promise<OAuthTokenResult>;
|
|
214
|
+
export interface EnsureTokenOptions {
|
|
215
|
+
fetchFn?: typeof fetch;
|
|
216
|
+
signal?: AbortSignal;
|
|
217
|
+
/** Refresh even when the stored token still looks valid. */
|
|
218
|
+
force?: boolean;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Return a usable credential, refreshing and persisting it first when needed.
|
|
222
|
+
*
|
|
223
|
+
* SINGLE-FLIGHT, and that is a correctness property rather than an
|
|
224
|
+
* optimisation. The refresh token rotates: the first refresh spends the token
|
|
225
|
+
* that was sent, so a burst of callers arriving at expiry must NOT each send
|
|
226
|
+
* it. Under the naive implementation the second request carries a token the
|
|
227
|
+
* first already spent, the endpoint answers with a final verdict, and the user
|
|
228
|
+
* is signed out by their own concurrency. One shared promise means exactly one
|
|
229
|
+
* rotation per expiry, and it is cleared in a 'finally' so a FAILED refresh
|
|
230
|
+
* does not wedge the account: the next call retries instead of forever joining
|
|
231
|
+
* a rejected promise.
|
|
232
|
+
*/
|
|
233
|
+
export declare function ensureAccessToken(store: ClaudeTokenStore, options?: EnsureTokenOptions): Promise<ClaudeCredentials>;
|
|
234
|
+
/**
|
|
235
|
+
* Open a URL in the user's default browser, best effort.
|
|
236
|
+
*
|
|
237
|
+
* The caller ALWAYS renders the URL as well, so a machine with no browser, no
|
|
238
|
+
* xdg-open, or a blocked spawn stays usable. The failure is swallowed rather
|
|
239
|
+
* than surfaced because there is no action a user could take on it that they
|
|
240
|
+
* cannot take by copying the URL themselves.
|
|
241
|
+
*/
|
|
242
|
+
export declare function openBrowser(url: string): void;
|
|
243
|
+
/** Which redirect URI an authorization request was issued for. */
|
|
244
|
+
export type LoginMode = 'manual' | 'loopback';
|
|
245
|
+
/** Where a flow currently stands. */
|
|
246
|
+
export type LoginStatus = 'idle' | 'pending' | 'exchanging' | 'complete' | 'error';
|
|
247
|
+
/**
|
|
248
|
+
* One sign-in attempt.
|
|
249
|
+
*
|
|
250
|
+
* mode, redirectUri, verifier and state are fixed at creation and never
|
|
251
|
+
* rewritten: an authorization request already in flight is bound to all four,
|
|
252
|
+
* so mutating any of them would silently invalidate the code it returns.
|
|
253
|
+
* 'exchanging' is the compare-and-set word that makes the exchange exactly-once
|
|
254
|
+
* (see beginExchange).
|
|
255
|
+
*/
|
|
256
|
+
export interface LoginFlow {
|
|
257
|
+
flowId: string;
|
|
258
|
+
/** Immutable for this flow's lifetime; switching mode starts a new flow. */
|
|
259
|
+
readonly mode: LoginMode;
|
|
260
|
+
/** The URI the authorize request carried; the ONLY one the exchange may send. */
|
|
261
|
+
readonly redirectUri: string;
|
|
262
|
+
/** SECRET. */
|
|
263
|
+
readonly verifier: string;
|
|
264
|
+
/** A one-time forgery token, not a credential — but still never logged. */
|
|
265
|
+
readonly state: string;
|
|
266
|
+
readonly createdAt: number;
|
|
267
|
+
/** Where the exchange is in its single-flight lifecycle. */
|
|
268
|
+
exchanging: 'idle' | 'in-progress' | 'done';
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* The pollable status of the sign-in surface.
|
|
272
|
+
*
|
|
273
|
+
* NO SECRET EVER APPEARS HERE, and tests enforce that rather than trusting the
|
|
274
|
+
* convention: this object is serialized straight into an HTTP response, so the
|
|
275
|
+
* verifier, the state, the authorization code and both tokens have no field to
|
|
276
|
+
* live in. There is no SSE anywhere in this plugin — the client polls.
|
|
277
|
+
*/
|
|
278
|
+
export interface LoginFlowStatus {
|
|
279
|
+
status: LoginStatus;
|
|
280
|
+
/** Correlates a status reading with the flow the user started. */
|
|
281
|
+
flowId?: string;
|
|
282
|
+
/** Not a secret: it is the value that goes INTO the browser. */
|
|
283
|
+
authUrl?: string;
|
|
284
|
+
mode?: LoginMode;
|
|
285
|
+
/** Which redirect URI is armed, for the card to display. */
|
|
286
|
+
redirectUri?: string;
|
|
287
|
+
hint?: string;
|
|
288
|
+
error?: string;
|
|
289
|
+
/** Why a loopback attempt degraded to manual. */
|
|
290
|
+
fallbackReason?: string;
|
|
291
|
+
createdAt?: number;
|
|
292
|
+
completedAt?: number;
|
|
293
|
+
}
|
|
294
|
+
/** Everything a caller may override, so tests never touch the network or a browser. */
|
|
295
|
+
export interface BeginLoginOptions {
|
|
296
|
+
/** Not a credential: it decides which redirect URI the flow is issued for. */
|
|
297
|
+
mode?: LoginMode;
|
|
298
|
+
/** Injected so tests do not depend on machine state or on a real browser. */
|
|
299
|
+
fetchFn?: typeof fetch;
|
|
300
|
+
openBrowser?: (url: string) => void;
|
|
301
|
+
/** Injected so a test can drive a callback against a listener it controls. */
|
|
302
|
+
listen?: (port: number, host: string) => Promise<Server>;
|
|
303
|
+
/** Injected so a test can make a port look unavailable. */
|
|
304
|
+
probe?: (port: number) => Promise<boolean>;
|
|
305
|
+
/** Ceiling for this attempt; defaults to LOGIN_TIMEOUT_MS from types.ts. */
|
|
306
|
+
timeoutMs?: number;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Status of the current (or last) sign-in, for the client to poll.
|
|
310
|
+
*
|
|
311
|
+
* A copy, not the live object: a caller that mutated what it received would
|
|
312
|
+
* otherwise desynchronize the surface from the flow.
|
|
313
|
+
*/
|
|
314
|
+
export declare function getLoginStatus(): LoginFlowStatus;
|
|
315
|
+
/**
|
|
316
|
+
* First usable loopback port, or null when the probe finds none.
|
|
317
|
+
*
|
|
318
|
+
* null rather than a throw is deliberate (see beginLogin): a failed probe is
|
|
319
|
+
* NOT a hard error, it is the signal to fall back to the manual flow. Windows
|
|
320
|
+
* (Hyper-V/WinNAT) reserves TCP port ranges that move on every reboot, and
|
|
321
|
+
* CALLBACK_PORT_ATTEMPTS covers any single 100-port excluded block the default
|
|
322
|
+
* port can start inside.
|
|
323
|
+
*/
|
|
324
|
+
export declare function resolveCallbackPort(probe?: (port: number) => Promise<boolean>, attempts?: number): Promise<number | null>;
|
|
325
|
+
/** A value a user pasted into the manual sign-in box, or why it was rejected. */
|
|
326
|
+
export type LoginInputResult = {
|
|
327
|
+
ok: true;
|
|
328
|
+
code: string;
|
|
329
|
+
state: string;
|
|
330
|
+
} | {
|
|
331
|
+
ok: false;
|
|
332
|
+
error: string;
|
|
333
|
+
};
|
|
334
|
+
/**
|
|
335
|
+
* Parse the string a user pastes back from the browser.
|
|
336
|
+
*
|
|
337
|
+
* Three shapes are accepted, because the page the manual flow lands on offers
|
|
338
|
+
* the user more than one thing to copy: a full redirect URL, the shortened
|
|
339
|
+
* <code>#<state> pair the page displays, and a bare 'code=..&state=..' query
|
|
340
|
+
* fragment.
|
|
341
|
+
*
|
|
342
|
+
* A BARE CODE IS REJECTED. It cannot be bound to this flow — there is no state
|
|
343
|
+
* to compare against — and forcing the flow's own state into the exchange would
|
|
344
|
+
* defeat the state parameter entirely, turning the manual box into a login-CSRF
|
|
345
|
+
* oracle: anyone who talks a user into pasting a code they supplied would get
|
|
346
|
+
* that user's session bound to the attacker's account. The error says exactly
|
|
347
|
+
* what to copy instead.
|
|
348
|
+
*/
|
|
349
|
+
export declare function resolveLoginInput(text: string): LoginInputResult;
|
|
350
|
+
/**
|
|
351
|
+
* Exchange a manually pasted value.
|
|
352
|
+
*
|
|
353
|
+
* The state is checked against the armed flow BEFORE anything is claimed or
|
|
354
|
+
* sent, so a mistyped paste costs a 400 and leaves the flow usable — the user
|
|
355
|
+
* can simply paste again. Only a value carrying the flow's own state can
|
|
356
|
+
* consume the exactly-once slot, and the CAS result is mapped onto the same
|
|
357
|
+
* 409/410 semantics the callback uses.
|
|
358
|
+
*/
|
|
359
|
+
export declare function submitLoginInput(text: string, options?: {
|
|
360
|
+
fetchFn?: typeof fetch;
|
|
361
|
+
}): Promise<{
|
|
362
|
+
ok: true;
|
|
363
|
+
} | {
|
|
364
|
+
ok: false;
|
|
365
|
+
error: string;
|
|
366
|
+
httpStatus: number;
|
|
367
|
+
}>;
|
|
368
|
+
/** Build the authorize URL for one flow. The VERIFIER IS NOT IN IT. */
|
|
369
|
+
export declare function buildAuthorizeUrl(flow: Pick<LoginFlow, 'redirectUri' | 'state'>, challenge: string): string;
|
|
370
|
+
/**
|
|
371
|
+
* Start a sign-in and return IMMEDIATELY.
|
|
372
|
+
*
|
|
373
|
+
* The returned status is what the settings card polls; nothing here awaits the
|
|
374
|
+
* exchange, the listener, or the browser, because the HTTP request behind the
|
|
375
|
+
* button must not stay open for the whole authorization.
|
|
376
|
+
*
|
|
377
|
+
* A loopback probe that finds no usable port is NOT a hard error: the flow
|
|
378
|
+
* degrades to manual and the caller is told why, since the manual flow needs no
|
|
379
|
+
* port at all and a user whose Windows excluded range covers the default should
|
|
380
|
+
* not be blocked from signing in.
|
|
381
|
+
*/
|
|
382
|
+
export declare function beginLogin(store: ClaudeTokenStore, options?: BeginLoginOptions): Promise<LoginFlowStatus>;
|
|
383
|
+
/**
|
|
384
|
+
* Abandon the current sign-in and return to idle.
|
|
385
|
+
*
|
|
386
|
+
* Aborts the flow's controller (so an in-flight exchange or timer stops),
|
|
387
|
+
* closes the listener AND its connections (a closed listener with a live
|
|
388
|
+
* keep-alive socket still holds the port), and clears the flow so the next
|
|
389
|
+
* beginLogin starts from a clean slate instead of inheriting a spent
|
|
390
|
+
* exactly-once slot.
|
|
391
|
+
*/
|
|
392
|
+
export declare function cancelLogin(): void;
|
|
393
|
+
//# sourceMappingURL=oauth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../../src/host/claude/oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The '/claude/api' surface: the settings card for the Claude subscription line.
|
|
3
|
+
*
|
|
4
|
+
* The route set, the '{ok,value}' / '{ok,error}' envelope, the 64 KiB body cap,
|
|
5
|
+
* the 405/404/500 conventions and the same-origin requirement on every mutation
|
|
6
|
+
* are all mirrors of the sibling lines' route modules ('src/host/kimi-code/routes.ts',
|
|
7
|
+
* 'src/host/command-code/routes.ts', 'src/host/workbuddy/routes.ts') — deliberately,
|
|
8
|
+
* because the card that renders this line is the same card whose shape those lines
|
|
9
|
+
* established, and a further dialect would be another bug surface for no gain.
|
|
10
|
+
*
|
|
11
|
+
* ---------------------------------------------------------------------------
|
|
12
|
+
* WHAT THIS FILE IS
|
|
13
|
+
* ---------------------------------------------------------------------------
|
|
14
|
+
*
|
|
15
|
+
* It is the whole settings surface for the line and nothing more: the sign-in
|
|
16
|
+
* flow (loopback and the manual paste), adoption of a local Claude Code sign-in,
|
|
17
|
+
* the quota reads, the model catalog and selection, the account pool, and the
|
|
18
|
+
* status payload the card renders. No route is gated on an acknowledgement, a
|
|
19
|
+
* feature flag or any other prior state of the card: each one works from the
|
|
20
|
+
* credentials and the preferences it is handed, and refuses only what it cannot
|
|
21
|
+
* do (not signed in, unsupported action, oversized body, cross-origin caller).
|
|
22
|
+
*
|
|
23
|
+
* Two properties here are structural rather than conventional, and both are load
|
|
24
|
+
* bearing:
|
|
25
|
+
*
|
|
26
|
+
* - 'GET ""' and 'GET "status"' are the card's single source of truth. They
|
|
27
|
+
* report the account, the catalog, the quota, and whether this plugin owns the
|
|
28
|
+
* provider route ({@link ClaudeStatusOptions.serving} /
|
|
29
|
+
* {@link ClaudeStatusOptions.conflict}), so an id already held by another
|
|
30
|
+
* adapter family shows up as a banner on the card instead of as a model list
|
|
31
|
+
* that is mysteriously empty.
|
|
32
|
+
* - 'adopt' is the ONLY route that reads the local Claude Code credential file.
|
|
33
|
+
* The status route asks {@link ClaudeStatusOptions.adoptPaths} whether such a
|
|
34
|
+
* file EXISTS and never opens it, which is what keeps a status poll from
|
|
35
|
+
* turning into a scan of the user's disk (see 'adopt.ts' Rule 2).
|
|
36
|
+
*
|
|
37
|
+
* ---------------------------------------------------------------------------
|
|
38
|
+
* WHAT THIS FILE DOES NOT DECIDE
|
|
39
|
+
* ---------------------------------------------------------------------------
|
|
40
|
+
*
|
|
41
|
+
* Whether the adapter is REGISTERED is the plugin entry's call, not this
|
|
42
|
+
* module's: the entry claims the provider route and reports the outcome back
|
|
43
|
+
* through {@link ClaudeStatusOptions.serving} and
|
|
44
|
+
* {@link ClaudeStatusOptions.conflict}, which is what the card's route banner
|
|
45
|
+
* renders. The route surface itself is registered unconditionally, because the
|
|
46
|
+
* card needs it in every state — including the state where another adapter
|
|
47
|
+
* family owns the provider id and the only thing to show is that fact.
|
|
48
|
+
*/
|
|
49
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
50
|
+
import { FileCredentialStore, FileModelSettingsStore, type ClaudeCredentials, type ClaudePreferenceStore } from './token-store.ts';
|
|
51
|
+
import { type ClaudeModelEntry } from './model-catalog.ts';
|
|
52
|
+
import { clearCachedCatalog, clearCachedQuota, getCachedQuota } from './client.ts';
|
|
53
|
+
import { type BeginLoginOptions } from './oauth.ts';
|
|
54
|
+
import { claudeCodeCredentialPaths, claudeCodeCredentialPresence } from './adopt.ts';
|
|
55
|
+
import { DEFAULT_CONTEXT_WINDOW, PROVIDER_ID, PROVIDER_NAME } from './types.ts';
|
|
56
|
+
import type { ClaudeAccountPool } from './account-pool.ts';
|
|
57
|
+
import { type ClaudeModelOption, type ClaudeWebStatus,
|
|
58
|
+
/** The shared declaration, imported under its own name so it can be re-exported below. */
|
|
59
|
+
type ClaudeAccountSummaryDto } from '../../shared/claude-contracts.ts';
|
|
60
|
+
/** Prefix this line's routes are registered under. */
|
|
61
|
+
export declare const ROUTE_PREFIX = "/claude/api";
|
|
62
|
+
/**
|
|
63
|
+
* The selection the card should show.
|
|
64
|
+
*
|
|
65
|
+
* A stored list that still equals the shipped default has never been edited, so
|
|
66
|
+
* it cannot know about models the live listing has since added; treating it as
|
|
67
|
+
* "everything this account can call" keeps a first run from hiding models behind
|
|
68
|
+
* an unedited default. Any explicit edit is honoured exactly. The rule is the
|
|
69
|
+
* same one every sibling line states, and it is stated locally because the
|
|
70
|
+
* helper is not shared.
|
|
71
|
+
*/
|
|
72
|
+
export declare function resolveEnabledModelIds(stored: readonly string[], available: readonly string[], enabled?: boolean): string[];
|
|
73
|
+
/** Build the model options the settings card renders, in catalog order. */
|
|
74
|
+
export declare function buildClaudeModelOptions(catalog: readonly ClaudeModelEntry[], available: readonly string[], enabledModelIds: readonly string[], overrides: Record<string, number>): ClaudeModelOption[];
|
|
75
|
+
export interface ClaudeStatusOptions {
|
|
76
|
+
fetchFn?: typeof fetch;
|
|
77
|
+
/** Whether this plugin currently owns the provider route; re-read on every status. */
|
|
78
|
+
serving?: boolean | (() => boolean);
|
|
79
|
+
/** Diagnostic when another plugin owns the provider route; re-read on every status. */
|
|
80
|
+
conflict?: string | null | (() => string | null);
|
|
81
|
+
/** Multi-account pool this line schedules through; absent keeps the single-account card. */
|
|
82
|
+
accountPool?: ClaudeAccountPool;
|
|
83
|
+
/**
|
|
84
|
+
* Test seam for the model listing.
|
|
85
|
+
*
|
|
86
|
+
* Defaults to 'client.ts''s loader against the resolved credential; injected so
|
|
87
|
+
* a test drives the card without a network round trip.
|
|
88
|
+
*/
|
|
89
|
+
loadCatalog?: (credentials: ClaudeCredentials) => Promise<readonly ClaudeModelEntry[]>;
|
|
90
|
+
/** Test seam for adoption: the paths the reader consults. */
|
|
91
|
+
adoptPaths?: readonly string[];
|
|
92
|
+
/**
|
|
93
|
+
* Test seam for the sign-in flow.
|
|
94
|
+
*
|
|
95
|
+
* Mirrors 'oauth.ts''s own BeginLoginOptions so a test never opens a browser
|
|
96
|
+
* and never binds a loopback port. The route always overrides fetchFn with the
|
|
97
|
+
* one it was registered with, so the flow and the rest of the surface share a
|
|
98
|
+
* single fetch.
|
|
99
|
+
*/
|
|
100
|
+
login?: Omit<BeginLoginOptions, 'fetchFn'>;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Everything the settings card renders: the account, the catalog, the quota.
|
|
104
|
+
*
|
|
105
|
+
* Exported so a caller (and a test) can render the same payload the route
|
|
106
|
+
* returns without going through the HTTP surface.
|
|
107
|
+
*/
|
|
108
|
+
export declare function getClaudeWebStatus(store: FileCredentialStore, modelSettings: FileModelSettingsStore, preferences: ClaudePreferenceStore | undefined, options?: ClaudeStatusOptions, quotaError?: string | null,
|
|
109
|
+
/** Credential and id the route already resolved for this request. */
|
|
110
|
+
active?: {
|
|
111
|
+
id: string | undefined;
|
|
112
|
+
credentials: ClaudeCredentials | undefined;
|
|
113
|
+
}): Promise<ClaudeWebStatus>;
|
|
114
|
+
/**
|
|
115
|
+
* Register the Claude subscription settings routes under '/claude/api'.
|
|
116
|
+
*
|
|
117
|
+
* Returns the disposer. Registration is UNCONDITIONAL: the card's status poll is
|
|
118
|
+
* how the user learns whether this plugin owns the provider route, so the
|
|
119
|
+
* surface has to answer even when another adapter family holds the id.
|
|
120
|
+
*/
|
|
121
|
+
export declare function registerClaudeRoutes(ctx: Context, store: FileCredentialStore, modelSettings: FileModelSettingsStore, preferences?: ClaudePreferenceStore, options?: ClaudeStatusOptions): () => void;
|
|
122
|
+
/** The same check, exposed so the test suite can assert it without importing order games. */
|
|
123
|
+
export declare function claudeReasoningEffortDrift(): {
|
|
124
|
+
missing: string[];
|
|
125
|
+
extra: string[];
|
|
126
|
+
};
|
|
127
|
+
export { DEFAULT_CONTEXT_WINDOW, PROVIDER_ID, PROVIDER_NAME, getCachedQuota, clearCachedQuota, clearCachedCatalog, claudeCodeCredentialPaths, claudeCodeCredentialPresence, type ClaudeAccountSummaryDto, };
|
|
128
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../../src/host/claude/routes.ts"],"names":[],"mappings":"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"}
|