@modelprofile.com/authswitch 3.3.0 → 5.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/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/accounts.d.ts +52 -15
- package/dist_ts/accounts.js +110 -27
- package/dist_ts/classes.accountlist.d.ts +0 -25
- package/dist_ts/classes.accountlist.js +2 -216
- package/dist_ts/classes.claudecodeharness.d.ts +81 -2
- package/dist_ts/classes.claudecodeharness.js +208 -14
- package/dist_ts/classes.claudecodelocks.d.ts +38 -0
- package/dist_ts/classes.claudecodelocks.js +118 -0
- package/dist_ts/classes.claudestatus.d.ts +15 -2
- package/dist_ts/classes.claudestatus.js +100 -83
- package/dist_ts/classes.claudetokenrefresh.d.ts +32 -0
- package/dist_ts/classes.claudetokenrefresh.js +77 -0
- package/dist_ts/classes.cli.d.ts +14 -7
- package/dist_ts/classes.cli.js +126 -66
- package/dist_ts/classes.codexharness.d.ts +4 -0
- package/dist_ts/classes.codexharness.js +5 -1
- package/dist_ts/classes.codexstatus.d.ts +7 -2
- package/dist_ts/classes.codexstatus.js +49 -21
- package/dist_ts/classes.credentialstore.d.ts +43 -2
- package/dist_ts/classes.credentialstore.js +60 -13
- package/dist_ts/classes.fileharness.d.ts +45 -21
- package/dist_ts/classes.fileharness.js +64 -26
- package/dist_ts/classes.limits.d.ts +46 -7
- package/dist_ts/classes.limits.js +94 -36
- package/dist_ts/classes.listrenderer.d.ts +17 -0
- package/dist_ts/classes.listrenderer.js +313 -0
- package/dist_ts/classes.login.d.ts +1 -1
- package/dist_ts/classes.login.js +1 -1
- package/dist_ts/classes.opencodeharness.d.ts +4 -0
- package/dist_ts/classes.opencodeharness.js +8 -4
- package/dist_ts/classes.operations.js +3 -2
- package/dist_ts/classes.tui.js +4 -3
- package/dist_ts/classes.watch.d.ts +108 -0
- package/dist_ts/classes.watch.js +219 -0
- package/dist_ts/classes.watchlock.d.ts +33 -0
- package/dist_ts/classes.watchlock.js +118 -0
- package/dist_ts/claudehttp.d.ts +39 -0
- package/dist_ts/claudehttp.js +83 -0
- package/dist_ts/cliargs.d.ts +36 -0
- package/dist_ts/cliargs.js +60 -0
- package/dist_ts/consoletable.d.ts +21 -0
- package/dist_ts/consoletable.js +63 -0
- package/dist_ts/helpers.d.ts +7 -0
- package/dist_ts/helpers.js +16 -1
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +4 -1
- package/dist_ts/interfaces.harness.d.ts +60 -11
- package/dist_ts/interfaces.list.d.ts +3 -1
- package/dist_ts/plugins.d.ts +7 -0
- package/dist_ts/plugins.js +6 -1
- package/dist_ts/ratelimit.d.ts +8 -0
- package/dist_ts/ratelimit.js +13 -0
- package/dist_ts/watchpolicy.d.ts +44 -0
- package/dist_ts/watchpolicy.js +82 -0
- package/package.json +5 -3
- package/readme.md +349 -115
- package/ts/00_commitinfo_data.ts +3 -3
- package/ts/accounts.ts +122 -35
- package/ts/classes.accountlist.ts +2 -219
- package/ts/classes.claudecodeharness.ts +199 -13
- package/ts/classes.claudecodelocks.ts +133 -0
- package/ts/classes.claudestatus.ts +100 -65
- package/ts/classes.claudetokenrefresh.ts +85 -0
- package/ts/classes.cli.ts +114 -54
- package/ts/classes.codexharness.ts +4 -0
- package/ts/classes.codexstatus.ts +40 -18
- package/ts/classes.credentialstore.ts +78 -10
- package/ts/classes.fileharness.ts +76 -34
- package/ts/classes.limits.ts +110 -36
- package/ts/classes.listrenderer.ts +328 -0
- package/ts/classes.login.ts +1 -1
- package/ts/classes.opencodeharness.ts +7 -3
- package/ts/classes.operations.ts +2 -1
- package/ts/classes.tui.ts +3 -2
- package/ts/classes.watch.ts +263 -0
- package/ts/classes.watchlock.ts +100 -0
- package/ts/claudehttp.ts +92 -0
- package/ts/cliargs.ts +71 -0
- package/ts/consoletable.ts +62 -0
- package/ts/helpers.ts +14 -0
- package/ts/index.ts +3 -0
- package/ts/interfaces.harness.ts +60 -5
- package/ts/interfaces.list.ts +3 -1
- package/ts/plugins.ts +9 -0
- package/ts/ratelimit.ts +14 -0
- package/ts/watchpolicy.ts +121 -0
|
@@ -1,15 +1,48 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { FileHarness } from './classes.fileharness.js';
|
|
3
|
-
import { CredentialStore, credentialRecord, credentialText, readCredentialDocument, readCredentialRaw } from './classes.credentialstore.js';
|
|
3
|
+
import { CredentialStore, credentialHash, credentialRecord, credentialText, readCredentialDocument, readCredentialRaw } from './classes.credentialstore.js';
|
|
4
4
|
import { HarnessProcesses } from './classes.harnessprocesses.js';
|
|
5
5
|
import { ClaudeAccountStatus } from './classes.claudestatus.js';
|
|
6
|
+
import { ClaudeCodeLocks } from './classes.claudecodelocks.js';
|
|
7
|
+
import { ClaudeTokenRefresh } from './classes.claudetokenrefresh.js';
|
|
8
|
+
import { CLAUDE_LOGIN_REJECTED, ClaudeLoginRejectedError, ClaudeRateLimitError } from './claudehttp.js';
|
|
6
9
|
import { writeSecretFileAtomically } from './helpers.js';
|
|
10
|
+
/**
|
|
11
|
+
* How long a read waits for the store and for Claude Code's locks before leaving the saved copy as it found it.
|
|
12
|
+
*
|
|
13
|
+
* Reading accounts must stay as quick as it is while a switch, a refresh or a Claude Code session holds a lock. The
|
|
14
|
+
* saved copy has nothing to finish: whatever the operation holding the lock writes is what the next read mirrors.
|
|
15
|
+
*/
|
|
16
|
+
const MIRROR_WAIT_MS = 1_000;
|
|
17
|
+
/**
|
|
18
|
+
* A saved login the sign-in service refuses, in terms the user can act on.
|
|
19
|
+
*
|
|
20
|
+
* Claude Code rotates the refresh token of the login it is running on (hints.md), and a saved copy keeps the token
|
|
21
|
+
* it was stashed with. Once such a login has been replaced outside authswitch -- a `claude /login`, a new device
|
|
22
|
+
* login -- nothing writes the rotation back, and the service was observed refusing the older token the saved copy
|
|
23
|
+
* still holds (2026-09-18, two saved logins). No retry, no other account and no switch changes that answer; logging
|
|
24
|
+
* in again and saving that login does, so the message says so.
|
|
25
|
+
*/
|
|
26
|
+
const SAVED_LOGIN_REJECTED = `${CLAUDE_LOGIN_REJECTED} Claude Code rotates a login's refresh token as it uses it, and the service can refuse the older one a saved copy still holds once that login has been replaced outside authswitch; authswitch claude stash --keep saves the new one.`;
|
|
7
27
|
const accountCaches = ['additionalModelOptionsCache', 'additionalModelOptionsAnsweredAt', 'additionalModelCostsCache', 'modelAccessCache', 'orgModelDefaultCache', 'lastSeenOrgDefaultUpdatedAt', 'clientDataCache', 'clientDataCacheSlots', 'autoCompactWindowsCache', 'cachedUsageUtilization'];
|
|
8
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* File-backed Claude Code subscriber login and its matching global oauthAccount metadata.
|
|
30
|
+
*
|
|
31
|
+
* A running Claude Code (verified against 2.1.273) re-reads its credential file whenever the file's mtime changes,
|
|
32
|
+
* before every request, and watches `.claude.json`, so a swap is picked up live without a restart. Every native read
|
|
33
|
+
* and write therefore runs under Claude Code's own locks instead of asking for it to be stopped.
|
|
34
|
+
*
|
|
35
|
+
* Nothing else refreshes a saved login, so its access token expires a few hours after it was saved. Reading such a
|
|
36
|
+
* login's status refreshes it first, the way Claude Code would; the active login's tokens belong to Claude Code, and
|
|
37
|
+
* reading the accounts mirrors that login into its own saved copy, so the stash keeps what Claude Code last wrote.
|
|
38
|
+
*/
|
|
9
39
|
export class ClaudeCodeHarness extends FileHarness {
|
|
10
40
|
id = 'claude';
|
|
11
41
|
label = 'Claude Code';
|
|
12
42
|
loginHint = 'Log in using claude auth login, then authswitch claude stash --keep; Claude Code may stay running.';
|
|
43
|
+
liveSwap = true;
|
|
44
|
+
autoSwitch = true;
|
|
45
|
+
renewalUnavailableReason = "renewal dates are not exposed by Claude's account API.";
|
|
13
46
|
store;
|
|
14
47
|
file;
|
|
15
48
|
configFile;
|
|
@@ -18,6 +51,8 @@ export class ClaudeCodeHarness extends FileHarness {
|
|
|
18
51
|
status;
|
|
19
52
|
processes;
|
|
20
53
|
settingsFiles;
|
|
54
|
+
locks;
|
|
55
|
+
tokens;
|
|
21
56
|
constructor(options = {}) {
|
|
22
57
|
super();
|
|
23
58
|
this.env = options.env ?? process.env;
|
|
@@ -27,10 +62,16 @@ export class ClaudeCodeHarness extends FileHarness {
|
|
|
27
62
|
this.configFile = options.globalConfigFile ?? plugins.path.join(custom || plugins.os.homedir(), '.claude.json');
|
|
28
63
|
this.store = new CredentialStore(this.id, options.stashRoot);
|
|
29
64
|
this.platform = options.platform ?? process.platform;
|
|
30
|
-
this.status = new ClaudeAccountStatus(options.fetch);
|
|
65
|
+
this.status = new ClaudeAccountStatus(options.fetch, options.now);
|
|
66
|
+
this.tokens = new ClaudeTokenRefresh(options.fetch, options.now);
|
|
31
67
|
this.processes = options.processes ?? new HarnessProcesses('claude', { platform: this.platform });
|
|
32
68
|
this.settingsFiles = options.settingsFiles ?? [plugins.path.join(dir, 'settings.json'),
|
|
33
69
|
plugins.path.join(process.cwd(), '.claude/settings.json'), plugins.path.join(process.cwd(), '.claude/settings.local.json')];
|
|
70
|
+
this.locks = new ClaudeCodeLocks(dir, this.configFile, { timeoutMs: options.lockTimeoutMs });
|
|
71
|
+
}
|
|
72
|
+
/** A login this adapter cannot manage has no Claude Code file to lock; the action itself reports why. */
|
|
73
|
+
nativeTransaction(actionArg) {
|
|
74
|
+
return this.unavailableReason() === null ? this.locks.hold(actionArg) : super.nativeTransaction(actionArg);
|
|
34
75
|
}
|
|
35
76
|
/** One record holds the credential and its matching metadata, so both files must be proven stable. */
|
|
36
77
|
nativeSources() { return [readCredentialRaw(this.file), readCredentialRaw(this.configFile)]; }
|
|
@@ -44,9 +85,10 @@ export class ClaudeCodeHarness extends FileHarness {
|
|
|
44
85
|
throw new Error('Claude Code login or its matching account metadata is incomplete. Log in again with Claude Code before saving.');
|
|
45
86
|
return { slotId, identity: JSON.stringify([account.accountUuid, account.organizationUuid]), label: String(account.emailAddress).toLowerCase(), credential };
|
|
46
87
|
}
|
|
47
|
-
|
|
88
|
+
/** Why this installation's login is not a subscriber file login this adapter can manage; null when it is. */
|
|
89
|
+
unavailableReason() {
|
|
48
90
|
if (this.platform === 'darwin')
|
|
49
|
-
return
|
|
91
|
+
return 'Claude Code uses the macOS Keychain. This adapter supports file credentials on Linux and Windows; Keychain switching is unavailable.';
|
|
50
92
|
const overrides = ['CLAUDE_CODE_OAUTH_TOKEN', 'CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR', 'ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN', 'ANTHROPIC_PROFILE', 'CLAUDE_CODE_USE_BEDROCK', 'CLAUDE_CODE_USE_VERTEX', 'CLAUDE_CODE_USE_FOUNDRY', 'ANTHROPIC_BASE_URL'];
|
|
51
93
|
const settings = {};
|
|
52
94
|
const environment = { ...this.env };
|
|
@@ -56,8 +98,13 @@ export class ClaudeCodeHarness extends FileHarness {
|
|
|
56
98
|
if (data.env != null)
|
|
57
99
|
Object.assign(environment, credentialRecord(data.env));
|
|
58
100
|
}
|
|
59
|
-
|
|
60
|
-
|
|
101
|
+
return overrides.some(key => environment[key]) || credentialText(settings.apiKeyHelper)
|
|
102
|
+
? 'Claude Code has a settings or environment credential/provider override. Remove it before managing subscriber file logins.' : null;
|
|
103
|
+
}
|
|
104
|
+
snapshot() {
|
|
105
|
+
const unavailable = this.unavailableReason();
|
|
106
|
+
if (unavailable !== null)
|
|
107
|
+
return { accounts: [], unavailable };
|
|
61
108
|
const data = readCredentialDocument(this.file).data;
|
|
62
109
|
if (data.claudeAiOauth == null)
|
|
63
110
|
return { accounts: [], unavailable: null };
|
|
@@ -92,7 +139,7 @@ export class ClaudeCodeHarness extends FileHarness {
|
|
|
92
139
|
const raw = JSON.stringify(next, null, 2) + '\n';
|
|
93
140
|
const configRaw = JSON.stringify(nextConfig, null, 2) + '\n';
|
|
94
141
|
if (readCredentialDocument(this.file).raw !== original.raw || readCredentialDocument(this.configFile).raw !== config.raw)
|
|
95
|
-
throw new Error('Claude Code files changed during the operation;
|
|
142
|
+
throw new Error('Claude Code files changed during the operation; no credential was replaced. Try again.');
|
|
96
143
|
plugins.fs.mkdirSync(plugins.path.dirname(this.file), { recursive: true, mode: 0o700 });
|
|
97
144
|
plugins.fs.mkdirSync(plugins.path.dirname(this.configFile), { recursive: true, mode: 0o700 });
|
|
98
145
|
try {
|
|
@@ -112,14 +159,161 @@ export class ClaudeCodeHarness extends FileHarness {
|
|
|
112
159
|
writeSecretFileAtomically(this.configFile, config.raw ?? '{}\n');
|
|
113
160
|
}
|
|
114
161
|
catch {
|
|
115
|
-
throw new Error('Claude Code switch and rollback were incomplete
|
|
162
|
+
throw new Error('Claude Code switch and rollback were incomplete, so its login and account metadata may not match. Activate a verified saved account with authswitch claude use, then check authswitch claude active.');
|
|
116
163
|
}
|
|
117
|
-
throw new Error('Claude Code switch failed while updating account metadata. The outgoing login remains saved; check
|
|
164
|
+
throw new Error('Claude Code switch failed while updating account metadata and was rolled back. The outgoing login remains saved; check authswitch claude doctor.');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/** The hash that identifies a saved login's refresh token, so a rejected grant is remembered without keeping it. */
|
|
168
|
+
grantKey(oauthArg) { return credentialHash(credentialText(oauthArg.refreshToken) ?? ''); }
|
|
169
|
+
/**
|
|
170
|
+
* The harness's accounts, with the saved copy of the active login brought up to date first.
|
|
171
|
+
*
|
|
172
|
+
* Claude Code rotates the refresh token of the login it is running on, and until now only a switch or a save wrote
|
|
173
|
+
* that back into the stash. A login replaced outside authswitch between two switches therefore left a saved copy
|
|
174
|
+
* holding the token from before the rotation, which the service was observed refusing -- a saved copy that only
|
|
175
|
+
* turns out to be unusable when that account's status is next read. Every read of the native login now mirrors it
|
|
176
|
+
* into its own saved record, so the stash keeps the credential Claude Code last wrote for an account that has one.
|
|
177
|
+
*/
|
|
178
|
+
async readState() {
|
|
179
|
+
await this.mirrorActiveLogin();
|
|
180
|
+
return super.readState();
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Writes the active login into its own saved record when the two differ.
|
|
184
|
+
*
|
|
185
|
+
* This is the only write a read makes, and it is advisory: a store another operation holds, a lock Claude Code
|
|
186
|
+
* holds and files that keep changing under it all leave the saved copy as it is, because the next read mirrors
|
|
187
|
+
* whatever they wrote. The native files are only ever read, and a login without a saved record of its own is
|
|
188
|
+
* never saved implicitly -- that is what `stash` is for.
|
|
189
|
+
*/
|
|
190
|
+
async mirrorActiveLogin() {
|
|
191
|
+
try {
|
|
192
|
+
if (this.staleSavedCopy(this.snapshot()) === null)
|
|
193
|
+
return;
|
|
194
|
+
await this.store.locked(() => this.locks.hold(() => {
|
|
195
|
+
// Under both locks the decision is taken again, from a snapshot proven not to have been read across a write.
|
|
196
|
+
const stale = this.staleSavedCopy(this.stableSnapshot());
|
|
197
|
+
if (stale !== null)
|
|
198
|
+
this.store.replaceCredential(stale.id, stale.credential);
|
|
199
|
+
return [];
|
|
200
|
+
}, { timeoutMs: MIRROR_WAIT_MS }), { signal: AbortSignal.timeout(MIRROR_WAIT_MS) });
|
|
201
|
+
}
|
|
202
|
+
catch { /* A saved copy that could not be brought up to date is no reason to fail a read of the accounts. */ }
|
|
203
|
+
}
|
|
204
|
+
/** The active login's saved record when it no longer holds what Claude Code wrote, with the credential to write. */
|
|
205
|
+
staleSavedCopy(snapshotArg) {
|
|
206
|
+
// Claude Code runs one login, and an installation this adapter cannot read reports none at all.
|
|
207
|
+
const [active] = snapshotArg.accounts;
|
|
208
|
+
if (!active)
|
|
209
|
+
return null;
|
|
210
|
+
const id = this.store.id(active.slotId, active.identity);
|
|
211
|
+
let saved;
|
|
212
|
+
try {
|
|
213
|
+
saved = this.store.read(id);
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return null;
|
|
118
217
|
}
|
|
218
|
+
return credentialHash(JSON.stringify(saved.credential)) === credentialHash(JSON.stringify(active.credential))
|
|
219
|
+
? null : { id, credential: active.credential };
|
|
119
220
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
221
|
+
/**
|
|
222
|
+
* What the native files say about this account: its active login, and why they could not be read at all.
|
|
223
|
+
*
|
|
224
|
+
* Both answers come from one snapshot, because only their combination proves that a login is *not* the active one.
|
|
225
|
+
* An installation this adapter cannot read reports no accounts, so the login Claude Code is actually running on
|
|
226
|
+
* reads as inactive there; anything that would renew a saved login has to refuse instead.
|
|
227
|
+
*/
|
|
228
|
+
nativeView(idArg) {
|
|
229
|
+
const snapshot = this.snapshot();
|
|
230
|
+
return { active: snapshot.accounts.find(account => this.store.id(account.slotId, account.identity) === idArg) ?? null, unavailable: snapshot.unavailable };
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* The account's status. The active login is read as it is: Claude Code refreshes it. A saved login whose access token
|
|
234
|
+
* is due is refreshed first; when that fails, the status says why and keeps the stored plan, and the saved login is
|
|
235
|
+
* left exactly as it was.
|
|
236
|
+
*
|
|
237
|
+
* A refresh is only ever sent for a login the native files prove is not the active one (`nativeView`), and a grant
|
|
238
|
+
* the service already rejected is not sent again while the saved record still holds it.
|
|
239
|
+
*/
|
|
240
|
+
async readAccountStatus(id, optionsArg = {}) {
|
|
241
|
+
const read = (accountArg) => this.status.read(credentialRecord(accountArg.credential.claudeAiOauth), credentialRecord(accountArg.credential.oauthAccount), optionsArg);
|
|
242
|
+
const view = this.nativeView(id);
|
|
243
|
+
if (view.active)
|
|
244
|
+
return read(view.active);
|
|
245
|
+
const saved = this.savedCredential(id);
|
|
246
|
+
const oauth = credentialRecord(saved.credential.claudeAiOauth);
|
|
247
|
+
if (!this.tokens.due(oauth))
|
|
248
|
+
return read(saved);
|
|
249
|
+
if (view.unavailable !== null) {
|
|
250
|
+
return this.status.unavailable(oauth, `Login refresh: this saved login's access token has expired and cannot be renewed for this installation. ${view.unavailable}`);
|
|
251
|
+
}
|
|
252
|
+
if (this.store.read(id).rejectedGrant === this.grantKey(oauth))
|
|
253
|
+
return this.status.unavailable(oauth, `Login refresh: ${SAVED_LOGIN_REJECTED}`);
|
|
254
|
+
let refreshed;
|
|
255
|
+
try {
|
|
256
|
+
refreshed = await this.refreshSaved(id, optionsArg.signal);
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
if (optionsArg.signal?.aborted)
|
|
260
|
+
throw error;
|
|
261
|
+
const problem = error instanceof ClaudeLoginRejectedError ? SAVED_LOGIN_REJECTED
|
|
262
|
+
: error instanceof Error ? error.message : 'the saved login could not be refreshed.';
|
|
263
|
+
return this.status.unavailable(oauth, `Login refresh: ${problem}`, error instanceof ClaudeRateLimitError ? { retryAt: error.retryAt } : undefined);
|
|
264
|
+
}
|
|
265
|
+
return read(refreshed);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* A saved login with fresh tokens, refreshed as the only operation on the store: a switch, a save or another refresh
|
|
269
|
+
* waits for it, so none of them can read or activate a refresh token the service is replacing. Under the lock the
|
|
270
|
+
* native files are read again, so the decision that this is not the active login is taken where it holds: one that
|
|
271
|
+
* became active meanwhile belongs to Claude Code and is returned as it is, one in an installation that can no
|
|
272
|
+
* longer be read is returned unrefreshed, and one another refresh already renewed is not refreshed twice. The new
|
|
273
|
+
* tokens replace the saved ones only while the record still holds the refresh token that was sent, the
|
|
274
|
+
* compare-and-swap Claude Code 2.1.273 applies to its own store (`$fn`, @15410824).
|
|
275
|
+
*/
|
|
276
|
+
refreshSaved(id, signal) {
|
|
277
|
+
return this.store.locked(async () => {
|
|
278
|
+
const view = this.nativeView(id);
|
|
279
|
+
if (view.active)
|
|
280
|
+
return view.active;
|
|
281
|
+
const saved = this.savedCredential(id);
|
|
282
|
+
const oauth = credentialRecord(saved.credential.claudeAiOauth);
|
|
283
|
+
if (view.unavailable !== null || !this.tokens.due(oauth))
|
|
284
|
+
return saved;
|
|
285
|
+
signal?.throwIfAborted();
|
|
286
|
+
let tokens;
|
|
287
|
+
try {
|
|
288
|
+
tokens = await this.tokens.refresh(oauth);
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
// Only this token was rejected; a login saved again replaces it and is tried like any other.
|
|
292
|
+
if (error instanceof ClaudeLoginRejectedError)
|
|
293
|
+
this.recordRejectedGrant(id, oauth);
|
|
294
|
+
throw error;
|
|
295
|
+
}
|
|
296
|
+
const latest = this.savedCredential(id);
|
|
297
|
+
const latestOauth = credentialRecord(latest.credential.claudeAiOauth);
|
|
298
|
+
if (latestOauth.refreshToken !== oauth.refreshToken)
|
|
299
|
+
return latest;
|
|
300
|
+
this.store.replaceCredential(id, { ...latest.credential, claudeAiOauth: { ...latestOauth, ...tokens } });
|
|
301
|
+
return this.savedCredential(id);
|
|
302
|
+
}, { signal });
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Remembers a rejected grant in the saved record, so the next process does not send it again either -- a watch
|
|
306
|
+
* would otherwise replay a dead login every tick, and every new CLI run once more. It is written only while the
|
|
307
|
+
* record still holds the token that was sent, and a record that could not be written changes nothing but that:
|
|
308
|
+
* the refusal the caller reports is the answer, and the grant is simply tried once more.
|
|
309
|
+
*/
|
|
310
|
+
recordRejectedGrant(id, oauthArg) {
|
|
311
|
+
try {
|
|
312
|
+
const latest = credentialRecord(this.savedCredential(id).credential.claudeAiOauth);
|
|
313
|
+
if (latest.refreshToken === oauthArg.refreshToken)
|
|
314
|
+
this.store.rememberRejectedGrant(id, this.grantKey(oauthArg));
|
|
315
|
+
}
|
|
316
|
+
catch { /* Recording is advisory; the rejection is reported either way. */ }
|
|
123
317
|
}
|
|
124
318
|
}
|
|
125
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jbGF1ZGVjb2RlaGFybmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuY2xhdWRlY29kZWhhcm5lc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLFdBQVcsRUFBZ0QsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRyxPQUFPLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxzQkFBc0IsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzVJLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQWdCekQsTUFBTSxhQUFhLEdBQUcsQ0FBQyw2QkFBNkIsRUFBRSxrQ0FBa0MsRUFBRSwyQkFBMkIsRUFBRSxrQkFBa0IsRUFBRSxzQkFBc0IsRUFBRSw2QkFBNkIsRUFBRSxpQkFBaUIsRUFBRSxzQkFBc0IsRUFBRSx5QkFBeUIsRUFBRSx3QkFBd0IsQ0FBQyxDQUFDO0FBRWxTLDhGQUE4RjtBQUM5RixNQUFNLE9BQU8saUJBQWtCLFNBQVEsV0FBVztJQUNoQyxFQUFFLEdBQUcsUUFBUSxDQUFDO0lBQ2QsS0FBSyxHQUFHLGFBQWEsQ0FBQztJQUN0QixTQUFTLEdBQUcsb0dBQW9HLENBQUM7SUFDOUcsS0FBSyxDQUFrQjtJQUN6QixJQUFJLENBQVM7SUFDYixVQUFVLENBQVM7SUFDbkIsR0FBRyxDQUFvQjtJQUN2QixRQUFRLENBQWtCO0lBQzFCLE1BQU0sQ0FBc0I7SUFDN0IsU0FBUyxDQUF5QjtJQUNqQyxhQUFhLENBQVc7SUFFekMsWUFBWSxVQUFxQyxFQUFFO1FBQ2pELEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFB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
|
|
319
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jbGF1ZGVjb2RlaGFybmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuY2xhdWRlY29kZWhhcm5lc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLFdBQVcsRUFBZ0QsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRyxPQUFPLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsc0JBQXNCLEVBQUUsaUJBQWlCLEVBQTBCLE1BQU0sOEJBQThCLENBQUM7QUFDcEwsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxrQkFBa0IsRUFBc0IsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6RixPQUFPLEVBQUUscUJBQXFCLEVBQUUsd0JBQXdCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFvQnpEOzs7OztHQUtHO0FBQ0gsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDO0FBRTdCOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLHFCQUFxQix1T0FBdU8sQ0FBQztBQUU3UixNQUFNLGFBQWEsR0FBRyxDQUFDLDZCQUE2QixFQUFFLGtDQUFrQyxFQUFFLDJCQUEyQixFQUFFLGtCQUFrQixFQUFFLHNCQUFzQixFQUFFLDZCQUE2QixFQUFFLGlCQUFpQixFQUFFLHNCQUFzQixFQUFFLHlCQUF5QixFQUFFLHdCQUF3QixDQUFDLENBQUM7QUFFbFM7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0s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
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface IClaudeCodeLocksOptions {
|
|
2
|
+
/** How long an operation waits for a lock that Claude Code holds. */
|
|
3
|
+
timeoutMs?: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Claude Code's own locks around its login and global config, taken with its own library and options.
|
|
7
|
+
*
|
|
8
|
+
* A running Claude Code picks a swapped credential up on its next request, so a switch no longer waits for it to
|
|
9
|
+
* stop. What it must not do is interleave with that session's own writes: a token refresh that is in flight when
|
|
10
|
+
* the credential is swapped leaves the outgoing account's saved copy with a refresh token the server may already
|
|
11
|
+
* have replaced, and a config save that read `.claude.json` before the swap writes the previous account's
|
|
12
|
+
* metadata back. Claude Code 2.1.273 serialises those writers with proper-lockfile (see hints.md); this class
|
|
13
|
+
* takes the same locks, in the order a refresh nests them, waits a bounded time for a held one, and releases them
|
|
14
|
+
* in reverse order on every path. A lock left behind by a Claude Code that died is stale after its own threshold
|
|
15
|
+
* and is taken over, exactly as Claude Code itself would.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ClaudeCodeLocks {
|
|
18
|
+
private readonly configDir;
|
|
19
|
+
private readonly configFile;
|
|
20
|
+
private readonly timeoutMs;
|
|
21
|
+
constructor(configDir: string, configFile: string, optionsArg?: IClaudeCodeLocksOptions);
|
|
22
|
+
/** The locks of Claude Code 2.1.273, in acquisition order. */
|
|
23
|
+
private locks;
|
|
24
|
+
/**
|
|
25
|
+
* Runs a synchronous read-and-write of the native login while every lock is held.
|
|
26
|
+
*
|
|
27
|
+
* A held lock never makes authswitch sit on the others: like Claude Code, it releases what it holds, waits and
|
|
28
|
+
* starts again, so a live session is never blocked by a switch that is still waiting. A lock that could not be
|
|
29
|
+
* released afterwards is reported as an outcome line, because the write it guarded has completed and the lock
|
|
30
|
+
* expires on its own. `timeoutMs` shortens the wait for a caller that must not make a user wait for it -- a read
|
|
31
|
+
* bringing a saved copy up to date has nothing to finish and can leave it to the next read.
|
|
32
|
+
*/
|
|
33
|
+
hold(actionArg: () => string[], optionsArg?: {
|
|
34
|
+
timeoutMs?: number;
|
|
35
|
+
}): Promise<string[]>;
|
|
36
|
+
/** Takes the locks in order into `heldArg` and returns the first one another process holds, or null once all are held. */
|
|
37
|
+
private acquireAll;
|
|
38
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { errorCode } from './helpers.js';
|
|
3
|
+
const DEFAULT_TIMEOUT_MS = 15_000;
|
|
4
|
+
const RETRY_MS = 250;
|
|
5
|
+
/**
|
|
6
|
+
* Claude Code's own locks around its login and global config, taken with its own library and options.
|
|
7
|
+
*
|
|
8
|
+
* A running Claude Code picks a swapped credential up on its next request, so a switch no longer waits for it to
|
|
9
|
+
* stop. What it must not do is interleave with that session's own writes: a token refresh that is in flight when
|
|
10
|
+
* the credential is swapped leaves the outgoing account's saved copy with a refresh token the server may already
|
|
11
|
+
* have replaced, and a config save that read `.claude.json` before the swap writes the previous account's
|
|
12
|
+
* metadata back. Claude Code 2.1.273 serialises those writers with proper-lockfile (see hints.md); this class
|
|
13
|
+
* takes the same locks, in the order a refresh nests them, waits a bounded time for a held one, and releases them
|
|
14
|
+
* in reverse order on every path. A lock left behind by a Claude Code that died is stale after its own threshold
|
|
15
|
+
* and is taken over, exactly as Claude Code itself would.
|
|
16
|
+
*/
|
|
17
|
+
export class ClaudeCodeLocks {
|
|
18
|
+
configDir;
|
|
19
|
+
configFile;
|
|
20
|
+
timeoutMs;
|
|
21
|
+
constructor(configDir, configFile, optionsArg = {}) {
|
|
22
|
+
this.configDir = configDir;
|
|
23
|
+
this.configFile = configFile;
|
|
24
|
+
this.timeoutMs = optionsArg.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
25
|
+
}
|
|
26
|
+
/** The locks of Claude Code 2.1.273, in acquisition order. */
|
|
27
|
+
async locks() {
|
|
28
|
+
// The OAuth refresh lock's legacy twin is keyed by the resolved directory; Claude Code falls back to the path as given.
|
|
29
|
+
const resolved = await plugins.fs.promises.realpath(this.configDir).catch(() => this.configDir);
|
|
30
|
+
const storageWrite = plugins.path.join(this.configDir, '.storage-write');
|
|
31
|
+
return [
|
|
32
|
+
{ file: this.configDir, lockfilePath: plugins.path.join(this.configDir, '.oauth_refresh.lock'), stale: 60_000, update: 5_000, bestEffort: false },
|
|
33
|
+
{ file: `${resolved}.lock`, lockfilePath: `${resolved}.lock`, stale: 60_000, update: 5_000, bestEffort: true },
|
|
34
|
+
{ file: storageWrite, lockfilePath: `${storageWrite}.lock`, stale: 15_000, bestEffort: false },
|
|
35
|
+
{ file: this.configFile, lockfilePath: `${this.configFile}.lock`, stale: 10_000, bestEffort: false },
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Runs a synchronous read-and-write of the native login while every lock is held.
|
|
40
|
+
*
|
|
41
|
+
* A held lock never makes authswitch sit on the others: like Claude Code, it releases what it holds, waits and
|
|
42
|
+
* starts again, so a live session is never blocked by a switch that is still waiting. A lock that could not be
|
|
43
|
+
* released afterwards is reported as an outcome line, because the write it guarded has completed and the lock
|
|
44
|
+
* expires on its own. `timeoutMs` shortens the wait for a caller that must not make a user wait for it -- a read
|
|
45
|
+
* bringing a saved copy up to date has nothing to finish and can leave it to the next read.
|
|
46
|
+
*/
|
|
47
|
+
async hold(actionArg, optionsArg = {}) {
|
|
48
|
+
const lockfile = await plugins.loadProperLockfile();
|
|
49
|
+
const deadline = Date.now() + (optionsArg.timeoutMs ?? this.timeoutMs);
|
|
50
|
+
const held = [];
|
|
51
|
+
const unreleased = [];
|
|
52
|
+
const releaseAll = async () => {
|
|
53
|
+
for (const lock of held.splice(0).reverse()) {
|
|
54
|
+
// A compromised lock is no longer ours to release; the operation already failed for it.
|
|
55
|
+
try {
|
|
56
|
+
await lock.release();
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (errorCode(error) !== 'ERELEASED')
|
|
60
|
+
unreleased.push(lock.lockfilePath);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
let outcome;
|
|
65
|
+
try {
|
|
66
|
+
for (const directory of new Set([this.configDir, plugins.path.dirname(this.configFile)])) {
|
|
67
|
+
plugins.fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
68
|
+
}
|
|
69
|
+
const locks = await this.locks();
|
|
70
|
+
for (;;) {
|
|
71
|
+
// Each attempt owns its flag, so a late report about a lock released in an earlier attempt changes nothing.
|
|
72
|
+
const attempt = { compromised: false };
|
|
73
|
+
const busy = await this.acquireAll(lockfile, locks, held, () => { attempt.compromised = true; });
|
|
74
|
+
if (busy === null) {
|
|
75
|
+
if (attempt.compromised)
|
|
76
|
+
throw new Error('A Claude Code lock was taken over while authswitch took the others; nothing was changed. Try again.');
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
await releaseAll();
|
|
80
|
+
if (Date.now() >= deadline) {
|
|
81
|
+
throw new Error(`Claude Code is refreshing or saving its login (${busy.lockfilePath} is held); nothing was changed. Try again in a moment.`);
|
|
82
|
+
}
|
|
83
|
+
await new Promise(resolve => { setTimeout(resolve, Math.min(RETRY_MS, Math.max(1, deadline - Date.now()))); });
|
|
84
|
+
}
|
|
85
|
+
outcome = { lines: actionArg() };
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
outcome = { error };
|
|
89
|
+
}
|
|
90
|
+
await releaseAll();
|
|
91
|
+
const note = unreleased.length ? `Claude Code's lock ${unreleased.join(', ')} could not be released; it expires on its own within a minute.` : null;
|
|
92
|
+
if ('error' in outcome) {
|
|
93
|
+
if (note === null)
|
|
94
|
+
throw outcome.error;
|
|
95
|
+
throw new Error(`${outcome.error instanceof Error ? outcome.error.message : 'Credential operation failed.'} ${note}`);
|
|
96
|
+
}
|
|
97
|
+
return note === null ? outcome.lines : [...outcome.lines, note];
|
|
98
|
+
}
|
|
99
|
+
/** Takes the locks in order into `heldArg` and returns the first one another process holds, or null once all are held. */
|
|
100
|
+
async acquireAll(lockfileArg, locksArg, heldArg, onCompromisedArg) {
|
|
101
|
+
for (const lock of locksArg) {
|
|
102
|
+
try {
|
|
103
|
+
const release = await lockfileArg.lock(lock.file, {
|
|
104
|
+
lockfilePath: lock.lockfilePath, realpath: false, stale: lock.stale, update: lock.update, onCompromised: onCompromisedArg,
|
|
105
|
+
});
|
|
106
|
+
heldArg.push({ lockfilePath: lock.lockfilePath, release });
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (errorCode(error) === 'ELOCKED')
|
|
110
|
+
return lock;
|
|
111
|
+
if (!lock.bestEffort)
|
|
112
|
+
throw new Error(`Claude Code's lock ${lock.lockfilePath} could not be taken (${errorCode(error) ?? 'unknown error'}); nothing was changed.`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jbGF1ZGVjb2RlbG9ja3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLmNsYXVkZWNvZGVsb2Nrcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBeUJ6QyxNQUFNLGtCQUFrQixHQUFHLE1BQU0sQ0FBQztBQUNsQyxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUM7QUFFckI7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUdHO0lBQW9DO0lBRmhELFNBQVMsQ0FBUztJQUVuQyxZQUE2QixTQUFpQixFQUFtQixVQUFrQixFQUFFLGFBQXNDLEVBQUU7UUFBaEcsY0FBUyxHQUFULFNBQVMsQ0FBUTtRQUFtQixlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQ2pGLElBQUksQ0FBQyxTQUFTLEdBQUcsVUFBVSxDQUFDLFNBQVMsSUFBSSxrQkFBa0IsQ0FBQztJQUM5RCxDQUFDO0lBRUQsOERBQThEO0lBQ3RELEtBQUssQ0FBQyxLQUFLO1FBQ2pCLHdIQUF3SDtRQUN4SCxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoRyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFDekUsT0FBTztZQUNMLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUscUJB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
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import type { IHarnessAccountStatus, IHarnessStatusOptions } from './interfaces.harness.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code's read-only OAuth account endpoints: the profile and usage of one login, with the access token it
|
|
4
|
+
* carries. It never refreshes that token; `ClaudeCodeHarness` refreshes a saved login first, and leaves the active
|
|
5
|
+
* login's tokens to Claude Code. No inference or browser session is used.
|
|
6
|
+
*/
|
|
3
7
|
export declare class ClaudeAccountStatus {
|
|
4
8
|
private readonly fetcher;
|
|
5
|
-
|
|
9
|
+
private readonly now;
|
|
10
|
+
constructor(fetcher?: typeof fetch, now?: () => number);
|
|
6
11
|
private get;
|
|
12
|
+
/** The profile, from the session while it is younger than an hour; the session key is a hash of the token, never the token. */
|
|
13
|
+
private profile;
|
|
14
|
+
/** A rejected login and an unsupported or foreign profile are answers; a rate limit or a failed request is thrown. */
|
|
15
|
+
private lookupProfile;
|
|
16
|
+
/** The plan the login was saved with, the only one known while the service cannot be asked. */
|
|
17
|
+
private storedSummary;
|
|
18
|
+
/** A login that could not be made usable for a lookup: its stored plan and why, with the service's retry time for a rate limit. */
|
|
19
|
+
unavailable(oauth: Record<string, unknown>, problem: string, rateLimit?: IHarnessAccountStatus['rateLimit']): IHarnessAccountStatus;
|
|
7
20
|
read(oauth: Record<string, unknown>, account: Record<string, unknown>, optionsArg?: IHarnessStatusOptions): Promise<IHarnessAccountStatus>;
|
|
8
21
|
}
|