@cgaravitoq/claude-code-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # @cgaravitoq/claude-code-core
2
+
3
+ Framework-agnostic core for using the **Claude Code OAuth subscription** as an Anthropic
4
+ provider. No Pi, no LangChain — just the native stack, with **zero runtime dependencies**.
5
+
6
+ It exists so the Claude Code internals live in one place and are shared by
7
+ [`@cgaravitoq/open-langchain-ts`](https://github.com/cgaravitoq/open-langchain-ts) and the
8
+ [`pi-claude-code-auth`](https://github.com/cgaravitoq/pi-claude-code-auth) Pi extension.
9
+
10
+ ## What's inside
11
+
12
+ - **creds** — read/refresh `~/.claude/.credentials.json` (and macOS Keychain), with a
13
+ `claude` CLI fallback and a force-refresh path for 401s.
14
+ - **signing** — the reverse-engineered `x-anthropic-billing-header`.
15
+ - **model-config** — `ccVersion`, beta computation (`computeBetas`/`requestBetas`) and frozen
16
+ per-model overrides (adaptive thinking, long context, etc.).
17
+ - **transforms** — Claude Code payload reshaping: billing header injection, identity split,
18
+ `mcp_<PascalCase>` tool prefixing, and orphan tool-pair repair.
19
+
20
+ ## Install
21
+
22
+ ```sh
23
+ npm install @cgaravitoq/claude-code-core
24
+ ```
25
+
26
+ ESM-only, **Node >= 22.19.0**.
27
+
28
+ ## Usage
29
+
30
+ ```ts
31
+ import {
32
+ readClaudeCodeCreds,
33
+ refreshClaudeCodeCreds,
34
+ applyClaudeCodeTransforms,
35
+ requestBetas,
36
+ } from "@cgaravitoq/claude-code-core";
37
+
38
+ const creds = readClaudeCodeCreds();
39
+ if (creds) {
40
+ const fresh = await refreshClaudeCodeCreds(creds);
41
+ // build your Anthropic request, then:
42
+ const params = applyClaudeCodeTransforms(rawParams);
43
+ // send with "anthropic-beta": requestBetas(model, longContext).join(",")
44
+ }
45
+ ```
46
+
47
+ This is the building block, not a chat client — see the consumers above for ready-to-use
48
+ LangChain chat models or a Pi provider.
49
+
50
+ ## Notes
51
+
52
+ Using a subscription OAuth session from a third-party app may violate Anthropic's terms and
53
+ risk your account.
54
+
55
+ ## License
56
+
57
+ MIT
@@ -0,0 +1,69 @@
1
+ declare const OAUTH_TOKEN_URL = "https://claude.ai/v1/oauth/token";
2
+ declare const OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
3
+ interface ClaudeCodeCreds {
4
+ accessToken: string;
5
+ refreshToken: string;
6
+ expiresAt: number;
7
+ }
8
+ declare function readClaudeCodeCreds(): ClaudeCodeCreds | null;
9
+ declare function refreshClaudeCodeCreds(current: ClaudeCodeCreds): Promise<ClaudeCodeCreds>;
10
+ declare function forceRefreshClaudeCodeCreds(current: ClaudeCodeCreds): Promise<ClaudeCodeCreds>;
11
+
12
+ interface ModelOverride {
13
+ readonly exclude?: readonly string[];
14
+ readonly add?: readonly string[];
15
+ longContext?: boolean;
16
+ disableEffort?: boolean;
17
+ adaptiveThinking?: boolean;
18
+ }
19
+ interface ModelConfig {
20
+ ccVersion: string;
21
+ readonly baseBetas: readonly string[];
22
+ readonly longContextBetas: readonly string[];
23
+ readonly modelOverrides: Readonly<Record<string, ModelOverride>>;
24
+ }
25
+ declare const config: ModelConfig;
26
+ declare function getModelOverride(modelId: string): ModelOverride | null;
27
+ declare function computeBetas(modelId: string): string[];
28
+ declare const LONG_CONTEXT_BETA = "context-1m-2025-08-07";
29
+ declare function requestBetas(modelId: string, longContext: boolean): string[];
30
+
31
+ interface Message$1 {
32
+ role?: string;
33
+ content?: string | Array<{
34
+ type?: string;
35
+ text?: string;
36
+ }>;
37
+ }
38
+ declare function buildBillingHeaderValue(messages: Message$1[], version: string, entrypoint: string): string;
39
+
40
+ declare const SYSTEM_IDENTITY = "You are Claude Code, Anthropic's official CLI for Claude.";
41
+ declare function unprefixToolName(name: string): string;
42
+ type SystemEntry = {
43
+ type?: string;
44
+ text?: string;
45
+ cache_control?: unknown;
46
+ };
47
+ type ContentBlock = {
48
+ type?: string;
49
+ text?: string;
50
+ name?: string;
51
+ };
52
+ type Message = {
53
+ role?: string;
54
+ content?: string | ContentBlock[];
55
+ };
56
+ interface ClaudeCodeParams {
57
+ model?: string;
58
+ system?: SystemEntry[] | string;
59
+ thinking?: object;
60
+ output_config?: unknown;
61
+ tools?: Array<{
62
+ name?: string;
63
+ }>;
64
+ messages?: Message[];
65
+ }
66
+ /** Mutates and returns params. Do not call twice on the same object. */
67
+ declare function applyClaudeCodeTransforms<T extends ClaudeCodeParams>(params: T): T;
68
+
69
+ export { type ClaudeCodeCreds, type ClaudeCodeParams, LONG_CONTEXT_BETA, type ModelConfig, type ModelOverride, OAUTH_CLIENT_ID, OAUTH_TOKEN_URL, SYSTEM_IDENTITY, applyClaudeCodeTransforms, buildBillingHeaderValue, computeBetas, config, forceRefreshClaudeCodeCreds, getModelOverride, readClaudeCodeCreds, refreshClaudeCodeCreds, requestBetas, unprefixToolName };
package/dist/index.js ADDED
@@ -0,0 +1,463 @@
1
+ // src/creds.ts
2
+ import { execSync } from "child_process";
3
+ import {
4
+ chmodSync,
5
+ existsSync,
6
+ mkdirSync,
7
+ readFileSync,
8
+ renameSync,
9
+ unlinkSync,
10
+ writeFileSync
11
+ } from "fs";
12
+ import { homedir, tmpdir } from "os";
13
+ import { dirname, join } from "path";
14
+ var OAUTH_TOKEN_URL = "https://claude.ai/v1/oauth/token";
15
+ var OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
16
+ function parseBlob(raw) {
17
+ let parsed;
18
+ try {
19
+ parsed = JSON.parse(raw);
20
+ } catch {
21
+ return null;
22
+ }
23
+ const data = parsed.claudeAiOauth ?? parsed;
24
+ const access = data.accessToken ?? data.access_token;
25
+ const refresh = data.refreshToken ?? data.refresh_token;
26
+ const expires = data.expiresAt ?? data.expires_at;
27
+ if (!access || !refresh || typeof expires !== "number") return null;
28
+ return { accessToken: access, refreshToken: refresh, expiresAt: expires };
29
+ }
30
+ function isExecTimeout(err) {
31
+ const e = err;
32
+ return e.code === "ETIMEDOUT" || e.signal === "SIGTERM" || e.name === "TimeoutError";
33
+ }
34
+ function readFromKeychain() {
35
+ if (process.platform !== "darwin") return null;
36
+ const services = ["Claude Code-credentials"];
37
+ try {
38
+ const dump = execSync(
39
+ `security dump-keychain 2>/dev/null | grep -o '"Claude Code-credentials[^"]*"'`,
40
+ { encoding: "utf-8", timeout: 5e3 }
41
+ );
42
+ const found = Array.from(
43
+ new Set(
44
+ dump.split("\n").map((s) => s.replace(/"/g, "").trim()).filter(Boolean)
45
+ )
46
+ );
47
+ if (found.length > 0) services.splice(0, services.length, ...found);
48
+ } catch (err) {
49
+ if (isExecTimeout(err)) return null;
50
+ }
51
+ for (const svc of services) {
52
+ try {
53
+ const out = execSync(`security find-generic-password -s ${JSON.stringify(svc)} -w`, {
54
+ encoding: "utf-8",
55
+ timeout: 5e3
56
+ }).trim();
57
+ const creds = parseBlob(out);
58
+ if (creds) return creds;
59
+ } catch (err) {
60
+ if (isExecTimeout(err)) return null;
61
+ }
62
+ }
63
+ return null;
64
+ }
65
+ function getCredentialsFilePath() {
66
+ return join(homedir(), ".claude", ".credentials.json");
67
+ }
68
+ function readFromFile() {
69
+ const path = getCredentialsFilePath();
70
+ if (!existsSync(path)) return null;
71
+ try {
72
+ return parseBlob(readFileSync(path, "utf-8"));
73
+ } catch {
74
+ return null;
75
+ }
76
+ }
77
+ function readClaudeCodeCreds() {
78
+ return readFromKeychain() ?? readFromFile();
79
+ }
80
+ function writeBackToFile(creds) {
81
+ const path = getCredentialsFilePath();
82
+ const dir = dirname(path);
83
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true, mode: 448 });
84
+ let existing = {};
85
+ if (existsSync(path)) {
86
+ try {
87
+ existing = JSON.parse(readFileSync(path, "utf-8"));
88
+ } catch {
89
+ }
90
+ }
91
+ const updated = {
92
+ ...existing,
93
+ claudeAiOauth: {
94
+ accessToken: creds.accessToken,
95
+ refreshToken: creds.refreshToken,
96
+ expiresAt: creds.expiresAt
97
+ }
98
+ };
99
+ const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
100
+ try {
101
+ writeFileSync(tmp, JSON.stringify(updated, null, 2), {
102
+ encoding: "utf-8",
103
+ mode: 384
104
+ });
105
+ if (process.platform !== "win32") chmodSync(tmp, 384);
106
+ renameSync(tmp, path);
107
+ } catch (err) {
108
+ try {
109
+ unlinkSync(tmp);
110
+ } catch {
111
+ }
112
+ throw err;
113
+ }
114
+ }
115
+ async function refreshViaOAuth(refreshToken) {
116
+ const body = new URLSearchParams({
117
+ grant_type: "refresh_token",
118
+ client_id: OAUTH_CLIENT_ID,
119
+ refresh_token: refreshToken
120
+ });
121
+ const res = await fetch(OAUTH_TOKEN_URL, {
122
+ method: "POST",
123
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
124
+ body: body.toString()
125
+ });
126
+ if (!res.ok) return null;
127
+ const data = await res.json();
128
+ if (!data.access_token) return null;
129
+ const ttlSec = Number(data.expires_in);
130
+ return {
131
+ accessToken: data.access_token,
132
+ refreshToken: data.refresh_token ?? refreshToken,
133
+ expiresAt: Date.now() + (Number.isFinite(ttlSec) && ttlSec > 0 ? ttlSec : 36e3) * 1e3
134
+ };
135
+ }
136
+ function stringifyRefreshError(err) {
137
+ const message = err instanceof Error ? err.message : String(err);
138
+ return message.length > 200 ? `${message.slice(0, 200)}...` : message;
139
+ }
140
+ function claudeCliPath() {
141
+ const probe = process.platform === "win32" ? "where claude" : "command -v claude";
142
+ try {
143
+ const out = execSync(probe, {
144
+ encoding: "utf-8",
145
+ stdio: ["ignore", "pipe", "ignore"]
146
+ }).trim().split(/\r?\n/)[0];
147
+ return out || null;
148
+ } catch {
149
+ return null;
150
+ }
151
+ }
152
+ function refreshViaCli() {
153
+ const cli = claudeCliPath();
154
+ if (!cli) return "claude CLI not found on PATH";
155
+ try {
156
+ execSync(`${JSON.stringify(cli)} -p . --model haiku`, {
157
+ timeout: 2e4,
158
+ encoding: "utf-8",
159
+ env: { ...process.env, TERM: "dumb" },
160
+ stdio: ["ignore", "ignore", "pipe"],
161
+ cwd: tmpdir()
162
+ });
163
+ return null;
164
+ } catch (err) {
165
+ const e = err;
166
+ if (e.signal === "SIGTERM") return "claude CLI refresh timed out after 20s";
167
+ const stderr = typeof e.stderr === "string" ? e.stderr : e.stderr?.toString("utf-8") ?? "";
168
+ const firstLine = stderr.split(/\r?\n/).find((l) => l.trim());
169
+ return firstLine ? `claude CLI: ${firstLine}` : `claude CLI failed (${e.code ?? "unknown"})`;
170
+ }
171
+ }
172
+ var inFlightRefresh = null;
173
+ function refreshClaudeCodeCreds(current) {
174
+ if (current.expiresAt > Date.now() + 6e4) return Promise.resolve(current);
175
+ return performRefresh(current);
176
+ }
177
+ function forceRefreshClaudeCodeCreds(current) {
178
+ if (inFlightRefresh) return inFlightRefresh;
179
+ const onDisk = readClaudeCodeCreds();
180
+ if (onDisk && onDisk.refreshToken !== current.refreshToken && onDisk.expiresAt > Date.now() + 6e4) {
181
+ return Promise.resolve(onDisk);
182
+ }
183
+ return performRefresh(current);
184
+ }
185
+ function performRefresh(current) {
186
+ if (inFlightRefresh) return inFlightRefresh;
187
+ inFlightRefresh = (async () => {
188
+ try {
189
+ let oauthError;
190
+ const oauth = await refreshViaOAuth(current.refreshToken).catch((e) => {
191
+ oauthError = e;
192
+ return null;
193
+ });
194
+ if (oauth && oauth.expiresAt > Date.now() + 6e4) {
195
+ try {
196
+ writeBackToFile(oauth);
197
+ } catch {
198
+ }
199
+ return oauth;
200
+ }
201
+ const cliReason = refreshViaCli();
202
+ const reread = readClaudeCodeCreds();
203
+ if (reread && reread.expiresAt > Date.now() + 6e4) return reread;
204
+ const reasons = [
205
+ cliReason,
206
+ oauthError ? `OAuth: ${stringifyRefreshError(oauthError)}` : null
207
+ ].filter(Boolean);
208
+ const suffix = reasons.length > 0 ? ` (${reasons.join("; ")})` : "";
209
+ throw new Error(
210
+ `Failed to refresh Claude Code credentials${suffix}. Run \`claude\` once to re-authenticate.`
211
+ );
212
+ } finally {
213
+ inFlightRefresh = null;
214
+ }
215
+ })();
216
+ return inFlightRefresh;
217
+ }
218
+
219
+ // src/model-config.ts
220
+ var config = {
221
+ ccVersion: "2.1.112",
222
+ baseBetas: [
223
+ "claude-code-20250219",
224
+ "oauth-2025-04-20",
225
+ "interleaved-thinking-2025-05-14",
226
+ "prompt-caching-scope-2026-01-05",
227
+ "context-management-2025-06-27",
228
+ "advisor-tool-2026-03-01"
229
+ ],
230
+ longContextBetas: ["context-1m-2025-08-07", "interleaved-thinking-2025-05-14"],
231
+ // Insertion order matters: getModelOverride returns the first key that is a
232
+ // substring of the lowercased model id.
233
+ modelOverrides: {
234
+ haiku: {
235
+ exclude: ["interleaved-thinking-2025-05-14"],
236
+ disableEffort: true
237
+ },
238
+ "4-6": {
239
+ longContext: true,
240
+ add: ["effort-2025-11-24"]
241
+ },
242
+ "4-7": {
243
+ longContext: true,
244
+ add: ["effort-2025-11-24"],
245
+ adaptiveThinking: true
246
+ },
247
+ "4-8": {
248
+ longContext: true,
249
+ add: ["effort-2025-11-24"],
250
+ adaptiveThinking: true
251
+ }
252
+ }
253
+ };
254
+ function getModelOverride(modelId) {
255
+ const lower = modelId.toLowerCase();
256
+ for (const [pattern, override] of Object.entries(config.modelOverrides)) {
257
+ if (lower.includes(pattern)) return override;
258
+ }
259
+ return null;
260
+ }
261
+ function computeBetas(modelId) {
262
+ const override = getModelOverride(modelId);
263
+ let betas = [...config.baseBetas];
264
+ if (override?.longContext) betas = [...betas, ...config.longContextBetas];
265
+ if (override?.exclude) betas = betas.filter((b) => !override.exclude.includes(b));
266
+ if (override?.add) betas = [...betas, ...override.add];
267
+ return Array.from(new Set(betas));
268
+ }
269
+ var LONG_CONTEXT_BETA = "context-1m-2025-08-07";
270
+ function requestBetas(modelId, longContext) {
271
+ const betas = computeBetas(modelId);
272
+ return longContext ? betas : betas.filter((b) => b !== LONG_CONTEXT_BETA);
273
+ }
274
+ Object.values(config.modelOverrides).forEach(Object.freeze);
275
+ Object.freeze(config);
276
+
277
+ // src/signing.ts
278
+ import { createHash } from "crypto";
279
+ var BILLING_SALT = "59cf53e54c78";
280
+ function extractFirstUserMessageText(messages) {
281
+ const userMsg = messages.find((m) => m.role === "user");
282
+ if (!userMsg) return "";
283
+ const content = userMsg.content;
284
+ if (typeof content === "string") return content;
285
+ if (Array.isArray(content)) {
286
+ const textBlock = content.find((b) => b.type === "text");
287
+ if (textBlock && textBlock.type === "text" && textBlock.text) {
288
+ return textBlock.text;
289
+ }
290
+ }
291
+ return "";
292
+ }
293
+ function computeCch(messageText) {
294
+ return createHash("sha256").update(messageText).digest("hex").slice(0, 5);
295
+ }
296
+ function computeVersionSuffix(messageText, version) {
297
+ const sampled = [4, 7, 20].map((i) => i < messageText.length ? messageText[i] : "0").join("");
298
+ const input = `${BILLING_SALT}${sampled}${version}`;
299
+ return createHash("sha256").update(input).digest("hex").slice(0, 3);
300
+ }
301
+ function buildBillingHeaderValue(messages, version, entrypoint) {
302
+ const text = extractFirstUserMessageText(messages);
303
+ const suffix = computeVersionSuffix(text, version);
304
+ const cch = computeCch(text);
305
+ return `x-anthropic-billing-header: cc_version=${version}.${suffix}; cc_entrypoint=${entrypoint}; cch=${cch};`;
306
+ }
307
+
308
+ // src/transforms.ts
309
+ var TOOL_PREFIX = "mcp_";
310
+ var SYSTEM_IDENTITY = "You are Claude Code, Anthropic's official CLI for Claude.";
311
+ var BILLING_PREFIX = "x-anthropic-billing-header";
312
+ function prefixToolName(name) {
313
+ return `${TOOL_PREFIX}${name.charAt(0).toUpperCase()}${name.slice(1)}`;
314
+ }
315
+ function unprefixToolName(name) {
316
+ if (!name.startsWith(TOOL_PREFIX)) return name;
317
+ const rest = name.slice(TOOL_PREFIX.length);
318
+ return rest.charAt(0).toLowerCase() + rest.slice(1);
319
+ }
320
+ function repairToolPairs(messages) {
321
+ const toolUseIds = /* @__PURE__ */ new Set();
322
+ const toolResultIds = /* @__PURE__ */ new Set();
323
+ for (const m of messages) {
324
+ if (!Array.isArray(m.content)) continue;
325
+ for (const block of m.content) {
326
+ const id = block.id;
327
+ const toolUseId = block.tool_use_id;
328
+ if (block.type === "tool_use" && typeof id === "string") toolUseIds.add(id);
329
+ if (block.type === "tool_result" && typeof toolUseId === "string")
330
+ toolResultIds.add(toolUseId);
331
+ }
332
+ }
333
+ const orphanedUses = /* @__PURE__ */ new Set();
334
+ const orphanedResults = /* @__PURE__ */ new Set();
335
+ for (const id of toolUseIds) if (!toolResultIds.has(id)) orphanedUses.add(id);
336
+ for (const id of toolResultIds) if (!toolUseIds.has(id)) orphanedResults.add(id);
337
+ if (!orphanedUses.size && !orphanedResults.size) return messages;
338
+ return messages.map((m) => {
339
+ if (!Array.isArray(m.content)) return m;
340
+ const filtered = m.content.filter((b) => {
341
+ const id = b.id;
342
+ const toolUseId = b.tool_use_id;
343
+ if (b.type === "tool_use" && typeof id === "string") return !orphanedUses.has(id);
344
+ if (b.type === "tool_result" && typeof toolUseId === "string")
345
+ return !orphanedResults.has(toolUseId);
346
+ return true;
347
+ });
348
+ if (filtered.length === 0) {
349
+ return {
350
+ ...m,
351
+ content: m.role === "user" ? [{ type: "text", text: "[tool result omitted]" }] : [{ type: "text", text: "(no content)" }]
352
+ };
353
+ }
354
+ return { ...m, content: filtered };
355
+ });
356
+ }
357
+ function applyClaudeCodeTransforms(params) {
358
+ const version = process.env.ANTHROPIC_CLI_VERSION ?? config.ccVersion;
359
+ const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? "sdk-cli";
360
+ const billingHeader = buildBillingHeaderValue(
361
+ params.messages ?? [],
362
+ version,
363
+ entrypoint
364
+ );
365
+ let system = [];
366
+ if (typeof params.system === "string") {
367
+ if (params.system.trim()) system.push({ type: "text", text: params.system });
368
+ } else if (Array.isArray(params.system)) {
369
+ system = [...params.system];
370
+ }
371
+ system = system.filter((e) => !(typeof e.text === "string" && e.text.startsWith(BILLING_PREFIX)));
372
+ const hasIdentity = system.some(
373
+ (e) => typeof e.text === "string" && e.text.startsWith(SYSTEM_IDENTITY)
374
+ );
375
+ const split = [];
376
+ for (const entry of system) {
377
+ const text = typeof entry.text === "string" ? entry.text : "";
378
+ if (text.startsWith(SYSTEM_IDENTITY) && text.length > SYSTEM_IDENTITY.length) {
379
+ const rest = text.slice(SYSTEM_IDENTITY.length).replace(/^\n+/, "");
380
+ const { text: _t, cache_control: _cc, ...identityProps } = entry;
381
+ const { text: _t2, ...restProps } = entry;
382
+ split.push({ ...identityProps, type: "text", text: SYSTEM_IDENTITY });
383
+ if (rest) split.push({ ...restProps, type: "text", text: rest });
384
+ } else {
385
+ split.push(entry);
386
+ }
387
+ }
388
+ system = split;
389
+ if (!hasIdentity) {
390
+ system.unshift({ type: "text", text: SYSTEM_IDENTITY });
391
+ }
392
+ const kept = [];
393
+ const moved = [];
394
+ for (const entry of system) {
395
+ const text = typeof entry.text === "string" ? entry.text : "";
396
+ if (text.startsWith(BILLING_PREFIX) || text.startsWith(SYSTEM_IDENTITY)) {
397
+ kept.push(entry);
398
+ } else if (text) {
399
+ moved.push(text);
400
+ }
401
+ }
402
+ if (moved.length && Array.isArray(params.messages)) {
403
+ const prefix = moved.join("\n\n");
404
+ const firstUser = params.messages.find((m) => m.role === "user");
405
+ if (firstUser) {
406
+ if (typeof firstUser.content === "string") {
407
+ firstUser.content = `${prefix}
408
+
409
+ ${firstUser.content}`;
410
+ } else if (Array.isArray(firstUser.content)) {
411
+ firstUser.content.unshift({ type: "text", text: prefix });
412
+ }
413
+ } else {
414
+ params.messages.unshift({ role: "user", content: prefix });
415
+ }
416
+ }
417
+ kept.unshift({ type: "text", text: billingHeader });
418
+ params.system = kept;
419
+ const override = getModelOverride(params.model ?? "");
420
+ if (override?.disableEffort && params.thinking && "effort" in params.thinking) {
421
+ delete params.thinking.effort;
422
+ if (!Object.keys(params.thinking).length) delete params.thinking;
423
+ }
424
+ if (Array.isArray(params.tools)) {
425
+ params.tools = params.tools.map((t) => ({
426
+ ...t,
427
+ name: t.name ? prefixToolName(t.name) : t.name
428
+ }));
429
+ }
430
+ if (Array.isArray(params.messages)) {
431
+ params.messages = params.messages.map((m) => {
432
+ if (!Array.isArray(m.content)) return m;
433
+ return {
434
+ ...m,
435
+ content: m.content.map((b) => {
436
+ if (b.type === "tool_use" && typeof b.name === "string") {
437
+ return { ...b, name: prefixToolName(b.name) };
438
+ }
439
+ return b;
440
+ })
441
+ };
442
+ });
443
+ params.messages = repairToolPairs(params.messages);
444
+ }
445
+ return params;
446
+ }
447
+ export {
448
+ LONG_CONTEXT_BETA,
449
+ OAUTH_CLIENT_ID,
450
+ OAUTH_TOKEN_URL,
451
+ SYSTEM_IDENTITY,
452
+ applyClaudeCodeTransforms,
453
+ buildBillingHeaderValue,
454
+ computeBetas,
455
+ config,
456
+ forceRefreshClaudeCodeCreds,
457
+ getModelOverride,
458
+ readClaudeCodeCreds,
459
+ refreshClaudeCodeCreds,
460
+ requestBetas,
461
+ unprefixToolName
462
+ };
463
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/creds.ts","../src/model-config.ts","../src/signing.ts","../src/transforms.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport {\n\tchmodSync,\n\texistsSync,\n\tmkdirSync,\n\treadFileSync,\n\trenameSync,\n\tunlinkSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nexport const OAUTH_TOKEN_URL = \"https://claude.ai/v1/oauth/token\";\nexport const OAUTH_CLIENT_ID = \"9d1c250a-e61b-44d9-88ed-5944d1962f5e\";\n\nexport interface ClaudeCodeCreds {\n\taccessToken: string;\n\trefreshToken: string;\n\texpiresAt: number;\n}\n\ninterface CredentialBlob {\n\taccessToken?: string;\n\trefreshToken?: string;\n\texpiresAt?: number;\n\taccess_token?: string;\n\trefresh_token?: string;\n\texpires_at?: number;\n}\n\nfunction parseBlob(raw: string): ClaudeCodeCreds | null {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch {\n\t\treturn null;\n\t}\n\tconst data =\n\t\t(parsed as { claudeAiOauth?: CredentialBlob }).claudeAiOauth ?? (parsed as CredentialBlob);\n\n\tconst access = data.accessToken ?? data.access_token;\n\tconst refresh = data.refreshToken ?? data.refresh_token;\n\tconst expires = data.expiresAt ?? data.expires_at;\n\n\tif (!access || !refresh || typeof expires !== \"number\") return null;\n\treturn { accessToken: access, refreshToken: refresh, expiresAt: expires };\n}\n\nfunction isExecTimeout(err: unknown): boolean {\n\tconst e = err as { code?: string; signal?: string; name?: string };\n\treturn e.code === \"ETIMEDOUT\" || e.signal === \"SIGTERM\" || e.name === \"TimeoutError\";\n}\n\nfunction readFromKeychain(): ClaudeCodeCreds | null {\n\tif (process.platform !== \"darwin\") return null;\n\tconst services = [\"Claude Code-credentials\"];\n\ttry {\n\t\tconst dump = execSync(\n\t\t\t'security dump-keychain 2>/dev/null | grep -o \\'\"Claude Code-credentials[^\"]*\"\\'',\n\t\t\t{ encoding: \"utf-8\", timeout: 5_000 },\n\t\t);\n\t\tconst found = Array.from(\n\t\t\tnew Set(\n\t\t\t\tdump\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.map((s) => s.replace(/\"/g, \"\").trim())\n\t\t\t\t\t.filter(Boolean),\n\t\t\t),\n\t\t);\n\t\tif (found.length > 0) services.splice(0, services.length, ...found);\n\t} catch (err) {\n\t\tif (isExecTimeout(err)) return null;\n\t}\n\tfor (const svc of services) {\n\t\ttry {\n\t\t\tconst out = execSync(`security find-generic-password -s ${JSON.stringify(svc)} -w`, {\n\t\t\t\tencoding: \"utf-8\",\n\t\t\t\ttimeout: 5_000,\n\t\t\t}).trim();\n\t\t\tconst creds = parseBlob(out);\n\t\t\tif (creds) return creds;\n\t\t} catch (err) {\n\t\t\tif (isExecTimeout(err)) return null;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction getCredentialsFilePath(): string {\n\treturn join(homedir(), \".claude\", \".credentials.json\");\n}\n\nfunction readFromFile(): ClaudeCodeCreds | null {\n\tconst path = getCredentialsFilePath();\n\tif (!existsSync(path)) return null;\n\ttry {\n\t\treturn parseBlob(readFileSync(path, \"utf-8\"));\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function readClaudeCodeCreds(): ClaudeCodeCreds | null {\n\treturn readFromKeychain() ?? readFromFile();\n}\n\nfunction writeBackToFile(creds: ClaudeCodeCreds): void {\n\tconst path = getCredentialsFilePath();\n\tconst dir = dirname(path);\n\tif (!existsSync(dir)) mkdirSync(dir, { recursive: true, mode: 0o700 });\n\tlet existing: Record<string, unknown> = {};\n\tif (existsSync(path)) {\n\t\ttry {\n\t\t\texisting = JSON.parse(readFileSync(path, \"utf-8\")) as Record<string, unknown>;\n\t\t} catch {\n\t\t\t// overwrite\n\t\t}\n\t}\n\tconst updated = {\n\t\t...existing,\n\t\tclaudeAiOauth: {\n\t\t\taccessToken: creds.accessToken,\n\t\t\trefreshToken: creds.refreshToken,\n\t\t\texpiresAt: creds.expiresAt,\n\t\t},\n\t};\n\tconst tmp = `${path}.${process.pid}.${Date.now()}.tmp`;\n\ttry {\n\t\twriteFileSync(tmp, JSON.stringify(updated, null, 2), {\n\t\t\tencoding: \"utf-8\",\n\t\t\tmode: 0o600,\n\t\t});\n\t\tif (process.platform !== \"win32\") chmodSync(tmp, 0o600);\n\t\trenameSync(tmp, path);\n\t} catch (err) {\n\t\ttry {\n\t\t\tunlinkSync(tmp);\n\t\t} catch {\n\t\t\t// already gone\n\t\t}\n\t\tthrow err;\n\t}\n}\n\ninterface OAuthResponse {\n\taccess_token?: string;\n\trefresh_token?: string;\n\texpires_in?: number | string;\n}\n\nasync function refreshViaOAuth(refreshToken: string): Promise<ClaudeCodeCreds | null> {\n\tconst body = new URLSearchParams({\n\t\tgrant_type: \"refresh_token\",\n\t\tclient_id: OAUTH_CLIENT_ID,\n\t\trefresh_token: refreshToken,\n\t});\n\tconst res = await fetch(OAUTH_TOKEN_URL, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\tbody: body.toString(),\n\t});\n\tif (!res.ok) return null;\n\tconst data = (await res.json()) as OAuthResponse;\n\tif (!data.access_token) return null;\n\tconst ttlSec = Number(data.expires_in);\n\treturn {\n\t\taccessToken: data.access_token,\n\t\trefreshToken: data.refresh_token ?? refreshToken,\n\t\texpiresAt: Date.now() + (Number.isFinite(ttlSec) && ttlSec > 0 ? ttlSec : 36_000) * 1000,\n\t};\n}\n\nfunction stringifyRefreshError(err: unknown): string {\n\tconst message = err instanceof Error ? err.message : String(err);\n\treturn message.length > 200 ? `${message.slice(0, 200)}...` : message;\n}\n\nfunction claudeCliPath(): string | null {\n\tconst probe = process.platform === \"win32\" ? \"where claude\" : \"command -v claude\";\n\ttry {\n\t\tconst out = execSync(probe, {\n\t\t\tencoding: \"utf-8\",\n\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t})\n\t\t\t.trim()\n\t\t\t.split(/\\r?\\n/)[0];\n\t\treturn out || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction refreshViaCli(): string | null {\n\tconst cli = claudeCliPath();\n\tif (!cli) return \"claude CLI not found on PATH\";\n\ttry {\n\t\texecSync(`${JSON.stringify(cli)} -p . --model haiku`, {\n\t\t\ttimeout: 20_000,\n\t\t\tencoding: \"utf-8\",\n\t\t\tenv: { ...process.env, TERM: \"dumb\" },\n\t\t\tstdio: [\"ignore\", \"ignore\", \"pipe\"],\n\t\t\tcwd: tmpdir(),\n\t\t});\n\t\treturn null;\n\t} catch (err) {\n\t\tconst e = err as {\n\t\t\tcode?: string;\n\t\t\tsignal?: string;\n\t\t\tstderr?: Buffer | string;\n\t\t};\n\t\tif (e.signal === \"SIGTERM\") return \"claude CLI refresh timed out after 20s\";\n\t\tconst stderr = typeof e.stderr === \"string\" ? e.stderr : (e.stderr?.toString(\"utf-8\") ?? \"\");\n\t\tconst firstLine = stderr.split(/\\r?\\n/).find((l) => l.trim());\n\t\treturn firstLine ? `claude CLI: ${firstLine}` : `claude CLI failed (${e.code ?? \"unknown\"})`;\n\t}\n}\n\n// Module-level lock so concurrent callers reuse the same refresh promise. The\n// OAuth server rotates the refresh token on success, so parallel refreshes with\n// the same token would race and all but one would fail.\nlet inFlightRefresh: Promise<ClaudeCodeCreds> | null = null;\n\nexport function refreshClaudeCodeCreds(current: ClaudeCodeCreds): Promise<ClaudeCodeCreds> {\n\tif (current.expiresAt > Date.now() + 60_000) return Promise.resolve(current);\n\treturn performRefresh(current);\n}\n\n// Force a refresh even when the token still looks fresh — used on a 401 where a\n// timestamp-fresh token was rejected (revoked or rotated out-of-band). Reuses a\n// token another caller already rotated to instead of re-POSTing the stale one.\nexport function forceRefreshClaudeCodeCreds(current: ClaudeCodeCreds): Promise<ClaudeCodeCreds> {\n\tif (inFlightRefresh) return inFlightRefresh;\n\tconst onDisk = readClaudeCodeCreds();\n\tif (\n\t\tonDisk &&\n\t\tonDisk.refreshToken !== current.refreshToken &&\n\t\tonDisk.expiresAt > Date.now() + 60_000\n\t) {\n\t\treturn Promise.resolve(onDisk);\n\t}\n\treturn performRefresh(current);\n}\n\nfunction performRefresh(current: ClaudeCodeCreds): Promise<ClaudeCodeCreds> {\n\tif (inFlightRefresh) return inFlightRefresh;\n\n\tinFlightRefresh = (async () => {\n\t\ttry {\n\t\t\tlet oauthError: unknown;\n\t\t\tconst oauth = await refreshViaOAuth(current.refreshToken).catch((e) => {\n\t\t\t\toauthError = e;\n\t\t\t\treturn null;\n\t\t\t});\n\t\t\tif (oauth && oauth.expiresAt > Date.now() + 60_000) {\n\t\t\t\ttry {\n\t\t\t\t\twriteBackToFile(oauth);\n\t\t\t\t} catch {\n\t\t\t\t\t// non-fatal\n\t\t\t\t}\n\t\t\t\treturn oauth;\n\t\t\t}\n\n\t\t\tconst cliReason = refreshViaCli();\n\t\t\tconst reread = readClaudeCodeCreds();\n\t\t\tif (reread && reread.expiresAt > Date.now() + 60_000) return reread;\n\n\t\t\tconst reasons = [\n\t\t\t\tcliReason,\n\t\t\t\toauthError ? `OAuth: ${stringifyRefreshError(oauthError)}` : null,\n\t\t\t].filter(Boolean);\n\t\t\tconst suffix = reasons.length > 0 ? ` (${reasons.join(\"; \")})` : \"\";\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to refresh Claude Code credentials${suffix}. Run \\`claude\\` once to re-authenticate.`,\n\t\t\t);\n\t\t} finally {\n\t\t\tinFlightRefresh = null;\n\t\t}\n\t})();\n\n\treturn inFlightRefresh;\n}\n","export interface ModelOverride {\n\treadonly exclude?: readonly string[];\n\treadonly add?: readonly string[];\n\tlongContext?: boolean;\n\tdisableEffort?: boolean;\n\t// Opus 4.8/4.7 require thinking:{type:\"adaptive\"} + output_config.effort;\n\t// a manual budget_tokens is rejected with a 400 on these models.\n\tadaptiveThinking?: boolean;\n}\n\nexport interface ModelConfig {\n\tccVersion: string;\n\treadonly baseBetas: readonly string[];\n\treadonly longContextBetas: readonly string[];\n\treadonly modelOverrides: Readonly<Record<string, ModelOverride>>;\n}\n\nexport const config: ModelConfig = {\n\tccVersion: \"2.1.112\",\n\tbaseBetas: [\n\t\t\"claude-code-20250219\",\n\t\t\"oauth-2025-04-20\",\n\t\t\"interleaved-thinking-2025-05-14\",\n\t\t\"prompt-caching-scope-2026-01-05\",\n\t\t\"context-management-2025-06-27\",\n\t\t\"advisor-tool-2026-03-01\",\n\t],\n\tlongContextBetas: [\"context-1m-2025-08-07\", \"interleaved-thinking-2025-05-14\"],\n\t// Insertion order matters: getModelOverride returns the first key that is a\n\t// substring of the lowercased model id.\n\tmodelOverrides: {\n\t\thaiku: {\n\t\t\texclude: [\"interleaved-thinking-2025-05-14\"],\n\t\t\tdisableEffort: true,\n\t\t},\n\t\t\"4-6\": {\n\t\t\tlongContext: true,\n\t\t\tadd: [\"effort-2025-11-24\"],\n\t\t},\n\t\t\"4-7\": {\n\t\t\tlongContext: true,\n\t\t\tadd: [\"effort-2025-11-24\"],\n\t\t\tadaptiveThinking: true,\n\t\t},\n\t\t\"4-8\": {\n\t\t\tlongContext: true,\n\t\t\tadd: [\"effort-2025-11-24\"],\n\t\t\tadaptiveThinking: true,\n\t\t},\n\t},\n};\n\nexport function getModelOverride(modelId: string): ModelOverride | null {\n\tconst lower = modelId.toLowerCase();\n\tfor (const [pattern, override] of Object.entries(config.modelOverrides)) {\n\t\tif (lower.includes(pattern)) return override;\n\t}\n\treturn null;\n}\n\nexport function computeBetas(modelId: string): string[] {\n\tconst override = getModelOverride(modelId);\n\tlet betas = [...config.baseBetas];\n\tif (override?.longContext) betas = [...betas, ...config.longContextBetas];\n\tif (override?.exclude) betas = betas.filter((b) => !override.exclude!.includes(b));\n\tif (override?.add) betas = [...betas, ...override.add];\n\treturn Array.from(new Set(betas));\n}\n\nexport const LONG_CONTEXT_BETA = \"context-1m-2025-08-07\";\n\n// The 1M-context beta classifies the request as long-context, which the Claude\n// Code subscription bills against extra credits; keep it opt-in.\nexport function requestBetas(modelId: string, longContext: boolean): string[] {\n\tconst betas = computeBetas(modelId);\n\treturn longContext ? betas : betas.filter((b) => b !== LONG_CONTEXT_BETA);\n}\n\nObject.values(config.modelOverrides).forEach(Object.freeze);\nObject.freeze(config);\n","import { createHash } from \"node:crypto\";\n\nconst BILLING_SALT = \"59cf53e54c78\";\n\ninterface Message {\n\trole?: string;\n\tcontent?: string | Array<{ type?: string; text?: string }>;\n}\n\nfunction extractFirstUserMessageText(messages: Message[]): string {\n\tconst userMsg = messages.find((m) => m.role === \"user\");\n\tif (!userMsg) return \"\";\n\tconst content = userMsg.content;\n\tif (typeof content === \"string\") return content;\n\tif (Array.isArray(content)) {\n\t\tconst textBlock = content.find((b) => b.type === \"text\");\n\t\tif (textBlock && textBlock.type === \"text\" && textBlock.text) {\n\t\t\treturn textBlock.text;\n\t\t}\n\t}\n\treturn \"\";\n}\n\nfunction computeCch(messageText: string): string {\n\treturn createHash(\"sha256\").update(messageText).digest(\"hex\").slice(0, 5);\n}\n\nfunction computeVersionSuffix(messageText: string, version: string): string {\n\tconst sampled = [4, 7, 20].map((i) => (i < messageText.length ? messageText[i] : \"0\")).join(\"\");\n\tconst input = `${BILLING_SALT}${sampled}${version}`;\n\treturn createHash(\"sha256\").update(input).digest(\"hex\").slice(0, 3);\n}\n\nexport function buildBillingHeaderValue(\n\tmessages: Message[],\n\tversion: string,\n\tentrypoint: string,\n): string {\n\tconst text = extractFirstUserMessageText(messages);\n\tconst suffix = computeVersionSuffix(text, version);\n\tconst cch = computeCch(text);\n\treturn (\n\t\t`x-anthropic-billing-header: ` +\n\t\t`cc_version=${version}.${suffix}; ` +\n\t\t`cc_entrypoint=${entrypoint}; ` +\n\t\t`cch=${cch};`\n\t);\n}\n","import { config, getModelOverride } from \"./model-config\";\nimport { buildBillingHeaderValue } from \"./signing\";\n\nconst TOOL_PREFIX = \"mcp_\";\nexport const SYSTEM_IDENTITY = \"You are Claude Code, Anthropic's official CLI for Claude.\";\nconst BILLING_PREFIX = \"x-anthropic-billing-header\";\n\nfunction prefixToolName(name: string): string {\n\treturn `${TOOL_PREFIX}${name.charAt(0).toUpperCase()}${name.slice(1)}`;\n}\n\nexport function unprefixToolName(name: string): string {\n\tif (!name.startsWith(TOOL_PREFIX)) return name;\n\tconst rest = name.slice(TOOL_PREFIX.length);\n\treturn rest.charAt(0).toLowerCase() + rest.slice(1);\n}\n\ntype SystemEntry = { type?: string; text?: string; cache_control?: unknown };\ntype ContentBlock = { type?: string; text?: string; name?: string };\ntype Message = { role?: string; content?: string | ContentBlock[] };\n\nfunction repairToolPairs(messages: Message[]): Message[] {\n\tconst toolUseIds = new Set<string>();\n\tconst toolResultIds = new Set<string>();\n\tfor (const m of messages) {\n\t\tif (!Array.isArray(m.content)) continue;\n\t\tfor (const block of m.content) {\n\t\t\tconst id = (block as { id?: string }).id;\n\t\t\tconst toolUseId = (block as { tool_use_id?: string }).tool_use_id;\n\t\t\tif (block.type === \"tool_use\" && typeof id === \"string\") toolUseIds.add(id);\n\t\t\tif (block.type === \"tool_result\" && typeof toolUseId === \"string\")\n\t\t\t\ttoolResultIds.add(toolUseId);\n\t\t}\n\t}\n\tconst orphanedUses = new Set<string>();\n\tconst orphanedResults = new Set<string>();\n\tfor (const id of toolUseIds) if (!toolResultIds.has(id)) orphanedUses.add(id);\n\tfor (const id of toolResultIds) if (!toolUseIds.has(id)) orphanedResults.add(id);\n\tif (!orphanedUses.size && !orphanedResults.size) return messages;\n\treturn messages.map((m) => {\n\t\tif (!Array.isArray(m.content)) return m;\n\t\tconst filtered = m.content.filter((b) => {\n\t\t\tconst id = (b as { id?: string }).id;\n\t\t\tconst toolUseId = (b as { tool_use_id?: string }).tool_use_id;\n\t\t\tif (b.type === \"tool_use\" && typeof id === \"string\") return !orphanedUses.has(id);\n\t\t\tif (b.type === \"tool_result\" && typeof toolUseId === \"string\")\n\t\t\t\treturn !orphanedResults.has(toolUseId);\n\t\t\treturn true;\n\t\t});\n\t\tif (filtered.length === 0) {\n\t\t\treturn {\n\t\t\t\t...m,\n\t\t\t\tcontent:\n\t\t\t\t\tm.role === \"user\"\n\t\t\t\t\t\t? [{ type: \"text\", text: \"[tool result omitted]\" }]\n\t\t\t\t\t\t: [{ type: \"text\", text: \"(no content)\" }],\n\t\t\t};\n\t\t}\n\t\treturn { ...m, content: filtered };\n\t});\n}\n\nexport interface ClaudeCodeParams {\n\tmodel?: string;\n\tsystem?: SystemEntry[] | string;\n\tthinking?: object;\n\toutput_config?: unknown;\n\ttools?: Array<{ name?: string }>;\n\tmessages?: Message[];\n}\n\n/** Mutates and returns params. Do not call twice on the same object. */\nexport function applyClaudeCodeTransforms<T extends ClaudeCodeParams>(params: T): T {\n\tconst version = process.env.ANTHROPIC_CLI_VERSION ?? config.ccVersion;\n\tconst entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT ?? \"sdk-cli\";\n\n\tconst billingHeader = buildBillingHeaderValue(\n\t\t(params.messages ?? []) as Parameters<typeof buildBillingHeaderValue>[0],\n\t\tversion,\n\t\tentrypoint,\n\t);\n\n\tlet system: SystemEntry[] = [];\n\tif (typeof params.system === \"string\") {\n\t\tif (params.system.trim()) system.push({ type: \"text\", text: params.system });\n\t} else if (Array.isArray(params.system)) {\n\t\tsystem = [...params.system];\n\t}\n\n\tsystem = system.filter((e) => !(typeof e.text === \"string\" && e.text.startsWith(BILLING_PREFIX)));\n\n\tconst hasIdentity = system.some(\n\t\t(e) => typeof e.text === \"string\" && e.text.startsWith(SYSTEM_IDENTITY),\n\t);\n\n\tconst split: SystemEntry[] = [];\n\tfor (const entry of system) {\n\t\tconst text = typeof entry.text === \"string\" ? entry.text : \"\";\n\t\tif (text.startsWith(SYSTEM_IDENTITY) && text.length > SYSTEM_IDENTITY.length) {\n\t\t\tconst rest = text.slice(SYSTEM_IDENTITY.length).replace(/^\\n+/, \"\");\n\t\t\tconst { text: _t, cache_control: _cc, ...identityProps } = entry;\n\t\t\tconst { text: _t2, ...restProps } = entry;\n\t\t\tsplit.push({ ...identityProps, type: \"text\", text: SYSTEM_IDENTITY });\n\t\t\tif (rest) split.push({ ...restProps, type: \"text\", text: rest });\n\t\t} else {\n\t\t\tsplit.push(entry);\n\t\t}\n\t}\n\tsystem = split;\n\n\tif (!hasIdentity) {\n\t\tsystem.unshift({ type: \"text\", text: SYSTEM_IDENTITY });\n\t}\n\n\tconst kept: SystemEntry[] = [];\n\tconst moved: string[] = [];\n\tfor (const entry of system) {\n\t\tconst text = typeof entry.text === \"string\" ? entry.text : \"\";\n\t\tif (text.startsWith(BILLING_PREFIX) || text.startsWith(SYSTEM_IDENTITY)) {\n\t\t\tkept.push(entry);\n\t\t} else if (text) {\n\t\t\tmoved.push(text);\n\t\t}\n\t}\n\tif (moved.length && Array.isArray(params.messages)) {\n\t\tconst prefix = moved.join(\"\\n\\n\");\n\t\tconst firstUser = params.messages.find((m) => m.role === \"user\");\n\t\tif (firstUser) {\n\t\t\tif (typeof firstUser.content === \"string\") {\n\t\t\t\tfirstUser.content = `${prefix}\\n\\n${firstUser.content}`;\n\t\t\t} else if (Array.isArray(firstUser.content)) {\n\t\t\t\tfirstUser.content.unshift({ type: \"text\", text: prefix });\n\t\t\t}\n\t\t} else {\n\t\t\t// No user turn to carry the system text; synthesize one so the prompt is\n\t\t\t// not dropped and the request is not sent with zero messages.\n\t\t\tparams.messages.unshift({ role: \"user\", content: prefix });\n\t\t}\n\t}\n\n\tkept.unshift({ type: \"text\", text: billingHeader });\n\tparams.system = kept;\n\n\tconst override = getModelOverride(params.model ?? \"\");\n\tif (override?.disableEffort && params.thinking && \"effort\" in params.thinking) {\n\t\tdelete (params.thinking as { effort?: unknown }).effort;\n\t\tif (!Object.keys(params.thinking).length) delete params.thinking;\n\t}\n\n\tif (Array.isArray(params.tools)) {\n\t\tparams.tools = params.tools.map((t) => ({\n\t\t\t...t,\n\t\t\tname: t.name ? prefixToolName(t.name) : t.name,\n\t\t}));\n\t}\n\n\tif (Array.isArray(params.messages)) {\n\t\tparams.messages = params.messages.map((m) => {\n\t\t\tif (!Array.isArray(m.content)) return m;\n\t\t\treturn {\n\t\t\t\t...m,\n\t\t\t\tcontent: m.content.map((b) => {\n\t\t\t\t\tif (b.type === \"tool_use\" && typeof b.name === \"string\") {\n\t\t\t\t\t\treturn { ...b, name: prefixToolName(b.name) };\n\t\t\t\t\t}\n\t\t\t\t\treturn b;\n\t\t\t\t}),\n\t\t\t};\n\t\t});\n\t\tparams.messages = repairToolPairs(params.messages);\n\t}\n\n\treturn params;\n}\n"],"mappings":";AAAA,SAAS,gBAAgB;AACzB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,SAAS,cAAc;AAChC,SAAS,SAAS,YAAY;AAEvB,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AAiB/B,SAAS,UAAU,KAAqC;AACvD,MAAI;AACJ,MAAI;AACH,aAAS,KAAK,MAAM,GAAG;AAAA,EACxB,QAAQ;AACP,WAAO;AAAA,EACR;AACA,QAAM,OACJ,OAA8C,iBAAkB;AAElE,QAAM,SAAS,KAAK,eAAe,KAAK;AACxC,QAAM,UAAU,KAAK,gBAAgB,KAAK;AAC1C,QAAM,UAAU,KAAK,aAAa,KAAK;AAEvC,MAAI,CAAC,UAAU,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AAC/D,SAAO,EAAE,aAAa,QAAQ,cAAc,SAAS,WAAW,QAAQ;AACzE;AAEA,SAAS,cAAc,KAAuB;AAC7C,QAAM,IAAI;AACV,SAAO,EAAE,SAAS,eAAe,EAAE,WAAW,aAAa,EAAE,SAAS;AACvE;AAEA,SAAS,mBAA2C;AACnD,MAAI,QAAQ,aAAa,SAAU,QAAO;AAC1C,QAAM,WAAW,CAAC,yBAAyB;AAC3C,MAAI;AACH,UAAM,OAAO;AAAA,MACZ;AAAA,MACA,EAAE,UAAU,SAAS,SAAS,IAAM;AAAA,IACrC;AACA,UAAM,QAAQ,MAAM;AAAA,MACnB,IAAI;AAAA,QACH,KACE,MAAM,IAAI,EACV,IAAI,CAAC,MAAM,EAAE,QAAQ,MAAM,EAAE,EAAE,KAAK,CAAC,EACrC,OAAO,OAAO;AAAA,MACjB;AAAA,IACD;AACA,QAAI,MAAM,SAAS,EAAG,UAAS,OAAO,GAAG,SAAS,QAAQ,GAAG,KAAK;AAAA,EACnE,SAAS,KAAK;AACb,QAAI,cAAc,GAAG,EAAG,QAAO;AAAA,EAChC;AACA,aAAW,OAAO,UAAU;AAC3B,QAAI;AACH,YAAM,MAAM,SAAS,qCAAqC,KAAK,UAAU,GAAG,CAAC,OAAO;AAAA,QACnF,UAAU;AAAA,QACV,SAAS;AAAA,MACV,CAAC,EAAE,KAAK;AACR,YAAM,QAAQ,UAAU,GAAG;AAC3B,UAAI,MAAO,QAAO;AAAA,IACnB,SAAS,KAAK;AACb,UAAI,cAAc,GAAG,EAAG,QAAO;AAAA,IAChC;AAAA,EACD;AACA,SAAO;AACR;AAEA,SAAS,yBAAiC;AACzC,SAAO,KAAK,QAAQ,GAAG,WAAW,mBAAmB;AACtD;AAEA,SAAS,eAAuC;AAC/C,QAAM,OAAO,uBAAuB;AACpC,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,MAAI;AACH,WAAO,UAAU,aAAa,MAAM,OAAO,CAAC;AAAA,EAC7C,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAEO,SAAS,sBAA8C;AAC7D,SAAO,iBAAiB,KAAK,aAAa;AAC3C;AAEA,SAAS,gBAAgB,OAA8B;AACtD,QAAM,OAAO,uBAAuB;AACpC,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,CAAC,WAAW,GAAG,EAAG,WAAU,KAAK,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACrE,MAAI,WAAoC,CAAC;AACzC,MAAI,WAAW,IAAI,GAAG;AACrB,QAAI;AACH,iBAAW,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,IAClD,QAAQ;AAAA,IAER;AAAA,EACD;AACA,QAAM,UAAU;AAAA,IACf,GAAG;AAAA,IACH,eAAe;AAAA,MACd,aAAa,MAAM;AAAA,MACnB,cAAc,MAAM;AAAA,MACpB,WAAW,MAAM;AAAA,IAClB;AAAA,EACD;AACA,QAAM,MAAM,GAAG,IAAI,IAAI,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;AAChD,MAAI;AACH,kBAAc,KAAK,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG;AAAA,MACpD,UAAU;AAAA,MACV,MAAM;AAAA,IACP,CAAC;AACD,QAAI,QAAQ,aAAa,QAAS,WAAU,KAAK,GAAK;AACtD,eAAW,KAAK,IAAI;AAAA,EACrB,SAAS,KAAK;AACb,QAAI;AACH,iBAAW,GAAG;AAAA,IACf,QAAQ;AAAA,IAER;AACA,UAAM;AAAA,EACP;AACD;AAQA,eAAe,gBAAgB,cAAuD;AACrF,QAAM,OAAO,IAAI,gBAAgB;AAAA,IAChC,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,eAAe;AAAA,EAChB,CAAC;AACD,QAAM,MAAM,MAAM,MAAM,iBAAiB;AAAA,IACxC,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,IAC/D,MAAM,KAAK,SAAS;AAAA,EACrB,CAAC;AACD,MAAI,CAAC,IAAI,GAAI,QAAO;AACpB,QAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,MAAI,CAAC,KAAK,aAAc,QAAO;AAC/B,QAAM,SAAS,OAAO,KAAK,UAAU;AACrC,SAAO;AAAA,IACN,aAAa,KAAK;AAAA,IAClB,cAAc,KAAK,iBAAiB;AAAA,IACpC,WAAW,KAAK,IAAI,KAAK,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,SAAS,QAAU;AAAA,EACrF;AACD;AAEA,SAAS,sBAAsB,KAAsB;AACpD,QAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,SAAO,QAAQ,SAAS,MAAM,GAAG,QAAQ,MAAM,GAAG,GAAG,CAAC,QAAQ;AAC/D;AAEA,SAAS,gBAA+B;AACvC,QAAM,QAAQ,QAAQ,aAAa,UAAU,iBAAiB;AAC9D,MAAI;AACH,UAAM,MAAM,SAAS,OAAO;AAAA,MAC3B,UAAU;AAAA,MACV,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACnC,CAAC,EACC,KAAK,EACL,MAAM,OAAO,EAAE,CAAC;AAClB,WAAO,OAAO;AAAA,EACf,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAEA,SAAS,gBAA+B;AACvC,QAAM,MAAM,cAAc;AAC1B,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI;AACH,aAAS,GAAG,KAAK,UAAU,GAAG,CAAC,uBAAuB;AAAA,MACrD,SAAS;AAAA,MACT,UAAU;AAAA,MACV,KAAK,EAAE,GAAG,QAAQ,KAAK,MAAM,OAAO;AAAA,MACpC,OAAO,CAAC,UAAU,UAAU,MAAM;AAAA,MAClC,KAAK,OAAO;AAAA,IACb,CAAC;AACD,WAAO;AAAA,EACR,SAAS,KAAK;AACb,UAAM,IAAI;AAKV,QAAI,EAAE,WAAW,UAAW,QAAO;AACnC,UAAM,SAAS,OAAO,EAAE,WAAW,WAAW,EAAE,SAAU,EAAE,QAAQ,SAAS,OAAO,KAAK;AACzF,UAAM,YAAY,OAAO,MAAM,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;AAC5D,WAAO,YAAY,eAAe,SAAS,KAAK,sBAAsB,EAAE,QAAQ,SAAS;AAAA,EAC1F;AACD;AAKA,IAAI,kBAAmD;AAEhD,SAAS,uBAAuB,SAAoD;AAC1F,MAAI,QAAQ,YAAY,KAAK,IAAI,IAAI,IAAQ,QAAO,QAAQ,QAAQ,OAAO;AAC3E,SAAO,eAAe,OAAO;AAC9B;AAKO,SAAS,4BAA4B,SAAoD;AAC/F,MAAI,gBAAiB,QAAO;AAC5B,QAAM,SAAS,oBAAoB;AACnC,MACC,UACA,OAAO,iBAAiB,QAAQ,gBAChC,OAAO,YAAY,KAAK,IAAI,IAAI,KAC/B;AACD,WAAO,QAAQ,QAAQ,MAAM;AAAA,EAC9B;AACA,SAAO,eAAe,OAAO;AAC9B;AAEA,SAAS,eAAe,SAAoD;AAC3E,MAAI,gBAAiB,QAAO;AAE5B,qBAAmB,YAAY;AAC9B,QAAI;AACH,UAAI;AACJ,YAAM,QAAQ,MAAM,gBAAgB,QAAQ,YAAY,EAAE,MAAM,CAAC,MAAM;AACtE,qBAAa;AACb,eAAO;AAAA,MACR,CAAC;AACD,UAAI,SAAS,MAAM,YAAY,KAAK,IAAI,IAAI,KAAQ;AACnD,YAAI;AACH,0BAAgB,KAAK;AAAA,QACtB,QAAQ;AAAA,QAER;AACA,eAAO;AAAA,MACR;AAEA,YAAM,YAAY,cAAc;AAChC,YAAM,SAAS,oBAAoB;AACnC,UAAI,UAAU,OAAO,YAAY,KAAK,IAAI,IAAI,IAAQ,QAAO;AAE7D,YAAM,UAAU;AAAA,QACf;AAAA,QACA,aAAa,UAAU,sBAAsB,UAAU,CAAC,KAAK;AAAA,MAC9D,EAAE,OAAO,OAAO;AAChB,YAAM,SAAS,QAAQ,SAAS,IAAI,KAAK,QAAQ,KAAK,IAAI,CAAC,MAAM;AACjE,YAAM,IAAI;AAAA,QACT,4CAA4C,MAAM;AAAA,MACnD;AAAA,IACD,UAAE;AACD,wBAAkB;AAAA,IACnB;AAAA,EACD,GAAG;AAEH,SAAO;AACR;;;ACxQO,IAAM,SAAsB;AAAA,EAClC,WAAW;AAAA,EACX,WAAW;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAAA,EACA,kBAAkB,CAAC,yBAAyB,iCAAiC;AAAA;AAAA;AAAA,EAG7E,gBAAgB;AAAA,IACf,OAAO;AAAA,MACN,SAAS,CAAC,iCAAiC;AAAA,MAC3C,eAAe;AAAA,IAChB;AAAA,IACA,OAAO;AAAA,MACN,aAAa;AAAA,MACb,KAAK,CAAC,mBAAmB;AAAA,IAC1B;AAAA,IACA,OAAO;AAAA,MACN,aAAa;AAAA,MACb,KAAK,CAAC,mBAAmB;AAAA,MACzB,kBAAkB;AAAA,IACnB;AAAA,IACA,OAAO;AAAA,MACN,aAAa;AAAA,MACb,KAAK,CAAC,mBAAmB;AAAA,MACzB,kBAAkB;AAAA,IACnB;AAAA,EACD;AACD;AAEO,SAAS,iBAAiB,SAAuC;AACvE,QAAM,QAAQ,QAAQ,YAAY;AAClC,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,OAAO,cAAc,GAAG;AACxE,QAAI,MAAM,SAAS,OAAO,EAAG,QAAO;AAAA,EACrC;AACA,SAAO;AACR;AAEO,SAAS,aAAa,SAA2B;AACvD,QAAM,WAAW,iBAAiB,OAAO;AACzC,MAAI,QAAQ,CAAC,GAAG,OAAO,SAAS;AAChC,MAAI,UAAU,YAAa,SAAQ,CAAC,GAAG,OAAO,GAAG,OAAO,gBAAgB;AACxE,MAAI,UAAU,QAAS,SAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,QAAS,SAAS,CAAC,CAAC;AACjF,MAAI,UAAU,IAAK,SAAQ,CAAC,GAAG,OAAO,GAAG,SAAS,GAAG;AACrD,SAAO,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC;AACjC;AAEO,IAAM,oBAAoB;AAI1B,SAAS,aAAa,SAAiB,aAAgC;AAC7E,QAAM,QAAQ,aAAa,OAAO;AAClC,SAAO,cAAc,QAAQ,MAAM,OAAO,CAAC,MAAM,MAAM,iBAAiB;AACzE;AAEA,OAAO,OAAO,OAAO,cAAc,EAAE,QAAQ,OAAO,MAAM;AAC1D,OAAO,OAAO,MAAM;;;AC/EpB,SAAS,kBAAkB;AAE3B,IAAM,eAAe;AAOrB,SAAS,4BAA4B,UAA6B;AACjE,QAAM,UAAU,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AACtD,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,UAAU,QAAQ;AACxB,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC3B,UAAM,YAAY,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AACvD,QAAI,aAAa,UAAU,SAAS,UAAU,UAAU,MAAM;AAC7D,aAAO,UAAU;AAAA,IAClB;AAAA,EACD;AACA,SAAO;AACR;AAEA,SAAS,WAAW,aAA6B;AAChD,SAAO,WAAW,QAAQ,EAAE,OAAO,WAAW,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AACzE;AAEA,SAAS,qBAAqB,aAAqB,SAAyB;AAC3E,QAAM,UAAU,CAAC,GAAG,GAAG,EAAE,EAAE,IAAI,CAAC,MAAO,IAAI,YAAY,SAAS,YAAY,CAAC,IAAI,GAAI,EAAE,KAAK,EAAE;AAC9F,QAAM,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,OAAO;AACjD,SAAO,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AACnE;AAEO,SAAS,wBACf,UACA,SACA,YACS;AACT,QAAM,OAAO,4BAA4B,QAAQ;AACjD,QAAM,SAAS,qBAAqB,MAAM,OAAO;AACjD,QAAM,MAAM,WAAW,IAAI;AAC3B,SACC,0CACc,OAAO,IAAI,MAAM,mBACd,UAAU,SACpB,GAAG;AAEZ;;;AC5CA,IAAM,cAAc;AACb,IAAM,kBAAkB;AAC/B,IAAM,iBAAiB;AAEvB,SAAS,eAAe,MAAsB;AAC7C,SAAO,GAAG,WAAW,GAAG,KAAK,OAAO,CAAC,EAAE,YAAY,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;AACrE;AAEO,SAAS,iBAAiB,MAAsB;AACtD,MAAI,CAAC,KAAK,WAAW,WAAW,EAAG,QAAO;AAC1C,QAAM,OAAO,KAAK,MAAM,YAAY,MAAM;AAC1C,SAAO,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AACnD;AAMA,SAAS,gBAAgB,UAAgC;AACxD,QAAM,aAAa,oBAAI,IAAY;AACnC,QAAM,gBAAgB,oBAAI,IAAY;AACtC,aAAW,KAAK,UAAU;AACzB,QAAI,CAAC,MAAM,QAAQ,EAAE,OAAO,EAAG;AAC/B,eAAW,SAAS,EAAE,SAAS;AAC9B,YAAM,KAAM,MAA0B;AACtC,YAAM,YAAa,MAAmC;AACtD,UAAI,MAAM,SAAS,cAAc,OAAO,OAAO,SAAU,YAAW,IAAI,EAAE;AAC1E,UAAI,MAAM,SAAS,iBAAiB,OAAO,cAAc;AACxD,sBAAc,IAAI,SAAS;AAAA,IAC7B;AAAA,EACD;AACA,QAAM,eAAe,oBAAI,IAAY;AACrC,QAAM,kBAAkB,oBAAI,IAAY;AACxC,aAAW,MAAM,WAAY,KAAI,CAAC,cAAc,IAAI,EAAE,EAAG,cAAa,IAAI,EAAE;AAC5E,aAAW,MAAM,cAAe,KAAI,CAAC,WAAW,IAAI,EAAE,EAAG,iBAAgB,IAAI,EAAE;AAC/E,MAAI,CAAC,aAAa,QAAQ,CAAC,gBAAgB,KAAM,QAAO;AACxD,SAAO,SAAS,IAAI,CAAC,MAAM;AAC1B,QAAI,CAAC,MAAM,QAAQ,EAAE,OAAO,EAAG,QAAO;AACtC,UAAM,WAAW,EAAE,QAAQ,OAAO,CAAC,MAAM;AACxC,YAAM,KAAM,EAAsB;AAClC,YAAM,YAAa,EAA+B;AAClD,UAAI,EAAE,SAAS,cAAc,OAAO,OAAO,SAAU,QAAO,CAAC,aAAa,IAAI,EAAE;AAChF,UAAI,EAAE,SAAS,iBAAiB,OAAO,cAAc;AACpD,eAAO,CAAC,gBAAgB,IAAI,SAAS;AACtC,aAAO;AAAA,IACR,CAAC;AACD,QAAI,SAAS,WAAW,GAAG;AAC1B,aAAO;AAAA,QACN,GAAG;AAAA,QACH,SACC,EAAE,SAAS,SACR,CAAC,EAAE,MAAM,QAAQ,MAAM,wBAAwB,CAAC,IAChD,CAAC,EAAE,MAAM,QAAQ,MAAM,eAAe,CAAC;AAAA,MAC5C;AAAA,IACD;AACA,WAAO,EAAE,GAAG,GAAG,SAAS,SAAS;AAAA,EAClC,CAAC;AACF;AAYO,SAAS,0BAAsD,QAAc;AACnF,QAAM,UAAU,QAAQ,IAAI,yBAAyB,OAAO;AAC5D,QAAM,aAAa,QAAQ,IAAI,0BAA0B;AAEzD,QAAM,gBAAgB;AAAA,IACpB,OAAO,YAAY,CAAC;AAAA,IACrB;AAAA,IACA;AAAA,EACD;AAEA,MAAI,SAAwB,CAAC;AAC7B,MAAI,OAAO,OAAO,WAAW,UAAU;AACtC,QAAI,OAAO,OAAO,KAAK,EAAG,QAAO,KAAK,EAAE,MAAM,QAAQ,MAAM,OAAO,OAAO,CAAC;AAAA,EAC5E,WAAW,MAAM,QAAQ,OAAO,MAAM,GAAG;AACxC,aAAS,CAAC,GAAG,OAAO,MAAM;AAAA,EAC3B;AAEA,WAAS,OAAO,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,WAAW,cAAc,EAAE;AAEhG,QAAM,cAAc,OAAO;AAAA,IAC1B,CAAC,MAAM,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,WAAW,eAAe;AAAA,EACvE;AAEA,QAAM,QAAuB,CAAC;AAC9B,aAAW,SAAS,QAAQ;AAC3B,UAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAC3D,QAAI,KAAK,WAAW,eAAe,KAAK,KAAK,SAAS,gBAAgB,QAAQ;AAC7E,YAAM,OAAO,KAAK,MAAM,gBAAgB,MAAM,EAAE,QAAQ,QAAQ,EAAE;AAClE,YAAM,EAAE,MAAM,IAAI,eAAe,KAAK,GAAG,cAAc,IAAI;AAC3D,YAAM,EAAE,MAAM,KAAK,GAAG,UAAU,IAAI;AACpC,YAAM,KAAK,EAAE,GAAG,eAAe,MAAM,QAAQ,MAAM,gBAAgB,CAAC;AACpE,UAAI,KAAM,OAAM,KAAK,EAAE,GAAG,WAAW,MAAM,QAAQ,MAAM,KAAK,CAAC;AAAA,IAChE,OAAO;AACN,YAAM,KAAK,KAAK;AAAA,IACjB;AAAA,EACD;AACA,WAAS;AAET,MAAI,CAAC,aAAa;AACjB,WAAO,QAAQ,EAAE,MAAM,QAAQ,MAAM,gBAAgB,CAAC;AAAA,EACvD;AAEA,QAAM,OAAsB,CAAC;AAC7B,QAAM,QAAkB,CAAC;AACzB,aAAW,SAAS,QAAQ;AAC3B,UAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAC3D,QAAI,KAAK,WAAW,cAAc,KAAK,KAAK,WAAW,eAAe,GAAG;AACxE,WAAK,KAAK,KAAK;AAAA,IAChB,WAAW,MAAM;AAChB,YAAM,KAAK,IAAI;AAAA,IAChB;AAAA,EACD;AACA,MAAI,MAAM,UAAU,MAAM,QAAQ,OAAO,QAAQ,GAAG;AACnD,UAAM,SAAS,MAAM,KAAK,MAAM;AAChC,UAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAC/D,QAAI,WAAW;AACd,UAAI,OAAO,UAAU,YAAY,UAAU;AAC1C,kBAAU,UAAU,GAAG,MAAM;AAAA;AAAA,EAAO,UAAU,OAAO;AAAA,MACtD,WAAW,MAAM,QAAQ,UAAU,OAAO,GAAG;AAC5C,kBAAU,QAAQ,QAAQ,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,MACzD;AAAA,IACD,OAAO;AAGN,aAAO,SAAS,QAAQ,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAC;AAAA,IAC1D;AAAA,EACD;AAEA,OAAK,QAAQ,EAAE,MAAM,QAAQ,MAAM,cAAc,CAAC;AAClD,SAAO,SAAS;AAEhB,QAAM,WAAW,iBAAiB,OAAO,SAAS,EAAE;AACpD,MAAI,UAAU,iBAAiB,OAAO,YAAY,YAAY,OAAO,UAAU;AAC9E,WAAQ,OAAO,SAAkC;AACjD,QAAI,CAAC,OAAO,KAAK,OAAO,QAAQ,EAAE,OAAQ,QAAO,OAAO;AAAA,EACzD;AAEA,MAAI,MAAM,QAAQ,OAAO,KAAK,GAAG;AAChC,WAAO,QAAQ,OAAO,MAAM,IAAI,CAAC,OAAO;AAAA,MACvC,GAAG;AAAA,MACH,MAAM,EAAE,OAAO,eAAe,EAAE,IAAI,IAAI,EAAE;AAAA,IAC3C,EAAE;AAAA,EACH;AAEA,MAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG;AACnC,WAAO,WAAW,OAAO,SAAS,IAAI,CAAC,MAAM;AAC5C,UAAI,CAAC,MAAM,QAAQ,EAAE,OAAO,EAAG,QAAO;AACtC,aAAO;AAAA,QACN,GAAG;AAAA,QACH,SAAS,EAAE,QAAQ,IAAI,CAAC,MAAM;AAC7B,cAAI,EAAE,SAAS,cAAc,OAAO,EAAE,SAAS,UAAU;AACxD,mBAAO,EAAE,GAAG,GAAG,MAAM,eAAe,EAAE,IAAI,EAAE;AAAA,UAC7C;AACA,iBAAO;AAAA,QACR,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AACD,WAAO,WAAW,gBAAgB,OAAO,QAAQ;AAAA,EAClD;AAEA,SAAO;AACR;","names":[]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@cgaravitoq/claude-code-core",
3
+ "version": "0.1.0",
4
+ "description": "Framework-agnostic core for using Claude Code's OAuth subscription as an Anthropic provider: credential read/refresh, signed billing header, beta computation, and request transforms. No Pi, no LangChain — just the native Claude Code stack.",
5
+ "type": "module",
6
+ "types": "./dist/index.d.ts",
7
+ "module": "./dist/index.js",
8
+ "main": "./dist/index.js",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "sideEffects": false,
20
+ "engines": {
21
+ "node": ">=22.19.0"
22
+ },
23
+ "scripts": {
24
+ "build": "tsup",
25
+ "test": "bun test",
26
+ "typecheck": "tsc --noEmit",
27
+ "format": "biome format --write .",
28
+ "check": "biome check --write .",
29
+ "prepublishOnly": "bun run typecheck && bun run build"
30
+ },
31
+ "keywords": [
32
+ "claude-code",
33
+ "anthropic",
34
+ "oauth",
35
+ "claude",
36
+ "llm",
37
+ "coding-agent"
38
+ ],
39
+ "license": "MIT",
40
+ "author": "cgaravitoq",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/cgaravitoq/claude-code-core.git"
44
+ },
45
+ "homepage": "https://github.com/cgaravitoq/claude-code-core#readme",
46
+ "bugs": {
47
+ "url": "https://github.com/cgaravitoq/claude-code-core/issues"
48
+ },
49
+ "devDependencies": {
50
+ "@biomejs/biome": "^2.4.16",
51
+ "@types/bun": "^1.3.14",
52
+ "@types/node": "^22.0.0",
53
+ "tsup": "^8.5.0",
54
+ "typescript": "^6.0.3"
55
+ }
56
+ }