@xiaoso/dsh-tool-plus 0.1.0-beta.3 → 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 (155) hide show
  1. package/lib/abort-D1_Z5Ut5.mjs +51 -0
  2. package/lib/abort-dIkZBV7Q.mjs +51 -0
  3. package/lib/amazon-bedrock-B0nxT06F.mjs +917 -0
  4. package/lib/amazon-bedrock-WQhvjHYu.mjs +917 -0
  5. package/lib/anthropic-CJCauvYz.mjs +3115 -0
  6. package/lib/anthropic-CZghe_9U.mjs +3115 -0
  7. package/lib/anthropic-sCMH7JID.mjs +262 -0
  8. package/lib/anthropic-tTntD8BD.mjs +262 -0
  9. package/lib/api-key-login-BzqNdM2y.mjs +157 -0
  10. package/lib/api-key-login-CWVwvHT1.mjs +157 -0
  11. package/lib/aws-credentials-CXryMobh.mjs +867 -0
  12. package/lib/aws-credentials-ChG79ey-.mjs +867 -0
  13. package/lib/azure-openai-responses-Cgmc-rbL.mjs +274 -0
  14. package/lib/azure-openai-responses-DuukbD0F.mjs +274 -0
  15. package/lib/bun-shim.mjs +81 -6
  16. package/lib/bundled-references-Cavaffah.mjs +55 -0
  17. package/lib/bundled-references-sLN0YdXU.mjs +55 -0
  18. package/lib/callback-server-CQ5Jo8F-.mjs +398 -0
  19. package/lib/callback-server-DDSrZ6l_.mjs +398 -0
  20. package/lib/client.js +1 -1
  21. package/lib/cursor-B3zg7EHj.mjs +273 -0
  22. package/lib/cursor-B6TUEmgP.mjs +135 -0
  23. package/lib/cursor-D8gvtTL3.mjs +135 -0
  24. package/lib/cursor-DkSX2h3H.mjs +5441 -0
  25. package/lib/cursor-aJrXeYCb.mjs +273 -0
  26. package/lib/cursor-mJQwUKXK.mjs +5441 -0
  27. package/lib/device-code-DBo3B5nh.mjs +51 -0
  28. package/lib/device-code-DIb0FU-H.mjs +51 -0
  29. package/lib/devin-BHZZyMhO.mjs +95 -0
  30. package/lib/devin-BK7DHeca.mjs +114 -0
  31. package/lib/devin-CfMp3cXS.mjs +95 -0
  32. package/lib/devin-D9zR5B_R.mjs +542 -0
  33. package/lib/devin-Q1yem3lp.mjs +114 -0
  34. package/lib/devin-vNZTNUON.mjs +542 -0
  35. package/lib/error-Dd8DIqs-.mjs +1449 -0
  36. package/lib/error-yCSG0mGC.mjs +1449 -0
  37. package/lib/event-stream-BbFZJy-z.mjs +151 -0
  38. package/lib/event-stream-loUa0s1T.mjs +151 -0
  39. package/lib/fs-promises-shim-Bx0fpxuk.mjs +57 -0
  40. package/lib/github-copilot-B1yiyVRh.mjs +104 -0
  41. package/lib/github-copilot-BWT3eAOF.mjs +208 -0
  42. package/lib/github-copilot-CYkjeTi3.mjs +208 -0
  43. package/lib/github-copilot-jscUZ8Hf.mjs +104 -0
  44. package/lib/gitlab-duo-CM7Ref1H.mjs +155 -0
  45. package/lib/gitlab-duo-gubO4FNw.mjs +155 -0
  46. package/lib/gitlab-duo-workflow-BGAF6JDw.mjs +91 -0
  47. package/lib/gitlab-duo-workflow-D78tdn8E.mjs +91 -0
  48. package/lib/google-BS4T25Pn.mjs +30 -0
  49. package/lib/google-TFe-7-of.mjs +30 -0
  50. package/lib/google-antigravity-DGmwC2KV.mjs +198 -0
  51. package/lib/google-antigravity-DNYhgTpA.mjs +198 -0
  52. package/lib/google-auth-B6gjsZvg.mjs +232 -0
  53. package/lib/google-auth-De7_s3eo.mjs +232 -0
  54. package/lib/google-gemini-cli-CWu8HvXW.mjs +211 -0
  55. package/lib/google-gemini-cli-Cb97bzQc.mjs +850 -0
  56. package/lib/google-gemini-cli-Cqds_Q5T.mjs +850 -0
  57. package/lib/google-gemini-cli-Dsztq0N5.mjs +211 -0
  58. package/lib/google-oauth-shared-CuEHaDDj.mjs +147 -0
  59. package/lib/google-oauth-shared-yqlyqPPC.mjs +147 -0
  60. package/lib/google-shared-CgKmmdO3.mjs +760 -0
  61. package/lib/google-shared-Dr-VG-ap.mjs +760 -0
  62. package/lib/google-vertex-BDN2tLaD.mjs +99 -0
  63. package/lib/google-vertex-DopVOQOG.mjs +99 -0
  64. package/lib/identity-Da1GPU9a.mjs +219 -0
  65. package/lib/identity-xRP7_eSR.mjs +219 -0
  66. package/lib/idle-iterator-Baoyn3Hp.mjs +366 -0
  67. package/lib/idle-iterator-DUjKQEGT.mjs +366 -0
  68. package/lib/index.mjs +1731 -1178
  69. package/lib/kimi--wUOWER5.mjs +236 -0
  70. package/lib/kimi-Dh0pv3WZ.mjs +236 -0
  71. package/lib/markit-BL3cH47U.mjs +1417 -0
  72. package/lib/markit-BNiNY6SE.mjs +1417 -0
  73. package/lib/minimax-code-DCbuA6Yk.mjs +53 -0
  74. package/lib/minimax-code-Uq8Qu9LW.mjs +53 -0
  75. package/lib/models-D_XnT6ay.mjs +104660 -0
  76. package/lib/models-SGASygJ3.mjs +104660 -0
  77. package/lib/ollama-DPzBmq89.mjs +589 -0
  78. package/lib/ollama-DoBz5SFm.mjs +589 -0
  79. package/lib/openai-codex-Bi-4S4PX.mjs +255 -0
  80. package/lib/openai-codex-Ch8CkT3p.mjs +255 -0
  81. package/lib/openai-codex-responses-CvxL_FMF.mjs +3144 -0
  82. package/lib/openai-codex-responses-pejZgdZo.mjs +3144 -0
  83. package/lib/openai-completions-CF8IyNtP.mjs +1360 -0
  84. package/lib/openai-completions-DIf361kF.mjs +1360 -0
  85. package/lib/openai-reasoning-fallback-Nj6yB2rY.mjs +286 -0
  86. package/lib/openai-reasoning-fallback-OdJREP1o.mjs +286 -0
  87. package/lib/openai-responses-BqXJInHX.mjs +867 -0
  88. package/lib/openai-responses-Db_a-U4-.mjs +867 -0
  89. package/lib/opencode-DhMolSoB.mjs +38 -0
  90. package/lib/opencode-Rq_Q2vAO.mjs +38 -0
  91. package/lib/perplexity-C4iLVMUj.mjs +194 -0
  92. package/lib/perplexity-Uu7Jzg5b.mjs +194 -0
  93. package/lib/proxy-DDqrmjjC.mjs +190 -0
  94. package/lib/proxy-pM_NIv-H.mjs +190 -0
  95. package/lib/request-debug-HJMoJncL.mjs +183 -0
  96. package/lib/sanitize-text-CfcXzw5X.mjs +33 -0
  97. package/lib/scrapers-BkFfcPHj.mjs +9198 -0
  98. package/lib/scrapers-CVptboMs.mjs +9198 -0
  99. package/lib/scrapers-nhQAvc8d.mjs +9198 -0
  100. package/lib/shell-snapshot-fn-env.sh +67 -43
  101. package/lib/src-BgpusnsB.mjs +5076 -0
  102. package/lib/src-lDmkSRbm.mjs +5006 -0
  103. package/lib/stream-BlldLkVq.mjs +10236 -0
  104. package/lib/stream-CRtexYLe.mjs +10236 -0
  105. package/lib/stream-markup-healing-DMsxBx1L.mjs +491 -0
  106. package/lib/stream-markup-healing-KMkiAA00.mjs +491 -0
  107. package/lib/turndown-DN7ByzEI.mjs +667 -0
  108. package/lib/types/config/settings.d.ts +9 -1
  109. package/lib/types/config/truncate.d.ts +9 -5
  110. package/lib/types/tools/bash/background.d.ts +1 -1
  111. package/lib/types/tools/bash/bash-executor.d.ts +4 -0
  112. package/lib/types/tools/bash/bash-interceptor.d.ts +10 -8
  113. package/lib/types/tools/bash/cd-workdir.d.ts +35 -0
  114. package/lib/types/tools/bash/non-interactive-env.d.ts +2 -0
  115. package/lib/types/tools/bash/render.d.ts +4 -3
  116. package/lib/types/tools/bash/sanitize-text.d.ts +5 -0
  117. package/lib/types/tools/bash/shell-snapshot.d.ts +4 -1
  118. package/lib/types/tools/bash/shell-tokenize.d.ts +60 -0
  119. package/lib/types/tools/bash/streaming-output.d.ts +12 -212
  120. package/lib/types/tools/bash/which.d.ts +20 -0
  121. package/lib/types/tools/bash/windows-shell.d.ts +31 -0
  122. package/lib/types/tools/edit/adapter/index.d.ts +25 -3
  123. package/lib/types/tools/edit/adapter/tools/auto-generated-guard.d.ts +7 -17
  124. package/lib/types/tools/glob/adapter/index.d.ts +27 -1
  125. package/lib/types/tools/grep/adapter/index.d.ts +29 -1
  126. package/lib/types/tools/omp/edit/dispatch.d.ts +43 -0
  127. package/lib/types/tools/omp/edit/hashline/noop-loop-guard.d.ts +3 -1
  128. package/lib/types/tools/omp/tools/auto-generated-guard.d.ts +20 -0
  129. package/lib/types/tools/omp/tools/write.d.ts +4 -4
  130. package/lib/types/tools/shared/auto-generated-guard.dsh.d.ts +16 -4
  131. package/lib/types/tools/shared/bun-shim.d.ts +4 -0
  132. package/lib/types/tools/shared/fs-promises-shim.d.ts +3 -1
  133. package/lib/types/tools/shared/omp-prompt.d.ts +13 -7
  134. package/lib/types/tools/shared/session-state.d.ts +9 -3
  135. package/lib/utils-Bw139LTz.mjs +8119 -0
  136. package/lib/utils-CZw4tVZQ.mjs +12315 -0
  137. package/lib/utils-CiGN7OHR.mjs +12315 -0
  138. package/lib/utils-Cp76gCyk.mjs +8119 -0
  139. package/lib/utils-D0GRDgAr.mjs +12315 -0
  140. package/lib/utils-D2YknRk4.mjs +51 -0
  141. package/lib/utils-DzXZDfYc.mjs +51 -0
  142. package/lib/vision-guard-01qSwFpf.mjs +92 -0
  143. package/lib/vision-guard-DzZGaOga.mjs +92 -0
  144. package/lib/wafer-CgtPHerf.mjs +17 -0
  145. package/lib/wafer-cBtrn6q9.mjs +17 -0
  146. package/lib/xai-oauth-Buk8XVvM.mjs +446 -0
  147. package/lib/xai-oauth-CMal8l1O.mjs +446 -0
  148. package/lib/xiaomi-CZgwvX2G.mjs +157 -0
  149. package/lib/xiaomi-D2qT5cAC.mjs +157 -0
  150. package/lib/zai-7DWMkEqM.mjs +203 -0
  151. package/lib/zai-C59YnomG.mjs +203 -0
  152. package/lib/zip-Cg9ANN_U.mjs +1316 -0
  153. package/lib/zip-D36ZKsP8.mjs +1316 -0
  154. package/package.json +1 -1
  155. package/presets/package.json +1 -1
