@askalf/dario 2.11.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -29
- package/dist/cc-template.d.ts +434 -0
- package/dist/cc-template.js +364 -0
- package/dist/oauth.js +2 -2
- package/dist/proxy.js +23 -245
- package/package.json +63 -63
package/dist/proxy.js
CHANGED
|
@@ -6,6 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
import { homedir, tmpdir } from 'node:os';
|
|
7
7
|
import { arch, platform } from 'node:process';
|
|
8
8
|
import { getAccessToken, getStatus } from './oauth.js';
|
|
9
|
+
import { buildCCRequest, reverseMapResponse } from './cc-template.js';
|
|
9
10
|
const ANTHROPIC_API = 'https://api.anthropic.com';
|
|
10
11
|
const DEFAULT_PORT = 3456;
|
|
11
12
|
const MAX_BODY_BYTES = 10 * 1024 * 1024; // 10 MB — generous for large prompts, prevents abuse
|
|
@@ -236,194 +237,12 @@ function sanitizeMessages(body) {
|
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
239
|
}
|
|
239
|
-
/**
|
|
240
|
-
* Strip thinking blocks from prior assistant messages.
|
|
241
|
-
* Real Claude Code strips thinking from conversation history before building the next request.
|
|
242
|
-
* The API's context_management: clear_thinking does NOT reduce input token billing —
|
|
243
|
-
* tokens are counted before server-side edits. Client-side stripping is the only way
|
|
244
|
-
* to avoid burning the 5h window on stale thinking traces.
|
|
245
|
-
* Only strips from prior turns — the most recent assistant message is left intact.
|
|
246
|
-
*/
|
|
247
|
-
function stripThinkingFromHistory(body) {
|
|
248
|
-
const messages = body.messages;
|
|
249
|
-
if (!messages)
|
|
250
|
-
return;
|
|
251
|
-
// Strip thinking blocks from ALL assistant messages.
|
|
252
|
-
// Real Claude Code never sends thinking blocks in the messages array —
|
|
253
|
-
// it strips them before building the next request. The API will generate
|
|
254
|
-
// fresh thinking for the current turn; prior thinking is dead weight.
|
|
255
|
-
for (const msg of messages) {
|
|
256
|
-
if (msg.role !== 'assistant')
|
|
257
|
-
continue;
|
|
258
|
-
if (Array.isArray(msg.content)) {
|
|
259
|
-
msg.content = msg.content.filter(b => b.type !== 'thinking');
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
240
|
/**
|
|
264
241
|
* Scrub non-Claude-Code fields and normalize field ordering.
|
|
265
242
|
* Real Claude Code never sends these fields. Their presence is a fingerprint.
|
|
266
243
|
* JSON field order is also detectable — Claude Code always sends fields in a
|
|
267
244
|
* specific order. We rebuild the object to match.
|
|
268
245
|
*/
|
|
269
|
-
const NON_CC_FIELDS = new Set(['service_tier', 'top_p', 'top_k', 'stop_sequences', 'temperature']);
|
|
270
|
-
// ── Tool name rewriting ──
|
|
271
|
-
// Anthropic fingerprints on tool names — non-CC names trigger overage classification.
|
|
272
|
-
// Map third-party tool names to CC equivalents on the way in, reverse on the way out.
|
|
273
|
-
const CC_TOOLS = new Set([
|
|
274
|
-
'Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep', 'Browser', 'WebFetch', 'WebSearch',
|
|
275
|
-
'NotebookEdit', 'NotebookRead', 'TodoRead', 'TodoWrite',
|
|
276
|
-
'Agent', 'MCPListTools', 'MCPCallTool',
|
|
277
|
-
'AskUserQuestion', 'EnterPlanMode', 'ExitPlanMode',
|
|
278
|
-
'EnterWorktree', 'ExitWorktree', 'TaskCreate', 'TaskUpdate',
|
|
279
|
-
]);
|
|
280
|
-
// Common third-party tool names → CC equivalents
|
|
281
|
-
const TOOL_NAME_MAP = {
|
|
282
|
-
bash: 'Bash', sh: 'Bash', exec: 'Bash', shell: 'Bash', run: 'Bash', execute: 'Bash',
|
|
283
|
-
command: 'Bash', terminal: 'Bash', process: 'Bash',
|
|
284
|
-
read: 'Read', read_file: 'Read', file_read: 'Read', get_file: 'Read',
|
|
285
|
-
write: 'Write', write_file: 'Write', file_write: 'Write', create_file: 'Write', save_file: 'Write',
|
|
286
|
-
edit: 'Edit', edit_file: 'Edit', modify_file: 'Edit', patch: 'Edit', replace: 'Edit',
|
|
287
|
-
glob: 'Glob', find_files: 'Glob', list_files: 'Glob', ls: 'Glob',
|
|
288
|
-
grep: 'Grep', search: 'Grep', search_files: 'Grep', find_in_files: 'Grep', rg: 'Grep',
|
|
289
|
-
web_search: 'WebSearch', websearch: 'WebSearch', google: 'WebSearch',
|
|
290
|
-
web_fetch: 'WebFetch', webfetch: 'WebFetch', fetch: 'WebFetch', http: 'WebFetch', curl: 'WebFetch',
|
|
291
|
-
browse: 'Browser', browser: 'Browser', open_url: 'Browser',
|
|
292
|
-
notebook: 'NotebookEdit', notebook_edit: 'NotebookEdit',
|
|
293
|
-
};
|
|
294
|
-
/**
|
|
295
|
-
* Rewrite tool names in the request to match CC toolset.
|
|
296
|
-
* Returns the mapping so we can reverse it in the response.
|
|
297
|
-
* Tools that don't map to a known CC name get wrapped as MCPCallTool.
|
|
298
|
-
*/
|
|
299
|
-
function rewriteToolNames(body) {
|
|
300
|
-
const tools = body.tools;
|
|
301
|
-
if (!tools || !Array.isArray(tools))
|
|
302
|
-
return [];
|
|
303
|
-
const mappings = [];
|
|
304
|
-
const usedNames = new Set();
|
|
305
|
-
// First pass: collect CC tool names already in the list
|
|
306
|
-
for (const tool of tools) {
|
|
307
|
-
if (CC_TOOLS.has(tool.name))
|
|
308
|
-
usedNames.add(tool.name);
|
|
309
|
-
}
|
|
310
|
-
let mcpIndex = 0;
|
|
311
|
-
for (const tool of tools) {
|
|
312
|
-
const originalName = tool.name;
|
|
313
|
-
if (!originalName)
|
|
314
|
-
continue;
|
|
315
|
-
// Already a CC tool name
|
|
316
|
-
if (CC_TOOLS.has(originalName))
|
|
317
|
-
continue;
|
|
318
|
-
// Check direct map — but avoid duplicates
|
|
319
|
-
const directMap = TOOL_NAME_MAP[originalName.toLowerCase()];
|
|
320
|
-
if (directMap && !usedNames.has(directMap)) {
|
|
321
|
-
mappings.push({ original: originalName, mapped: directMap });
|
|
322
|
-
tool.name = directMap;
|
|
323
|
-
usedNames.add(directMap);
|
|
324
|
-
}
|
|
325
|
-
else {
|
|
326
|
-
// Wrap as mcp_<original_name> — MCP tools use this prefix in real CC
|
|
327
|
-
const mcpName = `mcp_${originalName}`;
|
|
328
|
-
mappings.push({ original: originalName, mapped: mcpName });
|
|
329
|
-
tool.name = mcpName;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
// Cap tool count — CC sends max ~22 tools. Excess tools get consolidated
|
|
333
|
-
// into a single MCPCallTool dispatch with routing table.
|
|
334
|
-
const MAX_TOOLS = 22;
|
|
335
|
-
if (tools.length > MAX_TOOLS) {
|
|
336
|
-
const keep = tools.slice(0, MAX_TOOLS - 1); // keep first N-1
|
|
337
|
-
const overflow = tools.slice(MAX_TOOLS - 1);
|
|
338
|
-
// Build dispatch tool that wraps all overflow tools
|
|
339
|
-
const dispatchDesc = overflow.map((t) => `${t.name}: ${(t.description || '').slice(0, 50)}`).join('\n');
|
|
340
|
-
const dispatchTool = {
|
|
341
|
-
name: 'mcp_dispatch',
|
|
342
|
-
description: `Route to one of these tools:\n${dispatchDesc}`,
|
|
343
|
-
input_schema: {
|
|
344
|
-
type: 'object',
|
|
345
|
-
properties: {
|
|
346
|
-
tool_name: { type: 'string', description: 'Which tool to call', enum: overflow.map((t) => t.name) },
|
|
347
|
-
input: { type: 'object', description: 'Arguments to pass to the tool' },
|
|
348
|
-
},
|
|
349
|
-
required: ['tool_name', 'input'],
|
|
350
|
-
},
|
|
351
|
-
};
|
|
352
|
-
// Track overflow mappings for reverse
|
|
353
|
-
for (const t of overflow) {
|
|
354
|
-
mappings.push({ original: t.name, mapped: 'mcp_dispatch' });
|
|
355
|
-
}
|
|
356
|
-
// Replace tools array
|
|
357
|
-
keep.push(dispatchTool);
|
|
358
|
-
body.tools = keep;
|
|
359
|
-
}
|
|
360
|
-
return mappings;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Reverse tool name mapping in the response body.
|
|
364
|
-
* Restores original tool names in tool_use content blocks.
|
|
365
|
-
*/
|
|
366
|
-
function reverseToolNames(body, mappings) {
|
|
367
|
-
if (mappings.length === 0)
|
|
368
|
-
return body;
|
|
369
|
-
let result = body;
|
|
370
|
-
for (const { original, mapped } of mappings) {
|
|
371
|
-
// Replace in tool_use blocks: "name":"MCPCallTool" → "name":"original"
|
|
372
|
-
result = result.replace(new RegExp(`"name"\\s*:\\s*"${mapped}"`, 'g'), `"name":"${original}"`);
|
|
373
|
-
}
|
|
374
|
-
return result;
|
|
375
|
-
}
|
|
376
|
-
// Claude Code's field order (from MITM capture). Fields not in this list are appended at end.
|
|
377
|
-
const CC_FIELD_ORDER = [
|
|
378
|
-
'model', 'messages', 'system', 'max_tokens', 'thinking', 'output_config',
|
|
379
|
-
'context_management', 'metadata', 'stream', 'tools', 'tool_choice',
|
|
380
|
-
];
|
|
381
|
-
function scrubAndReorderFields(body) {
|
|
382
|
-
// Remove non-CC fields
|
|
383
|
-
for (const field of NON_CC_FIELDS) {
|
|
384
|
-
delete body[field];
|
|
385
|
-
}
|
|
386
|
-
// Rebuild with Claude Code field ordering
|
|
387
|
-
const ordered = {};
|
|
388
|
-
for (const key of CC_FIELD_ORDER) {
|
|
389
|
-
if (key in body) {
|
|
390
|
-
ordered[key] = body[key];
|
|
391
|
-
delete body[key];
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
// Append any remaining fields (custom client fields we don't recognize)
|
|
395
|
-
for (const [key, value] of Object.entries(body)) {
|
|
396
|
-
ordered[key] = value;
|
|
397
|
-
}
|
|
398
|
-
return ordered;
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Normalize system prompt to exactly 3 blocks.
|
|
402
|
-
* Real Claude Code always sends exactly 3 system blocks:
|
|
403
|
-
* [0] billing tag (no cache), [1] agent identity (cache 1h), [2] system prompt (cache 1h)
|
|
404
|
-
* If the client sends multiple system blocks, merge them into block [2].
|
|
405
|
-
*/
|
|
406
|
-
function normalizeSystemTo3Blocks(system, billingTag, agentIdentity, cache1h) {
|
|
407
|
-
let systemText;
|
|
408
|
-
if (typeof system === 'string') {
|
|
409
|
-
systemText = system;
|
|
410
|
-
}
|
|
411
|
-
else if (Array.isArray(system)) {
|
|
412
|
-
// Merge all text blocks into one, skip any existing billing tags
|
|
413
|
-
systemText = system
|
|
414
|
-
.filter(b => b.text && !b.text.includes('x-anthropic-billing-header:'))
|
|
415
|
-
.map(b => b.text)
|
|
416
|
-
.join('\n\n');
|
|
417
|
-
}
|
|
418
|
-
else {
|
|
419
|
-
systemText = '';
|
|
420
|
-
}
|
|
421
|
-
return [
|
|
422
|
-
{ type: 'text', text: billingTag },
|
|
423
|
-
{ type: 'text', text: agentIdentity, cache_control: cache1h },
|
|
424
|
-
{ type: 'text', text: systemText || 'You are a helpful assistant.', cache_control: cache1h },
|
|
425
|
-
];
|
|
426
|
-
}
|
|
427
246
|
// OpenAI model names → Anthropic (fallback if client sends GPT names)
|
|
428
247
|
const OPENAI_MODEL_MAP = {
|
|
429
248
|
'gpt-5.4': 'claude-opus-4-6',
|
|
@@ -699,7 +518,7 @@ export async function startProxy(opts = {}) {
|
|
|
699
518
|
'accept': 'application/json',
|
|
700
519
|
'Content-Type': 'application/json',
|
|
701
520
|
'anthropic-dangerous-direct-browser-access': 'true',
|
|
702
|
-
'user-agent': `claude-cli/${cliVersion} (external, cli)`,
|
|
521
|
+
'user-agent': `claude-cli/${cliVersion} (external, cli, workload/cron)`,
|
|
703
522
|
'x-app': 'cli',
|
|
704
523
|
'x-claude-code-session-id': SESSION_ID,
|
|
705
524
|
'x-stainless-arch': arch,
|
|
@@ -735,7 +554,7 @@ export async function startProxy(opts = {}) {
|
|
|
735
554
|
const JSON_HEADERS = { 'Content-Type': 'application/json', ...SECURITY_HEADERS };
|
|
736
555
|
const MODELS_JSON = JSON.stringify(OPENAI_MODELS_LIST);
|
|
737
556
|
const ERR_UNAUTH = JSON.stringify({ error: 'Unauthorized', message: 'Invalid or missing API key' });
|
|
738
|
-
const ERR_FORBIDDEN = JSON.stringify({ error: 'Forbidden', message: 'Path not allowed' });
|
|
557
|
+
const ERR_FORBIDDEN = JSON.stringify({ error: 'Forbidden', message: 'Path not allowed. Supported paths: POST /v1/messages, POST /v1/chat/completions, GET /v1/models' });
|
|
739
558
|
const ERR_METHOD = JSON.stringify({ error: 'Method not allowed' });
|
|
740
559
|
function checkAuth(req) {
|
|
741
560
|
if (!apiKeyBuf)
|
|
@@ -858,7 +677,7 @@ export async function startProxy(opts = {}) {
|
|
|
858
677
|
}
|
|
859
678
|
// Parse body once, apply OpenAI translation, model override, and sanitization
|
|
860
679
|
let finalBody = body.length > 0 ? body : undefined;
|
|
861
|
-
let
|
|
680
|
+
let ccToolMap = null;
|
|
862
681
|
if (body.length > 0) {
|
|
863
682
|
try {
|
|
864
683
|
const parsed = JSON.parse(body.toString());
|
|
@@ -868,67 +687,24 @@ export async function startProxy(opts = {}) {
|
|
|
868
687
|
const r = result;
|
|
869
688
|
// In passthrough mode, skip all Claude-specific injection — OAuth swap only
|
|
870
689
|
if (!passthrough) {
|
|
871
|
-
// ──
|
|
872
|
-
//
|
|
873
|
-
//
|
|
874
|
-
//
|
|
875
|
-
stripThinkingFromHistory(r);
|
|
876
|
-
// 2. Strip client cache_control from messages (prevents overflow — max 4 breakpoints)
|
|
877
|
-
const msgs = r.messages;
|
|
878
|
-
if (msgs) {
|
|
879
|
-
for (const msg of msgs) {
|
|
880
|
-
if (Array.isArray(msg.content)) {
|
|
881
|
-
for (const block of msg.content) {
|
|
882
|
-
delete block.cache_control;
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
// 3. Rewrite tool names to CC equivalents (Anthropic fingerprints on tool names)
|
|
888
|
-
toolMappings = rewriteToolNames(r);
|
|
889
|
-
// 3. Scrub non-CC fields and normalize field ordering
|
|
890
|
-
const reordered = scrubAndReorderFields(r);
|
|
891
|
-
for (const key of Object.keys(r))
|
|
892
|
-
delete r[key];
|
|
893
|
-
Object.assign(r, reordered);
|
|
894
|
-
// 3. Inject device identity metadata for session tracking
|
|
895
|
-
if (identity.deviceId) {
|
|
896
|
-
r.metadata = {
|
|
897
|
-
user_id: JSON.stringify({
|
|
898
|
-
device_id: identity.deviceId,
|
|
899
|
-
account_uuid: identity.accountUuid,
|
|
900
|
-
session_id: SESSION_ID,
|
|
901
|
-
}),
|
|
902
|
-
};
|
|
903
|
-
}
|
|
904
|
-
// 4. Model-aware defaults matching Claude Code behavior
|
|
905
|
-
const modelName = (r.model || '').toLowerCase();
|
|
906
|
-
const supportsThinking = !modelName.includes('haiku');
|
|
907
|
-
if (supportsThinking && !r.thinking) {
|
|
908
|
-
r.thinking = { type: 'adaptive' };
|
|
909
|
-
}
|
|
910
|
-
// Claude Code always sends max_tokens: 64000. Values above this
|
|
911
|
-
// are a fingerprint — cap to match real CC behavior.
|
|
912
|
-
if (!r.max_tokens || r.max_tokens !== 64000) {
|
|
913
|
-
r.max_tokens = 64000;
|
|
914
|
-
}
|
|
915
|
-
// Force effort to medium — CC default. Client 'high' is a fingerprint.
|
|
916
|
-
if (supportsThinking) {
|
|
917
|
-
r.output_config = { effort: 'medium' };
|
|
918
|
-
}
|
|
919
|
-
if (supportsThinking && !r.context_management) {
|
|
920
|
-
r.context_management = { edits: [{ type: 'clear_thinking_20251015', keep: 'all' }] };
|
|
921
|
-
}
|
|
922
|
-
// 5. Build per-request billing tag matching Claude Code binary (Oz$ algorithm)
|
|
690
|
+
// ── Template replay: replace the entire request with a CC template ──
|
|
691
|
+
// Instead of transforming signals one by one, we build a new request
|
|
692
|
+
// from CC's exact template and inject only the conversation content.
|
|
693
|
+
// The upstream sees a genuine CC request structure.
|
|
923
694
|
const userMsg = extractFirstUserMessage(r);
|
|
924
695
|
const buildTag = computeBuildTag(userMsg, cliVersion);
|
|
925
696
|
const cch = computeCch();
|
|
926
697
|
const fullVersion = `${cliVersion}.${buildTag}`;
|
|
927
|
-
const billingTag = `x-anthropic-billing-header: cc_version=${fullVersion}; cc_entrypoint=cli; cch=${cch};`;
|
|
928
|
-
// 6. Normalize system prompt to exactly 3 blocks (real Claude Code always sends 3)
|
|
698
|
+
const billingTag = `x-anthropic-billing-header: cc_version=${fullVersion}; cc_entrypoint=cli; cch=${cch}; cc_workload=cron;`;
|
|
929
699
|
const AGENT_IDENTITY = 'You are a Claude agent, built on Anthropic\'s Claude Agent SDK.';
|
|
930
700
|
const CACHE_1H = { type: 'ephemeral', ttl: '1h' };
|
|
931
|
-
|
|
701
|
+
const { body: ccBody, toolMap } = buildCCRequest(r, billingTag, AGENT_IDENTITY, CACHE_1H, { deviceId: identity.deviceId, accountUuid: identity.accountUuid, sessionId: SESSION_ID });
|
|
702
|
+
// Store tool map for response reverse-mapping
|
|
703
|
+
ccToolMap = toolMap;
|
|
704
|
+
// Replace request body entirely with CC template
|
|
705
|
+
for (const key of Object.keys(r))
|
|
706
|
+
delete r[key];
|
|
707
|
+
Object.assign(r, ccBody);
|
|
932
708
|
}
|
|
933
709
|
finalBody = Buffer.from(JSON.stringify(r));
|
|
934
710
|
}
|
|
@@ -949,7 +725,8 @@ export async function startProxy(opts = {}) {
|
|
|
949
725
|
}
|
|
950
726
|
else {
|
|
951
727
|
// Claude-optimized: full beta set matching real Claude Code (exact order from MITM capture)
|
|
952
|
-
|
|
728
|
+
// Beta set from CC v2.1.104 binary RE — some are CC-internal/gated, only include publicly accepted ones
|
|
729
|
+
beta = 'claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14,context-management-2025-06-27,prompt-caching-scope-2026-01-05,advisor-tool-2026-03-01,effort-2025-11-24,fast-mode-2026-02-01,redact-thinking-2026-02-12,context-1m-2025-08-07,web-search-2025-03-05,advanced-tool-use-2025-11-20,tool-search-tool-2025-10-19';
|
|
953
730
|
if (clientBeta) {
|
|
954
731
|
const baseSet = new Set(beta.split(','));
|
|
955
732
|
const filtered = filterBillableBetas(clientBeta)
|
|
@@ -961,7 +738,7 @@ export async function startProxy(opts = {}) {
|
|
|
961
738
|
const headers = {
|
|
962
739
|
...staticHeaders,
|
|
963
740
|
'Authorization': `Bearer ${accessToken}`,
|
|
964
|
-
'anthropic-version': req.headers['anthropic-version'] || '2023-06-01',
|
|
741
|
+
'anthropic-version': passthrough ? (req.headers['anthropic-version'] || '2023-06-01') : '2023-06-01',
|
|
965
742
|
'anthropic-beta': beta,
|
|
966
743
|
// Real Claude Code adds x-client-request-id for firstParty + api.anthropic.com
|
|
967
744
|
'x-client-request-id': randomUUID(),
|
|
@@ -1062,9 +839,9 @@ export async function startProxy(opts = {}) {
|
|
|
1062
839
|
}
|
|
1063
840
|
else {
|
|
1064
841
|
// Reverse tool names in streaming chunks
|
|
1065
|
-
if (
|
|
842
|
+
if (ccToolMap && ccToolMap.size > 0) {
|
|
1066
843
|
const text = new TextDecoder().decode(value);
|
|
1067
|
-
res.write(
|
|
844
|
+
res.write(reverseMapResponse(text, ccToolMap));
|
|
1068
845
|
}
|
|
1069
846
|
else {
|
|
1070
847
|
res.write(value);
|
|
@@ -1088,7 +865,8 @@ export async function startProxy(opts = {}) {
|
|
|
1088
865
|
// Buffer and forward
|
|
1089
866
|
let responseBody = await upstream.text();
|
|
1090
867
|
// Reverse tool name mapping so client sees original names
|
|
1091
|
-
|
|
868
|
+
if (ccToolMap)
|
|
869
|
+
responseBody = reverseMapResponse(responseBody, ccToolMap);
|
|
1092
870
|
if (isOpenAI && upstream.status >= 200 && upstream.status < 300) {
|
|
1093
871
|
try {
|
|
1094
872
|
const parsed = JSON.parse(responseBody);
|
package/package.json
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@askalf/dario",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Use your Claude subscription as an API. No API key needed. Local proxy for Claude Max/Pro subscriptions.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"dario": "./dist/cli.js"
|
|
8
|
-
},
|
|
9
|
-
"main": "./dist/index.js",
|
|
10
|
-
"types": "./dist/index.d.ts",
|
|
11
|
-
"exports": {
|
|
12
|
-
".": {
|
|
13
|
-
"import": "./dist/index.js",
|
|
14
|
-
"types": "./dist/index.d.ts"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"dist",
|
|
19
|
-
"README.md",
|
|
20
|
-
"LICENSE"
|
|
21
|
-
],
|
|
22
|
-
"scripts": {
|
|
23
|
-
"build": "tsc",
|
|
24
|
-
"audit": "npm audit --production --audit-level=high",
|
|
25
|
-
"prepublishOnly": "npm run build",
|
|
26
|
-
"start": "node dist/cli.js",
|
|
27
|
-
"dev": "tsx src/cli.ts",
|
|
28
|
-
"e2e": "node test/e2e.mjs",
|
|
29
|
-
"compat": "node test/compat.mjs"
|
|
30
|
-
},
|
|
31
|
-
"keywords": [
|
|
32
|
-
"claude",
|
|
33
|
-
"anthropic",
|
|
34
|
-
"oauth",
|
|
35
|
-
"proxy",
|
|
36
|
-
"api",
|
|
37
|
-
"bridge",
|
|
38
|
-
"subscription",
|
|
39
|
-
"claude-max",
|
|
40
|
-
"claude-pro",
|
|
41
|
-
"llm",
|
|
42
|
-
"ai",
|
|
43
|
-
"cli",
|
|
44
|
-
"developer-tools"
|
|
45
|
-
],
|
|
46
|
-
"author": "askalf (https://github.com/askalf)",
|
|
47
|
-
"license": "MIT",
|
|
48
|
-
"repository": {
|
|
49
|
-
"type": "git",
|
|
50
|
-
"url": "https://github.com/askalf/dario.git"
|
|
51
|
-
},
|
|
52
|
-
"homepage": "https://github.com/askalf/dario",
|
|
53
|
-
"bugs": {
|
|
54
|
-
"url": "https://github.com/askalf/dario/issues"
|
|
55
|
-
},
|
|
56
|
-
"engines": {
|
|
57
|
-
"node": ">=18.0.0"
|
|
58
|
-
},
|
|
59
|
-
"devDependencies": {
|
|
60
|
-
"@types/node": "^22.0.0",
|
|
61
|
-
"tsx": "^4.19.0",
|
|
62
|
-
"typescript": "^5.7.0"
|
|
63
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@askalf/dario",
|
|
3
|
+
"version": "3.0.2",
|
|
4
|
+
"description": "Use your Claude subscription as an API. No API key needed. Local proxy for Claude Max/Pro subscriptions.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dario": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"audit": "npm audit --production --audit-level=high",
|
|
25
|
+
"prepublishOnly": "npm run build",
|
|
26
|
+
"start": "node dist/cli.js",
|
|
27
|
+
"dev": "tsx src/cli.ts",
|
|
28
|
+
"e2e": "node test/e2e.mjs",
|
|
29
|
+
"compat": "node test/compat.mjs"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"claude",
|
|
33
|
+
"anthropic",
|
|
34
|
+
"oauth",
|
|
35
|
+
"proxy",
|
|
36
|
+
"api",
|
|
37
|
+
"bridge",
|
|
38
|
+
"subscription",
|
|
39
|
+
"claude-max",
|
|
40
|
+
"claude-pro",
|
|
41
|
+
"llm",
|
|
42
|
+
"ai",
|
|
43
|
+
"cli",
|
|
44
|
+
"developer-tools"
|
|
45
|
+
],
|
|
46
|
+
"author": "askalf (https://github.com/askalf)",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "https://github.com/askalf/dario.git"
|
|
51
|
+
},
|
|
52
|
+
"homepage": "https://github.com/askalf/dario",
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/askalf/dario/issues"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=18.0.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@types/node": "^22.0.0",
|
|
61
|
+
"tsx": "^4.19.0",
|
|
62
|
+
"typescript": "^5.7.0"
|
|
63
|
+
}
|
|
64
64
|
}
|