@hypeitnow/opencode-claude-auth 1.6.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/LICENSE +21 -0
- package/README.md +238 -0
- package/dist/anthropic-prompt.txt +166 -0
- package/dist/betas.d.ts +9 -0
- package/dist/betas.d.ts.map +1 -0
- package/dist/betas.js +102 -0
- package/dist/betas.js.map +1 -0
- package/dist/credentials.d.ts +29 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +313 -0
- package/dist/credentials.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +495 -0
- package/dist/index.js.map +1 -0
- package/dist/keychain.d.ts +23 -0
- package/dist/keychain.d.ts.map +1 -0
- package/dist/keychain.js +365 -0
- package/dist/keychain.js.map +1 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +74 -0
- package/dist/logger.js.map +1 -0
- package/dist/model-config.d.ts +22 -0
- package/dist/model-config.d.ts.map +1 -0
- package/dist/model-config.js +44 -0
- package/dist/model-config.js.map +1 -0
- package/dist/oauth.d.ts +31 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +158 -0
- package/dist/oauth.js.map +1 -0
- package/dist/pkce.d.ts +6 -0
- package/dist/pkce.d.ts.map +1 -0
- package/dist/pkce.js +23 -0
- package/dist/pkce.js.map +1 -0
- package/dist/plugin-config.d.ts +45 -0
- package/dist/plugin-config.d.ts.map +1 -0
- package/dist/plugin-config.js +66 -0
- package/dist/plugin-config.js.map +1 -0
- package/dist/signing.d.ts +31 -0
- package/dist/signing.d.ts.map +1 -0
- package/dist/signing.js +55 -0
- package/dist/signing.js.map +1 -0
- package/dist/transforms.d.ts +14 -0
- package/dist/transforms.d.ts.map +1 -0
- package/dist/transforms.js +271 -0
- package/dist/transforms.js.map +1 -0
- package/installation.md +98 -0
- package/opencode-claude-auth.js +2 -0
- package/package.json +79 -0
package/dist/oauth.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// OAuth 2.0 + PKCE flow for Anthropic's platform console.
|
|
2
|
+
// Ported from ex-machina/opencode-anthropic-auth to add a fallback auth
|
|
3
|
+
// method: when the raw `sk-ant-` Keychain key is rejected by Anthropic's
|
|
4
|
+
// API (typical for org-locked accounts where direct console API keys are
|
|
5
|
+
// unavailable), the plugin can prompt the user to authorize via the
|
|
6
|
+
// `org:create_api_key` / `user:inference` OAuth flow. The resulting
|
|
7
|
+
// {access, refresh, expires} triple is what Anthropic accepts.
|
|
8
|
+
//
|
|
9
|
+
// Two authorisation modes:
|
|
10
|
+
// - "console": full org scope, can create API keys (default for fallback)
|
|
11
|
+
// - "max": claude.ai Pro/Max subscription
|
|
12
|
+
//
|
|
13
|
+
// Tokens are exchanged at platform.claude.com/v1/oauth/token. The user
|
|
14
|
+
// pastes the callback URL (or just the `code#state` pair) into opencode's
|
|
15
|
+
// auth prompt, and the plugin exchanges it for the access/refresh pair.
|
|
16
|
+
import { generatePKCE } from "./pkce.js";
|
|
17
|
+
import { log } from "./logger.js";
|
|
18
|
+
export const CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
19
|
+
const AUTHORIZE_URLS = {
|
|
20
|
+
console: "https://platform.claude.com/oauth/authorize",
|
|
21
|
+
max: "https://claude.ai/oauth/authorize",
|
|
22
|
+
};
|
|
23
|
+
const CODE_CALLBACK_URL = "https://platform.claude.com/oauth/code/callback";
|
|
24
|
+
const TOKEN_URL = "https://platform.claude.com/v1/oauth/token";
|
|
25
|
+
const OAUTH_SCOPES = [
|
|
26
|
+
"org:create_api_key",
|
|
27
|
+
"user:profile",
|
|
28
|
+
"user:inference",
|
|
29
|
+
"user:sessions:claude_code",
|
|
30
|
+
"user:mcp_servers",
|
|
31
|
+
"user:file_upload",
|
|
32
|
+
];
|
|
33
|
+
function generateState() {
|
|
34
|
+
return crypto.randomUUID().replace(/-/g, "");
|
|
35
|
+
}
|
|
36
|
+
function parseCallbackInput(input) {
|
|
37
|
+
const trimmed = input.trim();
|
|
38
|
+
try {
|
|
39
|
+
const url = new URL(trimmed);
|
|
40
|
+
const code = url.searchParams.get("code");
|
|
41
|
+
const state = url.searchParams.get("state");
|
|
42
|
+
if (code && state)
|
|
43
|
+
return { code, state };
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Not a URL; try legacy formats below.
|
|
47
|
+
}
|
|
48
|
+
const hashSplits = trimmed.split("#");
|
|
49
|
+
if (hashSplits.length === 2 && hashSplits[0] && hashSplits[1]) {
|
|
50
|
+
return { code: hashSplits[0], state: hashSplits[1] };
|
|
51
|
+
}
|
|
52
|
+
const params = new URLSearchParams(trimmed);
|
|
53
|
+
const code = params.get("code");
|
|
54
|
+
const state = params.get("state");
|
|
55
|
+
if (code && state)
|
|
56
|
+
return { code, state };
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
export async function exchangeCode(callback, verifier, redirectUri, expectedState) {
|
|
60
|
+
if (expectedState && callback.state !== expectedState) {
|
|
61
|
+
log("oauth_state_mismatch", { expected: expectedState, got: callback.state });
|
|
62
|
+
return { type: "failed" };
|
|
63
|
+
}
|
|
64
|
+
let response;
|
|
65
|
+
try {
|
|
66
|
+
response = await fetch(TOKEN_URL, {
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: {
|
|
69
|
+
"Content-Type": "application/json",
|
|
70
|
+
Accept: "application/json, text/plain, */*",
|
|
71
|
+
"User-Agent": "axios/1.13.6",
|
|
72
|
+
},
|
|
73
|
+
body: JSON.stringify({
|
|
74
|
+
code: callback.code,
|
|
75
|
+
state: callback.state,
|
|
76
|
+
grant_type: "authorization_code",
|
|
77
|
+
client_id: CLIENT_ID,
|
|
78
|
+
redirect_uri: redirectUri,
|
|
79
|
+
code_verifier: verifier,
|
|
80
|
+
}),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
85
|
+
log("oauth_exchange_network_error", { error: message });
|
|
86
|
+
return { type: "failed" };
|
|
87
|
+
}
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
const body = await response.text().catch(() => "");
|
|
90
|
+
log("oauth_exchange_failed", { status: response.status, body });
|
|
91
|
+
return { type: "failed" };
|
|
92
|
+
}
|
|
93
|
+
const json = (await response.json());
|
|
94
|
+
return {
|
|
95
|
+
type: "success",
|
|
96
|
+
access: json.access_token,
|
|
97
|
+
refresh: json.refresh_token,
|
|
98
|
+
expires: Date.now() + json.expires_in * 1000,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export async function refreshTokens(refresh) {
|
|
102
|
+
let response;
|
|
103
|
+
try {
|
|
104
|
+
response = await fetch(TOKEN_URL, {
|
|
105
|
+
method: "POST",
|
|
106
|
+
headers: {
|
|
107
|
+
"Content-Type": "application/json",
|
|
108
|
+
Accept: "application/json, text/plain, */*",
|
|
109
|
+
"User-Agent": "axios/1.13.6",
|
|
110
|
+
},
|
|
111
|
+
body: JSON.stringify({
|
|
112
|
+
grant_type: "refresh_token",
|
|
113
|
+
refresh_token: refresh,
|
|
114
|
+
client_id: CLIENT_ID,
|
|
115
|
+
}),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
120
|
+
log("oauth_refresh_network_error", { error: message });
|
|
121
|
+
return { type: "failed" };
|
|
122
|
+
}
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
const body = await response.text().catch(() => "");
|
|
125
|
+
log("oauth_refresh_failed", { status: response.status, body });
|
|
126
|
+
return { type: "failed" };
|
|
127
|
+
}
|
|
128
|
+
const json = (await response.json());
|
|
129
|
+
return {
|
|
130
|
+
type: "success",
|
|
131
|
+
access: json.access_token,
|
|
132
|
+
refresh: json.refresh_token,
|
|
133
|
+
expires: Date.now() + json.expires_in * 1000,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
export async function buildAuthorizationUrl(mode = "console") {
|
|
137
|
+
const pkce = await generatePKCE();
|
|
138
|
+
const state = generateState();
|
|
139
|
+
const url = new URL(AUTHORIZE_URLS[mode]);
|
|
140
|
+
url.searchParams.set("code", "true");
|
|
141
|
+
url.searchParams.set("client_id", CLIENT_ID);
|
|
142
|
+
url.searchParams.set("response_type", "code");
|
|
143
|
+
url.searchParams.set("redirect_uri", CODE_CALLBACK_URL);
|
|
144
|
+
url.searchParams.set("scope", OAUTH_SCOPES.join(" "));
|
|
145
|
+
url.searchParams.set("code_challenge", pkce.challenge);
|
|
146
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
147
|
+
url.searchParams.set("state", state);
|
|
148
|
+
return {
|
|
149
|
+
url: url.toString(),
|
|
150
|
+
verifier: pkce.verifier,
|
|
151
|
+
state,
|
|
152
|
+
redirectUri: CODE_CALLBACK_URL,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
export function parseCallback(input) {
|
|
156
|
+
return parseCallbackInput(input);
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/pkce.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../src/pkce.ts"],"names":[],"mappings":"AAYA,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf,CAAC,CAaD"}
|
package/dist/pkce.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// PKCE (Proof Key for Code Exchange) helper for OAuth 2.0 flows.
|
|
2
|
+
// Ported from ex-machina/opencode-anthropic-auth to support the fallback
|
|
3
|
+
// "Claude OAuth" authorization method that triggers when the raw `sk-ant-`
|
|
4
|
+
// Keychain key is rejected by Anthropic's API (e.g. for org-locked accounts
|
|
5
|
+
// where the only direct auth method is OAuth, not a console API key).
|
|
6
|
+
function base64UrlEncode(bytes) {
|
|
7
|
+
let bin = "";
|
|
8
|
+
for (const byte of bytes)
|
|
9
|
+
bin += String.fromCharCode(byte);
|
|
10
|
+
return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
11
|
+
}
|
|
12
|
+
export async function generatePKCE() {
|
|
13
|
+
const buf = new Uint8Array(64);
|
|
14
|
+
crypto.getRandomValues(buf);
|
|
15
|
+
const verifier = base64UrlEncode(buf);
|
|
16
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
|
|
17
|
+
return {
|
|
18
|
+
verifier,
|
|
19
|
+
challenge: base64UrlEncode(new Uint8Array(digest)),
|
|
20
|
+
method: "S256",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=pkce.js.map
|
package/dist/pkce.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../src/pkce.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,yEAAyE;AACzE,2EAA2E;AAC3E,4EAA4E;AAC5E,sEAAsE;AAEtE,SAAS,eAAe,CAAC,KAAiB;IACxC,IAAI,GAAG,GAAG,EAAE,CAAA;IACZ,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;IAC1D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;AAC5E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAKhC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;IAC9B,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;IAC3B,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IACrC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CACvC,SAAS,EACT,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CACnC,CAAA;IACD,OAAO;QACL,QAAQ;QACR,SAAS,EAAE,eAAe,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,EAAE,MAAM;KACf,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin settings that can be set via opencode.json as an alternative
|
|
3
|
+
* to environment variables.
|
|
4
|
+
*
|
|
5
|
+
* Priority: environment variable > opencode.json config > hardcoded default
|
|
6
|
+
*
|
|
7
|
+
* In opencode.json (project-level or ~/.config/opencode/opencode.json):
|
|
8
|
+
*
|
|
9
|
+
* ```json
|
|
10
|
+
* {
|
|
11
|
+
* "agent": {
|
|
12
|
+
* "build": {
|
|
13
|
+
* "enable1mContext": true
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export interface PluginSettings {
|
|
20
|
+
enable1mContext?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Extract plugin settings from the opencode Config object.
|
|
24
|
+
*
|
|
25
|
+
* Scans all agent configs for our plugin-specific keys. AgentConfig has
|
|
26
|
+
* a catch-all `[key: string]: unknown` index signature, so arbitrary
|
|
27
|
+
* keys placed in agent configs are preserved through OpenCode's
|
|
28
|
+
* config parser and passed to the plugin via the `config` hook.
|
|
29
|
+
*
|
|
30
|
+
* NOTE: OpenCode's Zod schema may relocate unknown top-level agent keys
|
|
31
|
+
* into `agent.options`. We check both locations defensively so this
|
|
32
|
+
* survives future config parser changes.
|
|
33
|
+
*
|
|
34
|
+
* The first boolean value found (in any agent) wins — even if `false`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function applyOpencodeConfig(config: unknown): void;
|
|
37
|
+
/**
|
|
38
|
+
* Whether 1M context should be enabled.
|
|
39
|
+
*
|
|
40
|
+
* Priority: ANTHROPIC_ENABLE_1M_CONTEXT env var > opencode.json > false
|
|
41
|
+
*/
|
|
42
|
+
export declare function isEnable1mContext(): boolean;
|
|
43
|
+
export declare function resetPluginSettings(): void;
|
|
44
|
+
export declare function getPluginSettings(): Readonly<PluginSettings>;
|
|
45
|
+
//# sourceMappingURL=plugin-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-config.d.ts","sourceRoot":"","sources":["../src/plugin-config.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAoCzD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAI3C;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,iBAAiB,IAAI,QAAQ,CAAC,cAAc,CAAC,CAE5D"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { log } from "./logger.js";
|
|
2
|
+
let settings = {};
|
|
3
|
+
/**
|
|
4
|
+
* Extract plugin settings from the opencode Config object.
|
|
5
|
+
*
|
|
6
|
+
* Scans all agent configs for our plugin-specific keys. AgentConfig has
|
|
7
|
+
* a catch-all `[key: string]: unknown` index signature, so arbitrary
|
|
8
|
+
* keys placed in agent configs are preserved through OpenCode's
|
|
9
|
+
* config parser and passed to the plugin via the `config` hook.
|
|
10
|
+
*
|
|
11
|
+
* NOTE: OpenCode's Zod schema may relocate unknown top-level agent keys
|
|
12
|
+
* into `agent.options`. We check both locations defensively so this
|
|
13
|
+
* survives future config parser changes.
|
|
14
|
+
*
|
|
15
|
+
* The first boolean value found (in any agent) wins — even if `false`.
|
|
16
|
+
*/
|
|
17
|
+
export function applyOpencodeConfig(config) {
|
|
18
|
+
if (!config || typeof config !== "object")
|
|
19
|
+
return;
|
|
20
|
+
const cfg = config;
|
|
21
|
+
const agents = cfg.agent;
|
|
22
|
+
if (!agents || typeof agents !== "object")
|
|
23
|
+
return;
|
|
24
|
+
for (const agentConfig of Object.values(agents)) {
|
|
25
|
+
if (!agentConfig || typeof agentConfig !== "object")
|
|
26
|
+
continue;
|
|
27
|
+
const agent = agentConfig;
|
|
28
|
+
// Check top-level first, then fall back to options (where OpenCode's
|
|
29
|
+
// Zod transform may relocate unknown keys)
|
|
30
|
+
const val = agent.enable1mContext ??
|
|
31
|
+
agent.options?.enable1mContext;
|
|
32
|
+
if (typeof val === "boolean") {
|
|
33
|
+
settings.enable1mContext = val;
|
|
34
|
+
log("config_loaded", { enable1mContext: val });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (val !== undefined) {
|
|
38
|
+
log("config_invalid_type", {
|
|
39
|
+
key: "enable1mContext",
|
|
40
|
+
expectedType: "boolean",
|
|
41
|
+
actualType: typeof val,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
log("config_no_plugin_keys", {
|
|
46
|
+
agentCount: Object.keys(agents).length,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Whether 1M context should be enabled.
|
|
51
|
+
*
|
|
52
|
+
* Priority: ANTHROPIC_ENABLE_1M_CONTEXT env var > opencode.json > false
|
|
53
|
+
*/
|
|
54
|
+
export function isEnable1mContext() {
|
|
55
|
+
const envVal = process.env.ANTHROPIC_ENABLE_1M_CONTEXT;
|
|
56
|
+
if (envVal !== undefined)
|
|
57
|
+
return envVal === "true";
|
|
58
|
+
return settings.enable1mContext === true;
|
|
59
|
+
}
|
|
60
|
+
export function resetPluginSettings() {
|
|
61
|
+
settings = {};
|
|
62
|
+
}
|
|
63
|
+
export function getPluginSettings() {
|
|
64
|
+
return { ...settings };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=plugin-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-config.js","sourceRoot":"","sources":["../src/plugin-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAwBjC,IAAI,QAAQ,GAAmB,EAAE,CAAA;AAEjC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAM;IAEjD,MAAM,GAAG,GAAG,MAAiC,CAAA;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,KAA4C,CAAA;IAE/D,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAM;IAEjD,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ;YAAE,SAAQ;QAC7D,MAAM,KAAK,GAAG,WAAsC,CAAA;QAEpD,qEAAqE;QACrE,2CAA2C;QAC3C,MAAM,GAAG,GACP,KAAK,CAAC,eAAe;YACpB,KAAK,CAAC,OAA+C,EAAE,eAAe,CAAA;QAEzE,IAAI,OAAO,GAAG,KAAK,SAAS,EAAE,CAAC;YAC7B,QAAQ,CAAC,eAAe,GAAG,GAAG,CAAA;YAC9B,GAAG,CAAC,eAAe,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE,CAAC,CAAA;YAC9C,OAAM;QACR,CAAC;QAED,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,GAAG,CAAC,qBAAqB,EAAE;gBACzB,GAAG,EAAE,iBAAiB;gBACtB,YAAY,EAAE,SAAS;gBACvB,UAAU,EAAE,OAAO,GAAG;aACvB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,GAAG,CAAC,uBAAuB,EAAE;QAC3B,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM;KACvC,CAAC,CAAA;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAA;IACtD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,KAAK,MAAM,CAAA;IAClD,OAAO,QAAQ,CAAC,eAAe,KAAK,IAAI,CAAA;AAC1C,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,QAAQ,GAAG,EAAE,CAAA;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAA;AACxB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface Message {
|
|
2
|
+
role?: string;
|
|
3
|
+
content?: string | Array<{
|
|
4
|
+
type?: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
}>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Extract text from the first user message's first text block.
|
|
10
|
+
* Matches Claude Code's K19() function exactly: find the first message
|
|
11
|
+
* with role "user", then return the text of its first text content block.
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractFirstUserMessageText(messages: Message[]): string;
|
|
14
|
+
/**
|
|
15
|
+
* Compute cch: first 5 hex characters of SHA-256(messageText).
|
|
16
|
+
*/
|
|
17
|
+
export declare function computeCch(messageText: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Compute the 3-char version suffix.
|
|
20
|
+
* Samples characters at indices 4, 7, 20 from the message text (padding
|
|
21
|
+
* with "0" when the message is shorter), then hashes with the billing salt
|
|
22
|
+
* and version string.
|
|
23
|
+
*/
|
|
24
|
+
export declare function computeVersionSuffix(messageText: string, version: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Build the complete billing header string for insertion into system[0].
|
|
27
|
+
* Format: x-anthropic-billing-header: cc_version=V.S; cc_entrypoint=E; cch=H;
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildBillingHeaderValue(messages: Message[], version: string, entrypoint: string): string;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=signing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"AAIA,UAAU,OAAO;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC3D;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAYvE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,MAAM,CAUR"}
|
package/dist/signing.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
const BILLING_SALT = "59cf53e54c78";
|
|
3
|
+
/**
|
|
4
|
+
* Extract text from the first user message's first text block.
|
|
5
|
+
* Matches Claude Code's K19() function exactly: find the first message
|
|
6
|
+
* with role "user", then return the text of its first text content block.
|
|
7
|
+
*/
|
|
8
|
+
export function extractFirstUserMessageText(messages) {
|
|
9
|
+
const userMsg = messages.find((m) => m.role === "user");
|
|
10
|
+
if (!userMsg)
|
|
11
|
+
return "";
|
|
12
|
+
const content = userMsg.content;
|
|
13
|
+
if (typeof content === "string")
|
|
14
|
+
return content;
|
|
15
|
+
if (Array.isArray(content)) {
|
|
16
|
+
const textBlock = content.find((b) => b.type === "text");
|
|
17
|
+
if (textBlock && textBlock.type === "text" && textBlock.text) {
|
|
18
|
+
return textBlock.text;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return "";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Compute cch: first 5 hex characters of SHA-256(messageText).
|
|
25
|
+
*/
|
|
26
|
+
export function computeCch(messageText) {
|
|
27
|
+
return createHash("sha256").update(messageText).digest("hex").slice(0, 5);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Compute the 3-char version suffix.
|
|
31
|
+
* Samples characters at indices 4, 7, 20 from the message text (padding
|
|
32
|
+
* with "0" when the message is shorter), then hashes with the billing salt
|
|
33
|
+
* and version string.
|
|
34
|
+
*/
|
|
35
|
+
export function computeVersionSuffix(messageText, version) {
|
|
36
|
+
const sampled = [4, 7, 20]
|
|
37
|
+
.map((i) => (i < messageText.length ? messageText[i] : "0"))
|
|
38
|
+
.join("");
|
|
39
|
+
const input = `${BILLING_SALT}${sampled}${version}`;
|
|
40
|
+
return createHash("sha256").update(input).digest("hex").slice(0, 3);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the complete billing header string for insertion into system[0].
|
|
44
|
+
* Format: x-anthropic-billing-header: cc_version=V.S; cc_entrypoint=E; cch=H;
|
|
45
|
+
*/
|
|
46
|
+
export function buildBillingHeaderValue(messages, version, entrypoint) {
|
|
47
|
+
const text = extractFirstUserMessageText(messages);
|
|
48
|
+
const suffix = computeVersionSuffix(text, version);
|
|
49
|
+
const cch = computeCch(text);
|
|
50
|
+
return (`x-anthropic-billing-header: ` +
|
|
51
|
+
`cc_version=${version}.${suffix}; ` +
|
|
52
|
+
`cc_entrypoint=${entrypoint}; ` +
|
|
53
|
+
`cch=${cch};`);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=signing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.js","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,YAAY,GAAG,cAAc,CAAA;AAOnC;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,QAAmB;IAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAA;IACvD,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAA;IACvB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;IAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAA;IAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAA;QACxD,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;YAC7D,OAAO,SAAS,CAAC,IAAI,CAAA;QACvB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,WAAmB;IAC5C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAC3E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,WAAmB,EACnB,OAAe;IAEf,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;SACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAA;IACX,MAAM,KAAK,GAAG,GAAG,YAAY,GAAG,OAAO,GAAG,OAAO,EAAE,CAAA;IACnD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACrE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAAmB,EACnB,OAAe,EACf,UAAkB;IAElB,MAAM,IAAI,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAA;IAClD,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IAClD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;IAC5B,OAAO,CACL,8BAA8B;QAC9B,cAAc,OAAO,IAAI,MAAM,IAAI;QACnC,iBAAiB,UAAU,IAAI;QAC/B,OAAO,GAAG,GAAG,CACd,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type ContentBlock = {
|
|
2
|
+
type?: string;
|
|
3
|
+
text?: string;
|
|
4
|
+
} & Record<string, unknown>;
|
|
5
|
+
type Message = {
|
|
6
|
+
role?: string;
|
|
7
|
+
content?: string | ContentBlock[];
|
|
8
|
+
};
|
|
9
|
+
export declare function repairToolPairs(messages: Message[]): Message[];
|
|
10
|
+
export declare function transformBody(body: BodyInit | null | undefined): BodyInit | null | undefined;
|
|
11
|
+
export declare function stripToolPrefix(text: string): string;
|
|
12
|
+
export declare function transformResponseStream(response: Response): Response;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=transforms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transforms.d.ts","sourceRoot":"","sources":["../src/transforms.ts"],"names":[],"mappings":"AAyBA,KAAK,YAAY,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAC9E,KAAK,OAAO,GAAG;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAAA;CAClC,CAAA;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAuD9D;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,GAChC,QAAQ,GAAG,IAAI,GAAG,SAAS,CA2K7B;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAqEpE"}
|