@xiaoso/dsh-tool-plus 0.1.0-beta.2 → 0.1.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +122 -0
- package/README.md +3 -2
- package/THIRD_PARTY_NOTICES.md +4 -35
- package/lib/abort-B7izMMna.mjs +51 -0
- package/lib/abort-D1_Z5Ut5.mjs +51 -0
- package/lib/abort-dIkZBV7Q.mjs +51 -0
- package/lib/amazon-bedrock-B0nxT06F.mjs +917 -0
- package/lib/amazon-bedrock-D-shAr1X.mjs +917 -0
- package/lib/amazon-bedrock-WQhvjHYu.mjs +917 -0
- package/lib/anthropic-BWsZFzU8.mjs +262 -0
- package/lib/anthropic-CJCauvYz.mjs +3115 -0
- package/lib/anthropic-CMT1Qj1t.mjs +3115 -0
- package/lib/anthropic-CZghe_9U.mjs +3115 -0
- package/lib/anthropic-sCMH7JID.mjs +262 -0
- package/lib/anthropic-tTntD8BD.mjs +262 -0
- package/lib/api-key-login-BzqNdM2y.mjs +157 -0
- package/lib/api-key-login-CWVwvHT1.mjs +157 -0
- package/lib/api-key-login-CpzSezsi.mjs +157 -0
- package/lib/aws-credentials-8Mgn5MAy.mjs +867 -0
- package/lib/aws-credentials-CXryMobh.mjs +867 -0
- package/lib/aws-credentials-ChG79ey-.mjs +867 -0
- package/lib/azure-openai-responses-CNkHiLUh.mjs +274 -0
- package/lib/azure-openai-responses-Cgmc-rbL.mjs +274 -0
- package/lib/azure-openai-responses-DuukbD0F.mjs +274 -0
- package/lib/bun-shim.mjs +252 -12
- package/lib/bundled-references-CSuBco5p.mjs +55 -0
- package/lib/bundled-references-Cavaffah.mjs +55 -0
- package/lib/bundled-references-sLN0YdXU.mjs +55 -0
- package/lib/callback-server-BEFNf-jf.mjs +398 -0
- package/lib/callback-server-CQ5Jo8F-.mjs +398 -0
- package/lib/callback-server-DDSrZ6l_.mjs +398 -0
- package/lib/client.js +111 -41
- package/lib/cursor-B3zg7EHj.mjs +273 -0
- package/lib/cursor-B6TUEmgP.mjs +135 -0
- package/lib/cursor-BIQfBC6V.mjs +135 -0
- package/lib/cursor-D8gvtTL3.mjs +135 -0
- package/lib/cursor-DNk6eXDd.mjs +5470 -0
- package/lib/cursor-DkSX2h3H.mjs +5441 -0
- package/lib/cursor-MjSm74IJ.mjs +273 -0
- package/lib/cursor-aJrXeYCb.mjs +273 -0
- package/lib/cursor-mJQwUKXK.mjs +5441 -0
- package/lib/device-code-DBo3B5nh.mjs +51 -0
- package/lib/device-code-DIb0FU-H.mjs +51 -0
- package/lib/device-code-OI_tQcmc.mjs +51 -0
- package/lib/devin-BHZZyMhO.mjs +95 -0
- package/lib/devin-BK7DHeca.mjs +114 -0
- package/lib/devin-CfMp3cXS.mjs +95 -0
- package/lib/devin-CldyPD8K.mjs +95 -0
- package/lib/devin-CzRpTUOA.mjs +114 -0
- package/lib/devin-D9zR5B_R.mjs +542 -0
- package/lib/devin-DXOeNyU7.mjs +542 -0
- package/lib/devin-Q1yem3lp.mjs +114 -0
- package/lib/devin-vNZTNUON.mjs +542 -0
- package/lib/error-B3bevhrs.mjs +1449 -0
- package/lib/error-Dd8DIqs-.mjs +1449 -0
- package/lib/error-yCSG0mGC.mjs +1449 -0
- package/lib/event-stream-BDPi64mK.mjs +151 -0
- package/lib/event-stream-BbFZJy-z.mjs +151 -0
- package/lib/event-stream-loUa0s1T.mjs +151 -0
- package/lib/fs-promises-shim-Bx0fpxuk.mjs +57 -0
- package/lib/github-copilot-4GaMtQmg.mjs +208 -0
- package/lib/github-copilot-B1yiyVRh.mjs +104 -0
- package/lib/github-copilot-B2HGSIJK.mjs +104 -0
- package/lib/github-copilot-BWT3eAOF.mjs +208 -0
- package/lib/github-copilot-CYkjeTi3.mjs +208 -0
- package/lib/github-copilot-jscUZ8Hf.mjs +104 -0
- package/lib/gitlab-duo-CM7Ref1H.mjs +155 -0
- package/lib/gitlab-duo-akICyfeD.mjs +155 -0
- package/lib/gitlab-duo-gubO4FNw.mjs +155 -0
- package/lib/gitlab-duo-workflow-BGAF6JDw.mjs +91 -0
- package/lib/gitlab-duo-workflow-CSEgYk3N.mjs +91 -0
- package/lib/gitlab-duo-workflow-D78tdn8E.mjs +91 -0
- package/lib/google-BS4T25Pn.mjs +30 -0
- package/lib/google-TFe-7-of.mjs +30 -0
- package/lib/google-antigravity-DGmwC2KV.mjs +198 -0
- package/lib/google-antigravity-DNYhgTpA.mjs +198 -0
- package/lib/google-antigravity-Dlkdhahq.mjs +198 -0
- package/lib/google-auth-B6gjsZvg.mjs +232 -0
- package/lib/google-auth-De7_s3eo.mjs +232 -0
- package/lib/google-auth-DhqpOYrX.mjs +232 -0
- package/lib/google-gemini-cli-BG_LRdIV.mjs +850 -0
- package/lib/google-gemini-cli-CWu8HvXW.mjs +211 -0
- package/lib/google-gemini-cli-Cb97bzQc.mjs +850 -0
- package/lib/google-gemini-cli-Cqds_Q5T.mjs +850 -0
- package/lib/google-gemini-cli-Dsztq0N5.mjs +211 -0
- package/lib/google-gemini-cli-zJhiOcND.mjs +211 -0
- package/lib/google-oauth-shared-CuEHaDDj.mjs +147 -0
- package/lib/google-oauth-shared-CwNWYdmR.mjs +147 -0
- package/lib/google-oauth-shared-yqlyqPPC.mjs +147 -0
- package/lib/google-shared-CgKmmdO3.mjs +760 -0
- package/lib/google-shared-Dr-VG-ap.mjs +760 -0
- package/lib/google-shared-DzhCb9b0.mjs +760 -0
- package/lib/google-vertex-BDN2tLaD.mjs +99 -0
- package/lib/google-vertex-DopVOQOG.mjs +99 -0
- package/lib/google-vertex-kscbkyRb.mjs +99 -0
- package/lib/google-zyDOG9x7.mjs +30 -0
- package/lib/identity-Da1GPU9a.mjs +219 -0
- package/lib/identity-DnB63pS7.mjs +219 -0
- package/lib/identity-xRP7_eSR.mjs +219 -0
- package/lib/idle-iterator-Baoyn3Hp.mjs +366 -0
- package/lib/idle-iterator-C6XbWcuB.mjs +366 -0
- package/lib/idle-iterator-DUjKQEGT.mjs +366 -0
- package/lib/index.mjs +4608 -3935
- package/lib/kimi--wUOWER5.mjs +236 -0
- package/lib/kimi-DMVI-zrZ.mjs +236 -0
- package/lib/kimi-Dh0pv3WZ.mjs +236 -0
- package/lib/markit-BL3cH47U.mjs +1417 -0
- package/lib/markit-BNiNY6SE.mjs +1417 -0
- package/lib/markit-M0jhziqU.mjs +1417 -0
- package/lib/minimax-code-BK-3eBbz.mjs +53 -0
- package/lib/minimax-code-DCbuA6Yk.mjs +53 -0
- package/lib/minimax-code-Uq8Qu9LW.mjs +53 -0
- package/lib/models-CfT4coYT.mjs +104660 -0
- package/lib/models-D_XnT6ay.mjs +104660 -0
- package/lib/models-SGASygJ3.mjs +104660 -0
- package/lib/ollama-BQMGPxtV.mjs +589 -0
- package/lib/ollama-DPzBmq89.mjs +589 -0
- package/lib/ollama-DoBz5SFm.mjs +589 -0
- package/lib/openai-codex-Bi-4S4PX.mjs +255 -0
- package/lib/openai-codex-CQL_kvYL.mjs +255 -0
- package/lib/openai-codex-Ch8CkT3p.mjs +255 -0
- package/lib/openai-codex-responses-CvxL_FMF.mjs +3144 -0
- package/lib/openai-codex-responses-Cz-2qpC7.mjs +3144 -0
- package/lib/openai-codex-responses-pejZgdZo.mjs +3144 -0
- package/lib/openai-completions-CF8IyNtP.mjs +1360 -0
- package/lib/openai-completions-DIf361kF.mjs +1360 -0
- package/lib/openai-completions-i8doczAk.mjs +1360 -0
- package/lib/openai-reasoning-fallback-DGVVLgd1.mjs +286 -0
- package/lib/openai-reasoning-fallback-Nj6yB2rY.mjs +286 -0
- package/lib/openai-reasoning-fallback-OdJREP1o.mjs +286 -0
- package/lib/openai-responses-BqXJInHX.mjs +867 -0
- package/lib/openai-responses-DTkBiiy-.mjs +867 -0
- package/lib/openai-responses-Db_a-U4-.mjs +867 -0
- package/lib/opencode-DaJjcUbf.mjs +38 -0
- package/lib/opencode-DhMolSoB.mjs +38 -0
- package/lib/opencode-Rq_Q2vAO.mjs +38 -0
- package/lib/perplexity-9b-RQ0mV.mjs +194 -0
- package/lib/perplexity-C4iLVMUj.mjs +194 -0
- package/lib/perplexity-Uu7Jzg5b.mjs +194 -0
- package/lib/proxy-DDqrmjjC.mjs +190 -0
- package/lib/proxy-ZtUcl6r5.mjs +190 -0
- package/lib/proxy-pM_NIv-H.mjs +190 -0
- package/lib/request-debug-HJMoJncL.mjs +183 -0
- package/lib/sanitize-text-CfcXzw5X.mjs +33 -0
- package/lib/scrapers-BkFfcPHj.mjs +9198 -0
- package/lib/scrapers-CL-WgdU1.mjs +9198 -0
- package/lib/scrapers-CVptboMs.mjs +9198 -0
- package/lib/scrapers-CipyKyCH.mjs +9198 -0
- package/lib/scrapers-DGfrYhtw.mjs +9198 -0
- package/lib/scrapers-DSUPYoUF.mjs +9198 -0
- package/lib/scrapers-DZ2GXmp7.mjs +9198 -0
- package/lib/scrapers-nhQAvc8d.mjs +9198 -0
- package/lib/shell-snapshot-fn-env.sh +67 -43
- package/lib/src-BgpusnsB.mjs +5076 -0
- package/lib/src-DTid0g4K.mjs +5001 -0
- package/lib/src-lDmkSRbm.mjs +5006 -0
- package/lib/stream-BlldLkVq.mjs +10236 -0
- package/lib/stream-CRtexYLe.mjs +10236 -0
- package/lib/stream-C_RAoxJC.mjs +10236 -0
- package/lib/stream-markup-healing-2toHXWXM.mjs +491 -0
- package/lib/stream-markup-healing-DMsxBx1L.mjs +491 -0
- package/lib/stream-markup-healing-KMkiAA00.mjs +491 -0
- package/lib/turndown-DN7ByzEI.mjs +667 -0
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/config/fields.d.ts +1 -1
- package/lib/types/config/settings.d.ts +25 -3
- package/lib/types/config/truncate.d.ts +9 -5
- package/lib/types/tools/bash/background.d.ts +1 -1
- package/lib/types/tools/bash/bash-executor.d.ts +4 -0
- package/lib/types/tools/bash/bash-interceptor.d.ts +10 -8
- package/lib/types/tools/bash/cd-workdir.d.ts +35 -0
- package/lib/types/tools/bash/non-interactive-env.d.ts +2 -0
- package/lib/types/tools/bash/render.d.ts +4 -3
- package/lib/types/tools/bash/sanitize-text.d.ts +5 -0
- package/lib/types/tools/bash/shell-snapshot.d.ts +4 -1
- package/lib/types/tools/bash/shell-tokenize.d.ts +60 -0
- package/lib/types/tools/bash/streaming-output.d.ts +12 -212
- package/lib/types/tools/bash/which.d.ts +20 -0
- package/lib/types/tools/bash/windows-shell.d.ts +31 -0
- package/lib/types/tools/edit/adapter/index.d.ts +25 -3
- package/lib/types/tools/edit/adapter/tools/auto-generated-guard.d.ts +7 -17
- package/lib/types/tools/glob/adapter/index.d.ts +27 -1
- package/lib/types/tools/grep/adapter/index.d.ts +29 -1
- package/lib/types/tools/omp/edit/dispatch.d.ts +43 -0
- package/lib/types/tools/omp/edit/hashline/noop-loop-guard.d.ts +3 -1
- package/lib/types/tools/omp/sdk.d.ts +6 -0
- package/lib/types/tools/omp/tools/auto-generated-guard.d.ts +20 -0
- package/lib/types/tools/omp/tools/fetch.d.ts +2 -0
- package/lib/types/tools/omp/tools/read.d.ts +2 -8
- package/lib/types/tools/omp/tools/write.d.ts +4 -4
- package/lib/types/tools/omp/utils/image-loading.d.ts +10 -36
- package/lib/types/tools/read/adapter/index.d.ts +4 -1
- package/lib/types/tools/read-image/index.d.ts +4 -0
- package/lib/types/tools/shared/auto-generated-guard.dsh.d.ts +16 -4
- package/lib/types/tools/shared/bun-shim.d.ts +39 -3
- package/lib/types/tools/shared/fs-promises-shim.d.ts +3 -1
- package/lib/types/tools/shared/image-bridge.d.ts +98 -0
- package/lib/types/tools/shared/omp-prompt.d.ts +17 -9
- package/lib/types/tools/shared/session-state.d.ts +9 -3
- package/lib/utils-2Wq2eATG.mjs +8119 -0
- package/lib/utils-BnX8O3vi.mjs +12303 -0
- package/lib/utils-Bw139LTz.mjs +8119 -0
- package/lib/utils-CE8N8P4Q.mjs +12315 -0
- package/lib/utils-CZw4tVZQ.mjs +12315 -0
- package/lib/utils-C_MrQ_0z.mjs +12301 -0
- package/lib/utils-CiGN7OHR.mjs +12315 -0
- package/lib/utils-Cp76gCyk.mjs +8119 -0
- package/lib/utils-D0GRDgAr.mjs +12315 -0
- package/lib/utils-D0Z1fyoO.mjs +12299 -0
- package/lib/utils-D2YknRk4.mjs +51 -0
- package/lib/utils-DppGHXQB.mjs +51 -0
- package/lib/utils-DzXZDfYc.mjs +51 -0
- package/lib/utils-W8WdSBpX.mjs +12315 -0
- package/lib/vision-guard-01qSwFpf.mjs +92 -0
- package/lib/vision-guard-BDD4OrKo.mjs +92 -0
- package/lib/vision-guard-DzZGaOga.mjs +92 -0
- package/lib/wafer-CgtPHerf.mjs +17 -0
- package/lib/wafer-DRU0EjZX.mjs +17 -0
- package/lib/wafer-cBtrn6q9.mjs +17 -0
- package/lib/xai-oauth-Buk8XVvM.mjs +446 -0
- package/lib/xai-oauth-CMal8l1O.mjs +446 -0
- package/lib/xai-oauth-DPHDXKD7.mjs +446 -0
- package/lib/xiaomi-CZgwvX2G.mjs +157 -0
- package/lib/xiaomi-D2qT5cAC.mjs +157 -0
- package/lib/xiaomi-Dd87KSg5.mjs +157 -0
- package/lib/zai-7DWMkEqM.mjs +203 -0
- package/lib/zai-C59YnomG.mjs +203 -0
- package/lib/zai-CFeOt-53.mjs +203 -0
- package/lib/zip-Cg9ANN_U.mjs +1316 -0
- package/lib/zip-D36ZKsP8.mjs +1316 -0
- package/lib/zip-D6QXpvaJ.mjs +1316 -0
- package/package.json +14 -10
- package/presets/package.json +1 -1
- package/presets/tool-plus-ptc/preset.yml +1 -1
- package/presets/tool-plus-standard/preset.yml +1 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { c as OAuthError, h as LoginCancelledError } from "./error-B3bevhrs.mjs";
|
|
4
|
+
import { t as OAuthCallbackFlow } from "./callback-server-BEFNf-jf.mjs";
|
|
5
|
+
import { n as formatGoogleValidationRequiredMessage, t as extractGoogleValidationUrl } from "./google-validation-Cgbn3tWJ.mjs";
|
|
6
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/google-oauth-shared.ts
|
|
7
|
+
/**
|
|
8
|
+
* Shared OAuth flow for Google-style providers (Gemini CLI, Antigravity).
|
|
9
|
+
*
|
|
10
|
+
* Both providers use the same authorization-code flow shape; only the client
|
|
11
|
+
* credentials, scopes, endpoint constants, and project-discovery logic differ.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Per-request timeout for the post-callback provisioning phase (token exchange,
|
|
15
|
+
* user-info, project discovery/onboarding, LRO polling). These Cloud Code
|
|
16
|
+
* Assist calls normally settle in well under this window; a longer stall means
|
|
17
|
+
* a hung endpoint that must surface a login error instead of hanging forever.
|
|
18
|
+
* The callback server's own 300s deadline covers only the browser-callback wait
|
|
19
|
+
* ({@link OAuthCallbackFlow}) and does not gate this phase.
|
|
20
|
+
*/
|
|
21
|
+
const OAUTH_REQUEST_TIMEOUT_MS = 3e4;
|
|
22
|
+
/**
|
|
23
|
+
* Throw {@link AIError.LoginCancelledError} when the controller signal has
|
|
24
|
+
* already aborted. Gates each provisioning round-trip, which the callback-wait
|
|
25
|
+
* cancellation checks in {@link OAuthCallbackFlow} do not reach.
|
|
26
|
+
*/
|
|
27
|
+
function throwIfLoginCancelled(signal) {
|
|
28
|
+
if (signal?.aborted) throw new LoginCancelledError(`OAuth login cancelled: ${String(signal.reason)}`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* `fetch` for the provisioning phase: composes the controller signal with a
|
|
32
|
+
* per-request timeout so a stalled endpoint aborts instead of hanging login,
|
|
33
|
+
* and user cancellation aborts the in-flight request. Cancellation surfaces as
|
|
34
|
+
* {@link AIError.LoginCancelledError}; a timeout surfaces as an
|
|
35
|
+
* {@link AIError.OAuthError} with `kind: "timeout"`.
|
|
36
|
+
*/
|
|
37
|
+
async function oauthFetch(url, init, { provider, signal, timeoutMs = OAUTH_REQUEST_TIMEOUT_MS }) {
|
|
38
|
+
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
39
|
+
const requestSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
|
|
40
|
+
try {
|
|
41
|
+
return await fetch(url, {
|
|
42
|
+
...init,
|
|
43
|
+
signal: requestSignal
|
|
44
|
+
});
|
|
45
|
+
} catch (err) {
|
|
46
|
+
if (signal?.aborted) throw new LoginCancelledError(`OAuth login cancelled: ${String(signal.reason)}`);
|
|
47
|
+
if (timeoutSignal.aborted) throw new OAuthError(`Timed out after ${timeoutMs}ms waiting for ${url}`, {
|
|
48
|
+
kind: "timeout",
|
|
49
|
+
provider
|
|
50
|
+
});
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function getUserEmail(accessToken, provider, signal) {
|
|
55
|
+
try {
|
|
56
|
+
const response = await oauthFetch("https://www.googleapis.com/oauth2/v1/userinfo?alt=json", { headers: { Authorization: `Bearer ${accessToken}` } }, {
|
|
57
|
+
provider,
|
|
58
|
+
signal
|
|
59
|
+
});
|
|
60
|
+
if (response.ok) return (await response.json()).email;
|
|
61
|
+
} catch {}
|
|
62
|
+
}
|
|
63
|
+
var GoogleOAuthFlow = class extends OAuthCallbackFlow {
|
|
64
|
+
config;
|
|
65
|
+
constructor(ctrl, config) {
|
|
66
|
+
super(ctrl, {
|
|
67
|
+
preferredPort: config.callbackPort,
|
|
68
|
+
callbackPath: config.callbackPath,
|
|
69
|
+
callbackHostname: "127.0.0.1"
|
|
70
|
+
});
|
|
71
|
+
this.config = config;
|
|
72
|
+
}
|
|
73
|
+
async generateAuthUrl(state, redirectUri) {
|
|
74
|
+
const authParams = new URLSearchParams({
|
|
75
|
+
client_id: this.config.clientId,
|
|
76
|
+
response_type: "code",
|
|
77
|
+
redirect_uri: redirectUri,
|
|
78
|
+
scope: this.config.scopes.join(" "),
|
|
79
|
+
state,
|
|
80
|
+
access_type: "offline",
|
|
81
|
+
prompt: "consent"
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
url: `${this.config.authUrl}?${authParams.toString()}`,
|
|
85
|
+
instructions: "Complete the sign-in in your browser."
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async exchangeToken(code, _state, redirectUri) {
|
|
89
|
+
const { provider } = this.config;
|
|
90
|
+
const signal = this.ctrl.signal;
|
|
91
|
+
throwIfLoginCancelled(signal);
|
|
92
|
+
this.ctrl.onProgress?.("Exchanging authorization code for tokens...");
|
|
93
|
+
const tokenResponse = await oauthFetch(this.config.tokenUrl, {
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
96
|
+
body: new URLSearchParams({
|
|
97
|
+
client_id: this.config.clientId,
|
|
98
|
+
client_secret: this.config.clientSecret,
|
|
99
|
+
code,
|
|
100
|
+
grant_type: "authorization_code",
|
|
101
|
+
redirect_uri: redirectUri
|
|
102
|
+
})
|
|
103
|
+
}, {
|
|
104
|
+
provider,
|
|
105
|
+
signal
|
|
106
|
+
});
|
|
107
|
+
if (!tokenResponse.ok) {
|
|
108
|
+
const error = await tokenResponse.text();
|
|
109
|
+
throw new OAuthError(`Token exchange failed: ${error}`, {
|
|
110
|
+
kind: "token-exchange",
|
|
111
|
+
provider
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const tokenData = await tokenResponse.json();
|
|
115
|
+
if (!tokenData.refresh_token) throw new OAuthError("No refresh token received. Please try again.", {
|
|
116
|
+
kind: "validation",
|
|
117
|
+
provider
|
|
118
|
+
});
|
|
119
|
+
throwIfLoginCancelled(signal);
|
|
120
|
+
this.ctrl.onProgress?.("Getting user info...");
|
|
121
|
+
const email = await getUserEmail(tokenData.access_token, provider, signal);
|
|
122
|
+
throwIfLoginCancelled(signal);
|
|
123
|
+
let projectId;
|
|
124
|
+
try {
|
|
125
|
+
projectId = await this.config.discoverProject(tokenData.access_token, this.ctrl.onProgress, signal);
|
|
126
|
+
} catch (err) {
|
|
127
|
+
const validationUrl = extractGoogleValidationUrl(err instanceof Error ? err.message : String(err));
|
|
128
|
+
if (!validationUrl) throw err;
|
|
129
|
+
throw new OAuthError(formatGoogleValidationRequiredMessage(validationUrl, "sign in again", email), {
|
|
130
|
+
kind: "validation",
|
|
131
|
+
provider
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
refresh: tokenData.refresh_token,
|
|
136
|
+
access: tokenData.access_token,
|
|
137
|
+
expires: Date.now() + tokenData.expires_in * 1e3 - 3e5,
|
|
138
|
+
projectId,
|
|
139
|
+
email
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
async function runGoogleOAuthLogin(ctrl, config) {
|
|
144
|
+
return new GoogleOAuthFlow(ctrl, config).login();
|
|
145
|
+
}
|
|
146
|
+
//#endregion
|
|
147
|
+
export { runGoogleOAuthLogin as n, throwIfLoginCancelled as r, oauthFetch as t };
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
|
+
__installBunShim();
|
|
3
|
+
import { c as OAuthError, h as LoginCancelledError } from "./error-yCSG0mGC.mjs";
|
|
4
|
+
import { t as OAuthCallbackFlow } from "./callback-server-DDSrZ6l_.mjs";
|
|
5
|
+
import { n as formatGoogleValidationRequiredMessage, t as extractGoogleValidationUrl } from "./google-validation-Cgbn3tWJ.mjs";
|
|
6
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/google-oauth-shared.ts
|
|
7
|
+
/**
|
|
8
|
+
* Shared OAuth flow for Google-style providers (Gemini CLI, Antigravity).
|
|
9
|
+
*
|
|
10
|
+
* Both providers use the same authorization-code flow shape; only the client
|
|
11
|
+
* credentials, scopes, endpoint constants, and project-discovery logic differ.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Per-request timeout for the post-callback provisioning phase (token exchange,
|
|
15
|
+
* user-info, project discovery/onboarding, LRO polling). These Cloud Code
|
|
16
|
+
* Assist calls normally settle in well under this window; a longer stall means
|
|
17
|
+
* a hung endpoint that must surface a login error instead of hanging forever.
|
|
18
|
+
* The callback server's own 300s deadline covers only the browser-callback wait
|
|
19
|
+
* ({@link OAuthCallbackFlow}) and does not gate this phase.
|
|
20
|
+
*/
|
|
21
|
+
const OAUTH_REQUEST_TIMEOUT_MS = 3e4;
|
|
22
|
+
/**
|
|
23
|
+
* Throw {@link AIError.LoginCancelledError} when the controller signal has
|
|
24
|
+
* already aborted. Gates each provisioning round-trip, which the callback-wait
|
|
25
|
+
* cancellation checks in {@link OAuthCallbackFlow} do not reach.
|
|
26
|
+
*/
|
|
27
|
+
function throwIfLoginCancelled(signal) {
|
|
28
|
+
if (signal?.aborted) throw new LoginCancelledError(`OAuth login cancelled: ${String(signal.reason)}`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* `fetch` for the provisioning phase: composes the controller signal with a
|
|
32
|
+
* per-request timeout so a stalled endpoint aborts instead of hanging login,
|
|
33
|
+
* and user cancellation aborts the in-flight request. Cancellation surfaces as
|
|
34
|
+
* {@link AIError.LoginCancelledError}; a timeout surfaces as an
|
|
35
|
+
* {@link AIError.OAuthError} with `kind: "timeout"`.
|
|
36
|
+
*/
|
|
37
|
+
async function oauthFetch(url, init, { provider, signal, timeoutMs = OAUTH_REQUEST_TIMEOUT_MS }) {
|
|
38
|
+
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
39
|
+
const requestSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
|
|
40
|
+
try {
|
|
41
|
+
return await fetch(url, {
|
|
42
|
+
...init,
|
|
43
|
+
signal: requestSignal
|
|
44
|
+
});
|
|
45
|
+
} catch (err) {
|
|
46
|
+
if (signal?.aborted) throw new LoginCancelledError(`OAuth login cancelled: ${String(signal.reason)}`);
|
|
47
|
+
if (timeoutSignal.aborted) throw new OAuthError(`Timed out after ${timeoutMs}ms waiting for ${url}`, {
|
|
48
|
+
kind: "timeout",
|
|
49
|
+
provider
|
|
50
|
+
});
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function getUserEmail(accessToken, provider, signal) {
|
|
55
|
+
try {
|
|
56
|
+
const response = await oauthFetch("https://www.googleapis.com/oauth2/v1/userinfo?alt=json", { headers: { Authorization: `Bearer ${accessToken}` } }, {
|
|
57
|
+
provider,
|
|
58
|
+
signal
|
|
59
|
+
});
|
|
60
|
+
if (response.ok) return (await response.json()).email;
|
|
61
|
+
} catch {}
|
|
62
|
+
}
|
|
63
|
+
var GoogleOAuthFlow = class extends OAuthCallbackFlow {
|
|
64
|
+
config;
|
|
65
|
+
constructor(ctrl, config) {
|
|
66
|
+
super(ctrl, {
|
|
67
|
+
preferredPort: config.callbackPort,
|
|
68
|
+
callbackPath: config.callbackPath,
|
|
69
|
+
callbackHostname: "127.0.0.1"
|
|
70
|
+
});
|
|
71
|
+
this.config = config;
|
|
72
|
+
}
|
|
73
|
+
async generateAuthUrl(state, redirectUri) {
|
|
74
|
+
const authParams = new URLSearchParams({
|
|
75
|
+
client_id: this.config.clientId,
|
|
76
|
+
response_type: "code",
|
|
77
|
+
redirect_uri: redirectUri,
|
|
78
|
+
scope: this.config.scopes.join(" "),
|
|
79
|
+
state,
|
|
80
|
+
access_type: "offline",
|
|
81
|
+
prompt: "consent"
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
url: `${this.config.authUrl}?${authParams.toString()}`,
|
|
85
|
+
instructions: "Complete the sign-in in your browser."
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async exchangeToken(code, _state, redirectUri) {
|
|
89
|
+
const { provider } = this.config;
|
|
90
|
+
const signal = this.ctrl.signal;
|
|
91
|
+
throwIfLoginCancelled(signal);
|
|
92
|
+
this.ctrl.onProgress?.("Exchanging authorization code for tokens...");
|
|
93
|
+
const tokenResponse = await oauthFetch(this.config.tokenUrl, {
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
96
|
+
body: new URLSearchParams({
|
|
97
|
+
client_id: this.config.clientId,
|
|
98
|
+
client_secret: this.config.clientSecret,
|
|
99
|
+
code,
|
|
100
|
+
grant_type: "authorization_code",
|
|
101
|
+
redirect_uri: redirectUri
|
|
102
|
+
})
|
|
103
|
+
}, {
|
|
104
|
+
provider,
|
|
105
|
+
signal
|
|
106
|
+
});
|
|
107
|
+
if (!tokenResponse.ok) {
|
|
108
|
+
const error = await tokenResponse.text();
|
|
109
|
+
throw new OAuthError(`Token exchange failed: ${error}`, {
|
|
110
|
+
kind: "token-exchange",
|
|
111
|
+
provider
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const tokenData = await tokenResponse.json();
|
|
115
|
+
if (!tokenData.refresh_token) throw new OAuthError("No refresh token received. Please try again.", {
|
|
116
|
+
kind: "validation",
|
|
117
|
+
provider
|
|
118
|
+
});
|
|
119
|
+
throwIfLoginCancelled(signal);
|
|
120
|
+
this.ctrl.onProgress?.("Getting user info...");
|
|
121
|
+
const email = await getUserEmail(tokenData.access_token, provider, signal);
|
|
122
|
+
throwIfLoginCancelled(signal);
|
|
123
|
+
let projectId;
|
|
124
|
+
try {
|
|
125
|
+
projectId = await this.config.discoverProject(tokenData.access_token, this.ctrl.onProgress, signal);
|
|
126
|
+
} catch (err) {
|
|
127
|
+
const validationUrl = extractGoogleValidationUrl(err instanceof Error ? err.message : String(err));
|
|
128
|
+
if (!validationUrl) throw err;
|
|
129
|
+
throw new OAuthError(formatGoogleValidationRequiredMessage(validationUrl, "sign in again", email), {
|
|
130
|
+
kind: "validation",
|
|
131
|
+
provider
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
refresh: tokenData.refresh_token,
|
|
136
|
+
access: tokenData.access_token,
|
|
137
|
+
expires: Date.now() + tokenData.expires_in * 1e3 - 3e5,
|
|
138
|
+
projectId,
|
|
139
|
+
email
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
async function runGoogleOAuthLogin(ctrl, config) {
|
|
144
|
+
return new GoogleOAuthFlow(ctrl, config).login();
|
|
145
|
+
}
|
|
146
|
+
//#endregion
|
|
147
|
+
export { runGoogleOAuthLogin as n, throwIfLoginCancelled as r, oauthFetch as t };
|