forked from milady-ai/milady
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclaude-code-stealth.mjs
More file actions
109 lines (92 loc) · 3.34 KB
/
claude-code-stealth.mjs
File metadata and controls
109 lines (92 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
* Claude Code Stealth Mode
*
* Monkey-patches global fetch to intercept Anthropic API requests made with
* OAuth setup tokens (sk-ant-oat*). Mimics Claude Code's exact request pattern:
*
* 1. Replaces x-api-key with Authorization: Bearer
* 2. Adds Claude Code beta headers
* 3. Injects "You are Claude Code..." system prefix
* 4. Sets Claude CLI user-agent
*
* This is loaded before the ElizaOS runtime so ALL Anthropic calls are patched,
* regardless of which plugin/service makes them.
*/
const CLAUDE_CODE_VERSION = "2.1.2";
const CLAUDE_CODE_SYSTEM_PREFIX =
"You are Claude Code, Anthropic's official CLI for Claude.";
const ANTHROPIC_BETA =
"claude-code-20250219,oauth-2025-04-20,fine-grained-tool-streaming-2025-05-14,interleaved-thinking-2025-05-14";
function isOAuthToken(val) {
return typeof val === "string" && val.includes("sk-ant-oat");
}
const originalFetch = globalThis.fetch;
globalThis.fetch = async function stealthFetch(input, init) {
// Only intercept Anthropic API calls
const url = typeof input === "string" ? input : input?.url || "";
if (!url.includes("anthropic.com")) {
return originalFetch(input, init);
}
if (!init) {
return originalFetch(input, init);
}
// Check if we're using an OAuth token (via x-api-key or Authorization header)
const headers = init.headers || {};
const apiKey = headers["x-api-key"] || headers["X-Api-Key"];
const existingAuth = headers.Authorization || headers.authorization;
// Determine the token
let token = null;
if (apiKey && isOAuthToken(apiKey)) {
token = apiKey;
} else if (
existingAuth &&
isOAuthToken(existingAuth.replace("Bearer ", ""))
) {
token = existingAuth.replace("Bearer ", "");
}
if (!token) {
// Not an OAuth token, pass through normally
return originalFetch(input, init);
}
// === STEALTH MODE: Mimic Claude Code exactly ===
// 1. Fix headers: Bearer auth + Claude Code identity
const newHeaders = { ...headers };
delete newHeaders["x-api-key"];
delete newHeaders["X-Api-Key"];
newHeaders.Authorization = `Bearer ${token}`;
newHeaders["anthropic-beta"] = ANTHROPIC_BETA;
newHeaders["user-agent"] =
`claude-cli/${CLAUDE_CODE_VERSION} (external, cli)`;
newHeaders["x-app"] = "cli";
newHeaders.accept = "application/json";
newHeaders["anthropic-dangerous-direct-browser-access"] = "true";
// 2. Inject system prompt prefix into request body
if (typeof init.body === "string") {
try {
const body = JSON.parse(init.body);
const prefix = { type: "text", text: CLAUDE_CODE_SYSTEM_PREFIX };
if (Array.isArray(body.system)) {
if (
!body.system.some((s) => s.text?.startsWith("You are Claude Code"))
) {
body.system.unshift(prefix);
}
} else if (typeof body.system === "string") {
body.system = [prefix, { type: "text", text: body.system }];
} else if (!body.system) {
body.system = [prefix];
}
init.body = JSON.stringify(body);
console.log(
`[stealth] ${body.model} → Bearer auth + Claude Code system prefix (${body.system.length} blocks)`,
);
} catch {
// Not JSON body, pass through
}
}
init.headers = newHeaders;
return originalFetch(input, init);
};
console.log(
"[stealth] Claude Code stealth mode active — all Anthropic OAuth requests will be patched",
);