@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.
Files changed (235) hide show
  1. package/README.en.md +122 -0
  2. package/README.md +3 -2
  3. package/THIRD_PARTY_NOTICES.md +4 -35
  4. package/lib/abort-B7izMMna.mjs +51 -0
  5. package/lib/abort-D1_Z5Ut5.mjs +51 -0
  6. package/lib/abort-dIkZBV7Q.mjs +51 -0
  7. package/lib/amazon-bedrock-B0nxT06F.mjs +917 -0
  8. package/lib/amazon-bedrock-D-shAr1X.mjs +917 -0
  9. package/lib/amazon-bedrock-WQhvjHYu.mjs +917 -0
  10. package/lib/anthropic-BWsZFzU8.mjs +262 -0
  11. package/lib/anthropic-CJCauvYz.mjs +3115 -0
  12. package/lib/anthropic-CMT1Qj1t.mjs +3115 -0
  13. package/lib/anthropic-CZghe_9U.mjs +3115 -0
  14. package/lib/anthropic-sCMH7JID.mjs +262 -0
  15. package/lib/anthropic-tTntD8BD.mjs +262 -0
  16. package/lib/api-key-login-BzqNdM2y.mjs +157 -0
  17. package/lib/api-key-login-CWVwvHT1.mjs +157 -0
  18. package/lib/api-key-login-CpzSezsi.mjs +157 -0
  19. package/lib/aws-credentials-8Mgn5MAy.mjs +867 -0
  20. package/lib/aws-credentials-CXryMobh.mjs +867 -0
  21. package/lib/aws-credentials-ChG79ey-.mjs +867 -0
  22. package/lib/azure-openai-responses-CNkHiLUh.mjs +274 -0
  23. package/lib/azure-openai-responses-Cgmc-rbL.mjs +274 -0
  24. package/lib/azure-openai-responses-DuukbD0F.mjs +274 -0
  25. package/lib/bun-shim.mjs +252 -12
  26. package/lib/bundled-references-CSuBco5p.mjs +55 -0
  27. package/lib/bundled-references-Cavaffah.mjs +55 -0
  28. package/lib/bundled-references-sLN0YdXU.mjs +55 -0
  29. package/lib/callback-server-BEFNf-jf.mjs +398 -0
  30. package/lib/callback-server-CQ5Jo8F-.mjs +398 -0
  31. package/lib/callback-server-DDSrZ6l_.mjs +398 -0
  32. package/lib/client.js +111 -41
  33. package/lib/cursor-B3zg7EHj.mjs +273 -0
  34. package/lib/cursor-B6TUEmgP.mjs +135 -0
  35. package/lib/cursor-BIQfBC6V.mjs +135 -0
  36. package/lib/cursor-D8gvtTL3.mjs +135 -0
  37. package/lib/cursor-DNk6eXDd.mjs +5470 -0
  38. package/lib/cursor-DkSX2h3H.mjs +5441 -0
  39. package/lib/cursor-MjSm74IJ.mjs +273 -0
  40. package/lib/cursor-aJrXeYCb.mjs +273 -0
  41. package/lib/cursor-mJQwUKXK.mjs +5441 -0
  42. package/lib/device-code-DBo3B5nh.mjs +51 -0
  43. package/lib/device-code-DIb0FU-H.mjs +51 -0
  44. package/lib/device-code-OI_tQcmc.mjs +51 -0
  45. package/lib/devin-BHZZyMhO.mjs +95 -0
  46. package/lib/devin-BK7DHeca.mjs +114 -0
  47. package/lib/devin-CfMp3cXS.mjs +95 -0
  48. package/lib/devin-CldyPD8K.mjs +95 -0
  49. package/lib/devin-CzRpTUOA.mjs +114 -0
  50. package/lib/devin-D9zR5B_R.mjs +542 -0
  51. package/lib/devin-DXOeNyU7.mjs +542 -0
  52. package/lib/devin-Q1yem3lp.mjs +114 -0
  53. package/lib/devin-vNZTNUON.mjs +542 -0
  54. package/lib/error-B3bevhrs.mjs +1449 -0
  55. package/lib/error-Dd8DIqs-.mjs +1449 -0
  56. package/lib/error-yCSG0mGC.mjs +1449 -0
  57. package/lib/event-stream-BDPi64mK.mjs +151 -0
  58. package/lib/event-stream-BbFZJy-z.mjs +151 -0
  59. package/lib/event-stream-loUa0s1T.mjs +151 -0
  60. package/lib/fs-promises-shim-Bx0fpxuk.mjs +57 -0
  61. package/lib/github-copilot-4GaMtQmg.mjs +208 -0
  62. package/lib/github-copilot-B1yiyVRh.mjs +104 -0
  63. package/lib/github-copilot-B2HGSIJK.mjs +104 -0
  64. package/lib/github-copilot-BWT3eAOF.mjs +208 -0
  65. package/lib/github-copilot-CYkjeTi3.mjs +208 -0
  66. package/lib/github-copilot-jscUZ8Hf.mjs +104 -0
  67. package/lib/gitlab-duo-CM7Ref1H.mjs +155 -0
  68. package/lib/gitlab-duo-akICyfeD.mjs +155 -0
  69. package/lib/gitlab-duo-gubO4FNw.mjs +155 -0
  70. package/lib/gitlab-duo-workflow-BGAF6JDw.mjs +91 -0
  71. package/lib/gitlab-duo-workflow-CSEgYk3N.mjs +91 -0
  72. package/lib/gitlab-duo-workflow-D78tdn8E.mjs +91 -0
  73. package/lib/google-BS4T25Pn.mjs +30 -0
  74. package/lib/google-TFe-7-of.mjs +30 -0
  75. package/lib/google-antigravity-DGmwC2KV.mjs +198 -0
  76. package/lib/google-antigravity-DNYhgTpA.mjs +198 -0
  77. package/lib/google-antigravity-Dlkdhahq.mjs +198 -0
  78. package/lib/google-auth-B6gjsZvg.mjs +232 -0
  79. package/lib/google-auth-De7_s3eo.mjs +232 -0
  80. package/lib/google-auth-DhqpOYrX.mjs +232 -0
  81. package/lib/google-gemini-cli-BG_LRdIV.mjs +850 -0
  82. package/lib/google-gemini-cli-CWu8HvXW.mjs +211 -0
  83. package/lib/google-gemini-cli-Cb97bzQc.mjs +850 -0
  84. package/lib/google-gemini-cli-Cqds_Q5T.mjs +850 -0
  85. package/lib/google-gemini-cli-Dsztq0N5.mjs +211 -0
  86. package/lib/google-gemini-cli-zJhiOcND.mjs +211 -0
  87. package/lib/google-oauth-shared-CuEHaDDj.mjs +147 -0
  88. package/lib/google-oauth-shared-CwNWYdmR.mjs +147 -0
  89. package/lib/google-oauth-shared-yqlyqPPC.mjs +147 -0
  90. package/lib/google-shared-CgKmmdO3.mjs +760 -0
  91. package/lib/google-shared-Dr-VG-ap.mjs +760 -0
  92. package/lib/google-shared-DzhCb9b0.mjs +760 -0
  93. package/lib/google-vertex-BDN2tLaD.mjs +99 -0
  94. package/lib/google-vertex-DopVOQOG.mjs +99 -0
  95. package/lib/google-vertex-kscbkyRb.mjs +99 -0
  96. package/lib/google-zyDOG9x7.mjs +30 -0
  97. package/lib/identity-Da1GPU9a.mjs +219 -0
  98. package/lib/identity-DnB63pS7.mjs +219 -0
  99. package/lib/identity-xRP7_eSR.mjs +219 -0
  100. package/lib/idle-iterator-Baoyn3Hp.mjs +366 -0
  101. package/lib/idle-iterator-C6XbWcuB.mjs +366 -0
  102. package/lib/idle-iterator-DUjKQEGT.mjs +366 -0
  103. package/lib/index.mjs +4608 -3935
  104. package/lib/kimi--wUOWER5.mjs +236 -0
  105. package/lib/kimi-DMVI-zrZ.mjs +236 -0
  106. package/lib/kimi-Dh0pv3WZ.mjs +236 -0
  107. package/lib/markit-BL3cH47U.mjs +1417 -0
  108. package/lib/markit-BNiNY6SE.mjs +1417 -0
  109. package/lib/markit-M0jhziqU.mjs +1417 -0
  110. package/lib/minimax-code-BK-3eBbz.mjs +53 -0
  111. package/lib/minimax-code-DCbuA6Yk.mjs +53 -0
  112. package/lib/minimax-code-Uq8Qu9LW.mjs +53 -0
  113. package/lib/models-CfT4coYT.mjs +104660 -0
  114. package/lib/models-D_XnT6ay.mjs +104660 -0
  115. package/lib/models-SGASygJ3.mjs +104660 -0
  116. package/lib/ollama-BQMGPxtV.mjs +589 -0
  117. package/lib/ollama-DPzBmq89.mjs +589 -0
  118. package/lib/ollama-DoBz5SFm.mjs +589 -0
  119. package/lib/openai-codex-Bi-4S4PX.mjs +255 -0
  120. package/lib/openai-codex-CQL_kvYL.mjs +255 -0
  121. package/lib/openai-codex-Ch8CkT3p.mjs +255 -0
  122. package/lib/openai-codex-responses-CvxL_FMF.mjs +3144 -0
  123. package/lib/openai-codex-responses-Cz-2qpC7.mjs +3144 -0
  124. package/lib/openai-codex-responses-pejZgdZo.mjs +3144 -0
  125. package/lib/openai-completions-CF8IyNtP.mjs +1360 -0
  126. package/lib/openai-completions-DIf361kF.mjs +1360 -0
  127. package/lib/openai-completions-i8doczAk.mjs +1360 -0
  128. package/lib/openai-reasoning-fallback-DGVVLgd1.mjs +286 -0
  129. package/lib/openai-reasoning-fallback-Nj6yB2rY.mjs +286 -0
  130. package/lib/openai-reasoning-fallback-OdJREP1o.mjs +286 -0
  131. package/lib/openai-responses-BqXJInHX.mjs +867 -0
  132. package/lib/openai-responses-DTkBiiy-.mjs +867 -0
  133. package/lib/openai-responses-Db_a-U4-.mjs +867 -0
  134. package/lib/opencode-DaJjcUbf.mjs +38 -0
  135. package/lib/opencode-DhMolSoB.mjs +38 -0
  136. package/lib/opencode-Rq_Q2vAO.mjs +38 -0
  137. package/lib/perplexity-9b-RQ0mV.mjs +194 -0
  138. package/lib/perplexity-C4iLVMUj.mjs +194 -0
  139. package/lib/perplexity-Uu7Jzg5b.mjs +194 -0
  140. package/lib/proxy-DDqrmjjC.mjs +190 -0
  141. package/lib/proxy-ZtUcl6r5.mjs +190 -0
  142. package/lib/proxy-pM_NIv-H.mjs +190 -0
  143. package/lib/request-debug-HJMoJncL.mjs +183 -0
  144. package/lib/sanitize-text-CfcXzw5X.mjs +33 -0
  145. package/lib/scrapers-BkFfcPHj.mjs +9198 -0
  146. package/lib/scrapers-CL-WgdU1.mjs +9198 -0
  147. package/lib/scrapers-CVptboMs.mjs +9198 -0
  148. package/lib/scrapers-CipyKyCH.mjs +9198 -0
  149. package/lib/scrapers-DGfrYhtw.mjs +9198 -0
  150. package/lib/scrapers-DSUPYoUF.mjs +9198 -0
  151. package/lib/scrapers-DZ2GXmp7.mjs +9198 -0
  152. package/lib/scrapers-nhQAvc8d.mjs +9198 -0
  153. package/lib/shell-snapshot-fn-env.sh +67 -43
  154. package/lib/src-BgpusnsB.mjs +5076 -0
  155. package/lib/src-DTid0g4K.mjs +5001 -0
  156. package/lib/src-lDmkSRbm.mjs +5006 -0
  157. package/lib/stream-BlldLkVq.mjs +10236 -0
  158. package/lib/stream-CRtexYLe.mjs +10236 -0
  159. package/lib/stream-C_RAoxJC.mjs +10236 -0
  160. package/lib/stream-markup-healing-2toHXWXM.mjs +491 -0
  161. package/lib/stream-markup-healing-DMsxBx1L.mjs +491 -0
  162. package/lib/stream-markup-healing-KMkiAA00.mjs +491 -0
  163. package/lib/turndown-DN7ByzEI.mjs +667 -0
  164. package/lib/types/client/locales.d.ts +1 -1
  165. package/lib/types/config/fields.d.ts +1 -1
  166. package/lib/types/config/settings.d.ts +25 -3
  167. package/lib/types/config/truncate.d.ts +9 -5
  168. package/lib/types/tools/bash/background.d.ts +1 -1
  169. package/lib/types/tools/bash/bash-executor.d.ts +4 -0
  170. package/lib/types/tools/bash/bash-interceptor.d.ts +10 -8
  171. package/lib/types/tools/bash/cd-workdir.d.ts +35 -0
  172. package/lib/types/tools/bash/non-interactive-env.d.ts +2 -0
  173. package/lib/types/tools/bash/render.d.ts +4 -3
  174. package/lib/types/tools/bash/sanitize-text.d.ts +5 -0
  175. package/lib/types/tools/bash/shell-snapshot.d.ts +4 -1
  176. package/lib/types/tools/bash/shell-tokenize.d.ts +60 -0
  177. package/lib/types/tools/bash/streaming-output.d.ts +12 -212
  178. package/lib/types/tools/bash/which.d.ts +20 -0
  179. package/lib/types/tools/bash/windows-shell.d.ts +31 -0
  180. package/lib/types/tools/edit/adapter/index.d.ts +25 -3
  181. package/lib/types/tools/edit/adapter/tools/auto-generated-guard.d.ts +7 -17
  182. package/lib/types/tools/glob/adapter/index.d.ts +27 -1
  183. package/lib/types/tools/grep/adapter/index.d.ts +29 -1
  184. package/lib/types/tools/omp/edit/dispatch.d.ts +43 -0
  185. package/lib/types/tools/omp/edit/hashline/noop-loop-guard.d.ts +3 -1
  186. package/lib/types/tools/omp/sdk.d.ts +6 -0
  187. package/lib/types/tools/omp/tools/auto-generated-guard.d.ts +20 -0
  188. package/lib/types/tools/omp/tools/fetch.d.ts +2 -0
  189. package/lib/types/tools/omp/tools/read.d.ts +2 -8
  190. package/lib/types/tools/omp/tools/write.d.ts +4 -4
  191. package/lib/types/tools/omp/utils/image-loading.d.ts +10 -36
  192. package/lib/types/tools/read/adapter/index.d.ts +4 -1
  193. package/lib/types/tools/read-image/index.d.ts +4 -0
  194. package/lib/types/tools/shared/auto-generated-guard.dsh.d.ts +16 -4
  195. package/lib/types/tools/shared/bun-shim.d.ts +39 -3
  196. package/lib/types/tools/shared/fs-promises-shim.d.ts +3 -1
  197. package/lib/types/tools/shared/image-bridge.d.ts +98 -0
  198. package/lib/types/tools/shared/omp-prompt.d.ts +17 -9
  199. package/lib/types/tools/shared/session-state.d.ts +9 -3
  200. package/lib/utils-2Wq2eATG.mjs +8119 -0
  201. package/lib/utils-BnX8O3vi.mjs +12303 -0
  202. package/lib/utils-Bw139LTz.mjs +8119 -0
  203. package/lib/utils-CE8N8P4Q.mjs +12315 -0
  204. package/lib/utils-CZw4tVZQ.mjs +12315 -0
  205. package/lib/utils-C_MrQ_0z.mjs +12301 -0
  206. package/lib/utils-CiGN7OHR.mjs +12315 -0
  207. package/lib/utils-Cp76gCyk.mjs +8119 -0
  208. package/lib/utils-D0GRDgAr.mjs +12315 -0
  209. package/lib/utils-D0Z1fyoO.mjs +12299 -0
  210. package/lib/utils-D2YknRk4.mjs +51 -0
  211. package/lib/utils-DppGHXQB.mjs +51 -0
  212. package/lib/utils-DzXZDfYc.mjs +51 -0
  213. package/lib/utils-W8WdSBpX.mjs +12315 -0
  214. package/lib/vision-guard-01qSwFpf.mjs +92 -0
  215. package/lib/vision-guard-BDD4OrKo.mjs +92 -0
  216. package/lib/vision-guard-DzZGaOga.mjs +92 -0
  217. package/lib/wafer-CgtPHerf.mjs +17 -0
  218. package/lib/wafer-DRU0EjZX.mjs +17 -0
  219. package/lib/wafer-cBtrn6q9.mjs +17 -0
  220. package/lib/xai-oauth-Buk8XVvM.mjs +446 -0
  221. package/lib/xai-oauth-CMal8l1O.mjs +446 -0
  222. package/lib/xai-oauth-DPHDXKD7.mjs +446 -0
  223. package/lib/xiaomi-CZgwvX2G.mjs +157 -0
  224. package/lib/xiaomi-D2qT5cAC.mjs +157 -0
  225. package/lib/xiaomi-Dd87KSg5.mjs +157 -0
  226. package/lib/zai-7DWMkEqM.mjs +203 -0
  227. package/lib/zai-C59YnomG.mjs +203 -0
  228. package/lib/zai-CFeOt-53.mjs +203 -0
  229. package/lib/zip-Cg9ANN_U.mjs +1316 -0
  230. package/lib/zip-D36ZKsP8.mjs +1316 -0
  231. package/lib/zip-D6QXpvaJ.mjs +1316 -0
  232. package/package.json +14 -10
  233. package/presets/package.json +1 -1
  234. package/presets/tool-plus-ptc/preset.yml +1 -1
  235. package/presets/tool-plus-standard/preset.yml +1 -1
