@cortexkit/anthropic-auth-core 1.22.0 → 2.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.
Files changed (133) hide show
  1. package/README.md +2 -0
  2. package/dist/accounts.d.ts +52 -8
  3. package/dist/cachekeep.d.ts +27 -1
  4. package/dist/cch.d.ts +11 -1
  5. package/dist/claude-code.d.ts +23 -1
  6. package/dist/claustrum-enrollment.d.ts +72 -0
  7. package/dist/claustrum-scoped-roster.d.ts +27 -0
  8. package/dist/claustrum-scoped-runtime.d.ts +31 -0
  9. package/dist/claustrum-scoped.d.ts +53 -0
  10. package/dist/claustrum.d.ts +16 -82
  11. package/dist/commands/account.d.ts +38 -11
  12. package/dist/constants.d.ts +3 -2
  13. package/dist/custom-headers.d.ts +3 -0
  14. package/dist/index.d.ts +50 -0
  15. package/dist/index.js +29700 -31
  16. package/dist/internal-types/LICENSE +21 -0
  17. package/dist/internal-types/commands/builtins.d.ts +71 -0
  18. package/dist/internal-types/commands/index.d.ts +10 -0
  19. package/dist/internal-types/commands/menu.d.ts +61 -0
  20. package/dist/internal-types/commands/model.d.ts +238 -0
  21. package/dist/internal-types/commands/pi.d.ts +23 -0
  22. package/dist/internal-types/commands/seam.d.ts +72 -0
  23. package/dist/internal-types/fs/refresh-file-lock.d.ts +33 -0
  24. package/dist/internal-types/logger/capture-sink.d.ts +14 -0
  25. package/dist/internal-types/logger/engine.d.ts +100 -0
  26. package/dist/internal-types/logger/index.d.ts +6 -0
  27. package/dist/internal-types/logger/redact.d.ts +11 -0
  28. package/dist/internal-types/pi-slot/index.d.ts +3 -0
  29. package/dist/internal-types/pi-slot/slot.d.ts +49 -0
  30. package/dist/internal-types/quota/codec.d.ts +11 -0
  31. package/dist/internal-types/quota/format.d.ts +46 -0
  32. package/dist/internal-types/quota/index.d.ts +10 -0
  33. package/dist/internal-types/quota/map.d.ts +63 -0
  34. package/dist/internal-types/quota/merge.d.ts +48 -0
  35. package/dist/internal-types/quota/projection.d.ts +64 -0
  36. package/dist/internal-types/store/attribution.d.ts +28 -0
  37. package/dist/internal-types/store/errors.d.ts +55 -0
  38. package/dist/internal-types/store/hooks.d.ts +12 -0
  39. package/dist/internal-types/store/identity.d.ts +39 -0
  40. package/dist/internal-types/store/index.d.ts +21 -0
  41. package/dist/internal-types/store/mutate.d.ts +189 -0
  42. package/dist/internal-types/store/pool.d.ts +196 -0
  43. package/dist/internal-types/store/provider-state.d.ts +131 -0
  44. package/dist/internal-types/store/publication.d.ts +47 -0
  45. package/dist/internal-types/store/pull.d.ts +36 -0
  46. package/dist/internal-types/store/refresh-lock.d.ts +63 -0
  47. package/dist/internal-types/store/refresh.d.ts +72 -0
  48. package/dist/internal-types/store/rows.d.ts +313 -0
  49. package/dist/internal-types/store/runtime.d.ts +36 -0
  50. package/dist/internal-types/store/schema.d.ts +443 -0
  51. package/dist/internal-types/store/settings.d.ts +63 -0
  52. package/dist/internal-types/store/torn.d.ts +78 -0
  53. package/dist/migration-source.d.ts +33 -0
  54. package/dist/model-remap.d.ts +27 -0
  55. package/dist/models.d.ts +60 -0
  56. package/dist/native-account-runtime.d.ts +121 -0
  57. package/dist/native-account-view.d.ts +126 -0
  58. package/dist/native-command-effects.d.ts +59 -0
  59. package/dist/native-credential-validation.d.ts +42 -0
  60. package/dist/native-custody-activation.d.ts +45 -0
  61. package/dist/native-custody.d.ts +114 -0
  62. package/dist/native-enrollment-authority.d.ts +2 -0
  63. package/dist/native-host-auth-read.d.ts +3 -0
  64. package/dist/native-host-auth-write.d.ts +51 -0
  65. package/dist/native-host-auth.d.ts +12 -0
  66. package/dist/native-local-credential-service.d.ts +76 -0
  67. package/dist/native-local-runtime-readers.d.ts +22 -0
  68. package/dist/native-lock-observer.d.ts +12 -0
  69. package/dist/native-menu-executor.d.ts +243 -0
  70. package/dist/native-menu-model.d.ts +142 -0
  71. package/dist/native-migration-proof.d.ts +28 -0
  72. package/dist/native-migration-source.d.ts +47 -0
  73. package/dist/native-migration.d.ts +66 -0
  74. package/dist/native-quota-codec.d.ts +32 -0
  75. package/dist/native-refresh-coordinator.d.ts +240 -0
  76. package/dist/native-roster-seed.d.ts +115 -0
  77. package/dist/native-runtime-registry.d.ts +19 -0
  78. package/dist/native-runtime.d.ts +204 -0
  79. package/dist/native-transient-account.d.ts +38 -0
  80. package/dist/native-ui.d.ts +45 -0
  81. package/dist/native-usage-publication.d.ts +11 -0
  82. package/dist/native-vault-admission.d.ts +8 -0
  83. package/dist/native-vault-connection.d.ts +33 -0
  84. package/dist/native-vault-paths.d.ts +13 -0
  85. package/dist/native-vault-runtime.d.ts +102 -0
  86. package/dist/native-vault-seed.d.ts +16 -0
  87. package/dist/oauth-profile.d.ts +2 -1
  88. package/dist/pool-authority.d.ts +159 -0
  89. package/dist/pool-binding.d.ts +32 -0
  90. package/dist/pool-paths.d.ts +21 -0
  91. package/dist/pool-store.d.ts +32 -0
  92. package/dist/prime.d.ts +11 -3
  93. package/dist/provider-error.d.ts +139 -0
  94. package/dist/quota-header-feed.d.ts +13 -0
  95. package/dist/quota-manager.d.ts +30 -5
  96. package/dist/relay.d.ts +22 -1
  97. package/dist/request-history.d.ts +34 -0
  98. package/dist/sse.d.ts +81 -0
  99. package/dist/sticky-routing.d.ts +29 -0
  100. package/package.json +9 -3
  101. package/dist/accounts.js +0 -3330
  102. package/dist/auth.js +0 -182
  103. package/dist/cache1h.js +0 -97
  104. package/dist/cachekeep-registry.js +0 -124
  105. package/dist/cachekeep.js +0 -578
  106. package/dist/cch.js +0 -127
  107. package/dist/claude-code.js +0 -388
  108. package/dist/claustrum.js +0 -529
  109. package/dist/commands/account.js +0 -239
  110. package/dist/constants.js +0 -82
  111. package/dist/dump.js +0 -616
  112. package/dist/fast.js +0 -66
  113. package/dist/json.js +0 -10
  114. package/dist/killswitch.js +0 -132
  115. package/dist/logger.js +0 -286
  116. package/dist/logging.js +0 -59
  117. package/dist/mid-conversation-output-config.js +0 -89
  118. package/dist/models.js +0 -141
  119. package/dist/network-errors.js +0 -27
  120. package/dist/oauth-profile.js +0 -54
  121. package/dist/pkce.js +0 -17
  122. package/dist/prime.js +0 -823
  123. package/dist/provider.js +0 -0
  124. package/dist/quota-header-feed.js +0 -279
  125. package/dist/quota-headers.js +0 -121
  126. package/dist/quota-manager.js +0 -805
  127. package/dist/quotas.js +0 -141
  128. package/dist/relay.js +0 -1243
  129. package/dist/routing.js +0 -94
  130. package/dist/start.js +0 -29
  131. package/dist/sticky-routing.js +0 -523
  132. package/dist/thinking-binding.js +0 -54
  133. package/dist/token-fingerprint.js +0 -8
