@xiaoso/dsh-tool-plus 0.1.0-beta.2 → 0.1.0-beta.4
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.en.md +122 -0
- package/README.md +3 -2
- package/THIRD_PARTY_NOTICES.md +4 -35
- package/lib/abort-B7izMMna.mjs +51 -0
- package/lib/abort-D1_Z5Ut5.mjs +51 -0
- package/lib/abort-dIkZBV7Q.mjs +51 -0
- package/lib/amazon-bedrock-B0nxT06F.mjs +917 -0
- package/lib/amazon-bedrock-D-shAr1X.mjs +917 -0
- package/lib/amazon-bedrock-WQhvjHYu.mjs +917 -0
- package/lib/anthropic-BWsZFzU8.mjs +262 -0
- package/lib/anthropic-CJCauvYz.mjs +3115 -0
- package/lib/anthropic-CMT1Qj1t.mjs +3115 -0
- package/lib/anthropic-CZghe_9U.mjs +3115 -0
- package/lib/anthropic-sCMH7JID.mjs +262 -0
- package/lib/anthropic-tTntD8BD.mjs +262 -0
- package/lib/api-key-login-BzqNdM2y.mjs +157 -0
- package/lib/api-key-login-CWVwvHT1.mjs +157 -0
- package/lib/api-key-login-CpzSezsi.mjs +157 -0
- package/lib/aws-credentials-8Mgn5MAy.mjs +867 -0
- package/lib/aws-credentials-CXryMobh.mjs +867 -0
- package/lib/aws-credentials-ChG79ey-.mjs +867 -0
- package/lib/azure-openai-responses-CNkHiLUh.mjs +274 -0
- package/lib/azure-openai-responses-Cgmc-rbL.mjs +274 -0
- package/lib/azure-openai-responses-DuukbD0F.mjs +274 -0
- package/lib/bun-shim.mjs +252 -12
- package/lib/bundled-references-CSuBco5p.mjs +55 -0
- package/lib/bundled-references-Cavaffah.mjs +55 -0
- package/lib/bundled-references-sLN0YdXU.mjs +55 -0
- package/lib/callback-server-BEFNf-jf.mjs +398 -0
- package/lib/callback-server-CQ5Jo8F-.mjs +398 -0
- package/lib/callback-server-DDSrZ6l_.mjs +398 -0
- package/lib/client.js +111 -41
- package/lib/cursor-B3zg7EHj.mjs +273 -0
- package/lib/cursor-B6TUEmgP.mjs +135 -0
- package/lib/cursor-BIQfBC6V.mjs +135 -0
- package/lib/cursor-D8gvtTL3.mjs +135 -0
- package/lib/cursor-DNk6eXDd.mjs +5470 -0
- package/lib/cursor-DkSX2h3H.mjs +5441 -0
- package/lib/cursor-MjSm74IJ.mjs +273 -0
- package/lib/cursor-aJrXeYCb.mjs +273 -0
- package/lib/cursor-mJQwUKXK.mjs +5441 -0
- package/lib/device-code-DBo3B5nh.mjs +51 -0
- package/lib/device-code-DIb0FU-H.mjs +51 -0
- package/lib/device-code-OI_tQcmc.mjs +51 -0
- package/lib/devin-BHZZyMhO.mjs +95 -0
- package/lib/devin-BK7DHeca.mjs +114 -0
- package/lib/devin-CfMp3cXS.mjs +95 -0
- package/lib/devin-CldyPD8K.mjs +95 -0
- package/lib/devin-CzRpTUOA.mjs +114 -0
- package/lib/devin-D9zR5B_R.mjs +542 -0
- package/lib/devin-DXOeNyU7.mjs +542 -0
- package/lib/devin-Q1yem3lp.mjs +114 -0
- package/lib/devin-vNZTNUON.mjs +542 -0
- package/lib/error-B3bevhrs.mjs +1449 -0
- package/lib/error-Dd8DIqs-.mjs +1449 -0
- package/lib/error-yCSG0mGC.mjs +1449 -0
- package/lib/event-stream-BDPi64mK.mjs +151 -0
- package/lib/event-stream-BbFZJy-z.mjs +151 -0
- package/lib/event-stream-loUa0s1T.mjs +151 -0
- package/lib/fs-promises-shim-Bx0fpxuk.mjs +57 -0
- package/lib/github-copilot-4GaMtQmg.mjs +208 -0
- package/lib/github-copilot-B1yiyVRh.mjs +104 -0
- package/lib/github-copilot-B2HGSIJK.mjs +104 -0
- package/lib/github-copilot-BWT3eAOF.mjs +208 -0
- package/lib/github-copilot-CYkjeTi3.mjs +208 -0
- package/lib/github-copilot-jscUZ8Hf.mjs +104 -0
- package/lib/gitlab-duo-CM7Ref1H.mjs +155 -0
- package/lib/gitlab-duo-akICyfeD.mjs +155 -0
- package/lib/gitlab-duo-gubO4FNw.mjs +155 -0
- package/lib/gitlab-duo-workflow-BGAF6JDw.mjs +91 -0
- package/lib/gitlab-duo-workflow-CSEgYk3N.mjs +91 -0
- package/lib/gitlab-duo-workflow-D78tdn8E.mjs +91 -0
- package/lib/google-BS4T25Pn.mjs +30 -0
- package/lib/google-TFe-7-of.mjs +30 -0
- package/lib/google-antigravity-DGmwC2KV.mjs +198 -0
- package/lib/google-antigravity-DNYhgTpA.mjs +198 -0
- package/lib/google-antigravity-Dlkdhahq.mjs +198 -0
- package/lib/google-auth-B6gjsZvg.mjs +232 -0
- package/lib/google-auth-De7_s3eo.mjs +232 -0
- package/lib/google-auth-DhqpOYrX.mjs +232 -0
- package/lib/google-gemini-cli-BG_LRdIV.mjs +850 -0
- package/lib/google-gemini-cli-CWu8HvXW.mjs +211 -0
- package/lib/google-gemini-cli-Cb97bzQc.mjs +850 -0
- package/lib/google-gemini-cli-Cqds_Q5T.mjs +850 -0
- package/lib/google-gemini-cli-Dsztq0N5.mjs +211 -0
- package/lib/google-gemini-cli-zJhiOcND.mjs +211 -0
- package/lib/google-oauth-shared-CuEHaDDj.mjs +147 -0
- package/lib/google-oauth-shared-CwNWYdmR.mjs +147 -0
- package/lib/google-oauth-shared-yqlyqPPC.mjs +147 -0
- package/lib/google-shared-CgKmmdO3.mjs +760 -0
- package/lib/google-shared-Dr-VG-ap.mjs +760 -0
- package/lib/google-shared-DzhCb9b0.mjs +760 -0
- package/lib/google-vertex-BDN2tLaD.mjs +99 -0
- package/lib/google-vertex-DopVOQOG.mjs +99 -0
- package/lib/google-vertex-kscbkyRb.mjs +99 -0
- package/lib/google-zyDOG9x7.mjs +30 -0
- package/lib/identity-Da1GPU9a.mjs +219 -0
- package/lib/identity-DnB63pS7.mjs +219 -0
- package/lib/identity-xRP7_eSR.mjs +219 -0
- package/lib/idle-iterator-Baoyn3Hp.mjs +366 -0
- package/lib/idle-iterator-C6XbWcuB.mjs +366 -0
- package/lib/idle-iterator-DUjKQEGT.mjs +366 -0
- package/lib/index.mjs +4608 -3935
- package/lib/kimi--wUOWER5.mjs +236 -0
- package/lib/kimi-DMVI-zrZ.mjs +236 -0
- package/lib/kimi-Dh0pv3WZ.mjs +236 -0
- package/lib/markit-BL3cH47U.mjs +1417 -0
- package/lib/markit-BNiNY6SE.mjs +1417 -0
- package/lib/markit-M0jhziqU.mjs +1417 -0
- package/lib/minimax-code-BK-3eBbz.mjs +53 -0
- package/lib/minimax-code-DCbuA6Yk.mjs +53 -0
- package/lib/minimax-code-Uq8Qu9LW.mjs +53 -0
- package/lib/models-CfT4coYT.mjs +104660 -0
- package/lib/models-D_XnT6ay.mjs +104660 -0
- package/lib/models-SGASygJ3.mjs +104660 -0
- package/lib/ollama-BQMGPxtV.mjs +589 -0
- package/lib/ollama-DPzBmq89.mjs +589 -0
- package/lib/ollama-DoBz5SFm.mjs +589 -0
- package/lib/openai-codex-Bi-4S4PX.mjs +255 -0
- package/lib/openai-codex-CQL_kvYL.mjs +255 -0
- package/lib/openai-codex-Ch8CkT3p.mjs +255 -0
- package/lib/openai-codex-responses-CvxL_FMF.mjs +3144 -0
- package/lib/openai-codex-responses-Cz-2qpC7.mjs +3144 -0
- package/lib/openai-codex-responses-pejZgdZo.mjs +3144 -0
- package/lib/openai-completions-CF8IyNtP.mjs +1360 -0
- package/lib/openai-completions-DIf361kF.mjs +1360 -0
- package/lib/openai-completions-i8doczAk.mjs +1360 -0
- package/lib/openai-reasoning-fallback-DGVVLgd1.mjs +286 -0
- package/lib/openai-reasoning-fallback-Nj6yB2rY.mjs +286 -0
- package/lib/openai-reasoning-fallback-OdJREP1o.mjs +286 -0
- package/lib/openai-responses-BqXJInHX.mjs +867 -0
- package/lib/openai-responses-DTkBiiy-.mjs +867 -0
- package/lib/openai-responses-Db_a-U4-.mjs +867 -0
- package/lib/opencode-DaJjcUbf.mjs +38 -0
- package/lib/opencode-DhMolSoB.mjs +38 -0
- package/lib/opencode-Rq_Q2vAO.mjs +38 -0
- package/lib/perplexity-9b-RQ0mV.mjs +194 -0
- package/lib/perplexity-C4iLVMUj.mjs +194 -0
- package/lib/perplexity-Uu7Jzg5b.mjs +194 -0
- package/lib/proxy-DDqrmjjC.mjs +190 -0
- package/lib/proxy-ZtUcl6r5.mjs +190 -0
- package/lib/proxy-pM_NIv-H.mjs +190 -0
- package/lib/request-debug-HJMoJncL.mjs +183 -0
- package/lib/sanitize-text-CfcXzw5X.mjs +33 -0
- package/lib/scrapers-BkFfcPHj.mjs +9198 -0
- package/lib/scrapers-CL-WgdU1.mjs +9198 -0
- package/lib/scrapers-CVptboMs.mjs +9198 -0
- package/lib/scrapers-CipyKyCH.mjs +9198 -0
- package/lib/scrapers-DGfrYhtw.mjs +9198 -0
- package/lib/scrapers-DSUPYoUF.mjs +9198 -0
- package/lib/scrapers-DZ2GXmp7.mjs +9198 -0
- package/lib/scrapers-nhQAvc8d.mjs +9198 -0
- package/lib/shell-snapshot-fn-env.sh +67 -43
- package/lib/src-BgpusnsB.mjs +5076 -0
- package/lib/src-DTid0g4K.mjs +5001 -0
- package/lib/src-lDmkSRbm.mjs +5006 -0
- package/lib/stream-BlldLkVq.mjs +10236 -0
- package/lib/stream-CRtexYLe.mjs +10236 -0
- package/lib/stream-C_RAoxJC.mjs +10236 -0
- package/lib/stream-markup-healing-2toHXWXM.mjs +491 -0
- package/lib/stream-markup-healing-DMsxBx1L.mjs +491 -0
- package/lib/stream-markup-healing-KMkiAA00.mjs +491 -0
- package/lib/turndown-DN7ByzEI.mjs +667 -0
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/config/fields.d.ts +1 -1
- package/lib/types/config/settings.d.ts +25 -3
- package/lib/types/config/truncate.d.ts +9 -5
- package/lib/types/tools/bash/background.d.ts +1 -1
- package/lib/types/tools/bash/bash-executor.d.ts +4 -0
- package/lib/types/tools/bash/bash-interceptor.d.ts +10 -8
- package/lib/types/tools/bash/cd-workdir.d.ts +35 -0
- package/lib/types/tools/bash/non-interactive-env.d.ts +2 -0
- package/lib/types/tools/bash/render.d.ts +4 -3
- package/lib/types/tools/bash/sanitize-text.d.ts +5 -0
- package/lib/types/tools/bash/shell-snapshot.d.ts +4 -1
- package/lib/types/tools/bash/shell-tokenize.d.ts +60 -0
- package/lib/types/tools/bash/streaming-output.d.ts +12 -212
- package/lib/types/tools/bash/which.d.ts +20 -0
- package/lib/types/tools/bash/windows-shell.d.ts +31 -0
- package/lib/types/tools/edit/adapter/index.d.ts +25 -3
- package/lib/types/tools/edit/adapter/tools/auto-generated-guard.d.ts +7 -17
- package/lib/types/tools/glob/adapter/index.d.ts +27 -1
- package/lib/types/tools/grep/adapter/index.d.ts +29 -1
- package/lib/types/tools/omp/edit/dispatch.d.ts +43 -0
- package/lib/types/tools/omp/edit/hashline/noop-loop-guard.d.ts +3 -1
- package/lib/types/tools/omp/sdk.d.ts +6 -0
- package/lib/types/tools/omp/tools/auto-generated-guard.d.ts +20 -0
- package/lib/types/tools/omp/tools/fetch.d.ts +2 -0
- package/lib/types/tools/omp/tools/read.d.ts +2 -8
- package/lib/types/tools/omp/tools/write.d.ts +4 -4
- package/lib/types/tools/omp/utils/image-loading.d.ts +10 -36
- package/lib/types/tools/read/adapter/index.d.ts +4 -1
- package/lib/types/tools/read-image/index.d.ts +4 -0
- package/lib/types/tools/shared/auto-generated-guard.dsh.d.ts +16 -4
- package/lib/types/tools/shared/bun-shim.d.ts +39 -3
- package/lib/types/tools/shared/fs-promises-shim.d.ts +3 -1
- package/lib/types/tools/shared/image-bridge.d.ts +98 -0
- package/lib/types/tools/shared/omp-prompt.d.ts +17 -9
- package/lib/types/tools/shared/session-state.d.ts +9 -3
- package/lib/utils-2Wq2eATG.mjs +8119 -0
- package/lib/utils-BnX8O3vi.mjs +12303 -0
- package/lib/utils-Bw139LTz.mjs +8119 -0
- package/lib/utils-CE8N8P4Q.mjs +12315 -0
- package/lib/utils-CZw4tVZQ.mjs +12315 -0
- package/lib/utils-C_MrQ_0z.mjs +12301 -0
- package/lib/utils-CiGN7OHR.mjs +12315 -0
- package/lib/utils-Cp76gCyk.mjs +8119 -0
- package/lib/utils-D0GRDgAr.mjs +12315 -0
- package/lib/utils-D0Z1fyoO.mjs +12299 -0
- package/lib/utils-D2YknRk4.mjs +51 -0
- package/lib/utils-DppGHXQB.mjs +51 -0
- package/lib/utils-DzXZDfYc.mjs +51 -0
- package/lib/utils-W8WdSBpX.mjs +12315 -0
- package/lib/vision-guard-01qSwFpf.mjs +92 -0
- package/lib/vision-guard-BDD4OrKo.mjs +92 -0
- package/lib/vision-guard-DzZGaOga.mjs +92 -0
- package/lib/wafer-CgtPHerf.mjs +17 -0
- package/lib/wafer-DRU0EjZX.mjs +17 -0
- package/lib/wafer-cBtrn6q9.mjs +17 -0
- package/lib/xai-oauth-Buk8XVvM.mjs +446 -0
- package/lib/xai-oauth-CMal8l1O.mjs +446 -0
- package/lib/xai-oauth-DPHDXKD7.mjs +446 -0
- package/lib/xiaomi-CZgwvX2G.mjs +157 -0
- package/lib/xiaomi-D2qT5cAC.mjs +157 -0
- package/lib/xiaomi-Dd87KSg5.mjs +157 -0
- package/lib/zai-7DWMkEqM.mjs +203 -0
- package/lib/zai-C59YnomG.mjs +203 -0
- package/lib/zai-CFeOt-53.mjs +203 -0
- package/lib/zip-Cg9ANN_U.mjs +1316 -0
- package/lib/zip-D36ZKsP8.mjs +1316 -0
- package/lib/zip-D6QXpvaJ.mjs +1316 -0
- package/package.json +14 -10
- package/presets/package.json +1 -1
- package/presets/tool-plus-ptc/preset.yml +1 -1
- package/presets/tool-plus-standard/preset.yml +1 -1
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { r as __exportAll } from "./fs-promises-shim-B-9cMxz5.mjs";
|
|
4
|
+
import { V as ProviderHttpError, c as OAuthError } from "./error-yCSG0mGC.mjs";
|
|
5
|
+
import { t as OAuthCallbackFlow } from "./callback-server-DDSrZ6l_.mjs";
|
|
6
|
+
import { t as generatePKCE } from "./pkce-BlQikGPu.mjs";
|
|
7
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/claude-code-fingerprint.ts
|
|
8
|
+
/**
|
|
9
|
+
* Cowork inference-fingerprint constants, kept in a leaf module so consumers
|
|
10
|
+
* outside the provider (`registry/oauth/anthropic`, `usage/claude`) don't
|
|
11
|
+
* import the heavy `providers/anthropic` module.
|
|
12
|
+
*
|
|
13
|
+
* That import edge was a live init cycle: `providers/anthropic` → `stream` →
|
|
14
|
+
* `registry` → `registry/oauth/anthropic` → back into the still-initializing
|
|
15
|
+
* provider module.
|
|
16
|
+
*/
|
|
17
|
+
/** Claude runtime version bundled by the current Cowork desktop release. */
|
|
18
|
+
const claudeCodeVersion = "2.1.220";
|
|
19
|
+
/** User-Agent emitted by Cowork's `claude-desktop` inference entrypoint. */
|
|
20
|
+
const coworkUserAgent = `claude-cli/${claudeCodeVersion} (external, claude-desktop)`;
|
|
21
|
+
/** Identity block prepended by Cowork's Claude runtime. */
|
|
22
|
+
const claudeCodeSystemInstruction = "You are a Claude agent, built on Anthropic's Claude Agent SDK.";
|
|
23
|
+
/** Cowork's per-request output-token ceiling. */
|
|
24
|
+
const CLAUDE_CODE_MAX_OUTPUT_TOKENS = 64e3;
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/anthropic.ts
|
|
27
|
+
/**
|
|
28
|
+
* Anthropic OAuth flow (Claude Pro/Max)
|
|
29
|
+
*/
|
|
30
|
+
var anthropic_exports = /* @__PURE__ */ __exportAll({
|
|
31
|
+
ANTHROPIC_OAUTH_GRANT_TTL_MS: () => ANTHROPIC_OAUTH_GRANT_TTL_MS,
|
|
32
|
+
AnthropicOAuthFlow: () => AnthropicOAuthFlow,
|
|
33
|
+
loginAnthropic: () => loginAnthropic,
|
|
34
|
+
refreshAnthropicToken: () => refreshAnthropicToken
|
|
35
|
+
});
|
|
36
|
+
const decode = (s) => atob(s);
|
|
37
|
+
const CLIENT_ID = decode("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
|
|
38
|
+
const AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
|
|
39
|
+
const TOKEN_URL = "https://api.anthropic.com/v1/oauth/token";
|
|
40
|
+
const BOOTSTRAP_URL = "https://api.anthropic.com/api/claude_cli/bootstrap";
|
|
41
|
+
const CLAUDE_CODE_BOOTSTRAP_MODEL = "claude-opus-4-8";
|
|
42
|
+
const CLAUDE_CODE_BOOTSTRAP_USER_AGENT = `claude-code/${claudeCodeVersion}`;
|
|
43
|
+
const CALLBACK_PORT = 54545;
|
|
44
|
+
const CALLBACK_PATH = "/callback";
|
|
45
|
+
const SCOPES = "org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload";
|
|
46
|
+
function formatErrorDetails(error) {
|
|
47
|
+
if (error instanceof Error) {
|
|
48
|
+
const details = [`${error.name}: ${error.message}`];
|
|
49
|
+
const errorWithCode = error;
|
|
50
|
+
if (errorWithCode.code) details.push(`code=${errorWithCode.code}`);
|
|
51
|
+
if (typeof errorWithCode.errno !== "undefined") details.push(`errno=${String(errorWithCode.errno)}`);
|
|
52
|
+
if (typeof error.cause !== "undefined") details.push(`cause=${formatErrorDetails(error.cause)}`);
|
|
53
|
+
if (error.stack) details.push(`stack=${error.stack}`);
|
|
54
|
+
return details.join("; ");
|
|
55
|
+
}
|
|
56
|
+
return String(error);
|
|
57
|
+
}
|
|
58
|
+
async function postJson(url, body, fetchImpl, extraHeaders) {
|
|
59
|
+
const response = await fetchImpl(url, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: {
|
|
62
|
+
...extraHeaders,
|
|
63
|
+
"Content-Type": "application/json"
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify(body),
|
|
66
|
+
signal: AbortSignal.timeout(3e4)
|
|
67
|
+
});
|
|
68
|
+
const responseBody = await response.text();
|
|
69
|
+
if (!response.ok) throw new ProviderHttpError(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`, response.status);
|
|
70
|
+
return responseBody;
|
|
71
|
+
}
|
|
72
|
+
function nonEmpty(value) {
|
|
73
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
74
|
+
}
|
|
75
|
+
function parseOAuthTokenResponse(responseBody, operation) {
|
|
76
|
+
try {
|
|
77
|
+
return JSON.parse(responseBody);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
throw new OAuthError(`Anthropic ${operation} returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`, {
|
|
80
|
+
kind: "validation",
|
|
81
|
+
provider: "anthropic",
|
|
82
|
+
cause: error
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Lift the OAuth response's `account: { uuid, email_address }` and
|
|
88
|
+
* `organization: { uuid, name }` blocks onto {@link OAuthCredentials} so
|
|
89
|
+
* downstream identity propagation (e.g. `metadata.user_id.account_uuid`,
|
|
90
|
+
* usage tracking, org-scoped credential identity) works without a separate
|
|
91
|
+
* `/api/oauth/profile` round-trip. Returns `undefined` for any field the
|
|
92
|
+
* response omits or carries as a non-string / empty value.
|
|
93
|
+
*/
|
|
94
|
+
function extractAccountFromTokenResponse(data) {
|
|
95
|
+
return {
|
|
96
|
+
accountId: nonEmpty(data.account?.uuid),
|
|
97
|
+
email: nonEmpty(data.account?.email_address),
|
|
98
|
+
orgId: nonEmpty(data.organization?.uuid),
|
|
99
|
+
orgName: nonEmpty(data.organization?.name)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function fetchBootstrapIdentity(accessToken, fetchImpl) {
|
|
103
|
+
const url = `${BOOTSTRAP_URL}?entrypoint=cli&model=${encodeURIComponent(CLAUDE_CODE_BOOTSTRAP_MODEL)}`;
|
|
104
|
+
const response = await fetchImpl(url, {
|
|
105
|
+
method: "GET",
|
|
106
|
+
headers: {
|
|
107
|
+
Accept: "application/json, text/plain, */*",
|
|
108
|
+
Authorization: `Bearer ${accessToken}`,
|
|
109
|
+
"Content-Type": "application/json",
|
|
110
|
+
"User-Agent": CLAUDE_CODE_BOOTSTRAP_USER_AGENT,
|
|
111
|
+
"anthropic-beta": "oauth-2025-04-20"
|
|
112
|
+
},
|
|
113
|
+
signal: AbortSignal.timeout(3e4)
|
|
114
|
+
});
|
|
115
|
+
const responseBody = await response.text();
|
|
116
|
+
if (!response.ok) throw new ProviderHttpError(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`, response.status);
|
|
117
|
+
let data;
|
|
118
|
+
try {
|
|
119
|
+
data = JSON.parse(responseBody);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
throw new OAuthError(`Anthropic bootstrap returned invalid JSON. url=${url}; body=${responseBody}; details=${formatErrorDetails(error)}`, {
|
|
122
|
+
kind: "validation",
|
|
123
|
+
provider: "anthropic",
|
|
124
|
+
cause: error
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
accountId: nonEmpty(data.oauth_account?.account_uuid),
|
|
129
|
+
email: nonEmpty(data.oauth_account?.account_email),
|
|
130
|
+
orgId: nonEmpty(data.oauth_account?.organization_uuid),
|
|
131
|
+
orgName: nonEmpty(data.oauth_account?.organization_name)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve account (and optionally organization) identity for a token
|
|
136
|
+
* response. `includeOrg` is login-only: the org an access token is scoped to
|
|
137
|
+
* is captured once when the credential is created and deliberately never
|
|
138
|
+
* refreshed afterwards — rewriting identity during background token
|
|
139
|
+
* refreshes could silently re-key stored credentials.
|
|
140
|
+
*/
|
|
141
|
+
async function resolveAccountIdentity(data, fetchImpl, options) {
|
|
142
|
+
const identity = extractAccountFromTokenResponse(data);
|
|
143
|
+
const orgSatisfied = !options?.includeOrg || identity.orgId !== void 0;
|
|
144
|
+
if (identity.accountId && identity.email && orgSatisfied) return identity;
|
|
145
|
+
try {
|
|
146
|
+
const bootstrap = await fetchBootstrapIdentity(data.access_token, fetchImpl);
|
|
147
|
+
return {
|
|
148
|
+
accountId: identity.accountId ?? bootstrap.accountId,
|
|
149
|
+
email: identity.email ?? bootstrap.email,
|
|
150
|
+
orgId: identity.orgId ?? bootstrap.orgId,
|
|
151
|
+
orgName: identity.orgName ?? bootstrap.orgName
|
|
152
|
+
};
|
|
153
|
+
} catch {
|
|
154
|
+
return identity;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
var AnthropicOAuthFlow = class extends OAuthCallbackFlow {
|
|
158
|
+
#verifier = "";
|
|
159
|
+
#challenge = "";
|
|
160
|
+
#fetch;
|
|
161
|
+
constructor(ctrl) {
|
|
162
|
+
super(ctrl, CALLBACK_PORT, CALLBACK_PATH);
|
|
163
|
+
this.#fetch = ctrl.fetch ?? fetch;
|
|
164
|
+
}
|
|
165
|
+
async generateAuthUrl(state, redirectUri) {
|
|
166
|
+
const pkce = await generatePKCE();
|
|
167
|
+
this.#verifier = pkce.verifier;
|
|
168
|
+
this.#challenge = pkce.challenge;
|
|
169
|
+
const authParams = new URLSearchParams({
|
|
170
|
+
code: "true",
|
|
171
|
+
client_id: CLIENT_ID,
|
|
172
|
+
response_type: "code",
|
|
173
|
+
redirect_uri: redirectUri,
|
|
174
|
+
scope: SCOPES,
|
|
175
|
+
code_challenge: this.#challenge,
|
|
176
|
+
code_challenge_method: "S256",
|
|
177
|
+
state
|
|
178
|
+
});
|
|
179
|
+
return {
|
|
180
|
+
url: `${AUTHORIZE_URL}?${authParams.toString()}`,
|
|
181
|
+
instructions: "Complete login in your browser. If the browser cannot reach this machine, paste the final redirect URL or authorization code when prompted."
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
async exchangeToken(code, state, redirectUri) {
|
|
185
|
+
let exchangeCode = code;
|
|
186
|
+
let exchangeState = state;
|
|
187
|
+
const codeFragmentIndex = code.indexOf("#");
|
|
188
|
+
if (codeFragmentIndex >= 0) {
|
|
189
|
+
exchangeCode = code.slice(0, codeFragmentIndex);
|
|
190
|
+
const codeFragmentState = code.slice(codeFragmentIndex + 1);
|
|
191
|
+
if (codeFragmentState.length > 0) exchangeState = codeFragmentState;
|
|
192
|
+
}
|
|
193
|
+
let responseBody;
|
|
194
|
+
try {
|
|
195
|
+
responseBody = await postJson(TOKEN_URL, {
|
|
196
|
+
grant_type: "authorization_code",
|
|
197
|
+
client_id: CLIENT_ID,
|
|
198
|
+
code: exchangeCode,
|
|
199
|
+
state: exchangeState,
|
|
200
|
+
redirect_uri: redirectUri,
|
|
201
|
+
code_verifier: this.#verifier
|
|
202
|
+
}, this.#fetch);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
throw new OAuthError(`Token exchange request failed. url=${TOKEN_URL}; redirect_uri=${redirectUri}; response_type=authorization_code; details=${formatErrorDetails(error)}`, {
|
|
205
|
+
kind: "token-exchange",
|
|
206
|
+
provider: "anthropic",
|
|
207
|
+
cause: error
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
const tokenData = parseOAuthTokenResponse(responseBody, "token exchange");
|
|
211
|
+
const { accountId, email, orgId, orgName } = await resolveAccountIdentity(tokenData, this.#fetch, { includeOrg: true });
|
|
212
|
+
return {
|
|
213
|
+
refresh: tokenData.refresh_token,
|
|
214
|
+
access: tokenData.access_token,
|
|
215
|
+
expires: Date.now() + tokenData.expires_in * 1e3 - 3e5,
|
|
216
|
+
accountId,
|
|
217
|
+
email,
|
|
218
|
+
orgId,
|
|
219
|
+
orgName
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Login with Anthropic OAuth
|
|
225
|
+
*/
|
|
226
|
+
async function loginAnthropic(ctrl) {
|
|
227
|
+
return new AnthropicOAuthFlow(ctrl).login();
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Refresh Anthropic OAuth token
|
|
231
|
+
*/
|
|
232
|
+
async function refreshAnthropicToken(refreshToken, fetchOverride) {
|
|
233
|
+
const fetchImpl = fetchOverride ?? fetch;
|
|
234
|
+
let responseBody;
|
|
235
|
+
try {
|
|
236
|
+
responseBody = await postJson(TOKEN_URL, {
|
|
237
|
+
grant_type: "refresh_token",
|
|
238
|
+
client_id: CLIENT_ID,
|
|
239
|
+
refresh_token: refreshToken
|
|
240
|
+
}, fetchImpl, {
|
|
241
|
+
"anthropic-beta": "oauth-2025-04-20",
|
|
242
|
+
"User-Agent": "anthropic-sdk-typescript/0.94.0 userOAuthProvider"
|
|
243
|
+
});
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw new OAuthError(`Anthropic token refresh request failed. url=${TOKEN_URL}; details=${formatErrorDetails(error)}`, {
|
|
246
|
+
kind: "token-refresh",
|
|
247
|
+
provider: "anthropic",
|
|
248
|
+
cause: error
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
const data = parseOAuthTokenResponse(responseBody, "token refresh");
|
|
252
|
+
const { accountId, email } = await resolveAccountIdentity(data, fetchImpl);
|
|
253
|
+
return {
|
|
254
|
+
refresh: data.refresh_token || refreshToken,
|
|
255
|
+
access: data.access_token,
|
|
256
|
+
expires: Date.now() + data.expires_in * 1e3 - 3e5,
|
|
257
|
+
accountId,
|
|
258
|
+
email
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
//#endregion
|
|
262
|
+
export { coworkUserAgent as a, claudeCodeVersion as i, CLAUDE_CODE_MAX_OUTPUT_TOKENS as n, claudeCodeSystemInstruction as r, anthropic_exports as t };
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { r as __exportAll } from "./fs-promises-shim-Bx0fpxuk.mjs";
|
|
4
|
+
import { V as ProviderHttpError, c as OAuthError } from "./error-Dd8DIqs-.mjs";
|
|
5
|
+
import { t as OAuthCallbackFlow } from "./callback-server-CQ5Jo8F-.mjs";
|
|
6
|
+
import { t as generatePKCE } from "./pkce-BlQikGPu.mjs";
|
|
7
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/claude-code-fingerprint.ts
|
|
8
|
+
/**
|
|
9
|
+
* Cowork inference-fingerprint constants, kept in a leaf module so consumers
|
|
10
|
+
* outside the provider (`registry/oauth/anthropic`, `usage/claude`) don't
|
|
11
|
+
* import the heavy `providers/anthropic` module.
|
|
12
|
+
*
|
|
13
|
+
* That import edge was a live init cycle: `providers/anthropic` → `stream` →
|
|
14
|
+
* `registry` → `registry/oauth/anthropic` → back into the still-initializing
|
|
15
|
+
* provider module.
|
|
16
|
+
*/
|
|
17
|
+
/** Claude runtime version bundled by the current Cowork desktop release. */
|
|
18
|
+
const claudeCodeVersion = "2.1.220";
|
|
19
|
+
/** User-Agent emitted by Cowork's `claude-desktop` inference entrypoint. */
|
|
20
|
+
const coworkUserAgent = `claude-cli/${claudeCodeVersion} (external, claude-desktop)`;
|
|
21
|
+
/** Identity block prepended by Cowork's Claude runtime. */
|
|
22
|
+
const claudeCodeSystemInstruction = "You are a Claude agent, built on Anthropic's Claude Agent SDK.";
|
|
23
|
+
/** Cowork's per-request output-token ceiling. */
|
|
24
|
+
const CLAUDE_CODE_MAX_OUTPUT_TOKENS = 64e3;
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/anthropic.ts
|
|
27
|
+
/**
|
|
28
|
+
* Anthropic OAuth flow (Claude Pro/Max)
|
|
29
|
+
*/
|
|
30
|
+
var anthropic_exports = /* @__PURE__ */ __exportAll({
|
|
31
|
+
ANTHROPIC_OAUTH_GRANT_TTL_MS: () => ANTHROPIC_OAUTH_GRANT_TTL_MS,
|
|
32
|
+
AnthropicOAuthFlow: () => AnthropicOAuthFlow,
|
|
33
|
+
loginAnthropic: () => loginAnthropic,
|
|
34
|
+
refreshAnthropicToken: () => refreshAnthropicToken
|
|
35
|
+
});
|
|
36
|
+
const decode = (s) => atob(s);
|
|
37
|
+
const CLIENT_ID = decode("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
|
|
38
|
+
const AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
|
|
39
|
+
const TOKEN_URL = "https://api.anthropic.com/v1/oauth/token";
|
|
40
|
+
const BOOTSTRAP_URL = "https://api.anthropic.com/api/claude_cli/bootstrap";
|
|
41
|
+
const CLAUDE_CODE_BOOTSTRAP_MODEL = "claude-opus-4-8";
|
|
42
|
+
const CLAUDE_CODE_BOOTSTRAP_USER_AGENT = `claude-code/${claudeCodeVersion}`;
|
|
43
|
+
const CALLBACK_PORT = 54545;
|
|
44
|
+
const CALLBACK_PATH = "/callback";
|
|
45
|
+
const SCOPES = "org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload";
|
|
46
|
+
function formatErrorDetails(error) {
|
|
47
|
+
if (error instanceof Error) {
|
|
48
|
+
const details = [`${error.name}: ${error.message}`];
|
|
49
|
+
const errorWithCode = error;
|
|
50
|
+
if (errorWithCode.code) details.push(`code=${errorWithCode.code}`);
|
|
51
|
+
if (typeof errorWithCode.errno !== "undefined") details.push(`errno=${String(errorWithCode.errno)}`);
|
|
52
|
+
if (typeof error.cause !== "undefined") details.push(`cause=${formatErrorDetails(error.cause)}`);
|
|
53
|
+
if (error.stack) details.push(`stack=${error.stack}`);
|
|
54
|
+
return details.join("; ");
|
|
55
|
+
}
|
|
56
|
+
return String(error);
|
|
57
|
+
}
|
|
58
|
+
async function postJson(url, body, fetchImpl, extraHeaders) {
|
|
59
|
+
const response = await fetchImpl(url, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: {
|
|
62
|
+
...extraHeaders,
|
|
63
|
+
"Content-Type": "application/json"
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify(body),
|
|
66
|
+
signal: AbortSignal.timeout(3e4)
|
|
67
|
+
});
|
|
68
|
+
const responseBody = await response.text();
|
|
69
|
+
if (!response.ok) throw new ProviderHttpError(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`, response.status);
|
|
70
|
+
return responseBody;
|
|
71
|
+
}
|
|
72
|
+
function nonEmpty(value) {
|
|
73
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
74
|
+
}
|
|
75
|
+
function parseOAuthTokenResponse(responseBody, operation) {
|
|
76
|
+
try {
|
|
77
|
+
return JSON.parse(responseBody);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
throw new OAuthError(`Anthropic ${operation} returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`, {
|
|
80
|
+
kind: "validation",
|
|
81
|
+
provider: "anthropic",
|
|
82
|
+
cause: error
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Lift the OAuth response's `account: { uuid, email_address }` and
|
|
88
|
+
* `organization: { uuid, name }` blocks onto {@link OAuthCredentials} so
|
|
89
|
+
* downstream identity propagation (e.g. `metadata.user_id.account_uuid`,
|
|
90
|
+
* usage tracking, org-scoped credential identity) works without a separate
|
|
91
|
+
* `/api/oauth/profile` round-trip. Returns `undefined` for any field the
|
|
92
|
+
* response omits or carries as a non-string / empty value.
|
|
93
|
+
*/
|
|
94
|
+
function extractAccountFromTokenResponse(data) {
|
|
95
|
+
return {
|
|
96
|
+
accountId: nonEmpty(data.account?.uuid),
|
|
97
|
+
email: nonEmpty(data.account?.email_address),
|
|
98
|
+
orgId: nonEmpty(data.organization?.uuid),
|
|
99
|
+
orgName: nonEmpty(data.organization?.name)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function fetchBootstrapIdentity(accessToken, fetchImpl) {
|
|
103
|
+
const url = `${BOOTSTRAP_URL}?entrypoint=cli&model=${encodeURIComponent(CLAUDE_CODE_BOOTSTRAP_MODEL)}`;
|
|
104
|
+
const response = await fetchImpl(url, {
|
|
105
|
+
method: "GET",
|
|
106
|
+
headers: {
|
|
107
|
+
Accept: "application/json, text/plain, */*",
|
|
108
|
+
Authorization: `Bearer ${accessToken}`,
|
|
109
|
+
"Content-Type": "application/json",
|
|
110
|
+
"User-Agent": CLAUDE_CODE_BOOTSTRAP_USER_AGENT,
|
|
111
|
+
"anthropic-beta": "oauth-2025-04-20"
|
|
112
|
+
},
|
|
113
|
+
signal: AbortSignal.timeout(3e4)
|
|
114
|
+
});
|
|
115
|
+
const responseBody = await response.text();
|
|
116
|
+
if (!response.ok) throw new ProviderHttpError(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`, response.status);
|
|
117
|
+
let data;
|
|
118
|
+
try {
|
|
119
|
+
data = JSON.parse(responseBody);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
throw new OAuthError(`Anthropic bootstrap returned invalid JSON. url=${url}; body=${responseBody}; details=${formatErrorDetails(error)}`, {
|
|
122
|
+
kind: "validation",
|
|
123
|
+
provider: "anthropic",
|
|
124
|
+
cause: error
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
accountId: nonEmpty(data.oauth_account?.account_uuid),
|
|
129
|
+
email: nonEmpty(data.oauth_account?.account_email),
|
|
130
|
+
orgId: nonEmpty(data.oauth_account?.organization_uuid),
|
|
131
|
+
orgName: nonEmpty(data.oauth_account?.organization_name)
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve account (and optionally organization) identity for a token
|
|
136
|
+
* response. `includeOrg` is login-only: the org an access token is scoped to
|
|
137
|
+
* is captured once when the credential is created and deliberately never
|
|
138
|
+
* refreshed afterwards — rewriting identity during background token
|
|
139
|
+
* refreshes could silently re-key stored credentials.
|
|
140
|
+
*/
|
|
141
|
+
async function resolveAccountIdentity(data, fetchImpl, options) {
|
|
142
|
+
const identity = extractAccountFromTokenResponse(data);
|
|
143
|
+
const orgSatisfied = !options?.includeOrg || identity.orgId !== void 0;
|
|
144
|
+
if (identity.accountId && identity.email && orgSatisfied) return identity;
|
|
145
|
+
try {
|
|
146
|
+
const bootstrap = await fetchBootstrapIdentity(data.access_token, fetchImpl);
|
|
147
|
+
return {
|
|
148
|
+
accountId: identity.accountId ?? bootstrap.accountId,
|
|
149
|
+
email: identity.email ?? bootstrap.email,
|
|
150
|
+
orgId: identity.orgId ?? bootstrap.orgId,
|
|
151
|
+
orgName: identity.orgName ?? bootstrap.orgName
|
|
152
|
+
};
|
|
153
|
+
} catch {
|
|
154
|
+
return identity;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
var AnthropicOAuthFlow = class extends OAuthCallbackFlow {
|
|
158
|
+
#verifier = "";
|
|
159
|
+
#challenge = "";
|
|
160
|
+
#fetch;
|
|
161
|
+
constructor(ctrl) {
|
|
162
|
+
super(ctrl, CALLBACK_PORT, CALLBACK_PATH);
|
|
163
|
+
this.#fetch = ctrl.fetch ?? fetch;
|
|
164
|
+
}
|
|
165
|
+
async generateAuthUrl(state, redirectUri) {
|
|
166
|
+
const pkce = await generatePKCE();
|
|
167
|
+
this.#verifier = pkce.verifier;
|
|
168
|
+
this.#challenge = pkce.challenge;
|
|
169
|
+
const authParams = new URLSearchParams({
|
|
170
|
+
code: "true",
|
|
171
|
+
client_id: CLIENT_ID,
|
|
172
|
+
response_type: "code",
|
|
173
|
+
redirect_uri: redirectUri,
|
|
174
|
+
scope: SCOPES,
|
|
175
|
+
code_challenge: this.#challenge,
|
|
176
|
+
code_challenge_method: "S256",
|
|
177
|
+
state
|
|
178
|
+
});
|
|
179
|
+
return {
|
|
180
|
+
url: `${AUTHORIZE_URL}?${authParams.toString()}`,
|
|
181
|
+
instructions: "Complete login in your browser. If the browser cannot reach this machine, paste the final redirect URL or authorization code when prompted."
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
async exchangeToken(code, state, redirectUri) {
|
|
185
|
+
let exchangeCode = code;
|
|
186
|
+
let exchangeState = state;
|
|
187
|
+
const codeFragmentIndex = code.indexOf("#");
|
|
188
|
+
if (codeFragmentIndex >= 0) {
|
|
189
|
+
exchangeCode = code.slice(0, codeFragmentIndex);
|
|
190
|
+
const codeFragmentState = code.slice(codeFragmentIndex + 1);
|
|
191
|
+
if (codeFragmentState.length > 0) exchangeState = codeFragmentState;
|
|
192
|
+
}
|
|
193
|
+
let responseBody;
|
|
194
|
+
try {
|
|
195
|
+
responseBody = await postJson(TOKEN_URL, {
|
|
196
|
+
grant_type: "authorization_code",
|
|
197
|
+
client_id: CLIENT_ID,
|
|
198
|
+
code: exchangeCode,
|
|
199
|
+
state: exchangeState,
|
|
200
|
+
redirect_uri: redirectUri,
|
|
201
|
+
code_verifier: this.#verifier
|
|
202
|
+
}, this.#fetch);
|
|
203
|
+
} catch (error) {
|
|
204
|
+
throw new OAuthError(`Token exchange request failed. url=${TOKEN_URL}; redirect_uri=${redirectUri}; response_type=authorization_code; details=${formatErrorDetails(error)}`, {
|
|
205
|
+
kind: "token-exchange",
|
|
206
|
+
provider: "anthropic",
|
|
207
|
+
cause: error
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
const tokenData = parseOAuthTokenResponse(responseBody, "token exchange");
|
|
211
|
+
const { accountId, email, orgId, orgName } = await resolveAccountIdentity(tokenData, this.#fetch, { includeOrg: true });
|
|
212
|
+
return {
|
|
213
|
+
refresh: tokenData.refresh_token,
|
|
214
|
+
access: tokenData.access_token,
|
|
215
|
+
expires: Date.now() + tokenData.expires_in * 1e3 - 3e5,
|
|
216
|
+
accountId,
|
|
217
|
+
email,
|
|
218
|
+
orgId,
|
|
219
|
+
orgName
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Login with Anthropic OAuth
|
|
225
|
+
*/
|
|
226
|
+
async function loginAnthropic(ctrl) {
|
|
227
|
+
return new AnthropicOAuthFlow(ctrl).login();
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Refresh Anthropic OAuth token
|
|
231
|
+
*/
|
|
232
|
+
async function refreshAnthropicToken(refreshToken, fetchOverride) {
|
|
233
|
+
const fetchImpl = fetchOverride ?? fetch;
|
|
234
|
+
let responseBody;
|
|
235
|
+
try {
|
|
236
|
+
responseBody = await postJson(TOKEN_URL, {
|
|
237
|
+
grant_type: "refresh_token",
|
|
238
|
+
client_id: CLIENT_ID,
|
|
239
|
+
refresh_token: refreshToken
|
|
240
|
+
}, fetchImpl, {
|
|
241
|
+
"anthropic-beta": "oauth-2025-04-20",
|
|
242
|
+
"User-Agent": "anthropic-sdk-typescript/0.94.0 userOAuthProvider"
|
|
243
|
+
});
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw new OAuthError(`Anthropic token refresh request failed. url=${TOKEN_URL}; details=${formatErrorDetails(error)}`, {
|
|
246
|
+
kind: "token-refresh",
|
|
247
|
+
provider: "anthropic",
|
|
248
|
+
cause: error
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
const data = parseOAuthTokenResponse(responseBody, "token refresh");
|
|
252
|
+
const { accountId, email } = await resolveAccountIdentity(data, fetchImpl);
|
|
253
|
+
return {
|
|
254
|
+
refresh: data.refresh_token || refreshToken,
|
|
255
|
+
access: data.access_token,
|
|
256
|
+
expires: Date.now() + data.expires_in * 1e3 - 3e5,
|
|
257
|
+
accountId,
|
|
258
|
+
email
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
//#endregion
|
|
262
|
+
export { coworkUserAgent as a, claudeCodeVersion as i, CLAUDE_CODE_MAX_OUTPUT_TOKENS as n, claudeCodeSystemInstruction as r, anthropic_exports as t };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { V as ProviderHttpError, _ as OnPromptRequiredError, h as LoginCancelledError, m as ApiKeyRequiredError } from "./error-Dd8DIqs-.mjs";
|
|
4
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/api-key-validation.ts
|
|
5
|
+
const VALIDATION_TIMEOUT_MS = 15e3;
|
|
6
|
+
function normalizeAnthropicCompatibleBaseUrl(baseUrl) {
|
|
7
|
+
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
8
|
+
return trimmed.endsWith("/v1") ? trimmed.slice(0, -3) : trimmed;
|
|
9
|
+
}
|
|
10
|
+
function resolveValidationHeaders(headers) {
|
|
11
|
+
return typeof headers === "function" ? headers() : headers;
|
|
12
|
+
}
|
|
13
|
+
async function createApiKeyValidationError(provider, response) {
|
|
14
|
+
let details = "";
|
|
15
|
+
try {
|
|
16
|
+
details = (await response.text()).trim();
|
|
17
|
+
} catch {}
|
|
18
|
+
const message = details ? `${provider} API key validation failed (${response.status}): ${details}` : `${provider} API key validation failed (${response.status})`;
|
|
19
|
+
return new ProviderHttpError(message, response.status, { headers: response.headers });
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validate an API key against an OpenAI-compatible chat completions endpoint.
|
|
23
|
+
*
|
|
24
|
+
* Performs a minimal request to verify credentials and endpoint access.
|
|
25
|
+
*/
|
|
26
|
+
async function validateOpenAICompatibleApiKey(options) {
|
|
27
|
+
const timeoutSignal = AbortSignal.timeout(VALIDATION_TIMEOUT_MS);
|
|
28
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
|
|
29
|
+
const response = await (options.fetch ?? fetch)(`${options.baseUrl}/chat/completions`, {
|
|
30
|
+
method: "POST",
|
|
31
|
+
headers: {
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify({
|
|
36
|
+
model: options.model,
|
|
37
|
+
messages: [{
|
|
38
|
+
role: "user",
|
|
39
|
+
content: "ping"
|
|
40
|
+
}],
|
|
41
|
+
max_tokens: 1,
|
|
42
|
+
temperature: 0
|
|
43
|
+
}),
|
|
44
|
+
signal
|
|
45
|
+
});
|
|
46
|
+
if (response.ok) return;
|
|
47
|
+
throw await createApiKeyValidationError(options.provider, response);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Validate an API key against an Anthropic-compatible messages endpoint.
|
|
51
|
+
*/
|
|
52
|
+
async function validateAnthropicCompatibleApiKey(options) {
|
|
53
|
+
const timeoutSignal = AbortSignal.timeout(VALIDATION_TIMEOUT_MS);
|
|
54
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
|
|
55
|
+
const baseUrl = normalizeAnthropicCompatibleBaseUrl(options.baseUrl);
|
|
56
|
+
const response = await (options.fetch ?? fetch)(`${baseUrl}/v1/messages`, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
"anthropic-version": "2023-06-01",
|
|
61
|
+
"x-api-key": options.apiKey
|
|
62
|
+
},
|
|
63
|
+
body: JSON.stringify({
|
|
64
|
+
model: options.model,
|
|
65
|
+
messages: [{
|
|
66
|
+
role: "user",
|
|
67
|
+
content: "ping"
|
|
68
|
+
}],
|
|
69
|
+
max_tokens: 1
|
|
70
|
+
}),
|
|
71
|
+
signal
|
|
72
|
+
});
|
|
73
|
+
if (response.ok) return;
|
|
74
|
+
throw await createApiKeyValidationError(options.provider, response);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Validate an API key against a provider models endpoint.
|
|
78
|
+
*
|
|
79
|
+
* Useful for providers where access to specific models may vary by plan and
|
|
80
|
+
* should not block key validation.
|
|
81
|
+
*/
|
|
82
|
+
async function validateApiKeyAgainstModelsEndpoint(options) {
|
|
83
|
+
const timeoutSignal = AbortSignal.timeout(VALIDATION_TIMEOUT_MS);
|
|
84
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
|
|
85
|
+
const response = await (options.fetch ?? fetch)(options.modelsUrl, {
|
|
86
|
+
method: "GET",
|
|
87
|
+
headers: {
|
|
88
|
+
...resolveValidationHeaders(options.headers) ?? {},
|
|
89
|
+
Authorization: `Bearer ${options.apiKey}`
|
|
90
|
+
},
|
|
91
|
+
signal
|
|
92
|
+
});
|
|
93
|
+
if (response.ok) return;
|
|
94
|
+
throw await createApiKeyValidationError(options.provider, response);
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/api-key-login.ts
|
|
98
|
+
/**
|
|
99
|
+
* Shared factory for API-key-paste "login" flows.
|
|
100
|
+
*
|
|
101
|
+
* Several providers (Cerebras, Synthetic, Moonshot, Together, NanoGPT, ZenMux)
|
|
102
|
+
* don't actually implement OAuth — they just ask the user to paste an API key,
|
|
103
|
+
* optionally validate it, and return the trimmed key.
|
|
104
|
+
*/
|
|
105
|
+
function createApiKeyLogin(config) {
|
|
106
|
+
return async function login(options) {
|
|
107
|
+
if (!options.onPrompt) throw new OnPromptRequiredError(config.providerLabel);
|
|
108
|
+
if (config.authUrl && config.instructions) options.onAuth?.({
|
|
109
|
+
url: config.authUrl,
|
|
110
|
+
instructions: config.instructions
|
|
111
|
+
});
|
|
112
|
+
const apiKey = config.emptyKeyFallback === void 0 ? await options.onPrompt({
|
|
113
|
+
message: config.promptMessage,
|
|
114
|
+
placeholder: config.placeholder
|
|
115
|
+
}) : await options.onPrompt({
|
|
116
|
+
message: config.promptMessage,
|
|
117
|
+
placeholder: config.placeholder,
|
|
118
|
+
allowEmpty: true
|
|
119
|
+
});
|
|
120
|
+
if (options.signal?.aborted) throw new LoginCancelledError();
|
|
121
|
+
const trimmed = apiKey.trim();
|
|
122
|
+
if (!trimmed) {
|
|
123
|
+
if (config.emptyKeyFallback !== void 0) return config.emptyKeyFallback;
|
|
124
|
+
throw new ApiKeyRequiredError();
|
|
125
|
+
}
|
|
126
|
+
if (config.validation) {
|
|
127
|
+
options.onProgress?.("Validating API key...");
|
|
128
|
+
if (config.validation.kind === "chat-completions") await validateOpenAICompatibleApiKey({
|
|
129
|
+
provider: config.validation.provider,
|
|
130
|
+
apiKey: trimmed,
|
|
131
|
+
baseUrl: config.validation.baseUrl,
|
|
132
|
+
model: config.validation.model,
|
|
133
|
+
signal: options.signal,
|
|
134
|
+
fetch: options.fetch
|
|
135
|
+
});
|
|
136
|
+
else if (config.validation.kind === "anthropic-messages") await validateAnthropicCompatibleApiKey({
|
|
137
|
+
provider: config.validation.provider,
|
|
138
|
+
apiKey: trimmed,
|
|
139
|
+
baseUrl: config.validation.baseUrl,
|
|
140
|
+
model: config.validation.model,
|
|
141
|
+
signal: options.signal,
|
|
142
|
+
fetch: options.fetch
|
|
143
|
+
});
|
|
144
|
+
else await validateApiKeyAgainstModelsEndpoint({
|
|
145
|
+
provider: config.validation.provider,
|
|
146
|
+
apiKey: trimmed,
|
|
147
|
+
modelsUrl: typeof config.validation.modelsUrl === "function" ? config.validation.modelsUrl() : config.validation.modelsUrl,
|
|
148
|
+
headers: config.validation.headers,
|
|
149
|
+
signal: options.signal,
|
|
150
|
+
fetch: options.fetch
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return trimmed;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
//#endregion
|
|
157
|
+
export { validateApiKeyAgainstModelsEndpoint as n, validateOpenAICompatibleApiKey as r, createApiKeyLogin as t };
|