@@ -0,0 +1,232 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { F as $envpos, S as debug, y as isEnoent } from "./src-BgpusnsB.mjs";
4
+ import { c as OAuthError, g as MissingApiKeyError, t as ConfigurationError } from "./error-Dd8DIqs-.mjs";
5
+ import { n as raceWithSignal } from "./abort-dIkZBV7Q.mjs";
6
+ import * as path from "node:path";
7
+ import * as os from "node:os";
8
+ import { Buffer } from "node:buffer";
9
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/google-auth.ts
10
+ /**
11
+ * Application Default Credentials (ADC) resolution for Vertex AI.
12
+ *
13
+ * Replaces `google-auth-library` with a direct WebCrypto + REST implementation.
14
+ * Sources, in priority order:
15
+ * 1. `GOOGLE_APPLICATION_CREDENTIALS` env → file with `type: "service_account"` (RS256 JWT exchange)
16
+ * or `type: "authorized_user"` (refresh-token exchange).
17
+ * 2. `~/.config/gcloud/application_default_credentials.json` (user ADC, same authorized_user flow).
18
+ * 3. GCE / Cloud Run metadata server (`metadata.google.internal`).
19
+ *
20
+ * Tokens are cached per source key and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` before expiry
21
+ * (default 60s). Concurrent callers waiting on a refresh share the same in-flight promise.
22
+ */
23
+ const OAUTH_TOKEN_URL = "https://oauth2.googleapis.com/token";
24
+ const METADATA_TOKEN_URL = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token";
25
+ const CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform";
26
+ const JWT_BEARER_GRANT = "urn:ietf:params:oauth:grant-type:jwt-bearer";
27
+ const tokenCache = /* @__PURE__ */ new Map();
28
+ const inflight = /* @__PURE__ */ new Map();
29
+ function getRefreshSkewMs() {
30
+ return $envpos("GOOGLE_VERTEX_REFRESH_SKEW_MS", 6e4);
31
+ }
32
+ function userAdcPath() {
33
+ return path.join(os.homedir(), ".config", "gcloud", "application_default_credentials.json");
34
+ }
35
+ async function readJsonFile(filePath) {
36
+ try {
37
+ return await Bun.file(filePath).json();
38
+ } catch (err) {
39
+ if (isEnoent(err)) return void 0;
40
+ throw err;
41
+ }
42
+ }
43
+ async function loadAdcCredentials() {
44
+ const gacPath = Bun.env.GOOGLE_APPLICATION_CREDENTIALS;
45
+ if (gacPath) {
46
+ const creds = await readJsonFile(gacPath);
47
+ if (!creds) throw new ConfigurationError(`GOOGLE_APPLICATION_CREDENTIALS points to a missing file: ${gacPath}`);
48
+ return {
49
+ source: `gac:${gacPath}`,
50
+ creds
51
+ };
52
+ }
53
+ const userPath = userAdcPath();
54
+ const creds = await readJsonFile(userPath);
55
+ if (creds) return {
56
+ source: `user:${userPath}`,
57
+ creds
58
+ };
59
+ }
60
+ function base64UrlEncode(bytes) {
61
+ const buf = typeof bytes === "string" ? Buffer.from(bytes, "utf8") : bytes;
62
+ return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).toString("base64url");
63
+ }
64
+ function pemToPkcs8(pem) {
65
+ const body = pem.replace(/-----BEGIN [^-]+-----/g, "").replace(/-----END [^-]+-----/g, "").replace(/\s+/g, "");
66
+ if (!body) throw new ConfigurationError("Invalid PEM: empty body");
67
+ return Uint8Array.fromBase64(body);
68
+ }
69
+ async function signJwtRs256(claims, privateKeyPem, keyId) {
70
+ const header = {
71
+ alg: "RS256",
72
+ typ: "JWT"
73
+ };
74
+ if (keyId) header.kid = keyId;
75
+ const payload = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(claims))}`;
76
+ const key = await globalThis.crypto.subtle.importKey("pkcs8", pemToPkcs8(privateKeyPem), {
77
+ name: "RSASSA-PKCS1-v1_5",
78
+ hash: "SHA-256"
79
+ }, false, ["sign"]);
80
+ return `${payload}.${base64UrlEncode(new Uint8Array(await globalThis.crypto.subtle.sign("RSASSA-PKCS1-v1_5", key, new TextEncoder().encode(payload))))}`;
81
+ }
82
+ async function exchangeJwtForToken(creds, signal, fetchImpl) {
83
+ const now = Math.floor(Date.now() / 1e3);
84
+ const assertion = await signJwtRs256({
85
+ iss: creds.client_email,
86
+ scope: CLOUD_PLATFORM_SCOPE,
87
+ aud: OAUTH_TOKEN_URL,
88
+ exp: now + 3600,
89
+ iat: now
90
+ }, creds.private_key, creds.private_key_id);
91
+ const body = new URLSearchParams({
92
+ grant_type: JWT_BEARER_GRANT,
93
+ assertion
94
+ });
95
+ return postForToken(OAUTH_TOKEN_URL, body, signal, fetchImpl);
96
+ }
97
+ async function exchangeRefreshToken(creds, signal, fetchImpl) {
98
+ const body = new URLSearchParams({
99
+ client_id: creds.client_id,
100
+ client_secret: creds.client_secret,
101
+ refresh_token: creds.refresh_token,
102
+ grant_type: "refresh_token"
103
+ });
104
+ return postForToken(OAUTH_TOKEN_URL, body, signal, fetchImpl);
105
+ }
106
+ async function fetchMetadataToken(signal, fetchImpl) {
107
+ const timeout = AbortSignal.timeout(2e3);
108
+ const combined = signal ? AbortSignal.any([signal, timeout]) : timeout;
109
+ try {
110
+ const response = await fetchImpl(METADATA_TOKEN_URL, {
111
+ method: "GET",
112
+ headers: { "Metadata-Flavor": "Google" },
113
+ signal: combined
114
+ });
115
+ if (!response.ok) return void 0;
116
+ return await response.json();
117
+ } catch {
118
+ return;
119
+ }
120
+ }
121
+ async function postForToken(url, body, signal, fetchImpl) {
122
+ const response = await fetchImpl(url, {
123
+ method: "POST",
124
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
125
+ body: body.toString(),
126
+ signal
127
+ });
128
+ if (!response.ok) {
129
+ const detail = await response.text().catch(() => "");
130
+ throw new OAuthError(`Google OAuth token exchange failed (${response.status}): ${detail}`, {
131
+ kind: "token-exchange",
132
+ provider: "google-vertex",
133
+ status: response.status
134
+ });
135
+ }
136
+ return await response.json();
137
+ }
138
+ async function resolveAccessTokenUncached(signal, fetchImpl) {
139
+ const adc = await loadAdcCredentials();
140
+ if (adc) {
141
+ const creds = adc.creds;
142
+ let token;
143
+ if (creds.type === "impersonated_service_account") {
144
+ const targetPrincipal = /(?<target>[^/]+):(generateAccessToken|generateIdToken)$/.exec(creds.service_account_impersonation_url)?.groups?.target;
145
+ if (!targetPrincipal) throw new RangeError(`Cannot extract target principal from ${creds.service_account_impersonation_url}`);
146
+ const sourceToken = creds.source_credentials.type === "service_account" ? await exchangeJwtForToken(creds.source_credentials, signal, fetchImpl) : await exchangeRefreshToken(creds.source_credentials, signal, fetchImpl);
147
+ const response = await fetchImpl(`https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${targetPrincipal}:generateAccessToken`, {
148
+ method: "POST",
149
+ headers: {
150
+ "Content-Type": "application/json",
151
+ Authorization: `Bearer ${sourceToken.access_token}`
152
+ },
153
+ body: JSON.stringify({
154
+ delegates: creds.delegates ?? [],
155
+ scope: [CLOUD_PLATFORM_SCOPE],
156
+ lifetime: "3600s"
157
+ }),
158
+ signal
159
+ });
160
+ if (!response.ok) {
161
+ const detail = await response.text().catch(() => "");
162
+ throw new OAuthError(`Google Impersonation token exchange failed (${response.status}): ${detail}`, {
163
+ kind: "token-exchange",
164
+ provider: "google-vertex",
165
+ status: response.status
166
+ });
167
+ }
168
+ const data = await response.json();
169
+ const expiresIn = Math.max(0, Math.floor((new Date(data.expireTime).getTime() - Date.now()) / 1e3));
170
+ token = {
171
+ access_token: data.accessToken,
172
+ expires_in: expiresIn,
173
+ token_type: "Bearer"
174
+ };
175
+ } else token = creds.type === "service_account" ? await exchangeJwtForToken(creds, signal, fetchImpl) : await exchangeRefreshToken(creds, signal, fetchImpl);
176
+ return {
177
+ source: adc.source,
178
+ token
179
+ };
180
+ }
181
+ const metadata = await fetchMetadataToken(signal, fetchImpl);
182
+ if (metadata) return {
183
+ source: "metadata",
184
+ token: metadata
185
+ };
186
+ throw new MissingApiKeyError(void 0, "Vertex AI requires Application Default Credentials. Set GOOGLE_APPLICATION_CREDENTIALS, run `gcloud auth application-default login`, or run on a GCE/Cloud Run instance with a service account.");
187
+ }
188
+ /**
189
+ * Bound for the detached (signal-free) shared token resolution: a hung OAuth
190
+ * exchange or metadata fetch must not pin the inflight slot forever — every
191
+ * later call would await the stuck promise until process restart.
192
+ */
193
+ const SHARED_TOKEN_RESOLVE_TIMEOUT_MS = 3e4;
194
+ /**
195
+ * Returns a Bearer access token suitable for the `Authorization` header on Vertex AI calls.
196
+ * The token is cached in module scope and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` ms before it expires.
197
+ */
198
+ async function getVertexAccessToken(options) {
199
+ const explicitToken = Bun.env.GOOGLE_CLOUD_ACCESS_TOKEN || Bun.env.CLOUDSDK_AUTH_ACCESS_TOKEN;
200
+ if (explicitToken) return explicitToken;
201
+ const fetchImpl = options?.fetch ?? globalThis.fetch.bind(globalThis);
202
+ const skew = getRefreshSkewMs();
203
+ const now = Date.now();
204
+ for (const [source, cached] of tokenCache) {
205
+ if (cached.expiresAtMs - skew > now) return cached.token;
206
+ tokenCache.delete(source);
207
+ }
208
+ const cacheKey = "vertex-adc";
209
+ const existing = inflight.get(cacheKey);
210
+ if (existing) return raceWithSignal(existing, options?.signal);
211
+ const promise = (async () => {
212
+ try {
213
+ const { source, token } = await resolveAccessTokenUncached(AbortSignal.timeout(SHARED_TOKEN_RESOLVE_TIMEOUT_MS), fetchImpl);
214
+ const expiresAtMs = Date.now() + Math.max(0, token.expires_in * 1e3);
215
+ tokenCache.set(source, {
216
+ token: token.access_token,
217
+ expiresAtMs
218
+ });
219
+ debug("vertex.adc acquired access token", {
220
+ source,
221
+ expiresInSec: token.expires_in
222
+ });
223
+ return token.access_token;
224
+ } finally {
225
+ inflight.delete(cacheKey);
226
+ }
227
+ })();
228
+ inflight.set(cacheKey, promise);
229
+ return raceWithSignal(promise, options?.signal);
230
+ }
231
+ //#endregion
232
+ export { getVertexAccessToken as t };
@@ -0,0 +1,232 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { F as $envpos, S as debug, y as isEnoent } from "./src-lDmkSRbm.mjs";
4
+ import { c as OAuthError, g as MissingApiKeyError, t as ConfigurationError } from "./error-yCSG0mGC.mjs";
5
+ import { n as raceWithSignal } from "./abort-D1_Z5Ut5.mjs";
6
+ import * as path from "node:path";
7
+ import * as os from "node:os";
8
+ import { Buffer } from "node:buffer";
9
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/providers/google-auth.ts
10
+ /**
11
+ * Application Default Credentials (ADC) resolution for Vertex AI.
12
+ *
13
+ * Replaces `google-auth-library` with a direct WebCrypto + REST implementation.
14
+ * Sources, in priority order:
15
+ * 1. `GOOGLE_APPLICATION_CREDENTIALS` env → file with `type: "service_account"` (RS256 JWT exchange)
16
+ * or `type: "authorized_user"` (refresh-token exchange).
17
+ * 2. `~/.config/gcloud/application_default_credentials.json` (user ADC, same authorized_user flow).
18
+ * 3. GCE / Cloud Run metadata server (`metadata.google.internal`).
19
+ *
20
+ * Tokens are cached per source key and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` before expiry
21
+ * (default 60s). Concurrent callers waiting on a refresh share the same in-flight promise.
22
+ */
23
+ const OAUTH_TOKEN_URL = "https://oauth2.googleapis.com/token";
24
+ const METADATA_TOKEN_URL = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token";
25
+ const CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform";
26
+ const JWT_BEARER_GRANT = "urn:ietf:params:oauth:grant-type:jwt-bearer";
27
+ const tokenCache = /* @__PURE__ */ new Map();
28
+ const inflight = /* @__PURE__ */ new Map();
29
+ function getRefreshSkewMs() {
30
+ return $envpos("GOOGLE_VERTEX_REFRESH_SKEW_MS", 6e4);
31
+ }
32
+ function userAdcPath() {
33
+ return path.join(os.homedir(), ".config", "gcloud", "application_default_credentials.json");
34
+ }
35
+ async function readJsonFile(filePath) {
36
+ try {
37
+ return await Bun.file(filePath).json();
38
+ } catch (err) {
39
+ if (isEnoent(err)) return void 0;
40
+ throw err;
41
+ }
42
+ }
43
+ async function loadAdcCredentials() {
44
+ const gacPath = Bun.env.GOOGLE_APPLICATION_CREDENTIALS;
45
+ if (gacPath) {
46
+ const creds = await readJsonFile(gacPath);
47
+ if (!creds) throw new ConfigurationError(`GOOGLE_APPLICATION_CREDENTIALS points to a missing file: ${gacPath}`);
48
+ return {
49
+ source: `gac:${gacPath}`,
50
+ creds
51
+ };
52
+ }
53
+ const userPath = userAdcPath();
54
+ const creds = await readJsonFile(userPath);
55
+ if (creds) return {
56
+ source: `user:${userPath}`,
57
+ creds
58
+ };
59
+ }
60
+ function base64UrlEncode(bytes) {
61
+ const buf = typeof bytes === "string" ? Buffer.from(bytes, "utf8") : bytes;
62
+ return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).toString("base64url");
63
+ }
64
+ function pemToPkcs8(pem) {
65
+ const body = pem.replace(/-----BEGIN [^-]+-----/g, "").replace(/-----END [^-]+-----/g, "").replace(/\s+/g, "");
66
+ if (!body) throw new ConfigurationError("Invalid PEM: empty body");
67
+ return Uint8Array.fromBase64(body);
68
+ }
69
+ async function signJwtRs256(claims, privateKeyPem, keyId) {
70
+ const header = {
71
+ alg: "RS256",
72
+ typ: "JWT"
73
+ };
74
+ if (keyId) header.kid = keyId;
75
+ const payload = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(claims))}`;
76
+ const key = await globalThis.crypto.subtle.importKey("pkcs8", pemToPkcs8(privateKeyPem), {
77
+ name: "RSASSA-PKCS1-v1_5",
78
+ hash: "SHA-256"
79
+ }, false, ["sign"]);
80
+ return `${payload}.${base64UrlEncode(new Uint8Array(await globalThis.crypto.subtle.sign("RSASSA-PKCS1-v1_5", key, new TextEncoder().encode(payload))))}`;
81
+ }
82
+ async function exchangeJwtForToken(creds, signal, fetchImpl) {
83
+ const now = Math.floor(Date.now() / 1e3);
84
+ const assertion = await signJwtRs256({
85
+ iss: creds.client_email,
86
+ scope: CLOUD_PLATFORM_SCOPE,
87
+ aud: OAUTH_TOKEN_URL,
88
+ exp: now + 3600,
89
+ iat: now
90
+ }, creds.private_key, creds.private_key_id);
91
+ const body = new URLSearchParams({
92
+ grant_type: JWT_BEARER_GRANT,
93
+ assertion
94
+ });
95
+ return postForToken(OAUTH_TOKEN_URL, body, signal, fetchImpl);
96
+ }
97
+ async function exchangeRefreshToken(creds, signal, fetchImpl) {
98
+ const body = new URLSearchParams({
99
+ client_id: creds.client_id,
100
+ client_secret: creds.client_secret,
101
+ refresh_token: creds.refresh_token,
102
+ grant_type: "refresh_token"
103
+ });
104
+ return postForToken(OAUTH_TOKEN_URL, body, signal, fetchImpl);
105
+ }
106
+ async function fetchMetadataToken(signal, fetchImpl) {
107
+ const timeout = AbortSignal.timeout(2e3);
108
+ const combined = signal ? AbortSignal.any([signal, timeout]) : timeout;
109
+ try {
110
+ const response = await fetchImpl(METADATA_TOKEN_URL, {
111
+ method: "GET",
112
+ headers: { "Metadata-Flavor": "Google" },
113
+ signal: combined
114
+ });
115
+ if (!response.ok) return void 0;
116
+ return await response.json();
117
+ } catch {
118
+ return;
119
+ }
120
+ }
121
+ async function postForToken(url, body, signal, fetchImpl) {
122
+ const response = await fetchImpl(url, {
123
+ method: "POST",
124
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
125
+ body: body.toString(),
126
+ signal
127
+ });
128
+ if (!response.ok) {
129
+ const detail = await response.text().catch(() => "");
130
+ throw new OAuthError(`Google OAuth token exchange failed (${response.status}): ${detail}`, {
131
+ kind: "token-exchange",
132
+ provider: "google-vertex",
133
+ status: response.status
134
+ });
135
+ }
136
+ return await response.json();
137
+ }
138
+ async function resolveAccessTokenUncached(signal, fetchImpl) {
139
+ const adc = await loadAdcCredentials();
140
+ if (adc) {
141
+ const creds = adc.creds;
142
+ let token;
143
+ if (creds.type === "impersonated_service_account") {
144
+ const targetPrincipal = /(?<target>[^/]+):(generateAccessToken|generateIdToken)$/.exec(creds.service_account_impersonation_url)?.groups?.target;
145
+ if (!targetPrincipal) throw new RangeError(`Cannot extract target principal from ${creds.service_account_impersonation_url}`);
146
+ const sourceToken = creds.source_credentials.type === "service_account" ? await exchangeJwtForToken(creds.source_credentials, signal, fetchImpl) : await exchangeRefreshToken(creds.source_credentials, signal, fetchImpl);
147
+ const response = await fetchImpl(`https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${targetPrincipal}:generateAccessToken`, {
148
+ method: "POST",
149
+ headers: {
150
+ "Content-Type": "application/json",
151
+ Authorization: `Bearer ${sourceToken.access_token}`
152
+ },
153
+ body: JSON.stringify({
154
+ delegates: creds.delegates ?? [],
155
+ scope: [CLOUD_PLATFORM_SCOPE],
156
+ lifetime: "3600s"
157
+ }),
158
+ signal
159
+ });
160
+ if (!response.ok) {
161
+ const detail = await response.text().catch(() => "");
162
+ throw new OAuthError(`Google Impersonation token exchange failed (${response.status}): ${detail}`, {
163
+ kind: "token-exchange",
164
+ provider: "google-vertex",
165
+ status: response.status
166
+ });
167
+ }
168
+ const data = await response.json();
169
+ const expiresIn = Math.max(0, Math.floor((new Date(data.expireTime).getTime() - Date.now()) / 1e3));
170
+ token = {
171
+ access_token: data.accessToken,
172
+ expires_in: expiresIn,
173
+ token_type: "Bearer"
174
+ };
175
+ } else token = creds.type === "service_account" ? await exchangeJwtForToken(creds, signal, fetchImpl) : await exchangeRefreshToken(creds, signal, fetchImpl);
176
+ return {
177
+ source: adc.source,
178
+ token
179
+ };
180
+ }
181
+ const metadata = await fetchMetadataToken(signal, fetchImpl);
182
+ if (metadata) return {
183
+ source: "metadata",
184
+ token: metadata
185
+ };
186
+ throw new MissingApiKeyError(void 0, "Vertex AI requires Application Default Credentials. Set GOOGLE_APPLICATION_CREDENTIALS, run `gcloud auth application-default login`, or run on a GCE/Cloud Run instance with a service account.");
187
+ }
188
+ /**
189
+ * Bound for the detached (signal-free) shared token resolution: a hung OAuth
190
+ * exchange or metadata fetch must not pin the inflight slot forever — every
191
+ * later call would await the stuck promise until process restart.
192
+ */
193
+ const SHARED_TOKEN_RESOLVE_TIMEOUT_MS = 3e4;
194
+ /**
195
+ * Returns a Bearer access token suitable for the `Authorization` header on Vertex AI calls.
196
+ * The token is cached in module scope and refreshed `GOOGLE_VERTEX_REFRESH_SKEW_MS` ms before it expires.
197
+ */
198
+ async function getVertexAccessToken(options) {
199
+ const explicitToken = Bun.env.GOOGLE_CLOUD_ACCESS_TOKEN || Bun.env.CLOUDSDK_AUTH_ACCESS_TOKEN;
200
+ if (explicitToken) return explicitToken;
201
+ const fetchImpl = options?.fetch ?? globalThis.fetch.bind(globalThis);
202
+ const skew = getRefreshSkewMs();
203
+ const now = Date.now();
204
+ for (const [source, cached] of tokenCache) {
205
+ if (cached.expiresAtMs - skew > now) return cached.token;
206
+ tokenCache.delete(source);
207
+ }
208
+ const cacheKey = "vertex-adc";
209
+ const existing = inflight.get(cacheKey);
210
+ if (existing) return raceWithSignal(existing, options?.signal);
211
+ const promise = (async () => {
212
+ try {
213
+ const { source, token } = await resolveAccessTokenUncached(AbortSignal.timeout(SHARED_TOKEN_RESOLVE_TIMEOUT_MS), fetchImpl);
214
+ const expiresAtMs = Date.now() + Math.max(0, token.expires_in * 1e3);
215
+ tokenCache.set(source, {
216
+ token: token.access_token,
217
+ expiresAtMs
218
+ });
219
+ debug("vertex.adc acquired access token", {
220
+ source,
221
+ expiresInSec: token.expires_in
222
+ });
223
+ return token.access_token;
224
+ } finally {
225
+ inflight.delete(cacheKey);
226
+ }
227
+ })();
228
+ inflight.set(cacheKey, promise);
229
+ return raceWithSignal(promise, options?.signal);
230
+ }
231
+ //#endregion
232
+ export { getVertexAccessToken as t };
@@ -0,0 +1,211 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { P as $env } from "./src-lDmkSRbm.mjs";
4
+ import { c as OAuthError } from "./error-yCSG0mGC.mjs";
5
+ import { i as getGeminiCliHeaders } from "./gemini-headers-DKUShltF.mjs";
6
+ import { n as runGoogleOAuthLogin, r as throwIfLoginCancelled, t as oauthFetch } from "./google-oauth-shared-yqlyqPPC.mjs";
7
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/google-gemini-cli.ts
8
+ /**
9
+ * Gemini CLI OAuth flow (Google Cloud Code Assist)
10
+ * Standard Gemini models only (gemini-2.0-flash, gemini-2.5-*)
11
+ */
12
+ const decode = (s) => atob(s);
13
+ const CLIENT_ID = decode("NjgxMjU1ODA5Mzk1LW9vOGZ0Mm9wcmRybnA5ZTNhcWY2YXYzaG1kaWIxMzVqLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29t");
14
+ const CLIENT_SECRET = decode("R09DU1BYLTR1SGdNUG0tMW83U2stZ2VWNkN1NWNsWEZzeGw=");
15
+ const CALLBACK_PORT = 8085;
16
+ const CALLBACK_PATH = "/oauth2callback";
17
+ const SCOPES = [
18
+ "https://www.googleapis.com/auth/cloud-platform",
19
+ "https://www.googleapis.com/auth/userinfo.email",
20
+ "https://www.googleapis.com/auth/userinfo.profile"
21
+ ];
22
+ const AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
23
+ const TOKEN_URL = "https://oauth2.googleapis.com/token";
24
+ const CODE_ASSIST_ENDPOINT = "https://cloudcode-pa.googleapis.com";
25
+ const TIER_FREE = "free-tier";
26
+ const TIER_LEGACY = "legacy-tier";
27
+ const TIER_STANDARD = "standard-tier";
28
+ function getDefaultTier(allowedTiers) {
29
+ if (!allowedTiers || allowedTiers.length === 0) return { id: TIER_LEGACY };
30
+ return allowedTiers.find((t) => t.isDefault) ?? { id: TIER_LEGACY };
31
+ }
32
+ function isVpcScAffectedUser(payload) {
33
+ if (!payload || typeof payload !== "object") return false;
34
+ if (!("error" in payload)) return false;
35
+ const error = payload.error;
36
+ if (!error?.details || !Array.isArray(error.details)) return false;
37
+ return error.details.some((detail) => detail.reason === "SECURITY_POLICY_VIOLATED");
38
+ }
39
+ /**
40
+ * LRO poll cadence and bound. Cloud Code Assist project provisioning normally
41
+ * completes within a handful of polls; the attempt cap converts a stuck
42
+ * `done: false` operation (or a service incident) into a bounded login error
43
+ * instead of the previous unbounded loop.
44
+ */
45
+ const POLL_INTERVAL_MS = 5e3;
46
+ async function pollOperation(operationName, headers, signal, onProgress) {
47
+ for (let attempt = 0; attempt < 24; attempt += 1) {
48
+ if (attempt > 0) {
49
+ onProgress?.(`Waiting for project provisioning (attempt ${attempt + 1}/24)...`);
50
+ throwIfLoginCancelled(signal);
51
+ await Bun.sleep(POLL_INTERVAL_MS);
52
+ }
53
+ throwIfLoginCancelled(signal);
54
+ const response = await oauthFetch(`${CODE_ASSIST_ENDPOINT}/v1internal/${operationName}`, {
55
+ method: "GET",
56
+ headers
57
+ }, {
58
+ provider: "google-gemini-cli",
59
+ signal
60
+ });
61
+ if (!response.ok) throw new OAuthError(`Failed to poll operation: ${response.status} ${response.statusText}`, {
62
+ kind: "polling",
63
+ provider: "google-gemini-cli",
64
+ status: response.status
65
+ });
66
+ const data = await response.json();
67
+ if (data.done) return data;
68
+ }
69
+ throw new OAuthError(`Project provisioning did not complete after 24 attempts`, {
70
+ kind: "timeout",
71
+ provider: "google-gemini-cli"
72
+ });
73
+ }
74
+ async function discoverProject(accessToken, onProgress, signal) {
75
+ const envProjectId = $env.GOOGLE_CLOUD_PROJECT || $env.GOOGLE_CLOUD_PROJECT_ID;
76
+ const headers = {
77
+ Authorization: `Bearer ${accessToken}`,
78
+ "Content-Type": "application/json",
79
+ ...getGeminiCliHeaders()
80
+ };
81
+ onProgress?.("Checking for existing Cloud Code Assist project...");
82
+ const loadResponse = await oauthFetch(`${CODE_ASSIST_ENDPOINT}/v1internal:loadCodeAssist`, {
83
+ method: "POST",
84
+ headers,
85
+ body: JSON.stringify({
86
+ cloudaicompanionProject: envProjectId,
87
+ metadata: {
88
+ ideType: "IDE_UNSPECIFIED",
89
+ platform: "PLATFORM_UNSPECIFIED",
90
+ pluginType: "GEMINI",
91
+ duetProject: envProjectId
92
+ }
93
+ })
94
+ }, {
95
+ provider: "google-gemini-cli",
96
+ signal
97
+ });
98
+ let data;
99
+ if (!loadResponse.ok) {
100
+ let errorPayload;
101
+ try {
102
+ errorPayload = await loadResponse.clone().json();
103
+ } catch {
104
+ errorPayload = void 0;
105
+ }
106
+ if (isVpcScAffectedUser(errorPayload)) data = { currentTier: { id: TIER_STANDARD } };
107
+ else {
108
+ const errorText = await loadResponse.text();
109
+ throw new OAuthError(`loadCodeAssist failed: ${loadResponse.status} ${loadResponse.statusText}: ${errorText}`, {
110
+ kind: "discovery",
111
+ provider: "google-gemini-cli",
112
+ status: loadResponse.status
113
+ });
114
+ }
115
+ } else data = await loadResponse.json();
116
+ if (data.currentTier) {
117
+ if (data.cloudaicompanionProject) return data.cloudaicompanionProject;
118
+ if (envProjectId) return envProjectId;
119
+ throw new OAuthError("This account requires setting the GOOGLE_CLOUD_PROJECT or GOOGLE_CLOUD_PROJECT_ID environment variable. See https://goo.gle/gemini-cli-auth-docs#workspace-gca", {
120
+ kind: "configuration",
121
+ provider: "google-gemini-cli"
122
+ });
123
+ }
124
+ const tierId = getDefaultTier(data.allowedTiers)?.id ?? TIER_FREE;
125
+ if (tierId !== TIER_FREE && !envProjectId) throw new OAuthError("This account requires setting the GOOGLE_CLOUD_PROJECT or GOOGLE_CLOUD_PROJECT_ID environment variable. See https://goo.gle/gemini-cli-auth-docs#workspace-gca", {
126
+ kind: "configuration",
127
+ provider: "google-gemini-cli"
128
+ });
129
+ onProgress?.("Provisioning Cloud Code Assist project (this may take a moment)...");
130
+ const onboardBody = {
131
+ tierId,
132
+ metadata: {
133
+ ideType: "IDE_UNSPECIFIED",
134
+ platform: "PLATFORM_UNSPECIFIED",
135
+ pluginType: "GEMINI"
136
+ }
137
+ };
138
+ if (tierId !== TIER_FREE && envProjectId) {
139
+ onboardBody.cloudaicompanionProject = envProjectId;
140
+ onboardBody.metadata.duetProject = envProjectId;
141
+ }
142
+ const onboardResponse = await oauthFetch(`${CODE_ASSIST_ENDPOINT}/v1internal:onboardUser`, {
143
+ method: "POST",
144
+ headers,
145
+ body: JSON.stringify(onboardBody)
146
+ }, {
147
+ provider: "google-gemini-cli",
148
+ signal
149
+ });
150
+ if (!onboardResponse.ok) {
151
+ const errorText = await onboardResponse.text();
152
+ throw new OAuthError(`onboardUser failed: ${onboardResponse.status} ${onboardResponse.statusText}: ${errorText}`, {
153
+ kind: "provisioning",
154
+ provider: "google-gemini-cli",
155
+ status: onboardResponse.status
156
+ });
157
+ }
158
+ let lroData = await onboardResponse.json();
159
+ if (!lroData.done && lroData.name) lroData = await pollOperation(lroData.name, headers, signal, onProgress);
160
+ const projectId = lroData.response?.cloudaicompanionProject?.id;
161
+ if (projectId) return projectId;
162
+ if (envProjectId) return envProjectId;
163
+ throw new OAuthError("Could not discover or provision a Google Cloud project. Try setting the GOOGLE_CLOUD_PROJECT or GOOGLE_CLOUD_PROJECT_ID environment variable. See https://goo.gle/gemini-cli-auth-docs#workspace-gca", {
164
+ kind: "validation",
165
+ provider: "google-gemini-cli"
166
+ });
167
+ }
168
+ async function loginGeminiCli(ctrl) {
169
+ return runGoogleOAuthLogin(ctrl, {
170
+ provider: "google-gemini-cli",
171
+ clientId: CLIENT_ID,
172
+ clientSecret: CLIENT_SECRET,
173
+ authUrl: AUTH_URL,
174
+ tokenUrl: TOKEN_URL,
175
+ scopes: SCOPES,
176
+ callbackPort: CALLBACK_PORT,
177
+ callbackPath: CALLBACK_PATH,
178
+ discoverProject
179
+ });
180
+ }
181
+ /**
182
+ * Refresh Google Cloud Code Assist token
183
+ */
184
+ async function refreshGoogleCloudToken(refreshToken, projectId) {
185
+ const response = await fetch(TOKEN_URL, {
186
+ method: "POST",
187
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
188
+ body: new URLSearchParams({
189
+ client_id: CLIENT_ID,
190
+ client_secret: CLIENT_SECRET,
191
+ refresh_token: refreshToken,
192
+ grant_type: "refresh_token"
193
+ })
194
+ });
195
+ if (!response.ok) {
196
+ const error = await response.text();
197
+ throw new OAuthError(`Google Cloud token refresh failed: ${error}`, {
198
+ kind: "token-refresh",
199
+ provider: "google-gemini-cli"
200
+ });
201
+ }
202
+ const data = await response.json();
203
+ return {
204
+ refresh: data.refresh_token || refreshToken,
205
+ access: data.access_token,
206
+ expires: Date.now() + data.expires_in * 1e3 - 3e5,
207
+ projectId
208
+ };
209
+ }
210
+ //#endregion
211
+ export { loginGeminiCli, refreshGoogleCloudToken };