package/dist/auth.js DELETED
@@ -1,182 +0,0 @@
1
- import { assertNotCustodyTombstone } from './claustrum.js';
2
- import { AUTHORIZE_URLS, AXIOS_USER_AGENT, CLIENT_ID, CODE_CALLBACK_URL, OAUTH_SCOPES, REFRESH_SCOPE, TOKEN_URL, } from './constants.js';
3
- import { isTransientNetworkError } from './network-errors.js';
4
- import { generatePKCE } from './pkce.js';
5
- export function parseRetryAfterHeader(value) {
6
- if (!value)
7
- return undefined;
8
- const seconds = Number(value);
9
- if (Number.isFinite(seconds) && seconds > 0)
10
- return Math.ceil(seconds);
11
- const date = Date.parse(value);
12
- if (Number.isFinite(date)) {
13
- const delta = Math.ceil((date - Date.now()) / 1000);
14
- return delta > 0 ? delta : undefined;
15
- }
16
- return undefined;
17
- }
18
- export class ClaudeOAuthRefreshError extends Error {
19
- status;
20
- body;
21
- /** Parsed Retry-After value in seconds, if the server provided one. */
22
- retryAfter;
23
- /**
24
- * Duck-typed marker: any error carrying `isRefreshError: true` arms the
25
- * refresh backoff in consumers that receive it (recordQuotaRefreshError).
26
- * Provider-agnostic — shared-core extraction of anthropic-auth and
27
- * openai-auth relies on this field instead of instanceof.
28
- */
29
- isRefreshError = true;
30
- constructor(status, body, retryAfterHeader) {
31
- super(`Claude OAuth refresh failed: ${status} — ${body}`);
32
- this.status = status;
33
- this.body = body;
34
- this.name = 'ClaudeOAuthRefreshError';
35
- this.retryAfter = parseRetryAfterHeader(retryAfterHeader ?? undefined);
36
- }
37
- }
38
- export async function refreshClaudeOAuthToken(input) {
39
- assertNotCustodyTombstone(input.refreshToken, 'anthropic');
40
- const fetchImpl = input.fetchImpl ?? fetch;
41
- const maxRetries = input.maxRetries ?? 2;
42
- const baseDelayMs = input.baseDelayMs ?? 500;
43
- const setTimeoutImpl = input.setTimeoutImpl ?? globalThis.setTimeout;
44
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
45
- try {
46
- if (attempt > 0) {
47
- const delay = baseDelayMs * 2 ** (attempt - 1);
48
- await new Promise((resolve) => setTimeoutImpl(resolve, delay));
49
- }
50
- const response = await fetchImpl(TOKEN_URL, {
51
- method: 'POST',
52
- headers: {
53
- 'Content-Type': 'application/json',
54
- Accept: 'application/json, text/plain, */*',
55
- 'User-Agent': AXIOS_USER_AGENT,
56
- },
57
- body: JSON.stringify({
58
- grant_type: 'refresh_token',
59
- refresh_token: input.refreshToken,
60
- client_id: CLIENT_ID,
61
- scope: REFRESH_SCOPE,
62
- }),
63
- });
64
- if (!response.ok) {
65
- if (response.status >= 500 && attempt < maxRetries) {
66
- await response.body?.cancel().catch(() => { });
67
- continue;
68
- }
69
- const body = await response.text().catch(() => '');
70
- throw new ClaudeOAuthRefreshError(response.status, body, response.headers.get('retry-after'));
71
- }
72
- const json = (await response.json());
73
- const refreshedAt = input.now?.() ?? Date.now();
74
- return {
75
- access: json.access_token,
76
- refresh: json.refresh_token ?? input.refreshToken,
77
- expires: refreshedAt + json.expires_in * 1000,
78
- expiresIn: json.expires_in,
79
- authLineageId: input.authLineageId,
80
- };
81
- }
82
- catch (error) {
83
- if (error instanceof ClaudeOAuthRefreshError)
84
- throw error;
85
- if (attempt < maxRetries && isTransientNetworkError(error))
86
- continue;
87
- throw error;
88
- }
89
- }
90
- throw new Error('Token refresh exhausted all retries');
91
- }
92
- function generateState() {
93
- return crypto.randomUUID().replace(/-/g, '');
94
- }
95
- function parseCallbackInput(input) {
96
- const trimmed = input.trim();
97
- try {
98
- const url = new URL(trimmed);
99
- const code = url.searchParams.get('code');
100
- const state = url.searchParams.get('state');
101
- if (code && state) {
102
- return { code, state };
103
- }
104
- }
105
- catch {
106
- // Fall through to legacy/manual formats.
107
- }
108
- const hashSplits = trimmed.split('#');
109
- if (hashSplits.length === 2 && hashSplits[0] && hashSplits[1]) {
110
- return { code: hashSplits[0], state: hashSplits[1] };
111
- }
112
- const params = new URLSearchParams(trimmed);
113
- const code = params.get('code');
114
- const state = params.get('state');
115
- if (code && state) {
116
- return { code, state };
117
- }
118
- return null;
119
- }
120
- async function exchangeCode(callback, verifier, redirectUri) {
121
- const result = await fetch(TOKEN_URL, {
122
- method: 'POST',
123
- headers: {
124
- 'Content-Type': 'application/json',
125
- Accept: 'application/json, text/plain, */*',
126
- 'User-Agent': AXIOS_USER_AGENT,
127
- },
128
- body: JSON.stringify({
129
- code: callback.code,
130
- state: callback.state,
131
- grant_type: 'authorization_code',
132
- client_id: CLIENT_ID,
133
- redirect_uri: redirectUri,
134
- code_verifier: verifier,
135
- }),
136
- });
137
- if (!result.ok) {
138
- return {
139
- type: 'failed',
140
- };
141
- }
142
- const json = (await result.json());
143
- return {
144
- type: 'success',
145
- refresh: json.refresh_token,
146
- access: json.access_token,
147
- expires: Date.now() + json.expires_in * 1000,
148
- };
149
- }
150
- export async function authorize(mode) {
151
- const pkce = await generatePKCE();
152
- const state = generateState();
153
- const url = new URL(AUTHORIZE_URLS[mode], import.meta.url);
154
- url.searchParams.set('code', 'true');
155
- url.searchParams.set('client_id', CLIENT_ID);
156
- url.searchParams.set('response_type', 'code');
157
- url.searchParams.set('redirect_uri', CODE_CALLBACK_URL);
158
- url.searchParams.set('scope', OAUTH_SCOPES.join(' '));
159
- url.searchParams.set('code_challenge', pkce.challenge);
160
- url.searchParams.set('code_challenge_method', 'S256');
161
- url.searchParams.set('state', state);
162
- return {
163
- url: url.toString(),
164
- redirectUri: CODE_CALLBACK_URL,
165
- state,
166
- verifier: pkce.verifier,
167
- };
168
- }
169
- export async function exchange(input, verifier, redirectUri, expectedState) {
170
- const callback = parseCallbackInput(input);
171
- if (!callback) {
172
- return {
173
- type: 'failed',
174
- };
175
- }
176
- if (expectedState && callback.state !== expectedState) {
177
- return {
178
- type: 'failed',
179
- };
180
- }
181
- return exchangeCode(callback, verifier, redirectUri);
182
- }
package/dist/cache1h.js DELETED
@@ -1,97 +0,0 @@
1
- import { DEFAULT_CACHE_1H_MODE } from './constants.js';
2
- export const CACHE_1H_COMMAND_NAME = 'claude-cache';
3
- const CACHE_1H_STATUS_TITLE = '## Claude Cache Status';
4
- const CACHE_1H_ENABLED_TITLE = '## Claude Cache Enabled';
5
- const CACHE_1H_DISABLED_TITLE = '## Claude Cache Disabled';
6
- const CACHE_1H_USAGE_TITLE = '## Claude Cache Usage';
7
- const CACHE_1H_USAGE = 'Usage: `/claude-cache`, `/claude-cache on`, `/claude-cache off`, or `/claude-cache mode explicit|automatic|hybrid`.';
8
- let cache1hEnabled = false;
9
- let cache1hMode = DEFAULT_CACHE_1H_MODE;
10
- export function isCache1hEnabled() {
11
- return cache1hEnabled;
12
- }
13
- export function getCache1hMode() {
14
- return cache1hMode;
15
- }
16
- export function setCache1hEnabled(enabled) {
17
- cache1hEnabled = enabled;
18
- }
19
- export function setCache1hMode(mode) {
20
- cache1hMode = mode;
21
- }
22
- export function setCache1hState(input) {
23
- cache1hEnabled = input.enabled;
24
- cache1hMode = input.mode;
25
- }
26
- export function resetCache1hState() {
27
- cache1hEnabled = false;
28
- cache1hMode = DEFAULT_CACHE_1H_MODE;
29
- }
30
- export function parseCache1hCommandAction(argumentsText) {
31
- const normalized = argumentsText.trim().split(/\s+/).filter(Boolean);
32
- if (normalized.length === 0)
33
- return { type: 'status' };
34
- if (normalized.length === 1 && normalized[0] === 'on')
35
- return { type: 'enable' };
36
- if (normalized.length === 1 && normalized[0] === 'off')
37
- return { type: 'disable' };
38
- if (normalized.length === 2 &&
39
- normalized[0] === 'mode' &&
40
- (normalized[1] === 'explicit' ||
41
- normalized[1] === 'automatic' ||
42
- normalized[1] === 'hybrid')) {
43
- return { type: 'mode', mode: normalized[1] };
44
- }
45
- return { type: 'usage' };
46
- }
47
- export function buildCache1hStatusSummary(input) {
48
- const enabled = input?.enabled ?? cache1hEnabled;
49
- const mode = input?.mode ?? cache1hMode;
50
- return [
51
- CACHE_1H_STATUS_TITLE,
52
- '',
53
- `- Enabled: ${enabled ? 'enabled' : 'disabled'}`,
54
- `- Mode: ${mode}`,
55
- '- Persisted: ~/.config/opencode/anthropic-auth.json',
56
- '- Scope: main sessions only; subagent sessions keep default ephemeral cache behavior',
57
- '- Modes: explicit = existing OpenCode breakpoints; automatic = top-level cache_control only; hybrid = system + messages[0] + top-level cache_control',
58
- '- TTL: 1h when enabled for main sessions; default ephemeral cache behavior otherwise',
59
- ].join('\n');
60
- }
61
- export function executeCache1hCommand(input) {
62
- const action = parseCache1hCommandAction(input.argumentsText);
63
- const enabled = input.enabled ?? cache1hEnabled;
64
- const mode = input.mode ?? cache1hMode;
65
- if (action.type === 'status')
66
- return buildCache1hStatusSummary({ enabled, mode });
67
- if (action.type === 'enable') {
68
- return [
69
- CACHE_1H_ENABLED_TITLE,
70
- '',
71
- buildCache1hStatusSummary({ enabled: true, mode }),
72
- ].join('\n');
73
- }
74
- if (action.type === 'disable') {
75
- return [
76
- CACHE_1H_DISABLED_TITLE,
77
- '',
78
- buildCache1hStatusSummary({ enabled: false, mode }),
79
- ].join('\n');
80
- }
81
- if (action.type === 'mode') {
82
- return [
83
- CACHE_1H_STATUS_TITLE,
84
- '',
85
- `Mode updated to \`${action.mode}\`.`,
86
- '',
87
- buildCache1hStatusSummary({ enabled, mode: action.mode }),
88
- ].join('\n');
89
- }
90
- return [
91
- CACHE_1H_USAGE_TITLE,
92
- '',
93
- CACHE_1H_USAGE,
94
- '',
95
- buildCache1hStatusSummary({ enabled, mode }),
96
- ].join('\n');
97
- }
@@ -1,124 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { mkdir, readdir, readFile, rename, rm, writeFile, } from 'node:fs/promises';
3
- import { tmpdir } from 'node:os';
4
- import { join } from 'node:path';
5
- export const CACHE_KEEP_REGISTRY_LEASE_MS = 3 * 60_000;
6
- function normalizeSession(value) {
7
- if (!value || typeof value !== 'object' || Array.isArray(value))
8
- return;
9
- const record = value;
10
- if (typeof record.id !== 'string' ||
11
- record.id.length === 0 ||
12
- typeof record.cacheExpiresAt !== 'number' ||
13
- !Number.isFinite(record.cacheExpiresAt) ||
14
- typeof record.nextPrewarmAt !== 'number' ||
15
- !Number.isFinite(record.nextPrewarmAt)) {
16
- return;
17
- }
18
- return {
19
- id: record.id,
20
- cacheExpiresAt: record.cacheExpiresAt,
21
- nextPrewarmAt: record.nextPrewarmAt,
22
- };
23
- }
24
- function normalizeRecord(value) {
25
- if (!value || typeof value !== 'object' || Array.isArray(value))
26
- return;
27
- const record = value;
28
- if (record.version !== 1 ||
29
- typeof record.updatedAt !== 'number' ||
30
- !Number.isFinite(record.updatedAt) ||
31
- !Array.isArray(record.sessions)) {
32
- return;
33
- }
34
- return {
35
- version: 1,
36
- updatedAt: record.updatedAt,
37
- sessions: record.sessions.flatMap((session) => {
38
- const normalized = normalizeSession(session);
39
- return normalized ? [normalized] : [];
40
- }),
41
- };
42
- }
43
- export function getDefaultCacheKeepRegistryDirectory(scope) {
44
- return join(tmpdir(), 'opencode-anthropic-auth', 'cachekeep-sessions', scope);
45
- }
46
- export class CacheKeepSessionRegistry {
47
- options;
48
- filePath;
49
- writeChain = Promise.resolve();
50
- constructor(options) {
51
- this.options = options;
52
- const instanceId = options.instanceId ?? `${process.pid}-${randomUUID()}`;
53
- this.filePath = join(options.directory, `${instanceId}.json`);
54
- }
55
- publish(sessions) {
56
- const snapshot = sessions.map((session) => ({ ...session }));
57
- this.writeChain = this.writeChain
58
- .catch(() => { })
59
- .then(async () => {
60
- if (snapshot.length === 0) {
61
- await rm(this.filePath, { force: true });
62
- return;
63
- }
64
- await mkdir(this.options.directory, { recursive: true, mode: 0o700 });
65
- const tempPath = `${this.filePath}.${randomUUID()}.tmp`;
66
- const record = {
67
- version: 1,
68
- updatedAt: this.options.now?.() ?? Date.now(),
69
- sessions: snapshot,
70
- };
71
- await writeFile(tempPath, `${JSON.stringify(record)}\n`, {
72
- mode: 0o600,
73
- });
74
- await rename(tempPath, this.filePath);
75
- });
76
- return this.writeChain;
77
- }
78
- async list(localSessions = []) {
79
- await this.writeChain.catch(() => { });
80
- const now = this.options.now?.() ?? Date.now();
81
- const leaseMs = this.options.leaseMs ?? CACHE_KEEP_REGISTRY_LEASE_MS;
82
- let names;
83
- try {
84
- names = (await readdir(this.options.directory)).filter((name) => name.endsWith('.json'));
85
- }
86
- catch {
87
- names = [];
88
- }
89
- const records = await Promise.all(names.map(async (name) => {
90
- try {
91
- const raw = await readFile(join(this.options.directory, name), 'utf8');
92
- return normalizeRecord(JSON.parse(raw));
93
- }
94
- catch {
95
- return undefined;
96
- }
97
- }));
98
- const sessions = new Map();
99
- for (const record of records) {
100
- if (!record ||
101
- now - record.updatedAt > leaseMs ||
102
- record.updatedAt > now) {
103
- continue;
104
- }
105
- for (const session of record.sessions) {
106
- const existing = sessions.get(session.id);
107
- if (!existing || session.cacheExpiresAt > existing.cacheExpiresAt) {
108
- sessions.set(session.id, session);
109
- }
110
- }
111
- }
112
- for (const session of localSessions) {
113
- const existing = sessions.get(session.id);
114
- if (!existing || session.cacheExpiresAt > existing.cacheExpiresAt) {
115
- sessions.set(session.id, { ...session });
116
- }
117
- }
118
- return [...sessions.values()].sort((left, right) => left.id.localeCompare(right.id));
119
- }
120
- async dispose() {
121
- await this.writeChain.catch(() => { });
122
- await rm(this.filePath, { force: true });
123
- }
124
- }