@xiaoso/dsh-tool-plus 0.1.5 → 0.1.7-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/THIRD_PARTY_NOTICES.md +9 -3
- package/lib/{abort-Cwwm4Err.mjs → abort-Caqff3M6.mjs} +2 -2
- package/lib/alibaba-coding-plan-DTupMiAi.mjs +73 -0
- package/lib/alibaba-token-plan-CHGyWOfX.mjs +46 -0
- package/lib/alibaba-token-plan-Dj3OZhEE.mjs +82 -0
- package/lib/{amazon-bedrock-TVMpUTRG.mjs → amazon-bedrock-DbFSYXfJ.mjs} +117 -38
- package/lib/{anthropic-BL6LFDQS.mjs → anthropic-CTJ3IQVa.mjs} +675 -166
- package/lib/anthropic-CXfWlp-x.mjs +105 -0
- package/lib/{aws-credentials-B20dliS7.mjs → anthropic-wire-CKuhDwZ1.mjs} +74 -14
- package/lib/{api-key-login-CIDnXeYd.mjs → api-key-validation-CGCJFbFr.mjs} +27 -68
- package/lib/{azure-openai-responses-BkhsLmN3.mjs → azure-openai-responses-ChFbWaGj.mjs} +27 -16
- package/lib/{browser-render-CmgvSNte.mjs → browser-render-9o0Rknop.mjs} +4 -4
- package/lib/bun-shim.mjs +71 -2
- package/lib/{bundled-references-ChZSPDFw.mjs → bundled-references-DY3EJxZV.mjs} +6 -5
- package/lib/cline-pass-Bwg3esu9.mjs +44 -0
- package/lib/cloudflare-ai-gateway-BupNXyKK.mjs +35 -0
- package/lib/cloudflare-ai-gateway-EWo0VkP5.mjs +44 -0
- package/lib/collapse-DOR8sOGf.mjs +2304 -0
- package/lib/coreweave-C82HrLpb.mjs +31 -0
- package/lib/coreweave-Ct8cF-da.mjs +14 -0
- package/lib/{cursor-B6HcmplF.mjs → cursor-B95LzVWV.mjs} +11 -3
- package/lib/{cursor-CRpLpaZ3.mjs → cursor-DJV_dcgB.mjs} +887 -1784
- package/lib/{cursor-B8m6SqAH.mjs → cursor-LKGjucn2.mjs} +48 -38
- package/lib/cursor-proto-B8Wj8bv9.mjs +10513 -0
- package/lib/{deterministic-id-D-yIV_eI.mjs → deterministic-id-CUEIMSqR.mjs} +1 -1
- package/lib/devin-BMTdx_hx.mjs +316 -0
- package/lib/{devin-DUAfvBsW.mjs → devin-DSp0Rw_E.mjs} +172 -86
- package/lib/devin-ExGIghmx.mjs +69 -0
- package/lib/devin-proto-Br8fdyNl.mjs +2888 -0
- package/lib/{dom-CawWi8fa.mjs → dom-DG3sPESc.mjs} +8 -8
- package/lib/effort-BdtQMN-_.mjs +23 -0
- package/lib/{error-C-f_Wnw4.mjs → error-CORgGg5a.mjs} +275 -154
- package/lib/{event-stream-Dh2guZxS.mjs → event-stream-ulcDenZD.mjs} +20 -4
- package/lib/{gemini-headers-DKUShltF.mjs → gemini-headers-Co9cVvex.mjs} +2 -2
- package/lib/{github-copilot-suDymKrx.mjs → github-copilot-Dstq1D3s.mjs} +69 -29
- package/lib/github-copilot-headers-DOh1gt_w.mjs +312 -0
- package/lib/gitlab-duo-DSCMrU0m.mjs +11 -0
- package/lib/google-CtsKkOQK.mjs +38 -0
- package/lib/google-antigravity-z-5KsEci.mjs +252 -0
- package/lib/{google-auth-DYJLM792.mjs → google-auth-ieLBaneO.mjs} +4 -4
- package/lib/{google-gemini-cli-8BT513Ul.mjs → google-gemini-cli-C6NE5mWz.mjs} +28 -54
- package/lib/{google-gemini-cli-D6cSmfvB.mjs → google-gemini-cli-CAIPSl7e.mjs} +23 -29
- package/lib/google-oauth-shared-DhMllAkt.mjs +53 -0
- package/lib/{google-shared-CVbHK5vZ.mjs → google-shared-B0aNCYEH.mjs} +140 -44
- package/lib/{google-validation-Cgbn3tWJ.mjs → google-validation-BEkNs-Bx.mjs} +1 -1
- package/lib/{google-vertex-Bui-ypAe.mjs → google-vertex-Bbd1tYNc.mjs} +8 -8
- package/lib/hosts-00rjRzUD.mjs +203 -0
- package/lib/id-AL5obQzR.mjs +71 -0
- package/lib/{idle-iterator-CYAxUkSD.mjs → idle-iterator-DlUkEfzW.mjs} +3 -3
- package/lib/index.mjs +587 -5266
- package/lib/kilo-ChJL54wq.mjs +81 -0
- package/lib/kimi-C2c_Zq8A.mjs +67 -0
- package/lib/{launch-BmgEUycu.mjs → launch-DKDH71En.mjs} +1 -1
- package/lib/markit-CmRfm4E2.mjs +9885 -0
- package/lib/models-DnXMYGcJ.mjs +381604 -0
- package/lib/muse-code-Di1VZmB1.mjs +143 -0
- package/lib/{ollama-Df9ce-Cp.mjs → ollama-B8ic3sEp.mjs} +15 -30
- package/lib/{openai-codex-CAVI3Me-.mjs → openai-codex-DuJNC99x.mjs} +29 -99
- package/lib/{openai-codex-responses-BcnOotRB.mjs → openai-codex-responses-BL29nh9K.mjs} +204 -116
- package/lib/{openai-completions-Bq4WT47M.mjs → openai-completions-BK2f2dBv.mjs} +152 -82
- package/lib/openai-configuration-update-xMYUjaK_.mjs +150 -0
- package/lib/{openai-reasoning-fallback-DXsfiSXO.mjs → openai-reasoning-fallback-BdB3RCbj.mjs} +106 -12
- package/lib/{openai-responses-Mq_-PjvE.mjs → openai-responses-CGQPlIIy.mjs} +76 -82
- package/lib/{perplexity-XgLF73E7.mjs → perplexity-TBjz3VMB.mjs} +52 -9
- package/lib/{pkce-BlQikGPu.mjs → pkce-BYjmugmw.mjs} +1 -1
- package/lib/protobuf-aab1UGVn.mjs +717 -0
- package/lib/{provider-response-C6vcbQyO.mjs → provider-response-SqKSkkUc.mjs} +1 -1
- package/lib/{proxy-D9lm7ONA.mjs → proxy-5nWqRL1f.mjs} +45 -5
- package/lib/{readability-Cpm-ocau.mjs → readability-uGhqb4GC.mjs} +2 -2
- package/lib/reference-CtvM4zLU.mjs +114 -0
- package/lib/{request-debug-HJMoJncL.mjs → request-debug-NQN0BjHH.mjs} +1 -1
- package/lib/{sanitize-text-CfcXzw5X.mjs → sanitize-text-BCf5KmCf.mjs} +1 -1
- package/lib/{scrapers-CE_qK1yk.mjs → scrapers-D8oWspgW.mjs} +12 -12
- package/lib/{src-BcD0_rQR.mjs → src-BwW51vA5.mjs} +979 -388
- package/lib/{sse-debug-CYdjOC96.mjs → sse-debug-B-tkLCPW.mjs} +1 -1
- package/lib/{stream-Bjq8wjfr.mjs → stream-B_7qN-bA.mjs} +3802 -2623
- package/lib/stream-markup-healing-DKT1lnkW.mjs +267 -0
- package/lib/{strict-tool-validation-imVLUcbI.mjs → strict-tool-validation-CBTz1dAA.mjs} +2 -2
- package/lib/taxonomy-DSIM99rS.mjs +15392 -0
- package/lib/{stream-markup-healing-DZ6bVDxH.mjs → thinking-CiLa2LFB.mjs} +31 -186
- package/lib/{turndown-DN7ByzEI.mjs → turndown-DrX1M4WG.mjs} +4 -4
- package/lib/{type-guards-B9VVjRDK.mjs → type-guards-CttAANEx.mjs} +1 -1
- package/lib/{types-DX_bvuus.mjs → types-PVueGi9S.mjs} +2 -2
- package/lib/{utils-APrc-TBB.mjs → utils-CCfhUQen.mjs} +2364 -2676
- package/lib/{utils-Cp2Mxf_U.mjs → utils-CUPhpw9A.mjs} +413 -134
- package/lib/{utils-CQHPEQ3W.mjs → utils-DeWqNWV8.mjs} +2 -2
- package/lib/{vision-guard-mBmtAHx0.mjs → vision-guard-_XwsL1DF.mjs} +14 -29
- package/lib/xai-oauth-CXhnz0gO.mjs +210 -0
- package/lib/{xiaomi-7mE345KX.mjs → xiaomi-psoUItal.mjs} +8 -37
- package/lib/{zai-CeNpMV3W.mjs → zai-ApJ8HBgT.mjs} +8 -71
- package/lib/{zip-BK7UHCwX.mjs → zip-Kd602XNe.mjs} +1 -1
- package/package.json +43 -41
- package/presets/package.json +1 -1
- package/presets/tool-plus-ptc/agent.cordis.yml +13 -4
- package/presets/tool-plus-standard/agent.cordis.yml +11 -3
- package/lib/agent_pb-Rizyt9Zg.mjs +0 -805
- package/lib/anthropic-CDmj476p.mjs +0 -262
- package/lib/api_server_pb-CDZgLMta.mjs +0 -252
- package/lib/callback-server-CFJK-jvK.mjs +0 -398
- package/lib/codex-P1dGpX7G.mjs +0 -54
- package/lib/device-code-CuXTWYwY.mjs +0 -51
- package/lib/devin-BcQwht1W.mjs +0 -114
- package/lib/devin-BvMfGevz.mjs +0 -95
- package/lib/github-copilot-B3kQl0g0.mjs +0 -104
- package/lib/gitlab-duo-BriUTP8k.mjs +0 -155
- package/lib/gitlab-duo-workflow-wK5Ljzmc.mjs +0 -91
- package/lib/google-CE5tFDod.mjs +0 -30
- package/lib/google-antigravity-C1jgNljz.mjs +0 -198
- package/lib/google-oauth-shared-BLVTvokk.mjs +0 -147
- package/lib/grammar-D-NqNUxQ.mjs +0 -49
- package/lib/identity-HNO1Oe9B.mjs +0 -219
- package/lib/kimi-DgcUpPtK.mjs +0 -236
- package/lib/markit-DtGoRE6M.mjs +0 -1417
- package/lib/minimax-code-Y3h5li9N.mjs +0 -53
- package/lib/models-DRA2c_8U.mjs +0 -104660
- package/lib/opencode-BsVw9rCD.mjs +0 -38
- package/lib/to-binary-B1BEBIPC.mjs +0 -6002
- package/lib/wafer-BlhWLweO.mjs +0 -17
- package/lib/xai-oauth-5pORHUrg.mjs +0 -446
|
@@ -1,398 +0,0 @@
|
|
|
1
|
-
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
-
__installBunShim();
|
|
3
|
-
import { c as OAuthError, h as LoginCancelledError, t as ConfigurationError } from "./error-C-f_Wnw4.mjs";
|
|
4
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/oauth.html
|
|
5
|
-
var oauth_default = "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>oh my pi · authentication</title>\n <style>\n :root {\n /* dark, slightly purple-tinted neutrals — never #000 */\n --ink-0: oklch(0.135 0.018 295);\n --ink-1: oklch(0.172 0.022 295);\n --ink-2: oklch(0.21 0.024 295);\n --ink-4: oklch(0.36 0.024 295);\n --ink-5: oklch(0.5 0.022 290);\n --ink-6: oklch(0.66 0.018 290);\n --ink-7: oklch(0.82 0.014 285);\n --ink-9: oklch(0.97 0.008 90);\n\n /* brand: magenta lead, cyan reply */\n --magenta: oklch(0.7 0.24 340);\n --iris: oklch(0.62 0.21 295);\n --cyan: oklch(0.81 0.14 200);\n\n /* signal */\n --success: oklch(0.78 0.16 150);\n --error: oklch(0.66 0.22 25);\n\n --bg: var(--ink-0);\n --fg: var(--ink-9);\n --fg-dim: var(--ink-7);\n --fg-faint: var(--ink-5);\n --rule: oklch(1 0 0 / 0.07);\n --rule-strong: oklch(1 0 0 / 0.14);\n --accent: var(--magenta);\n --accent-2: var(--cyan);\n\n color-scheme: dark;\n }\n\n * {\n box-sizing: border-box;\n }\n\n body {\n font-family: \"Geist\", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n background:\n radial-gradient(ellipse 80vw 60vh at 18% -10%, oklch(0.7 0.24 340 / 0.13), transparent 60%),\n radial-gradient(ellipse 70vw 70vh at 110% 30%, oklch(0.81 0.14 200 / 0.09), transparent 60%),\n var(--bg);\n color: var(--fg);\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n padding: 1.5rem;\n -webkit-font-smoothing: antialiased;\n text-rendering: optimizeLegibility;\n overflow-x: clip;\n }\n\n /* ascii grid backdrop */\n .grid-bg {\n position: fixed;\n inset: 0;\n background-image:\n linear-gradient(to right, oklch(1 0 0 / 0.025) 1px, transparent 1px),\n linear-gradient(to bottom, oklch(1 0 0 / 0.025) 1px, transparent 1px);\n background-size: 56px 56px;\n background-position: -1px -1px;\n mask-image: radial-gradient(ellipse at 50% 30%, #000 30%, transparent 75%);\n pointer-events: none;\n z-index: 0;\n }\n\n .container {\n position: relative;\n z-index: 1;\n background: oklch(0.172 0.022 295 / 0.72);\n backdrop-filter: blur(16px);\n -webkit-backdrop-filter: blur(16px);\n border: 1px solid var(--rule);\n border-radius: 16px;\n padding: 2.5rem 2.5rem 2rem;\n width: 100%;\n max-width: 420px;\n text-align: center;\n box-shadow:\n 0 24px 48px -12px oklch(0 0 0 / 0.55),\n 0 0 0 1px oklch(1 0 0 / 0.03) inset;\n opacity: 0;\n transform: translateY(10px);\n animation: rise 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;\n }\n @keyframes rise {\n to {\n opacity: 1;\n transform: none;\n }\n }\n\n /* brand header */\n .brand {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n margin-bottom: 2rem;\n }\n .brand svg {\n width: 22px;\n height: 22px;\n }\n .brand .wordmark {\n font-size: 13px;\n font-weight: 500;\n letter-spacing: -0.01em;\n color: var(--fg);\n }\n\n /* status mark */\n .mark-wrap {\n position: relative;\n width: 72px;\n height: 72px;\n margin: 0 auto 1.5rem;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .mark-wrap::before {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: oklch(1 0 0 / 0.05);\n z-index: 0;\n }\n .mark {\n width: 40px;\n height: 40px;\n z-index: 2;\n }\n .timer-svg {\n position: absolute;\n top: -2px;\n left: -2px;\n width: 76px;\n height: 76px;\n transform: rotate(-90deg);\n z-index: 1;\n pointer-events: none;\n }\n .timer-circle {\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-dasharray: 226;\n stroke-dashoffset: 0;\n }\n .countdown .timer-circle {\n animation: countdown 3s linear forwards;\n }\n @keyframes countdown {\n to {\n stroke-dashoffset: 226;\n }\n }\n\n h1 {\n font-family: \"Fraunces\", \"Iowan Old Style\", Georgia, serif;\n font-size: 1.6rem;\n font-weight: 500;\n letter-spacing: -0.022em;\n line-height: 1.15;\n margin: 0 0 0.75rem;\n text-wrap: balance;\n }\n p {\n color: var(--fg-dim);\n line-height: 1.6;\n margin: 0 0 1.75rem;\n font-size: 0.95rem;\n }\n\n .btn {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n background: var(--fg);\n color: var(--bg);\n font-family: inherit;\n font-weight: 500;\n padding: 0.65rem 1.4rem;\n border-radius: 8px;\n text-decoration: none;\n font-size: 0.9rem;\n transition: opacity 0.2s, transform 0.2s;\n cursor: pointer;\n border: none;\n }\n .btn:hover {\n opacity: 0.88;\n transform: translateY(-1px);\n }\n .btn:active {\n transform: translateY(0);\n }\n\n /* State: success */\n .success .mark-wrap::before {\n background: oklch(0.78 0.16 150 / 0.12);\n }\n .success .mark {\n color: var(--success);\n }\n .success .timer-circle {\n stroke: var(--success);\n }\n .success .icon-error {\n display: none;\n }\n\n /* State: error */\n .error .mark-wrap::before {\n background: oklch(0.66 0.22 25 / 0.12);\n }\n .error .mark {\n color: var(--error);\n }\n .error .timer-circle {\n stroke: var(--error);\n }\n .error .icon-success,\n .error .timer-svg {\n display: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .container,\n .countdown .timer-circle {\n animation: none;\n }\n .container {\n opacity: 1;\n transform: none;\n }\n }\n </style>\n </head>\n <body>\n <span aria-hidden=\"true\" class=\"grid-bg\"></span>\n <div id=\"app\" class=\"container\">\n <div class=\"brand\">\n <svg viewBox=\"0 0 64 64\" aria-hidden=\"true\">\n <defs>\n <linearGradient id=\"pi-grad\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0\" stop-color=\"oklch(0.7 0.24 340)\" />\n <stop offset=\".5\" stop-color=\"oklch(0.62 0.21 295)\" />\n <stop offset=\"1\" stop-color=\"oklch(0.81 0.14 200)\" />\n </linearGradient>\n </defs>\n <path fill=\"url(#pi-grad)\" d=\"M10 14h44v9H43v33h-9V23h-9v22h-9V23H10z\" />\n </svg>\n <span class=\"wordmark\">oh my pi</span>\n </div>\n\n <div class=\"mark-wrap\">\n <svg class=\"timer-svg\" viewBox=\"0 0 76 76\">\n <circle class=\"timer-circle\" cx=\"38\" cy=\"38\" r=\"36\"></circle>\n </svg>\n <svg class=\"mark icon-success\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n <svg class=\"mark icon-error\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </div>\n\n <h1 id=\"title\">Authentication</h1>\n <p id=\"message\"></p>\n <button onclick=\"window.close()\" class=\"btn\">Close Window</button>\n </div>\n\n <script id=\"server-state\" type=\"application/json\">\n __OAUTH_STATE__\n <\/script>\n\n <script>\n let serverState;\n try {\n serverState = JSON.parse(document.getElementById(\"server-state\").textContent);\n } catch {\n const params = new URLSearchParams(window.location.search);\n serverState = {\n ok: params.get(\"ok\") === \"1\",\n error: params.get(\"error\") || \"Authentication failed\",\n };\n }\n\n const app = document.getElementById(\"app\");\n const title = document.getElementById(\"title\");\n const message = document.getElementById(\"message\");\n\n if (serverState.ok) {\n app.classList.add(\"success\", \"countdown\");\n title.textContent = \"Authentication Successful\";\n message.innerHTML = \"You have successfully logged in.<br>You can now close this tab.\";\n setTimeout(() => window.close(), 3000);\n } else {\n app.classList.add(\"error\");\n title.textContent = \"Authentication Failed\";\n message.textContent = serverState.error || \"An error occurred\";\n }\n <\/script>\n </body>\n</html>\n";
|
|
6
|
-
//#endregion
|
|
7
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/callback-server.ts
|
|
8
|
-
/**
|
|
9
|
-
* Abstract base class for OAuth flows with local callback servers.
|
|
10
|
-
*
|
|
11
|
-
* Handles:
|
|
12
|
-
* - Port allocation (tries expected port, falls back to random)
|
|
13
|
-
* - Callback server setup and request handling
|
|
14
|
-
* - Common OAuth flow logic
|
|
15
|
-
*
|
|
16
|
-
* Providers extend this and implement:
|
|
17
|
-
* - generateAuthUrl(): Build provider-specific authorization URL
|
|
18
|
-
* - exchangeToken(): Exchange authorization code for tokens
|
|
19
|
-
*/
|
|
20
|
-
const DEFAULT_TIMEOUT = 3e5;
|
|
21
|
-
const DEFAULT_HOSTNAME = "localhost";
|
|
22
|
-
const CALLBACK_PATH = "/callback";
|
|
23
|
-
const IPV4_LOOPBACK = "127.0.0.1";
|
|
24
|
-
const IPV6_LOOPBACK = "::1";
|
|
25
|
-
/**
|
|
26
|
-
* How many times a random-port bind may be redrawn when the ephemeral port it
|
|
27
|
-
* landed on is already held on {@link IPV6_LOOPBACK} by that exact address.
|
|
28
|
-
* Small on purpose: each redraw picks a fresh port, so a repeat collision is
|
|
29
|
-
* vanishingly unlikely.
|
|
30
|
-
*/
|
|
31
|
-
const IPV6_COMPANION_ATTEMPTS = 4;
|
|
32
|
-
/**
|
|
33
|
-
* Path served by {@link OAuthCallbackFlow} that 302-redirects to the pending
|
|
34
|
-
* authorization URL. Kept out of {@link OAuthCallbackFlowOptions} because it
|
|
35
|
-
* lives on the loopback callback server alongside {@link CALLBACK_PATH} and
|
|
36
|
-
* must never clash with a provider-registered redirect URI (all known
|
|
37
|
-
* providers register `/callback`-shaped paths).
|
|
38
|
-
*/
|
|
39
|
-
const LAUNCH_PATH = "/launch";
|
|
40
|
-
/**
|
|
41
|
-
* Whether a failed bind means "another process already holds this port".
|
|
42
|
-
* Bun surfaces `EADDRINUSE` on the error's `code` where the platform reports
|
|
43
|
-
* it, and otherwise only in the message, so both are checked.
|
|
44
|
-
*/
|
|
45
|
-
function isAddressInUse(error) {
|
|
46
|
-
const code = error?.code;
|
|
47
|
-
if (typeof code === "string") return code === "EADDRINUSE";
|
|
48
|
-
return error instanceof Error && /EADDRINUSE|in use/i.test(error.message);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Abstract base class for OAuth flows with local callback servers.
|
|
52
|
-
*/
|
|
53
|
-
var OAuthCallbackFlow = class {
|
|
54
|
-
ctrl;
|
|
55
|
-
preferredPort;
|
|
56
|
-
callbackPath;
|
|
57
|
-
callbackHostname;
|
|
58
|
-
redirectUri;
|
|
59
|
-
allowPortFallback;
|
|
60
|
-
#manualInputOnly;
|
|
61
|
-
#callbackResolve;
|
|
62
|
-
#callbackReject;
|
|
63
|
-
/**
|
|
64
|
-
* Authorization URL the `/launch` route currently redirects to. Set by
|
|
65
|
-
* {@link login} after {@link generateAuthUrl} and before {@link OAuthController.onAuth}
|
|
66
|
-
* fires, cleared when the server stops. `undefined` before the flow reaches
|
|
67
|
-
* that point and after it finishes, so `/launch` returns 503 rather than
|
|
68
|
-
* a stale URL.
|
|
69
|
-
*/
|
|
70
|
-
#pendingAuthUrl;
|
|
71
|
-
constructor(ctrl, preferredPortOrOptions, callbackPath = CALLBACK_PATH) {
|
|
72
|
-
this.ctrl = ctrl;
|
|
73
|
-
if (typeof preferredPortOrOptions === "number") {
|
|
74
|
-
this.preferredPort = preferredPortOrOptions;
|
|
75
|
-
this.callbackPath = callbackPath;
|
|
76
|
-
this.callbackHostname = DEFAULT_HOSTNAME;
|
|
77
|
-
this.allowPortFallback = true;
|
|
78
|
-
this.#manualInputOnly = false;
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
this.preferredPort = preferredPortOrOptions.preferredPort;
|
|
82
|
-
this.callbackPath = preferredPortOrOptions.callbackPath ?? CALLBACK_PATH;
|
|
83
|
-
this.callbackHostname = preferredPortOrOptions.callbackHostname ?? DEFAULT_HOSTNAME;
|
|
84
|
-
this.redirectUri = preferredPortOrOptions.redirectUri;
|
|
85
|
-
this.allowPortFallback = preferredPortOrOptions.allowPortFallback ?? true;
|
|
86
|
-
this.#manualInputOnly = preferredPortOrOptions.manualInputOnly ?? false;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Generate CSRF state token. Override if provider needs custom state generation.
|
|
90
|
-
*/
|
|
91
|
-
generateState() {
|
|
92
|
-
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
93
|
-
crypto.getRandomValues(bytes);
|
|
94
|
-
return Array.from(bytes).map((value) => value.toString(16).padStart(2, "0")).join("");
|
|
95
|
-
}
|
|
96
|
-
#loginCancelledError() {
|
|
97
|
-
return new LoginCancelledError(`OAuth callback cancelled: ${this.ctrl.signal?.reason}`);
|
|
98
|
-
}
|
|
99
|
-
#throwIfCancelled() {
|
|
100
|
-
if (this.ctrl.signal?.aborted) throw this.#loginCancelledError();
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Execute the OAuth login flow.
|
|
104
|
-
*/
|
|
105
|
-
async login() {
|
|
106
|
-
const state = this.generateState();
|
|
107
|
-
this.#throwIfCancelled();
|
|
108
|
-
const { server, redirectUri, launchUrl } = this.#manualInputOnly ? {
|
|
109
|
-
server: void 0,
|
|
110
|
-
redirectUri: this.#buildRedirectUri(),
|
|
111
|
-
launchUrl: void 0
|
|
112
|
-
} : await this.#startCallbackServer(state);
|
|
113
|
-
try {
|
|
114
|
-
this.#throwIfCancelled();
|
|
115
|
-
const { url: authUrl, instructions } = await this.generateAuthUrl(state, redirectUri);
|
|
116
|
-
this.#throwIfCancelled();
|
|
117
|
-
this.#pendingAuthUrl = authUrl;
|
|
118
|
-
this.ctrl.onAuth?.({
|
|
119
|
-
url: authUrl,
|
|
120
|
-
launchUrl,
|
|
121
|
-
instructions
|
|
122
|
-
});
|
|
123
|
-
this.ctrl.onProgress?.(this.#manualInputOnly ? "Waiting for pasted authorization code..." : "Waiting for browser authentication...");
|
|
124
|
-
const { code } = await this.#waitForCallback(state);
|
|
125
|
-
this.#throwIfCancelled();
|
|
126
|
-
this.ctrl.onProgress?.("Exchanging authorization code for tokens...");
|
|
127
|
-
return await this.exchangeToken(code, state, redirectUri);
|
|
128
|
-
} finally {
|
|
129
|
-
this.#pendingAuthUrl = void 0;
|
|
130
|
-
server?.stop();
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
#buildRedirectUri() {
|
|
134
|
-
return this.redirectUri ?? `http://${this.callbackHostname}:${this.preferredPort}${this.callbackPath}`;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Start callback server, trying preferred port first, falling back to random.
|
|
138
|
-
* `launchUrl` is `undefined` when the caller configured `callbackPath` to
|
|
139
|
-
* collide with {@link LAUNCH_PATH} — the callback handler resolves the real
|
|
140
|
-
* callback in that case, so advertising a self-redirecting URL would be
|
|
141
|
-
* incorrect.
|
|
142
|
-
*/
|
|
143
|
-
async #startCallbackServer(expectedState) {
|
|
144
|
-
try {
|
|
145
|
-
const server = this.#createServer(this.preferredPort, expectedState);
|
|
146
|
-
const actualPort = this.#resolveServerPort(server);
|
|
147
|
-
const launchUrl = this.#launchUrlIfSafe(actualPort);
|
|
148
|
-
if (this.redirectUri) return {
|
|
149
|
-
server,
|
|
150
|
-
redirectUri: this.redirectUri,
|
|
151
|
-
launchUrl
|
|
152
|
-
};
|
|
153
|
-
return {
|
|
154
|
-
server,
|
|
155
|
-
redirectUri: `http://${this.callbackHostname}:${actualPort}${this.callbackPath}`,
|
|
156
|
-
launchUrl
|
|
157
|
-
};
|
|
158
|
-
} catch (cause) {
|
|
159
|
-
if (this.redirectUri) throw new ConfigurationError(`OAuth callback port ${this.preferredPort} is in use, but oauth.redirectUri (${this.redirectUri}) requires this exact port. Free port ${this.preferredPort} (e.g. stop the process bound to it) and retry, or change oauth.redirectUri to point at an available port.`, { cause });
|
|
160
|
-
if (!this.allowPortFallback) throw new ConfigurationError(`OAuth callback port ${this.preferredPort} is in use. The OAuth provider validates redirect URIs against its registered callback, so falling back to a random port would be rejected. Free port ${this.preferredPort} (e.g. stop the process bound to it) and retry, or set oauth.callbackPort/oauth.redirectUri to a port the provider has registered.`, { cause });
|
|
161
|
-
const server = this.#createServer(0, expectedState);
|
|
162
|
-
const actualPort = this.#resolveServerPort(server);
|
|
163
|
-
const redirectUri = `http://${this.callbackHostname}:${actualPort}${this.callbackPath}`;
|
|
164
|
-
const launchUrl = this.#launchUrlIfSafe(actualPort);
|
|
165
|
-
this.ctrl.onProgress?.(`Preferred port ${this.preferredPort} unavailable, using port ${actualPort}`);
|
|
166
|
-
return {
|
|
167
|
-
server,
|
|
168
|
-
redirectUri,
|
|
169
|
-
launchUrl
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Read the numeric port a callback server bound to. `Bun.Server.port` is
|
|
175
|
-
* declared `number | undefined` because Unix-socket servers have no port,
|
|
176
|
-
* but every callback flow uses TCP; a missing port here indicates a
|
|
177
|
-
* configuration error rather than a fallback case.
|
|
178
|
-
*/
|
|
179
|
-
#resolveServerPort(server) {
|
|
180
|
-
const port = server.port;
|
|
181
|
-
if (typeof port !== "number") throw new ConfigurationError("OAuth callback server bound to a non-TCP endpoint; expected a numeric port. Check `oauth.callbackPort`/`oauth.redirectUri`.");
|
|
182
|
-
return port;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Build the `/launch` URL served by the callback server bound to `port`, or
|
|
186
|
-
* `undefined` when it must not be advertised:
|
|
187
|
-
* - the configured `callbackPath` (or a `redirectUri` whose pathname
|
|
188
|
-
* resolves to {@link LAUNCH_PATH}) would collide with the launch route;
|
|
189
|
-
* - the flow's `redirectUri` never returns to this loopback server: fixed
|
|
190
|
-
* non-loopback hosts, or custom schemes like GitLab Duo's `vscode://`
|
|
191
|
-
* URI — which `new URL` parses without complaint, so a scheme/host check
|
|
192
|
-
* is required, not just the parse failure path. Advertising a localhost
|
|
193
|
-
* `/launch` target for such flows misrepresents the callback endpoint
|
|
194
|
-
* and hands remote users a URL that resolves nowhere.
|
|
195
|
-
* Kept short (~30 chars) so UIs can advertise it as a
|
|
196
|
-
* viewport-truncation-safe copy target for the full authorization URL.
|
|
197
|
-
*/
|
|
198
|
-
#launchUrlIfSafe(port) {
|
|
199
|
-
if (this.callbackPath === LAUNCH_PATH) return void 0;
|
|
200
|
-
if (this.redirectUri) try {
|
|
201
|
-
const parsed = new URL(this.redirectUri);
|
|
202
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return void 0;
|
|
203
|
-
if (parsed.hostname !== "localhost" && parsed.hostname !== "127.0.0.1" && parsed.hostname !== "[::1]") return;
|
|
204
|
-
if (parsed.pathname === LAUNCH_PATH) return void 0;
|
|
205
|
-
} catch {
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
return `http://${this.callbackHostname}:${port}${LAUNCH_PATH}`;
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Create the HTTP listener(s) for the OAuth callback.
|
|
212
|
-
*
|
|
213
|
-
* `localhost` is not a single endpoint: it resolves to both
|
|
214
|
-
* {@link IPV4_LOOPBACK} and {@link IPV6_LOOPBACK}, and clients commonly try
|
|
215
|
-
* `::1` first. Binding only the IPv4 literal hands the authorization code to
|
|
216
|
-
* whatever holds the IPv6 loopback on the same port — a dev server on
|
|
217
|
-
* `*:3000` is the common case — which answers from its own routes while this
|
|
218
|
-
* flow waits out the full {@link DEFAULT_TIMEOUT}. Nothing detects it either:
|
|
219
|
-
* a specific-address bind coexists with another process's wildcard bind, so
|
|
220
|
-
* `Bun.serve` reports the port as free and the random-port fallback in
|
|
221
|
-
* {@link #startCallbackServer} never runs.
|
|
222
|
-
*
|
|
223
|
-
* Binding both loopback literals fixes the delivery rather than dodging it:
|
|
224
|
-
* the kernel routes a connection to the most specific matching bind, so our
|
|
225
|
-
* `::1` listener receives `localhost` traffic that would otherwise reach a
|
|
226
|
-
* process bound to the `::` wildcard. Both listeners answer the same routes,
|
|
227
|
-
* so which family the client resolves stops mattering.
|
|
228
|
-
*
|
|
229
|
-
* A genuine collision — another process on exactly this loopback address and
|
|
230
|
-
* port — still raises EADDRINUSE and reaches the caller's in-use policy. A
|
|
231
|
-
* host that cannot bind `::1` at all (IPv6 disabled, address unavailable) is
|
|
232
|
-
* not a collision: the IPv4 listener is the only reachable endpoint there, so
|
|
233
|
-
* it serves alone.
|
|
234
|
-
*/
|
|
235
|
-
#createServer(port, expectedState) {
|
|
236
|
-
if (this.callbackHostname !== DEFAULT_HOSTNAME) return this.#serve(this.callbackHostname, port, expectedState);
|
|
237
|
-
for (let attempt = 0;; attempt++) {
|
|
238
|
-
const primary = this.#serve(IPV4_LOOPBACK, port, expectedState);
|
|
239
|
-
const boundPort = primary.port;
|
|
240
|
-
if (typeof boundPort !== "number") return primary;
|
|
241
|
-
let companion;
|
|
242
|
-
try {
|
|
243
|
-
companion = this.#serve(IPV6_LOOPBACK, boundPort, expectedState);
|
|
244
|
-
} catch (cause) {
|
|
245
|
-
if (!isAddressInUse(cause)) return primary;
|
|
246
|
-
primary.stop(true);
|
|
247
|
-
if (port !== 0 || attempt >= IPV6_COMPANION_ATTEMPTS) throw cause;
|
|
248
|
-
continue;
|
|
249
|
-
}
|
|
250
|
-
return {
|
|
251
|
-
get port() {
|
|
252
|
-
return primary.port;
|
|
253
|
-
},
|
|
254
|
-
stop: (closeActiveConnections) => {
|
|
255
|
-
companion.stop(closeActiveConnections);
|
|
256
|
-
return primary.stop(closeActiveConnections);
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
/** Bind one loopback listener serving the callback and launch routes. */
|
|
262
|
-
#serve(hostname, port, expectedState) {
|
|
263
|
-
return Bun.serve({
|
|
264
|
-
hostname,
|
|
265
|
-
port,
|
|
266
|
-
reusePort: false,
|
|
267
|
-
fetch: (req) => this.#handleCallback(req, expectedState)
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Handle OAuth callback HTTP request. Two routes on the same loopback server:
|
|
272
|
-
* - `callbackPath` (default `/callback`) — the provider redirect target.
|
|
273
|
-
* - {@link LAUNCH_PATH} (`/launch`) — 302 to the pending authorization URL so
|
|
274
|
-
* viewport-safe copy targets can survive TUI truncation.
|
|
275
|
-
*
|
|
276
|
-
* `callbackPath` wins any collision: an OMP config that pins the provider
|
|
277
|
-
* redirect at `/launch` (via `oauth.callbackPath` or a loopback
|
|
278
|
-
* `oauth.redirectUri`) must resolve the callback normally rather than
|
|
279
|
-
* self-redirect. `#startCallbackServer` also suppresses `launchUrl` in that
|
|
280
|
-
* case, so the launch route is never advertised when it would collide.
|
|
281
|
-
*/
|
|
282
|
-
#handleCallback(req, expectedState) {
|
|
283
|
-
const url = new URL(req.url);
|
|
284
|
-
if (url.pathname !== this.callbackPath) {
|
|
285
|
-
if (url.pathname === LAUNCH_PATH) {
|
|
286
|
-
const pending = this.#pendingAuthUrl;
|
|
287
|
-
if (!pending) return new Response("OAuth launch URL is no longer active", { status: 503 });
|
|
288
|
-
return Response.redirect(pending, 302);
|
|
289
|
-
}
|
|
290
|
-
return new Response("Not Found", { status: 404 });
|
|
291
|
-
}
|
|
292
|
-
const code = url.searchParams.get("code");
|
|
293
|
-
const state = url.searchParams.get("state") || "";
|
|
294
|
-
const error = url.searchParams.get("error") || "";
|
|
295
|
-
const errorDescription = url.searchParams.get("error_description") || error;
|
|
296
|
-
let resultState;
|
|
297
|
-
if (error) resultState = {
|
|
298
|
-
ok: false,
|
|
299
|
-
error: `Authorization failed: ${errorDescription}`
|
|
300
|
-
};
|
|
301
|
-
else if (!code) resultState = {
|
|
302
|
-
ok: false,
|
|
303
|
-
error: "Missing authorization code"
|
|
304
|
-
};
|
|
305
|
-
else if (expectedState && state !== expectedState) resultState = {
|
|
306
|
-
ok: false,
|
|
307
|
-
error: "State mismatch - possible CSRF attack"
|
|
308
|
-
};
|
|
309
|
-
else resultState = {
|
|
310
|
-
ok: true,
|
|
311
|
-
code,
|
|
312
|
-
state
|
|
313
|
-
};
|
|
314
|
-
if (resultState.ok) {
|
|
315
|
-
const resolve = this.#callbackResolve;
|
|
316
|
-
queueMicrotask(() => {
|
|
317
|
-
resolve?.({
|
|
318
|
-
code: resultState.code,
|
|
319
|
-
state: resultState.state
|
|
320
|
-
});
|
|
321
|
-
});
|
|
322
|
-
} else if (error && (!expectedState || state === expectedState)) {
|
|
323
|
-
const reject = this.#callbackReject;
|
|
324
|
-
const message = resultState.error ?? `Authorization failed: ${errorDescription}`;
|
|
325
|
-
queueMicrotask(() => {
|
|
326
|
-
reject?.(new OAuthError(message, { kind: "device-auth" }));
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
return new Response(oauth_default.replaceAll("__OAUTH_STATE__", JSON.stringify(resultState)), {
|
|
330
|
-
status: resultState.ok ? 200 : 500,
|
|
331
|
-
headers: { "Content-Type": "text/html" }
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Wait for OAuth callback or manual input (whichever comes first).
|
|
336
|
-
*/
|
|
337
|
-
#waitForCallback(expectedState) {
|
|
338
|
-
const timeoutSignal = AbortSignal.timeout(DEFAULT_TIMEOUT);
|
|
339
|
-
const signal = this.ctrl.signal ? AbortSignal.any([this.ctrl.signal, timeoutSignal]) : timeoutSignal;
|
|
340
|
-
if (signal.aborted) return Promise.reject(this.#loginCancelledError());
|
|
341
|
-
const callback = Promise.withResolvers();
|
|
342
|
-
this.#callbackResolve = callback.resolve;
|
|
343
|
-
this.#callbackReject = callback.reject;
|
|
344
|
-
signal.addEventListener("abort", () => {
|
|
345
|
-
this.#callbackResolve = void 0;
|
|
346
|
-
this.#callbackReject = void 0;
|
|
347
|
-
callback.reject(new LoginCancelledError(`OAuth callback cancelled: ${signal.reason}`));
|
|
348
|
-
});
|
|
349
|
-
const callbackPromise = callback.promise;
|
|
350
|
-
if (this.ctrl.onManualCodeInput) {
|
|
351
|
-
const requestManualInput = this.ctrl.onManualCodeInput;
|
|
352
|
-
const manualPromise = (async () => {
|
|
353
|
-
while (true) {
|
|
354
|
-
const result = await Promise.race([callbackPromise, requestManualInput().then((input) => {
|
|
355
|
-
const parsed = parseCallbackInput(input);
|
|
356
|
-
if (!parsed.code) return null;
|
|
357
|
-
if (expectedState && parsed.state && parsed.state !== expectedState) return null;
|
|
358
|
-
return {
|
|
359
|
-
code: parsed.code,
|
|
360
|
-
state: parsed.state ?? ""
|
|
361
|
-
};
|
|
362
|
-
}).catch(() => null)]);
|
|
363
|
-
if (result) return result;
|
|
364
|
-
}
|
|
365
|
-
})();
|
|
366
|
-
return Promise.race([callbackPromise, manualPromise]);
|
|
367
|
-
}
|
|
368
|
-
return callbackPromise;
|
|
369
|
-
}
|
|
370
|
-
};
|
|
371
|
-
/**
|
|
372
|
-
* Parse a redirect URL or code string to extract code and state.
|
|
373
|
-
*/
|
|
374
|
-
function parseCallbackInput(input) {
|
|
375
|
-
const value = input.trim();
|
|
376
|
-
if (!value) return {};
|
|
377
|
-
try {
|
|
378
|
-
const url = new URL(value);
|
|
379
|
-
return {
|
|
380
|
-
code: url.searchParams.get("code") ?? void 0,
|
|
381
|
-
state: url.searchParams.get("state") ?? void 0
|
|
382
|
-
};
|
|
383
|
-
} catch {}
|
|
384
|
-
if (value.includes("code=")) {
|
|
385
|
-
const params = new URLSearchParams(value.replace(/^[?#]/, ""));
|
|
386
|
-
return {
|
|
387
|
-
code: params.get("code") ?? void 0,
|
|
388
|
-
state: params.get("state") ?? void 0
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
const [code, state] = value.split("#", 2);
|
|
392
|
-
return {
|
|
393
|
-
code,
|
|
394
|
-
state
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
//#endregion
|
|
398
|
-
export { OAuthCallbackFlow as t };
|
package/lib/codex-P1dGpX7G.mjs
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
-
__installBunShim();
|
|
3
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-catalog@17.3.5/node_modules/@oh-my-pi/pi-catalog/src/wire/codex.ts
|
|
4
|
-
/**
|
|
5
|
-
* Constants for OpenAI Codex (ChatGPT OAuth) backend
|
|
6
|
-
*/
|
|
7
|
-
const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
8
|
-
/**
|
|
9
|
-
* Pinned OpenAI Codex client version (corresponds to @openai/codex package version).
|
|
10
|
-
*/
|
|
11
|
-
const CODEX_CLIENT_VERSION = "0.144.1";
|
|
12
|
-
const OPENAI_HEADERS = {
|
|
13
|
-
BETA: "OpenAI-Beta",
|
|
14
|
-
/** Codex feature-negotiation header; values identify opt-in wire protocols. */
|
|
15
|
-
CODEX_BETA_FEATURES: "x-codex-beta-features",
|
|
16
|
-
ACCOUNT_ID: "chatgpt-account-id",
|
|
17
|
-
ORIGINATOR: "originator",
|
|
18
|
-
VERSION: "version",
|
|
19
|
-
SESSION_ID: "session_id",
|
|
20
|
-
CONVERSATION_ID: "conversation_id",
|
|
21
|
-
SCOPED_SESSION_ID: "session-id",
|
|
22
|
-
THREAD_ID: "thread-id",
|
|
23
|
-
INSTALLATION_ID: "x-codex-installation-id",
|
|
24
|
-
WINDOW_ID: "x-codex-window-id",
|
|
25
|
-
TURN_METADATA: "x-codex-turn-metadata",
|
|
26
|
-
PARENT_THREAD_ID: "x-codex-parent-thread-id",
|
|
27
|
-
SUBAGENT: "x-openai-subagent",
|
|
28
|
-
/** Responses Lite transport marker (codex-rs `add_responses_lite_header`); value is always `"true"`. */
|
|
29
|
-
RESPONSES_LITE: "x-openai-internal-codex-responses-lite",
|
|
30
|
-
/** DeviceCheck attestation envelope (codex-rs `X_OAI_ATTESTATION_HEADER`); sent on ChatGPT-OAuth requests. */
|
|
31
|
-
ATTESTATION: "x-oai-attestation"
|
|
32
|
-
};
|
|
33
|
-
const OPENAI_HEADER_VALUES = {
|
|
34
|
-
BETA_RESPONSES: "responses=experimental",
|
|
35
|
-
BETA_RESPONSES_WEBSOCKETS_V2: "responses_websockets=2026-02-06",
|
|
36
|
-
REMOTE_COMPACTION_V2: "remote_compaction_v2",
|
|
37
|
-
ORIGINATOR_CODEX: "pi"
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Extract account ID from a Codex JWT access token.
|
|
41
|
-
* Returns undefined if the token is not a valid Codex JWT.
|
|
42
|
-
*/
|
|
43
|
-
function getCodexAccountId(accessToken) {
|
|
44
|
-
try {
|
|
45
|
-
const parts = accessToken.split(".");
|
|
46
|
-
if (parts.length !== 3) return void 0;
|
|
47
|
-
const decoded = Buffer.from(parts[1] ?? "", "base64").toString("utf-8");
|
|
48
|
-
return JSON.parse(decoded)["https://api.openai.com/auth"]?.chatgpt_account_id ?? void 0;
|
|
49
|
-
} catch {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
//#endregion
|
|
54
|
-
export { getCodexAccountId as a, OPENAI_HEADER_VALUES as i, CODEX_CLIENT_VERSION as n, OPENAI_HEADERS as r, CODEX_BASE_URL as t };
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
-
__installBunShim();
|
|
3
|
-
import { c as OAuthError, h as LoginCancelledError } from "./error-C-f_Wnw4.mjs";
|
|
4
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/device-code.ts
|
|
5
|
-
const DEVICE_FLOW_CANCEL_MESSAGE = "Login cancelled";
|
|
6
|
-
const DEVICE_FLOW_TIMEOUT_MESSAGE = "Device flow timed out";
|
|
7
|
-
const DEVICE_FLOW_SLOW_DOWN_TIMEOUT_MESSAGE = "Device flow timed out after one or more slow_down responses. This is often caused by clock drift in WSL or VM environments. Please sync or restart the VM clock and try again.";
|
|
8
|
-
const MINIMUM_DEVICE_FLOW_INTERVAL_MS = 1e3;
|
|
9
|
-
const DEFAULT_DEVICE_FLOW_INTERVAL_SECONDS = 5;
|
|
10
|
-
const SLOW_DOWN_INTERVAL_INCREMENT_MS = 5e3;
|
|
11
|
-
async function abortableDeviceFlowSleep(ms, signal) {
|
|
12
|
-
if (!signal) {
|
|
13
|
-
await Bun.sleep(ms);
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
if (signal.aborted) throw new LoginCancelledError(DEVICE_FLOW_CANCEL_MESSAGE);
|
|
17
|
-
const { promise, resolve, reject } = Promise.withResolvers();
|
|
18
|
-
let timer;
|
|
19
|
-
const onAbort = () => {
|
|
20
|
-
clearTimeout(timer);
|
|
21
|
-
reject(new LoginCancelledError(DEVICE_FLOW_CANCEL_MESSAGE));
|
|
22
|
-
};
|
|
23
|
-
timer = setTimeout(() => {
|
|
24
|
-
signal.removeEventListener("abort", onAbort);
|
|
25
|
-
resolve();
|
|
26
|
-
}, ms);
|
|
27
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
28
|
-
await promise;
|
|
29
|
-
}
|
|
30
|
-
/** Poll an OAuth device-code flow until completion, provider failure, timeout, or cancellation. */
|
|
31
|
-
async function pollOAuthDeviceCodeFlow(options) {
|
|
32
|
-
const deadline = typeof options.expiresInSeconds === "number" ? Date.now() + options.expiresInSeconds * 1e3 : Number.POSITIVE_INFINITY;
|
|
33
|
-
let intervalMs = Math.max(MINIMUM_DEVICE_FLOW_INTERVAL_MS, Math.floor((options.intervalSeconds ?? DEFAULT_DEVICE_FLOW_INTERVAL_SECONDS) * 1e3));
|
|
34
|
-
let slowDownResponses = 0;
|
|
35
|
-
while (Date.now() < deadline) {
|
|
36
|
-
if (options.signal?.aborted) throw new LoginCancelledError(DEVICE_FLOW_CANCEL_MESSAGE);
|
|
37
|
-
const result = await options.poll();
|
|
38
|
-
if (result.status === "complete") return result.value;
|
|
39
|
-
if (result.status === "failed") throw new OAuthError(result.message, { kind: "polling" });
|
|
40
|
-
if (result.status === "slow_down") {
|
|
41
|
-
slowDownResponses += 1;
|
|
42
|
-
intervalMs = Math.max(MINIMUM_DEVICE_FLOW_INTERVAL_MS, intervalMs + SLOW_DOWN_INTERVAL_INCREMENT_MS);
|
|
43
|
-
}
|
|
44
|
-
const remainingMs = deadline - Date.now();
|
|
45
|
-
if (remainingMs <= 0) break;
|
|
46
|
-
await abortableDeviceFlowSleep(Math.min(intervalMs, remainingMs), options.signal);
|
|
47
|
-
}
|
|
48
|
-
throw new OAuthError(slowDownResponses > 0 ? DEVICE_FLOW_SLOW_DOWN_TIMEOUT_MESSAGE : DEVICE_FLOW_TIMEOUT_MESSAGE, { kind: "timeout" });
|
|
49
|
-
}
|
|
50
|
-
//#endregion
|
|
51
|
-
export { pollOAuthDeviceCodeFlow as t };
|
package/lib/devin-BcQwht1W.mjs
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
-
__installBunShim();
|
|
3
|
-
import { n as discoveryFetch } from "./utils-CQHPEQ3W.mjs";
|
|
4
|
-
import { E as create, i as fromBinary, t as toBinary } from "./to-binary-B1BEBIPC.mjs";
|
|
5
|
-
import { f as MetadataSchema, i as GetCliModelConfigsResponseSchema, r as GetCliModelConfigsRequestSchema } from "./api_server_pb-CDZgLMta.mjs";
|
|
6
|
-
import { gunzipSync } from "node:zlib";
|
|
7
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-catalog@17.3.5/node_modules/@oh-my-pi/pi-catalog/src/discovery/devin.ts
|
|
8
|
-
const DEVIN_DEFAULT_BASE_URL = "https://server.codeium.com";
|
|
9
|
-
const DEVIN_GET_CLI_MODEL_CONFIGS_PATH = "/exa.api_server_pb.ApiServerService/GetCliModelConfigs";
|
|
10
|
-
const DEVIN_IDE_VERSION = "3.2.23";
|
|
11
|
-
const DEVIN_EXTENSION_VERSION = "1.48.2";
|
|
12
|
-
const DEVIN_SESSION_TOKEN_PREFIX = "devin-session-token$";
|
|
13
|
-
const DEFAULT_CONTEXT_WINDOW = 2e5;
|
|
14
|
-
const DEFAULT_MAX_TOKENS = 64e3;
|
|
15
|
-
/** Best-effort match for labels whose wording implies a thinking / reasoning-effort variant. */
|
|
16
|
-
const REASONING_LABEL_PATTERN = /think|thinking|minimal|high|medium|low|xhigh|max|reasoning/i;
|
|
17
|
-
const NO_REASONING_LABEL_PATTERN = /\bno thinking\b/i;
|
|
18
|
-
function supportsDevinThinking(config) {
|
|
19
|
-
if (NO_REASONING_LABEL_PATTERN.test(config.label)) return false;
|
|
20
|
-
return config.modelInfo?.modelFeatures?.supportsThinking === true || REASONING_LABEL_PATTERN.test(config.label);
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Fetches Devin models through the `GetCliModelConfigs` unary Connect RPC and
|
|
24
|
-
* normalizes them into canonical model entries.
|
|
25
|
-
*
|
|
26
|
-
* Returns `null` on request/decode failures.
|
|
27
|
-
* Returns `[]` only when the endpoint responds successfully with no usable models.
|
|
28
|
-
*/
|
|
29
|
-
async function fetchDevinModels(options) {
|
|
30
|
-
const timeoutMs = options.timeoutMs ?? 5e3;
|
|
31
|
-
const requestUrl = `${(options.baseUrl ?? DEVIN_DEFAULT_BASE_URL).replace(/\/+$/, "")}${DEVIN_GET_CLI_MODEL_CONFIGS_PATH}`;
|
|
32
|
-
const controller = new AbortController();
|
|
33
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
34
|
-
const signal = options.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;
|
|
35
|
-
try {
|
|
36
|
-
const request = create(GetCliModelConfigsRequestSchema, { metadata: create(MetadataSchema, {
|
|
37
|
-
apiKey: normalizeDevinSessionToken(options.apiKey),
|
|
38
|
-
ideName: "windsurf",
|
|
39
|
-
ideVersion: DEVIN_IDE_VERSION,
|
|
40
|
-
extensionName: "windsurf",
|
|
41
|
-
extensionVersion: DEVIN_EXTENSION_VERSION
|
|
42
|
-
}) });
|
|
43
|
-
const body = toBinary(GetCliModelConfigsRequestSchema, request);
|
|
44
|
-
const response = await discoveryFetch(options.fetch)(requestUrl, {
|
|
45
|
-
method: "POST",
|
|
46
|
-
headers: {
|
|
47
|
-
"content-type": "application/proto",
|
|
48
|
-
"connect-protocol-version": "1",
|
|
49
|
-
accept: "*/*"
|
|
50
|
-
},
|
|
51
|
-
body,
|
|
52
|
-
signal
|
|
53
|
-
});
|
|
54
|
-
if (!response.ok) return null;
|
|
55
|
-
const decoded = decodeCliModelConfigsResponse(new Uint8Array(await response.arrayBuffer()));
|
|
56
|
-
if (!decoded) return null;
|
|
57
|
-
return normalizeDevinModels(decoded.clientModelConfigs, options.baseUrl);
|
|
58
|
-
} catch {
|
|
59
|
-
return null;
|
|
60
|
-
} finally {
|
|
61
|
-
clearTimeout(timer);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
function normalizeDevinSessionToken(apiKey) {
|
|
65
|
-
if (!apiKey) return "";
|
|
66
|
-
return apiKey.startsWith(DEVIN_SESSION_TOKEN_PREFIX) ? apiKey : `${DEVIN_SESSION_TOKEN_PREFIX}${apiKey}`;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Decodes a raw (unframed) `GetCliModelConfigsResponse`. Bun's `fetch` usually
|
|
70
|
-
* auto-decompresses gzip, so the direct decode is attempted first; a
|
|
71
|
-
* `gunzipSync` fallback covers runtimes that hand back the still-compressed body.
|
|
72
|
-
*/
|
|
73
|
-
function decodeCliModelConfigsResponse(payload) {
|
|
74
|
-
try {
|
|
75
|
-
return fromBinary(GetCliModelConfigsResponseSchema, payload);
|
|
76
|
-
} catch {
|
|
77
|
-
try {
|
|
78
|
-
return fromBinary(GetCliModelConfigsResponseSchema, gunzipSync(payload));
|
|
79
|
-
} catch {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
function normalizeDevinModels(configs, baseUrlOverride) {
|
|
85
|
-
const byId = /* @__PURE__ */ new Map();
|
|
86
|
-
for (const config of configs) {
|
|
87
|
-
if (config.disabled) continue;
|
|
88
|
-
const id = config.modelUid.trim();
|
|
89
|
-
if (!id) continue;
|
|
90
|
-
const input = config.supportsImages ? ["text", "image"] : ["text"];
|
|
91
|
-
const contextWindow = config.maxTokens > 0 ? config.maxTokens : DEFAULT_CONTEXT_WINDOW;
|
|
92
|
-
byId.set(id, {
|
|
93
|
-
id,
|
|
94
|
-
name: config.label.trim() || id,
|
|
95
|
-
api: "devin-agent",
|
|
96
|
-
provider: "devin",
|
|
97
|
-
baseUrl: baseUrlOverride ?? DEVIN_DEFAULT_BASE_URL,
|
|
98
|
-
reasoning: supportsDevinThinking(config),
|
|
99
|
-
input,
|
|
100
|
-
supportsTools: true,
|
|
101
|
-
cost: {
|
|
102
|
-
input: 0,
|
|
103
|
-
output: 0,
|
|
104
|
-
cacheRead: 0,
|
|
105
|
-
cacheWrite: 0
|
|
106
|
-
},
|
|
107
|
-
contextWindow,
|
|
108
|
-
maxTokens: Math.min(config.maxTokens > 0 ? config.maxTokens : DEFAULT_MAX_TOKENS, DEFAULT_MAX_TOKENS)
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
return [...byId.values()].sort((a, b) => a.id.localeCompare(b.id));
|
|
112
|
-
}
|
|
113
|
-
//#endregion
|
|
114
|
-
export { fetchDevinModels };
|