@@ -0,0 +1,255 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { c as OAuthError, h as LoginCancelledError } from "./error-Dd8DIqs-.mjs";
4
+ import "./utils-Cp76gCyk.mjs";
5
+ import { n as isRecord } from "./type-guards-B9VVjRDK.mjs";
6
+ import { t as OAuthCallbackFlow } from "./callback-server-CQ5Jo8F-.mjs";
7
+ import { t as generatePKCE } from "./pkce-BlQikGPu.mjs";
8
+ import { i as OPENAI_HEADER_VALUES } from "./codex-P1dGpX7G.mjs";
9
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/openai-codex.ts
10
+ /**
11
+ * OpenAI Codex (ChatGPT OAuth) flow — browser and device-code flows.
12
+ */
13
+ const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
14
+ const AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize";
15
+ const TOKEN_URL = "https://auth.openai.com/oauth/token";
16
+ const CALLBACK_PORT = 1455;
17
+ const CALLBACK_PATH = "/auth/callback";
18
+ const SCOPE = "openid profile email offline_access api.connectors.read api.connectors.invoke";
19
+ const JWT_CLAIM_PATH = "https://api.openai.com/auth";
20
+ const JWT_PROFILE_CLAIM = "https://api.openai.com/profile";
21
+ const TOKEN_REQUEST_TIMEOUT_MS = 15e3;
22
+ const DEVICE_USERCODE_URL = "https://auth.openai.com/api/accounts/deviceauth/usercode";
23
+ const DEVICE_TOKEN_URL = "https://auth.openai.com/api/accounts/deviceauth/token";
24
+ const DEVICE_REDIRECT_URI = "https://auth.openai.com/deviceauth/callback";
25
+ const DEVICE_AUTH_URL = "https://auth.openai.com/codex/device";
26
+ const DEVICE_POLL_INTERVAL_MS = 5e3;
27
+ const DEVICE_POLL_SAFETY_MARGIN_MS = 3e3;
28
+ /** Upper bound on device-code polling to avoid infinite loops on server errors. */
29
+ const DEVICE_MAX_POLLS = 120;
30
+ function decodeJwt(token) {
31
+ try {
32
+ const parts = token.split(".");
33
+ if (parts.length !== 3) return null;
34
+ const payload = parts[1] ?? "";
35
+ const decoded = Buffer.from(payload, "base64").toString("utf-8");
36
+ return JSON.parse(decoded);
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+ /**
42
+ * Identity slice decoded from the token claims. The ChatGPT workspace
43
+ * (`chatgpt_account_id`) is the subscription pool the token draws limits
44
+ * from — one account email can hold several (e.g. a personal Pro plan plus a
45
+ * Team seat). `chatgpt_plan_type` may only be present on the `id_token`.
46
+ */
47
+ function getTokenProfile(accessToken, idToken) {
48
+ const payload = decodeJwt(accessToken);
49
+ const idPayload = idToken ? decodeJwt(idToken) : null;
50
+ const auth = payload?.[JWT_CLAIM_PATH];
51
+ const idAuth = idPayload?.[JWT_CLAIM_PATH];
52
+ const accountId = auth?.chatgpt_account_id;
53
+ const email = payload?.[JWT_PROFILE_CLAIM]?.email?.trim().toLowerCase();
54
+ const planType = (auth?.chatgpt_plan_type ?? idAuth?.chatgpt_plan_type)?.trim().toLowerCase();
55
+ return {
56
+ accountId: typeof accountId === "string" && accountId.length > 0 ? accountId : void 0,
57
+ email: typeof email === "string" && email.length > 0 ? email : void 0,
58
+ planType: typeof planType === "string" && planType.length > 0 ? planType : void 0
59
+ };
60
+ }
61
+ function describeTokenEndpointValue(value) {
62
+ if (typeof value === "string") {
63
+ const trimmed = value.trim();
64
+ return trimmed.length > 0 ? trimmed : void 0;
65
+ }
66
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
67
+ if (!isRecord(value)) return void 0;
68
+ const code = describeTokenEndpointValue(value.code ?? value.error);
69
+ const message = describeTokenEndpointValue(value.message ?? value.error_description ?? value.description);
70
+ if (code && message && code !== message) return `${code}: ${message}`;
71
+ return code ?? message ?? JSON.stringify(value);
72
+ }
73
+ /** Formats OpenAI Codex OAuth token endpoint errors for login and refresh failures. */
74
+ function formatOpenAICodexTokenEndpointError(status, bodyText) {
75
+ const trimmed = bodyText.trim();
76
+ if (trimmed.length === 0) return `${status}`;
77
+ try {
78
+ const body = JSON.parse(trimmed);
79
+ if (!isRecord(body)) return `${status} ${trimmed}`;
80
+ const error = describeTokenEndpointValue(body.error);
81
+ const description = describeTokenEndpointValue(body.error_description);
82
+ if (error && description && error !== description) return `${status} ${error}: ${description}`;
83
+ return `${status} ${error ?? description ?? describeTokenEndpointValue(body.message) ?? trimmed}`;
84
+ } catch {
85
+ return `${status} ${trimmed}`;
86
+ }
87
+ }
88
+ /** Builds the Codex browser OAuth URL used by browser login; exported for auth regression tests. */
89
+ function createOpenAICodexAuthorizationUrl(args) {
90
+ const originator = args.originator?.trim() || OPENAI_HEADER_VALUES.ORIGINATOR_CODEX;
91
+ const searchParams = new URLSearchParams({
92
+ response_type: "code",
93
+ client_id: CLIENT_ID,
94
+ redirect_uri: args.redirectUri,
95
+ scope: SCOPE,
96
+ code_challenge: args.challenge,
97
+ code_challenge_method: "S256",
98
+ state: args.state,
99
+ id_token_add_organizations: "true",
100
+ codex_cli_simplified_flow: "true",
101
+ originator
102
+ });
103
+ return `${AUTHORIZE_URL}?${searchParams.toString()}`;
104
+ }
105
+ var OpenAICodexOAuthFlow = class extends OAuthCallbackFlow {
106
+ #pkce;
107
+ #originator;
108
+ #fetch;
109
+ constructor(ctrl, pkce, originator, fetchImpl) {
110
+ super(ctrl, {
111
+ preferredPort: CALLBACK_PORT,
112
+ callbackPath: CALLBACK_PATH,
113
+ redirectUri: `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`
114
+ });
115
+ this.#pkce = pkce;
116
+ this.#originator = originator;
117
+ this.#fetch = fetchImpl;
118
+ }
119
+ async generateAuthUrl(state, redirectUri) {
120
+ return {
121
+ url: createOpenAICodexAuthorizationUrl({
122
+ state,
123
+ redirectUri,
124
+ challenge: this.#pkce.challenge,
125
+ originator: this.#originator
126
+ }),
127
+ instructions: "A browser window should open. Complete login to finish."
128
+ };
129
+ }
130
+ async exchangeToken(code, _state, redirectUri) {
131
+ return exchangeCodeForToken(code, this.#pkce.verifier, redirectUri, this.#fetch);
132
+ }
133
+ };
134
+ async function exchangeCodeForToken(code, verifier, redirectUri, fetchImpl = fetch) {
135
+ const tokenResponse = await fetchImpl(TOKEN_URL, {
136
+ method: "POST",
137
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
138
+ body: new URLSearchParams({
139
+ grant_type: "authorization_code",
140
+ client_id: CLIENT_ID,
141
+ code,
142
+ code_verifier: verifier,
143
+ redirect_uri: redirectUri
144
+ }),
145
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
146
+ });
147
+ if (!tokenResponse.ok) {
148
+ const bodyText = await tokenResponse.text();
149
+ throw new OAuthError(`Token exchange failed: ${formatOpenAICodexTokenEndpointError(tokenResponse.status, bodyText)}`, {
150
+ kind: "token-exchange",
151
+ status: tokenResponse.status
152
+ });
153
+ }
154
+ const tokenData = await tokenResponse.json();
155
+ if (!tokenData.access_token || !tokenData.refresh_token || typeof tokenData.expires_in !== "number") throw new OAuthError("Token response missing required fields", { kind: "validation" });
156
+ const { accountId, email, planType } = getTokenProfile(tokenData.access_token, tokenData.id_token);
157
+ if (!accountId) throw new OAuthError("Failed to extract accountId from token", { kind: "validation" });
158
+ return {
159
+ access: tokenData.access_token,
160
+ refresh: tokenData.refresh_token,
161
+ expires: Date.now() + tokenData.expires_in * 1e3,
162
+ accountId,
163
+ email,
164
+ orgId: accountId,
165
+ orgName: planType
166
+ };
167
+ }
168
+ async function loginOpenAICodex(options) {
169
+ return new OpenAICodexOAuthFlow(options, await generatePKCE(), options.originator?.trim() || OPENAI_HEADER_VALUES.ORIGINATOR_CODEX, options.fetch ?? fetch).login();
170
+ }
171
+ /**
172
+ * Login with OpenAI Codex using the device-code (headless) flow.
173
+ *
174
+ * Avoids a local callback server entirely — useful when port 1455 is unavailable
175
+ * or when the browser callback flow fails with 403 (e.g. network/proxy issues).
176
+ */
177
+ async function loginOpenAICodexDevice(ctrl) {
178
+ ctrl.onProgress?.("Initiating device authorization…");
179
+ const initResponse = await fetch(DEVICE_USERCODE_URL, {
180
+ method: "POST",
181
+ headers: { "Content-Type": "application/json" },
182
+ body: JSON.stringify({ client_id: CLIENT_ID }),
183
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
184
+ });
185
+ if (!initResponse.ok) throw new OAuthError(`Device authorization initiation failed: ${initResponse.status}`, {
186
+ kind: "device-auth",
187
+ status: initResponse.status
188
+ });
189
+ const initData = await initResponse.json();
190
+ if (!initData.device_auth_id || !initData.user_code) throw new OAuthError("Device authorization response missing required fields", { kind: "validation" });
191
+ const userCode = initData.user_code;
192
+ const pollIntervalMs = (typeof initData.interval === "number" ? initData.interval : parseInt(String(initData.interval ?? "5"), 10) || 5) * 1e3 + DEVICE_POLL_SAFETY_MARGIN_MS;
193
+ ctrl.onAuth?.({
194
+ url: DEVICE_AUTH_URL,
195
+ instructions: `Enter code: ${userCode}`
196
+ });
197
+ ctrl.onProgress?.(`Waiting for browser authorization (code: ${userCode})…`);
198
+ for (let poll = 0; poll < DEVICE_MAX_POLLS; poll++) {
199
+ await Bun.sleep(poll === 0 ? Math.min(pollIntervalMs, DEVICE_POLL_INTERVAL_MS) : pollIntervalMs);
200
+ if (ctrl.signal?.aborted) throw new LoginCancelledError("Device authorization cancelled");
201
+ const pollResponse = await fetch(DEVICE_TOKEN_URL, {
202
+ method: "POST",
203
+ headers: { "Content-Type": "application/json" },
204
+ body: JSON.stringify({
205
+ device_auth_id: initData.device_auth_id,
206
+ user_code: userCode
207
+ }),
208
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
209
+ });
210
+ if (pollResponse.status === 403 || pollResponse.status === 404) continue;
211
+ if (!pollResponse.ok) throw new OAuthError(`Device token polling failed: ${pollResponse.status}`, {
212
+ kind: "polling",
213
+ status: pollResponse.status
214
+ });
215
+ const pollData = await pollResponse.json();
216
+ if (!pollData.authorization_code || !pollData.code_verifier) throw new OAuthError("Device token response missing authorization_code or code_verifier", { kind: "validation" });
217
+ ctrl.onProgress?.("Exchanging authorization code for tokens…");
218
+ return exchangeCodeForToken(pollData.authorization_code, pollData.code_verifier, DEVICE_REDIRECT_URI);
219
+ }
220
+ throw new OAuthError("Device authorization timed out — user did not complete login in time", { kind: "timeout" });
221
+ }
222
+ /**
223
+ * Refresh OpenAI Codex OAuth token
224
+ */
225
+ async function refreshOpenAICodexToken(refreshToken) {
226
+ const response = await fetch(TOKEN_URL, {
227
+ method: "POST",
228
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
229
+ body: new URLSearchParams({
230
+ grant_type: "refresh_token",
231
+ refresh_token: refreshToken,
232
+ client_id: CLIENT_ID
233
+ }),
234
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
235
+ });
236
+ if (!response.ok) {
237
+ const bodyText = await response.text();
238
+ throw new OAuthError(`OpenAI Codex token refresh failed: ${formatOpenAICodexTokenEndpointError(response.status, bodyText)}`, {
239
+ kind: "token-refresh",
240
+ status: response.status
241
+ });
242
+ }
243
+ const tokenData = await response.json();
244
+ if (!tokenData.access_token || !tokenData.refresh_token || typeof tokenData.expires_in !== "number") throw new OAuthError("Token response missing required fields", { kind: "validation" });
245
+ const { accountId, email } = getTokenProfile(tokenData.access_token);
246
+ return {
247
+ access: tokenData.access_token,
248
+ refresh: tokenData.refresh_token || refreshToken,
249
+ expires: Date.now() + tokenData.expires_in * 1e3,
250
+ accountId: accountId ?? void 0,
251
+ email
252
+ };
253
+ }
254
+ //#endregion
255
+ export { loginOpenAICodex, loginOpenAICodexDevice, refreshOpenAICodexToken };