@mariozechner/pi-ai 0.27.9 → 0.29.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 +39 -80
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +145 -0
- package/dist/cli.js.map +1 -0
- package/dist/models.generated.d.ts +8 -8
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +46 -46
- package/dist/models.generated.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +2 -2
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +3 -7
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/openai-completions.d.ts.map +1 -1
- package/dist/providers/openai-completions.js +3 -1
- package/dist/providers/openai-completions.js.map +1 -1
- package/dist/providers/openai-responses.d.ts.map +1 -1
- package/dist/providers/openai-responses.js +3 -1
- package/dist/providers/openai-responses.js.map +1 -1
- package/dist/stream.d.ts +4 -16
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +3 -27
- package/dist/stream.js.map +1 -1
- package/dist/utils/oauth/anthropic.d.ts +2 -2
- package/dist/utils/oauth/anthropic.d.ts.map +1 -1
- package/dist/utils/oauth/anthropic.js +1 -5
- package/dist/utils/oauth/anthropic.js.map +1 -1
- package/dist/utils/oauth/github-copilot.d.ts +1 -17
- package/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/dist/utils/oauth/github-copilot.js +3 -7
- package/dist/utils/oauth/github-copilot.js.map +1 -1
- package/dist/utils/oauth/google-antigravity.d.ts +2 -6
- package/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/dist/utils/oauth/google-antigravity.js +0 -4
- package/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/dist/utils/oauth/google-gemini-cli.d.ts +2 -6
- package/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/dist/utils/oauth/google-gemini-cli.js +0 -4
- package/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/dist/utils/oauth/index.d.ts +11 -26
- package/dist/utils/oauth/index.d.ts.map +1 -1
- package/dist/utils/oauth/index.js +16 -48
- package/dist/utils/oauth/index.js.map +1 -1
- package/dist/utils/oauth/types.d.ts +24 -0
- package/dist/utils/oauth/types.d.ts.map +1 -0
- package/dist/utils/oauth/types.js +2 -0
- package/dist/utils/oauth/types.js.map +1 -0
- package/package.json +4 -2
- package/dist/utils/oauth/storage.d.ts +0 -81
- package/dist/utils/oauth/storage.d.ts.map +0 -1
- package/dist/utils/oauth/storage.js +0 -119
- package/dist/utils/oauth/storage.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-gemini-cli.js","sourceRoot":"","sources":["../../../src/utils/oauth/google-gemini-cli.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Gemini CLI OAuth flow (Google Cloud Code Assist)\n * Standard Gemini models only (gemini-2.0-flash, gemini-2.5-*)\n */\n\nimport { createHash, randomBytes } from \"crypto\";\nimport { createServer, type Server } from \"http\";\nimport { type OAuthCredentials, saveOAuthCredentials } from \"./storage.js\";\n\nconst decode = (s: string) => Buffer.from(s, \"base64\").toString();\nconst CLIENT_ID = decode(\n\t\"NjgxMjU1ODA5Mzk1LW9vOGZ0Mm9wcmRybnA5ZTNhcWY2YXYzaG1kaWIxMzVqLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29t\",\n);\nconst CLIENT_SECRET = decode(\"R09DU1BYLTR1SGdNUG0tMW83U2stZ2VWNkN1NWNsWEZzeGw=\");\nconst REDIRECT_URI = \"http://localhost:8085/oauth2callback\";\nconst SCOPES = [\n\t\"https://www.googleapis.com/auth/cloud-platform\",\n\t\"https://www.googleapis.com/auth/userinfo.email\",\n\t\"https://www.googleapis.com/auth/userinfo.profile\",\n];\nconst AUTH_URL = \"https://accounts.google.com/o/oauth2/v2/auth\";\nconst TOKEN_URL = \"https://oauth2.googleapis.com/token\";\nconst CODE_ASSIST_ENDPOINT = \"https://cloudcode-pa.googleapis.com\";\n\nexport interface GoogleCloudCredentials extends OAuthCredentials {\n\tprojectId: string;\n\temail?: string;\n}\n\n/**\n * Generate PKCE code verifier and challenge\n */\nfunction generatePKCE(): { verifier: string; challenge: string } {\n\tconst verifier = randomBytes(32).toString(\"base64url\");\n\tconst challenge = createHash(\"sha256\").update(verifier).digest(\"base64url\");\n\treturn { verifier, challenge };\n}\n\n/**\n * Start a local HTTP server to receive the OAuth callback\n */\nfunction startCallbackServer(): Promise<{ server: Server; getCode: () => Promise<{ code: string; state: string }> }> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet codeResolve: (value: { code: string; state: string }) => void;\n\t\tlet codeReject: (error: Error) => void;\n\n\t\tconst codePromise = new Promise<{ code: string; state: string }>((res, rej) => {\n\t\t\tcodeResolve = res;\n\t\t\tcodeReject = rej;\n\t\t});\n\n\t\tconst server = createServer((req, res) => {\n\t\t\tconst url = new URL(req.url || \"\", `http://localhost:8085`);\n\n\t\t\tif (url.pathname === \"/oauth2callback\") {\n\t\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\t\tconst state = url.searchParams.get(\"state\");\n\t\t\t\tconst error = url.searchParams.get(\"error\");\n\n\t\t\t\tif (error) {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html\" });\n\t\t\t\t\tres.end(\n\t\t\t\t\t\t`<html><body><h1>Authentication Failed</h1><p>Error: ${error}</p><p>You can close this window.</p></body></html>`,\n\t\t\t\t\t);\n\t\t\t\t\tcodeReject(new Error(`OAuth error: ${error}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (code && state) {\n\t\t\t\t\tres.writeHead(200, { \"Content-Type\": \"text/html\" });\n\t\t\t\t\tres.end(\n\t\t\t\t\t\t`<html><body><h1>Authentication Successful</h1><p>You can close this window and return to the terminal.</p></body></html>`,\n\t\t\t\t\t);\n\t\t\t\t\tcodeResolve({ code, state });\n\t\t\t\t} else {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html\" });\n\t\t\t\t\tres.end(\n\t\t\t\t\t\t`<html><body><h1>Authentication Failed</h1><p>Missing code or state parameter.</p></body></html>`,\n\t\t\t\t\t);\n\t\t\t\t\tcodeReject(new Error(\"Missing code or state in callback\"));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tres.writeHead(404);\n\t\t\t\tres.end();\n\t\t\t}\n\t\t});\n\n\t\tserver.on(\"error\", (err) => {\n\t\t\treject(err);\n\t\t});\n\n\t\tserver.listen(8085, \"127.0.0.1\", () => {\n\t\t\tresolve({\n\t\t\t\tserver,\n\t\t\t\tgetCode: () => codePromise,\n\t\t\t});\n\t\t});\n\t});\n}\n\ninterface LoadCodeAssistPayload {\n\tcloudaicompanionProject?: string;\n\tcurrentTier?: { id?: string };\n\tallowedTiers?: Array<{ id?: string; isDefault?: boolean }>;\n}\n\ninterface OnboardUserPayload {\n\tdone?: boolean;\n\tresponse?: {\n\t\tcloudaicompanionProject?: { id?: string };\n\t};\n}\n\n/**\n * Wait helper for onboarding retries\n */\nfunction wait(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Get default tier ID from allowed tiers\n */\nfunction getDefaultTierId(allowedTiers?: Array<{ id?: string; isDefault?: boolean }>): string | undefined {\n\tif (!allowedTiers || allowedTiers.length === 0) return undefined;\n\tconst defaultTier = allowedTiers.find((t) => t.isDefault);\n\treturn defaultTier?.id ?? allowedTiers[0]?.id;\n}\n\n/**\n * Discover or provision a Google Cloud project for the user\n */\nasync function discoverProject(accessToken: string, onProgress?: (message: string) => void): Promise<string> {\n\tconst headers = {\n\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\"Content-Type\": \"application/json\",\n\t\t\"User-Agent\": \"google-api-nodejs-client/9.15.1\",\n\t\t\"X-Goog-Api-Client\": \"gl-node/22.17.0\",\n\t};\n\n\t// Try to load existing project via loadCodeAssist\n\tonProgress?.(\"Checking for existing Cloud Code Assist project...\");\n\tconst loadResponse = await fetch(`${CODE_ASSIST_ENDPOINT}/v1internal:loadCodeAssist`, {\n\t\tmethod: \"POST\",\n\t\theaders,\n\t\tbody: JSON.stringify({\n\t\t\tmetadata: {\n\t\t\t\tideType: \"IDE_UNSPECIFIED\",\n\t\t\t\tplatform: \"PLATFORM_UNSPECIFIED\",\n\t\t\t\tpluginType: \"GEMINI\",\n\t\t\t},\n\t\t}),\n\t});\n\n\tif (loadResponse.ok) {\n\t\tconst data = (await loadResponse.json()) as LoadCodeAssistPayload;\n\n\t\t// If we have an existing project, use it\n\t\tif (data.cloudaicompanionProject) {\n\t\t\treturn data.cloudaicompanionProject;\n\t\t}\n\n\t\t// Otherwise, try to onboard with the FREE tier\n\t\tconst tierId = getDefaultTierId(data.allowedTiers) ?? \"FREE\";\n\n\t\tonProgress?.(\"Provisioning Cloud Code Assist project (this may take a moment)...\");\n\n\t\t// Onboard with retries (the API may take time to provision)\n\t\tfor (let attempt = 0; attempt < 10; attempt++) {\n\t\t\tconst onboardResponse = await fetch(`${CODE_ASSIST_ENDPOINT}/v1internal:onboardUser`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders,\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\ttierId,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tideType: \"IDE_UNSPECIFIED\",\n\t\t\t\t\t\tplatform: \"PLATFORM_UNSPECIFIED\",\n\t\t\t\t\t\tpluginType: \"GEMINI\",\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (onboardResponse.ok) {\n\t\t\t\tconst onboardData = (await onboardResponse.json()) as OnboardUserPayload;\n\t\t\t\tconst projectId = onboardData.response?.cloudaicompanionProject?.id;\n\n\t\t\t\tif (onboardData.done && projectId) {\n\t\t\t\t\treturn projectId;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Wait before retrying\n\t\t\tif (attempt < 9) {\n\t\t\t\tonProgress?.(`Waiting for project provisioning (attempt ${attempt + 2}/10)...`);\n\t\t\t\tawait wait(3000);\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow new Error(\n\t\t\"Could not discover or provision a Google Cloud project. \" +\n\t\t\t\"Please ensure you have access to Google Cloud Code Assist (Gemini CLI).\",\n\t);\n}\n\n/**\n * Get user email from the access token\n */\nasync function getUserEmail(accessToken: string): Promise<string | undefined> {\n\ttry {\n\t\tconst response = await fetch(\"https://www.googleapis.com/oauth2/v1/userinfo?alt=json\", {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\t},\n\t\t});\n\n\t\tif (response.ok) {\n\t\t\tconst data = (await response.json()) as { email?: string };\n\t\t\treturn data.email;\n\t\t}\n\t} catch {\n\t\t// Ignore errors, email is optional\n\t}\n\treturn undefined;\n}\n\n/**\n * Refresh Google Cloud Code Assist token\n */\nexport async function refreshGoogleCloudToken(refreshToken: string, projectId: string): Promise<OAuthCredentials> {\n\tconst response = await fetch(TOKEN_URL, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tclient_secret: CLIENT_SECRET,\n\t\t\trefresh_token: refreshToken,\n\t\t\tgrant_type: \"refresh_token\",\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.text();\n\t\tthrow new Error(`Google Cloud token refresh failed: ${error}`);\n\t}\n\n\tconst data = (await response.json()) as {\n\t\taccess_token: string;\n\t\texpires_in: number;\n\t\trefresh_token?: string;\n\t};\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: data.refresh_token || refreshToken,\n\t\taccess: data.access_token,\n\t\texpires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n\t\tprojectId,\n\t};\n}\n\n/**\n * Login with Gemini CLI (Google Cloud Code Assist) OAuth\n *\n * @param onAuth - Callback with URL and optional instructions\n * @param onProgress - Optional progress callback\n */\nexport async function loginGeminiCli(\n\tonAuth: (info: { url: string; instructions?: string }) => void,\n\tonProgress?: (message: string) => void,\n): Promise<GoogleCloudCredentials> {\n\tconst { verifier, challenge } = generatePKCE();\n\n\t// Start local server for callback\n\tonProgress?.(\"Starting local server for OAuth callback...\");\n\tconst { server, getCode } = await startCallbackServer();\n\n\ttry {\n\t\t// Build authorization URL\n\t\tconst authParams = new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tresponse_type: \"code\",\n\t\t\tredirect_uri: REDIRECT_URI,\n\t\t\tscope: SCOPES.join(\" \"),\n\t\t\tcode_challenge: challenge,\n\t\t\tcode_challenge_method: \"S256\",\n\t\t\tstate: verifier,\n\t\t\taccess_type: \"offline\",\n\t\t\tprompt: \"consent\",\n\t\t});\n\n\t\tconst authUrl = `${AUTH_URL}?${authParams.toString()}`;\n\n\t\t// Notify caller with URL to open\n\t\tonAuth({\n\t\t\turl: authUrl,\n\t\t\tinstructions: \"Complete the sign-in in your browser. The callback will be captured automatically.\",\n\t\t});\n\n\t\t// Wait for the callback\n\t\tonProgress?.(\"Waiting for OAuth callback...\");\n\t\tconst { code, state } = await getCode();\n\n\t\t// Verify state matches\n\t\tif (state !== verifier) {\n\t\t\tthrow new Error(\"OAuth state mismatch - possible CSRF attack\");\n\t\t}\n\n\t\t// Exchange code for tokens\n\t\tonProgress?.(\"Exchanging authorization code for tokens...\");\n\t\tconst tokenResponse = await fetch(TOKEN_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams({\n\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\tclient_secret: CLIENT_SECRET,\n\t\t\t\tcode,\n\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\tredirect_uri: REDIRECT_URI,\n\t\t\t\tcode_verifier: verifier,\n\t\t\t}),\n\t\t});\n\n\t\tif (!tokenResponse.ok) {\n\t\t\tconst error = await tokenResponse.text();\n\t\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t\t}\n\n\t\tconst tokenData = (await tokenResponse.json()) as {\n\t\t\taccess_token: string;\n\t\t\trefresh_token: string;\n\t\t\texpires_in: number;\n\t\t};\n\n\t\tif (!tokenData.refresh_token) {\n\t\t\tthrow new Error(\"No refresh token received. Please try again.\");\n\t\t}\n\n\t\t// Get user email\n\t\tonProgress?.(\"Getting user info...\");\n\t\tconst email = await getUserEmail(tokenData.access_token);\n\n\t\t// Discover project\n\t\tconst projectId = await discoverProject(tokenData.access_token, onProgress);\n\n\t\t// Calculate expiry time (current time + expires_in seconds - 5 min buffer)\n\t\tconst expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;\n\n\t\tconst credentials: GoogleCloudCredentials = {\n\t\t\ttype: \"oauth\",\n\t\t\trefresh: tokenData.refresh_token,\n\t\t\taccess: tokenData.access_token,\n\t\t\texpires: expiresAt,\n\t\t\tprojectId,\n\t\t\temail,\n\t\t};\n\n\t\tsaveOAuthCredentials(\"google-gemini-cli\", credentials);\n\n\t\treturn credentials;\n\t} finally {\n\t\tserver.close();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"google-gemini-cli.js","sourceRoot":"","sources":["../../../src/utils/oauth/google-gemini-cli.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Gemini CLI OAuth flow (Google Cloud Code Assist)\n * Standard Gemini models only (gemini-2.0-flash, gemini-2.5-*)\n */\n\nimport { createHash, randomBytes } from \"crypto\";\nimport { createServer, type Server } from \"http\";\nimport type { OAuthCredentials } from \"./types.js\";\n\nconst decode = (s: string) => Buffer.from(s, \"base64\").toString();\nconst CLIENT_ID = decode(\n\t\"NjgxMjU1ODA5Mzk1LW9vOGZ0Mm9wcmRybnA5ZTNhcWY2YXYzaG1kaWIxMzVqLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29t\",\n);\nconst CLIENT_SECRET = decode(\"R09DU1BYLTR1SGdNUG0tMW83U2stZ2VWNkN1NWNsWEZzeGw=\");\nconst REDIRECT_URI = \"http://localhost:8085/oauth2callback\";\nconst SCOPES = [\n\t\"https://www.googleapis.com/auth/cloud-platform\",\n\t\"https://www.googleapis.com/auth/userinfo.email\",\n\t\"https://www.googleapis.com/auth/userinfo.profile\",\n];\nconst AUTH_URL = \"https://accounts.google.com/o/oauth2/v2/auth\";\nconst TOKEN_URL = \"https://oauth2.googleapis.com/token\";\nconst CODE_ASSIST_ENDPOINT = \"https://cloudcode-pa.googleapis.com\";\n\n/**\n * Generate PKCE code verifier and challenge\n */\nfunction generatePKCE(): { verifier: string; challenge: string } {\n\tconst verifier = randomBytes(32).toString(\"base64url\");\n\tconst challenge = createHash(\"sha256\").update(verifier).digest(\"base64url\");\n\treturn { verifier, challenge };\n}\n\n/**\n * Start a local HTTP server to receive the OAuth callback\n */\nfunction startCallbackServer(): Promise<{ server: Server; getCode: () => Promise<{ code: string; state: string }> }> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet codeResolve: (value: { code: string; state: string }) => void;\n\t\tlet codeReject: (error: Error) => void;\n\n\t\tconst codePromise = new Promise<{ code: string; state: string }>((res, rej) => {\n\t\t\tcodeResolve = res;\n\t\t\tcodeReject = rej;\n\t\t});\n\n\t\tconst server = createServer((req, res) => {\n\t\t\tconst url = new URL(req.url || \"\", `http://localhost:8085`);\n\n\t\t\tif (url.pathname === \"/oauth2callback\") {\n\t\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\t\tconst state = url.searchParams.get(\"state\");\n\t\t\t\tconst error = url.searchParams.get(\"error\");\n\n\t\t\t\tif (error) {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html\" });\n\t\t\t\t\tres.end(\n\t\t\t\t\t\t`<html><body><h1>Authentication Failed</h1><p>Error: ${error}</p><p>You can close this window.</p></body></html>`,\n\t\t\t\t\t);\n\t\t\t\t\tcodeReject(new Error(`OAuth error: ${error}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (code && state) {\n\t\t\t\t\tres.writeHead(200, { \"Content-Type\": \"text/html\" });\n\t\t\t\t\tres.end(\n\t\t\t\t\t\t`<html><body><h1>Authentication Successful</h1><p>You can close this window and return to the terminal.</p></body></html>`,\n\t\t\t\t\t);\n\t\t\t\t\tcodeResolve({ code, state });\n\t\t\t\t} else {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html\" });\n\t\t\t\t\tres.end(\n\t\t\t\t\t\t`<html><body><h1>Authentication Failed</h1><p>Missing code or state parameter.</p></body></html>`,\n\t\t\t\t\t);\n\t\t\t\t\tcodeReject(new Error(\"Missing code or state in callback\"));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tres.writeHead(404);\n\t\t\t\tres.end();\n\t\t\t}\n\t\t});\n\n\t\tserver.on(\"error\", (err) => {\n\t\t\treject(err);\n\t\t});\n\n\t\tserver.listen(8085, \"127.0.0.1\", () => {\n\t\t\tresolve({\n\t\t\t\tserver,\n\t\t\t\tgetCode: () => codePromise,\n\t\t\t});\n\t\t});\n\t});\n}\n\ninterface LoadCodeAssistPayload {\n\tcloudaicompanionProject?: string;\n\tcurrentTier?: { id?: string };\n\tallowedTiers?: Array<{ id?: string; isDefault?: boolean }>;\n}\n\ninterface OnboardUserPayload {\n\tdone?: boolean;\n\tresponse?: {\n\t\tcloudaicompanionProject?: { id?: string };\n\t};\n}\n\n/**\n * Wait helper for onboarding retries\n */\nfunction wait(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Get default tier ID from allowed tiers\n */\nfunction getDefaultTierId(allowedTiers?: Array<{ id?: string; isDefault?: boolean }>): string | undefined {\n\tif (!allowedTiers || allowedTiers.length === 0) return undefined;\n\tconst defaultTier = allowedTiers.find((t) => t.isDefault);\n\treturn defaultTier?.id ?? allowedTiers[0]?.id;\n}\n\n/**\n * Discover or provision a Google Cloud project for the user\n */\nasync function discoverProject(accessToken: string, onProgress?: (message: string) => void): Promise<string> {\n\tconst headers = {\n\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\"Content-Type\": \"application/json\",\n\t\t\"User-Agent\": \"google-api-nodejs-client/9.15.1\",\n\t\t\"X-Goog-Api-Client\": \"gl-node/22.17.0\",\n\t};\n\n\t// Try to load existing project via loadCodeAssist\n\tonProgress?.(\"Checking for existing Cloud Code Assist project...\");\n\tconst loadResponse = await fetch(`${CODE_ASSIST_ENDPOINT}/v1internal:loadCodeAssist`, {\n\t\tmethod: \"POST\",\n\t\theaders,\n\t\tbody: JSON.stringify({\n\t\t\tmetadata: {\n\t\t\t\tideType: \"IDE_UNSPECIFIED\",\n\t\t\t\tplatform: \"PLATFORM_UNSPECIFIED\",\n\t\t\t\tpluginType: \"GEMINI\",\n\t\t\t},\n\t\t}),\n\t});\n\n\tif (loadResponse.ok) {\n\t\tconst data = (await loadResponse.json()) as LoadCodeAssistPayload;\n\n\t\t// If we have an existing project, use it\n\t\tif (data.cloudaicompanionProject) {\n\t\t\treturn data.cloudaicompanionProject;\n\t\t}\n\n\t\t// Otherwise, try to onboard with the FREE tier\n\t\tconst tierId = getDefaultTierId(data.allowedTiers) ?? \"FREE\";\n\n\t\tonProgress?.(\"Provisioning Cloud Code Assist project (this may take a moment)...\");\n\n\t\t// Onboard with retries (the API may take time to provision)\n\t\tfor (let attempt = 0; attempt < 10; attempt++) {\n\t\t\tconst onboardResponse = await fetch(`${CODE_ASSIST_ENDPOINT}/v1internal:onboardUser`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders,\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\ttierId,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tideType: \"IDE_UNSPECIFIED\",\n\t\t\t\t\t\tplatform: \"PLATFORM_UNSPECIFIED\",\n\t\t\t\t\t\tpluginType: \"GEMINI\",\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (onboardResponse.ok) {\n\t\t\t\tconst onboardData = (await onboardResponse.json()) as OnboardUserPayload;\n\t\t\t\tconst projectId = onboardData.response?.cloudaicompanionProject?.id;\n\n\t\t\t\tif (onboardData.done && projectId) {\n\t\t\t\t\treturn projectId;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Wait before retrying\n\t\t\tif (attempt < 9) {\n\t\t\t\tonProgress?.(`Waiting for project provisioning (attempt ${attempt + 2}/10)...`);\n\t\t\t\tawait wait(3000);\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow new Error(\n\t\t\"Could not discover or provision a Google Cloud project. \" +\n\t\t\t\"Please ensure you have access to Google Cloud Code Assist (Gemini CLI).\",\n\t);\n}\n\n/**\n * Get user email from the access token\n */\nasync function getUserEmail(accessToken: string): Promise<string | undefined> {\n\ttry {\n\t\tconst response = await fetch(\"https://www.googleapis.com/oauth2/v1/userinfo?alt=json\", {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${accessToken}`,\n\t\t\t},\n\t\t});\n\n\t\tif (response.ok) {\n\t\t\tconst data = (await response.json()) as { email?: string };\n\t\t\treturn data.email;\n\t\t}\n\t} catch {\n\t\t// Ignore errors, email is optional\n\t}\n\treturn undefined;\n}\n\n/**\n * Refresh Google Cloud Code Assist token\n */\nexport async function refreshGoogleCloudToken(refreshToken: string, projectId: string): Promise<OAuthCredentials> {\n\tconst response = await fetch(TOKEN_URL, {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\tbody: new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tclient_secret: CLIENT_SECRET,\n\t\t\trefresh_token: refreshToken,\n\t\t\tgrant_type: \"refresh_token\",\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.text();\n\t\tthrow new Error(`Google Cloud token refresh failed: ${error}`);\n\t}\n\n\tconst data = (await response.json()) as {\n\t\taccess_token: string;\n\t\texpires_in: number;\n\t\trefresh_token?: string;\n\t};\n\n\treturn {\n\t\trefresh: data.refresh_token || refreshToken,\n\t\taccess: data.access_token,\n\t\texpires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n\t\tprojectId,\n\t};\n}\n\n/**\n * Login with Gemini CLI (Google Cloud Code Assist) OAuth\n *\n * @param onAuth - Callback with URL and optional instructions\n * @param onProgress - Optional progress callback\n */\nexport async function loginGeminiCli(\n\tonAuth: (info: { url: string; instructions?: string }) => void,\n\tonProgress?: (message: string) => void,\n): Promise<OAuthCredentials> {\n\tconst { verifier, challenge } = generatePKCE();\n\n\t// Start local server for callback\n\tonProgress?.(\"Starting local server for OAuth callback...\");\n\tconst { server, getCode } = await startCallbackServer();\n\n\ttry {\n\t\t// Build authorization URL\n\t\tconst authParams = new URLSearchParams({\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tresponse_type: \"code\",\n\t\t\tredirect_uri: REDIRECT_URI,\n\t\t\tscope: SCOPES.join(\" \"),\n\t\t\tcode_challenge: challenge,\n\t\t\tcode_challenge_method: \"S256\",\n\t\t\tstate: verifier,\n\t\t\taccess_type: \"offline\",\n\t\t\tprompt: \"consent\",\n\t\t});\n\n\t\tconst authUrl = `${AUTH_URL}?${authParams.toString()}`;\n\n\t\t// Notify caller with URL to open\n\t\tonAuth({\n\t\t\turl: authUrl,\n\t\t\tinstructions: \"Complete the sign-in in your browser. The callback will be captured automatically.\",\n\t\t});\n\n\t\t// Wait for the callback\n\t\tonProgress?.(\"Waiting for OAuth callback...\");\n\t\tconst { code, state } = await getCode();\n\n\t\t// Verify state matches\n\t\tif (state !== verifier) {\n\t\t\tthrow new Error(\"OAuth state mismatch - possible CSRF attack\");\n\t\t}\n\n\t\t// Exchange code for tokens\n\t\tonProgress?.(\"Exchanging authorization code for tokens...\");\n\t\tconst tokenResponse = await fetch(TOKEN_URL, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams({\n\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\tclient_secret: CLIENT_SECRET,\n\t\t\t\tcode,\n\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\tredirect_uri: REDIRECT_URI,\n\t\t\t\tcode_verifier: verifier,\n\t\t\t}),\n\t\t});\n\n\t\tif (!tokenResponse.ok) {\n\t\t\tconst error = await tokenResponse.text();\n\t\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t\t}\n\n\t\tconst tokenData = (await tokenResponse.json()) as {\n\t\t\taccess_token: string;\n\t\t\trefresh_token: string;\n\t\t\texpires_in: number;\n\t\t};\n\n\t\tif (!tokenData.refresh_token) {\n\t\t\tthrow new Error(\"No refresh token received. Please try again.\");\n\t\t}\n\n\t\t// Get user email\n\t\tonProgress?.(\"Getting user info...\");\n\t\tconst email = await getUserEmail(tokenData.access_token);\n\n\t\t// Discover project\n\t\tconst projectId = await discoverProject(tokenData.access_token, onProgress);\n\n\t\t// Calculate expiry time (current time + expires_in seconds - 5 min buffer)\n\t\tconst expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;\n\n\t\tconst credentials: OAuthCredentials = {\n\t\t\trefresh: tokenData.refresh_token,\n\t\t\taccess: tokenData.access_token,\n\t\t\texpires: expiresAt,\n\t\t\tprojectId,\n\t\t\temail,\n\t\t};\n\n\t\treturn credentials;\n\t} finally {\n\t\tserver.close();\n\t}\n}\n"]}
|
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
* - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)
|
|
10
10
|
*/
|
|
11
11
|
export { loginAnthropic, refreshAnthropicToken } from "./anthropic.js";
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
14
|
-
export {
|
|
15
|
-
export
|
|
16
|
-
import type { OAuthProvider } from "./
|
|
12
|
+
export { getGitHubCopilotBaseUrl, loginGitHubCopilot, normalizeDomain, refreshGitHubCopilotToken, } from "./github-copilot.js";
|
|
13
|
+
export { loginAntigravity, refreshAntigravityToken, } from "./google-antigravity.js";
|
|
14
|
+
export { loginGeminiCli, refreshGoogleCloudToken, } from "./google-gemini-cli.js";
|
|
15
|
+
export * from "./types.js";
|
|
16
|
+
import type { OAuthCredentials, OAuthProvider, OAuthProviderInfo } from "./types.js";
|
|
17
17
|
/**
|
|
18
18
|
* Refresh token for any OAuth provider.
|
|
19
19
|
* Saves the new credentials and returns the new access token.
|
|
20
20
|
*/
|
|
21
|
-
export declare function
|
|
21
|
+
export declare function refreshOAuthToken(provider: OAuthProvider, credentials: OAuthCredentials): Promise<OAuthCredentials>;
|
|
22
22
|
/**
|
|
23
23
|
* Get API key for a provider from OAuth credentials.
|
|
24
24
|
* Automatically refreshes expired tokens.
|
|
@@ -26,27 +26,12 @@ export declare function refreshToken(provider: OAuthProvider): Promise<string>;
|
|
|
26
26
|
* For google-gemini-cli and antigravity, returns JSON-encoded { token, projectId }
|
|
27
27
|
*
|
|
28
28
|
* @returns API key string, or null if no credentials
|
|
29
|
+
* @throws Error if refresh fails
|
|
29
30
|
*/
|
|
30
|
-
export declare function getOAuthApiKey(provider: OAuthProvider
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
*/
|
|
35
|
-
export declare function getOAuthProviderForModelProvider(modelProvider: string): OAuthProvider | undefined;
|
|
36
|
-
export type OAuthPrompt = {
|
|
37
|
-
message: string;
|
|
38
|
-
placeholder?: string;
|
|
39
|
-
allowEmpty?: boolean;
|
|
40
|
-
};
|
|
41
|
-
export type OAuthAuthInfo = {
|
|
42
|
-
url: string;
|
|
43
|
-
instructions?: string;
|
|
44
|
-
};
|
|
45
|
-
export interface OAuthProviderInfo {
|
|
46
|
-
id: OAuthProvider;
|
|
47
|
-
name: string;
|
|
48
|
-
available: boolean;
|
|
49
|
-
}
|
|
31
|
+
export declare function getOAuthApiKey(provider: OAuthProvider, credentials: Record<string, OAuthCredentials>): Promise<{
|
|
32
|
+
newCredentials: OAuthCredentials;
|
|
33
|
+
apiKey: string;
|
|
34
|
+
} | null>;
|
|
50
35
|
/**
|
|
51
36
|
* Get list of OAuth providers
|
|
52
37
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvE,OAAO,EACN,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEvE,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,yBAAyB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACN,gBAAgB,EAChB,uBAAuB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACN,cAAc,EACd,uBAAuB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,cAAc,YAAY,CAAC;AAU3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAErF;;;GAGG;AACH,wBAAsB,iBAAiB,CACtC,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,gBAAgB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CA+B3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CACnC,QAAQ,EAAE,aAAa,EACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAC3C,OAAO,CAAC;IAAE,cAAc,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAmBtE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,iBAAiB,EAAE,CAuBvD","sourcesContent":["/**\n * OAuth credential management for AI providers.\n *\n * This module handles login, token refresh, and credential storage\n * for OAuth-based providers:\n * - Anthropic (Claude Pro/Max)\n * - GitHub Copilot\n * - Google Cloud Code Assist (Gemini CLI)\n * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)\n */\n\n// Anthropic\nexport { loginAnthropic, refreshAnthropicToken } from \"./anthropic.js\";\n// GitHub Copilot\nexport {\n\tgetGitHubCopilotBaseUrl,\n\tloginGitHubCopilot,\n\tnormalizeDomain,\n\trefreshGitHubCopilotToken,\n} from \"./github-copilot.js\";\n// Google Antigravity\nexport {\n\tloginAntigravity,\n\trefreshAntigravityToken,\n} from \"./google-antigravity.js\";\n// Google Gemini CLI\nexport {\n\tloginGeminiCli,\n\trefreshGoogleCloudToken,\n} from \"./google-gemini-cli.js\";\n\nexport * from \"./types.js\";\n\n// ============================================================================\n// High-level API\n// ============================================================================\n\nimport { refreshAnthropicToken } from \"./anthropic.js\";\nimport { refreshGitHubCopilotToken } from \"./github-copilot.js\";\nimport { refreshAntigravityToken } from \"./google-antigravity.js\";\nimport { refreshGoogleCloudToken } from \"./google-gemini-cli.js\";\nimport type { OAuthCredentials, OAuthProvider, OAuthProviderInfo } from \"./types.js\";\n\n/**\n * Refresh token for any OAuth provider.\n * Saves the new credentials and returns the new access token.\n */\nexport async function refreshOAuthToken(\n\tprovider: OAuthProvider,\n\tcredentials: OAuthCredentials,\n): Promise<OAuthCredentials> {\n\tif (!credentials) {\n\t\tthrow new Error(`No OAuth credentials found for ${provider}`);\n\t}\n\n\tlet newCredentials: OAuthCredentials;\n\n\tswitch (provider) {\n\t\tcase \"anthropic\":\n\t\t\tnewCredentials = await refreshAnthropicToken(credentials.refresh);\n\t\t\tbreak;\n\t\tcase \"github-copilot\":\n\t\t\tnewCredentials = await refreshGitHubCopilotToken(credentials.refresh, credentials.enterpriseUrl);\n\t\t\tbreak;\n\t\tcase \"google-gemini-cli\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Google Cloud credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshGoogleCloudToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"google-antigravity\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Antigravity credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshAntigravityToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown OAuth provider: ${provider}`);\n\t}\n\n\treturn newCredentials;\n}\n\n/**\n * Get API key for a provider from OAuth credentials.\n * Automatically refreshes expired tokens.\n *\n * For google-gemini-cli and antigravity, returns JSON-encoded { token, projectId }\n *\n * @returns API key string, or null if no credentials\n * @throws Error if refresh fails\n */\nexport async function getOAuthApiKey(\n\tprovider: OAuthProvider,\n\tcredentials: Record<string, OAuthCredentials>,\n): Promise<{ newCredentials: OAuthCredentials; apiKey: string } | null> {\n\tlet creds = credentials[provider];\n\tif (!creds) {\n\t\treturn null;\n\t}\n\n\t// Refresh if expired\n\tif (Date.now() >= creds.expires) {\n\t\ttry {\n\t\t\tcreds = await refreshOAuthToken(provider, creds);\n\t\t} catch (_error) {\n\t\t\tthrow new Error(`Failed to refresh OAuth token for ${provider}`);\n\t\t}\n\t}\n\n\t// For providers that need projectId, return JSON\n\tconst needsProjectId = provider === \"google-gemini-cli\" || provider === \"google-antigravity\";\n\tconst apiKey = needsProjectId ? JSON.stringify({ token: creds.access, projectId: creds.projectId }) : creds.access;\n\treturn { newCredentials: creds, apiKey };\n}\n\n/**\n * Get list of OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInfo[] {\n\treturn [\n\t\t{\n\t\t\tid: \"anthropic\",\n\t\t\tname: \"Anthropic (Claude Pro/Max)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"github-copilot\",\n\t\t\tname: \"GitHub Copilot\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-gemini-cli\",\n\t\t\tname: \"Google Cloud Code Assist (Gemini CLI)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-antigravity\",\n\t\t\tname: \"Antigravity (Gemini 3, Claude, GPT-OSS)\",\n\t\t\tavailable: true,\n\t\t},\n\t];\n}\n"]}
|
|
@@ -11,13 +11,12 @@
|
|
|
11
11
|
// Anthropic
|
|
12
12
|
export { loginAnthropic, refreshAnthropicToken } from "./anthropic.js";
|
|
13
13
|
// GitHub Copilot
|
|
14
|
-
export {
|
|
14
|
+
export { getGitHubCopilotBaseUrl, loginGitHubCopilot, normalizeDomain, refreshGitHubCopilotToken, } from "./github-copilot.js";
|
|
15
15
|
// Google Antigravity
|
|
16
16
|
export { loginAntigravity, refreshAntigravityToken, } from "./google-antigravity.js";
|
|
17
17
|
// Google Gemini CLI
|
|
18
18
|
export { loginGeminiCli, refreshGoogleCloudToken, } from "./google-gemini-cli.js";
|
|
19
|
-
|
|
20
|
-
export { getOAuthPath, hasOAuthCredentials, listOAuthProviders, loadOAuthCredentials, loadOAuthStorage, removeOAuthCredentials, resetOAuthStorage, saveOAuthCredentials, setOAuthStorage, } from "./storage.js";
|
|
19
|
+
export * from "./types.js";
|
|
21
20
|
// ============================================================================
|
|
22
21
|
// High-level API
|
|
23
22
|
// ============================================================================
|
|
@@ -25,13 +24,11 @@ import { refreshAnthropicToken } from "./anthropic.js";
|
|
|
25
24
|
import { refreshGitHubCopilotToken } from "./github-copilot.js";
|
|
26
25
|
import { refreshAntigravityToken } from "./google-antigravity.js";
|
|
27
26
|
import { refreshGoogleCloudToken } from "./google-gemini-cli.js";
|
|
28
|
-
import { loadOAuthCredentials, removeOAuthCredentials, saveOAuthCredentials } from "./storage.js";
|
|
29
27
|
/**
|
|
30
28
|
* Refresh token for any OAuth provider.
|
|
31
29
|
* Saves the new credentials and returns the new access token.
|
|
32
30
|
*/
|
|
33
|
-
export async function
|
|
34
|
-
const credentials = loadOAuthCredentials(provider);
|
|
31
|
+
export async function refreshOAuthToken(provider, credentials) {
|
|
35
32
|
if (!credentials) {
|
|
36
33
|
throw new Error(`No OAuth credentials found for ${provider}`);
|
|
37
34
|
}
|
|
@@ -58,8 +55,7 @@ export async function refreshToken(provider) {
|
|
|
58
55
|
default:
|
|
59
56
|
throw new Error(`Unknown OAuth provider: ${provider}`);
|
|
60
57
|
}
|
|
61
|
-
|
|
62
|
-
return newCredentials.access;
|
|
58
|
+
return newCredentials;
|
|
63
59
|
}
|
|
64
60
|
/**
|
|
65
61
|
* Get API key for a provider from OAuth credentials.
|
|
@@ -68,54 +64,26 @@ export async function refreshToken(provider) {
|
|
|
68
64
|
* For google-gemini-cli and antigravity, returns JSON-encoded { token, projectId }
|
|
69
65
|
*
|
|
70
66
|
* @returns API key string, or null if no credentials
|
|
67
|
+
* @throws Error if refresh fails
|
|
71
68
|
*/
|
|
72
|
-
export async function getOAuthApiKey(provider) {
|
|
73
|
-
|
|
74
|
-
if (!
|
|
69
|
+
export async function getOAuthApiKey(provider, credentials) {
|
|
70
|
+
let creds = credentials[provider];
|
|
71
|
+
if (!creds) {
|
|
75
72
|
return null;
|
|
76
73
|
}
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
// Check if expired
|
|
80
|
-
if (Date.now() >= credentials.expires) {
|
|
74
|
+
// Refresh if expired
|
|
75
|
+
if (Date.now() >= creds.expires) {
|
|
81
76
|
try {
|
|
82
|
-
|
|
83
|
-
// For providers that need projectId, return JSON
|
|
84
|
-
if (needsProjectId) {
|
|
85
|
-
const refreshedCreds = loadOAuthCredentials(provider);
|
|
86
|
-
if (refreshedCreds?.projectId) {
|
|
87
|
-
return JSON.stringify({ token: newToken, projectId: refreshedCreds.projectId });
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return newToken;
|
|
77
|
+
creds = await refreshOAuthToken(provider, creds);
|
|
91
78
|
}
|
|
92
|
-
catch (
|
|
93
|
-
|
|
94
|
-
removeOAuthCredentials(provider);
|
|
95
|
-
return null;
|
|
79
|
+
catch (_error) {
|
|
80
|
+
throw new Error(`Failed to refresh OAuth token for ${provider}`);
|
|
96
81
|
}
|
|
97
82
|
}
|
|
98
83
|
// For providers that need projectId, return JSON
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
return JSON.stringify({ token: credentials.access, projectId: credentials.projectId });
|
|
104
|
-
}
|
|
105
|
-
return credentials.access;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Map model provider to OAuth provider.
|
|
109
|
-
* Returns undefined if the provider doesn't use OAuth.
|
|
110
|
-
*/
|
|
111
|
-
export function getOAuthProviderForModelProvider(modelProvider) {
|
|
112
|
-
const mapping = {
|
|
113
|
-
anthropic: "anthropic",
|
|
114
|
-
"github-copilot": "github-copilot",
|
|
115
|
-
"google-gemini-cli": "google-gemini-cli",
|
|
116
|
-
"google-antigravity": "google-antigravity",
|
|
117
|
-
};
|
|
118
|
-
return mapping[modelProvider];
|
|
84
|
+
const needsProjectId = provider === "google-gemini-cli" || provider === "google-antigravity";
|
|
85
|
+
const apiKey = needsProjectId ? JSON.stringify({ token: creds.access, projectId: creds.projectId }) : creds.access;
|
|
86
|
+
return { newCredentials: creds, apiKey };
|
|
119
87
|
}
|
|
120
88
|
/**
|
|
121
89
|
* Get list of OAuth providers
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/oauth/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OAuth credential management for AI providers.\n *\n * This module handles login, token refresh, and credential storage\n * for OAuth-based providers:\n * - Anthropic (Claude Pro/Max)\n * - GitHub Copilot\n * - Google Cloud Code Assist (Gemini CLI)\n * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)\n */\n\n// Anthropic\nexport { loginAnthropic, refreshAnthropicToken } from \"./anthropic.js\";\n// GitHub Copilot\nexport {\n\tenableAllGitHubCopilotModels,\n\tenableGitHubCopilotModel,\n\tgetBaseUrlFromToken,\n\tgetGitHubCopilotBaseUrl,\n\tloginGitHubCopilot,\n\tnormalizeDomain,\n\trefreshGitHubCopilotToken,\n} from \"./github-copilot.js\";\n// Google Antigravity\nexport {\n\ttype AntigravityCredentials,\n\tloginAntigravity,\n\trefreshAntigravityToken,\n} from \"./google-antigravity.js\";\n// Google Gemini CLI\nexport {\n\ttype GoogleCloudCredentials,\n\tloginGeminiCli,\n\trefreshGoogleCloudToken,\n} from \"./google-gemini-cli.js\";\n// Storage\nexport {\n\tgetOAuthPath,\n\thasOAuthCredentials,\n\tlistOAuthProviders,\n\tloadOAuthCredentials,\n\tloadOAuthStorage,\n\ttype OAuthCredentials,\n\ttype OAuthProvider,\n\ttype OAuthStorage,\n\ttype OAuthStorageBackend,\n\tremoveOAuthCredentials,\n\tresetOAuthStorage,\n\tsaveOAuthCredentials,\n\tsetOAuthStorage,\n} from \"./storage.js\";\n\n// ============================================================================\n// High-level API\n// ============================================================================\n\nimport { refreshAnthropicToken } from \"./anthropic.js\";\nimport { refreshGitHubCopilotToken } from \"./github-copilot.js\";\nimport { refreshAntigravityToken } from \"./google-antigravity.js\";\nimport { refreshGoogleCloudToken } from \"./google-gemini-cli.js\";\nimport type { OAuthCredentials, OAuthProvider } from \"./storage.js\";\nimport { loadOAuthCredentials, removeOAuthCredentials, saveOAuthCredentials } from \"./storage.js\";\n\n/**\n * Refresh token for any OAuth provider.\n * Saves the new credentials and returns the new access token.\n */\nexport async function refreshToken(provider: OAuthProvider): Promise<string> {\n\tconst credentials = loadOAuthCredentials(provider);\n\tif (!credentials) {\n\t\tthrow new Error(`No OAuth credentials found for ${provider}`);\n\t}\n\n\tlet newCredentials: OAuthCredentials;\n\n\tswitch (provider) {\n\t\tcase \"anthropic\":\n\t\t\tnewCredentials = await refreshAnthropicToken(credentials.refresh);\n\t\t\tbreak;\n\t\tcase \"github-copilot\":\n\t\t\tnewCredentials = await refreshGitHubCopilotToken(credentials.refresh, credentials.enterpriseUrl);\n\t\t\tbreak;\n\t\tcase \"google-gemini-cli\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Google Cloud credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshGoogleCloudToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"google-antigravity\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Antigravity credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshAntigravityToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown OAuth provider: ${provider}`);\n\t}\n\n\tsaveOAuthCredentials(provider, newCredentials);\n\treturn newCredentials.access;\n}\n\n/**\n * Get API key for a provider from OAuth credentials.\n * Automatically refreshes expired tokens.\n *\n * For google-gemini-cli and antigravity, returns JSON-encoded { token, projectId }\n *\n * @returns API key string, or null if no credentials\n */\nexport async function getOAuthApiKey(provider: OAuthProvider): Promise<string | null> {\n\tconst credentials = loadOAuthCredentials(provider);\n\tif (!credentials) {\n\t\treturn null;\n\t}\n\n\t// Providers that need projectId in the API key\n\tconst needsProjectId = provider === \"google-gemini-cli\" || provider === \"google-antigravity\";\n\n\t// Check if expired\n\tif (Date.now() >= credentials.expires) {\n\t\ttry {\n\t\t\tconst newToken = await refreshToken(provider);\n\n\t\t\t// For providers that need projectId, return JSON\n\t\t\tif (needsProjectId) {\n\t\t\t\tconst refreshedCreds = loadOAuthCredentials(provider);\n\t\t\t\tif (refreshedCreds?.projectId) {\n\t\t\t\t\treturn JSON.stringify({ token: newToken, projectId: refreshedCreds.projectId });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn newToken;\n\t\t} catch (error) {\n\t\t\tconsole.error(`Failed to refresh OAuth token for ${provider}:`, error);\n\t\t\tremoveOAuthCredentials(provider);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// For providers that need projectId, return JSON\n\tif (needsProjectId) {\n\t\tif (!credentials.projectId) {\n\t\t\treturn null;\n\t\t}\n\t\treturn JSON.stringify({ token: credentials.access, projectId: credentials.projectId });\n\t}\n\n\treturn credentials.access;\n}\n\n/**\n * Map model provider to OAuth provider.\n * Returns undefined if the provider doesn't use OAuth.\n */\nexport function getOAuthProviderForModelProvider(modelProvider: string): OAuthProvider | undefined {\n\tconst mapping: Record<string, OAuthProvider> = {\n\t\tanthropic: \"anthropic\",\n\t\t\"github-copilot\": \"github-copilot\",\n\t\t\"google-gemini-cli\": \"google-gemini-cli\",\n\t\t\"google-antigravity\": \"google-antigravity\",\n\t};\n\treturn mapping[modelProvider];\n}\n\n// ============================================================================\n// Login/Logout types for convenience\n// ============================================================================\n\nexport type OAuthPrompt = {\n\tmessage: string;\n\tplaceholder?: string;\n\tallowEmpty?: boolean;\n};\n\nexport type OAuthAuthInfo = {\n\turl: string;\n\tinstructions?: string;\n};\n\nexport interface OAuthProviderInfo {\n\tid: OAuthProvider;\n\tname: string;\n\tavailable: boolean;\n}\n\n/**\n * Get list of OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInfo[] {\n\treturn [\n\t\t{\n\t\t\tid: \"anthropic\",\n\t\t\tname: \"Anthropic (Claude Pro/Max)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"github-copilot\",\n\t\t\tname: \"GitHub Copilot\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-gemini-cli\",\n\t\t\tname: \"Google Cloud Code Assist (Gemini CLI)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-antigravity\",\n\t\t\tname: \"Antigravity (Gemini 3, Claude, GPT-OSS)\",\n\t\t\tavailable: true,\n\t\t},\n\t];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/oauth/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OAuth credential management for AI providers.\n *\n * This module handles login, token refresh, and credential storage\n * for OAuth-based providers:\n * - Anthropic (Claude Pro/Max)\n * - GitHub Copilot\n * - Google Cloud Code Assist (Gemini CLI)\n * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud)\n */\n\n// Anthropic\nexport { loginAnthropic, refreshAnthropicToken } from \"./anthropic.js\";\n// GitHub Copilot\nexport {\n\tgetGitHubCopilotBaseUrl,\n\tloginGitHubCopilot,\n\tnormalizeDomain,\n\trefreshGitHubCopilotToken,\n} from \"./github-copilot.js\";\n// Google Antigravity\nexport {\n\tloginAntigravity,\n\trefreshAntigravityToken,\n} from \"./google-antigravity.js\";\n// Google Gemini CLI\nexport {\n\tloginGeminiCli,\n\trefreshGoogleCloudToken,\n} from \"./google-gemini-cli.js\";\n\nexport * from \"./types.js\";\n\n// ============================================================================\n// High-level API\n// ============================================================================\n\nimport { refreshAnthropicToken } from \"./anthropic.js\";\nimport { refreshGitHubCopilotToken } from \"./github-copilot.js\";\nimport { refreshAntigravityToken } from \"./google-antigravity.js\";\nimport { refreshGoogleCloudToken } from \"./google-gemini-cli.js\";\nimport type { OAuthCredentials, OAuthProvider, OAuthProviderInfo } from \"./types.js\";\n\n/**\n * Refresh token for any OAuth provider.\n * Saves the new credentials and returns the new access token.\n */\nexport async function refreshOAuthToken(\n\tprovider: OAuthProvider,\n\tcredentials: OAuthCredentials,\n): Promise<OAuthCredentials> {\n\tif (!credentials) {\n\t\tthrow new Error(`No OAuth credentials found for ${provider}`);\n\t}\n\n\tlet newCredentials: OAuthCredentials;\n\n\tswitch (provider) {\n\t\tcase \"anthropic\":\n\t\t\tnewCredentials = await refreshAnthropicToken(credentials.refresh);\n\t\t\tbreak;\n\t\tcase \"github-copilot\":\n\t\t\tnewCredentials = await refreshGitHubCopilotToken(credentials.refresh, credentials.enterpriseUrl);\n\t\t\tbreak;\n\t\tcase \"google-gemini-cli\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Google Cloud credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshGoogleCloudToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tcase \"google-antigravity\":\n\t\t\tif (!credentials.projectId) {\n\t\t\t\tthrow new Error(\"Antigravity credentials missing projectId\");\n\t\t\t}\n\t\t\tnewCredentials = await refreshAntigravityToken(credentials.refresh, credentials.projectId);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown OAuth provider: ${provider}`);\n\t}\n\n\treturn newCredentials;\n}\n\n/**\n * Get API key for a provider from OAuth credentials.\n * Automatically refreshes expired tokens.\n *\n * For google-gemini-cli and antigravity, returns JSON-encoded { token, projectId }\n *\n * @returns API key string, or null if no credentials\n * @throws Error if refresh fails\n */\nexport async function getOAuthApiKey(\n\tprovider: OAuthProvider,\n\tcredentials: Record<string, OAuthCredentials>,\n): Promise<{ newCredentials: OAuthCredentials; apiKey: string } | null> {\n\tlet creds = credentials[provider];\n\tif (!creds) {\n\t\treturn null;\n\t}\n\n\t// Refresh if expired\n\tif (Date.now() >= creds.expires) {\n\t\ttry {\n\t\t\tcreds = await refreshOAuthToken(provider, creds);\n\t\t} catch (_error) {\n\t\t\tthrow new Error(`Failed to refresh OAuth token for ${provider}`);\n\t\t}\n\t}\n\n\t// For providers that need projectId, return JSON\n\tconst needsProjectId = provider === \"google-gemini-cli\" || provider === \"google-antigravity\";\n\tconst apiKey = needsProjectId ? JSON.stringify({ token: creds.access, projectId: creds.projectId }) : creds.access;\n\treturn { newCredentials: creds, apiKey };\n}\n\n/**\n * Get list of OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInfo[] {\n\treturn [\n\t\t{\n\t\t\tid: \"anthropic\",\n\t\t\tname: \"Anthropic (Claude Pro/Max)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"github-copilot\",\n\t\t\tname: \"GitHub Copilot\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-gemini-cli\",\n\t\t\tname: \"Google Cloud Code Assist (Gemini CLI)\",\n\t\t\tavailable: true,\n\t\t},\n\t\t{\n\t\t\tid: \"google-antigravity\",\n\t\t\tname: \"Antigravity (Gemini 3, Claude, GPT-OSS)\",\n\t\t\tavailable: true,\n\t\t},\n\t];\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type OAuthCredentials = {
|
|
2
|
+
refresh: string;
|
|
3
|
+
access: string;
|
|
4
|
+
expires: number;
|
|
5
|
+
enterpriseUrl?: string;
|
|
6
|
+
projectId?: string;
|
|
7
|
+
email?: string;
|
|
8
|
+
};
|
|
9
|
+
export type OAuthProvider = "anthropic" | "github-copilot" | "google-gemini-cli" | "google-antigravity";
|
|
10
|
+
export type OAuthPrompt = {
|
|
11
|
+
message: string;
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
allowEmpty?: boolean;
|
|
14
|
+
};
|
|
15
|
+
export type OAuthAuthInfo = {
|
|
16
|
+
url: string;
|
|
17
|
+
instructions?: string;
|
|
18
|
+
};
|
|
19
|
+
export interface OAuthProviderInfo {
|
|
20
|
+
id: OAuthProvider;
|
|
21
|
+
name: string;
|
|
22
|
+
available: boolean;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;AAExG,MAAM,MAAM,WAAW,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,iBAAiB;IACjC,EAAE,EAAE,aAAa,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACnB","sourcesContent":["export type OAuthCredentials = {\n\trefresh: string;\n\taccess: string;\n\texpires: number;\n\tenterpriseUrl?: string;\n\tprojectId?: string;\n\temail?: string;\n};\n\nexport type OAuthProvider = \"anthropic\" | \"github-copilot\" | \"google-gemini-cli\" | \"google-antigravity\";\n\nexport type OAuthPrompt = {\n\tmessage: string;\n\tplaceholder?: string;\n\tallowEmpty?: boolean;\n};\n\nexport type OAuthAuthInfo = {\n\turl: string;\n\tinstructions?: string;\n};\n\nexport interface OAuthProviderInfo {\n\tid: OAuthProvider;\n\tname: string;\n\tavailable: boolean;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/oauth/types.ts"],"names":[],"mappings":"","sourcesContent":["export type OAuthCredentials = {\n\trefresh: string;\n\taccess: string;\n\texpires: number;\n\tenterpriseUrl?: string;\n\tprojectId?: string;\n\temail?: string;\n};\n\nexport type OAuthProvider = \"anthropic\" | \"github-copilot\" | \"google-gemini-cli\" | \"google-antigravity\";\n\nexport type OAuthPrompt = {\n\tmessage: string;\n\tplaceholder?: string;\n\tallowEmpty?: boolean;\n};\n\nexport type OAuthAuthInfo = {\n\turl: string;\n\tinstructions?: string;\n};\n\nexport interface OAuthProviderInfo {\n\tid: OAuthProvider;\n\tname: string;\n\tavailable: boolean;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mariozechner/pi-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"pi-ai": "./dist/cli.js"
|
|
10
|
+
},
|
|
8
11
|
"files": [
|
|
9
12
|
"dist",
|
|
10
13
|
"README.md"
|
|
@@ -15,7 +18,6 @@
|
|
|
15
18
|
"build": "npm run generate-models && tsgo -p tsconfig.build.json",
|
|
16
19
|
"dev": "tsgo -p tsconfig.build.json --watch --preserveWatchOutput",
|
|
17
20
|
"dev:tsc": "tsgo -p tsconfig.build.json --watch --preserveWatchOutput",
|
|
18
|
-
"check": "biome check --write . && tsgo --noEmit",
|
|
19
21
|
"test": "vitest --run",
|
|
20
22
|
"prepublishOnly": "npm run clean && npm run build"
|
|
21
23
|
},
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OAuth credential storage with configurable backend.
|
|
3
|
-
*
|
|
4
|
-
* Default: ~/.pi/agent/oauth.json
|
|
5
|
-
* Override with setOAuthStorage() for custom storage locations or backends.
|
|
6
|
-
*/
|
|
7
|
-
export interface OAuthCredentials {
|
|
8
|
-
type: "oauth";
|
|
9
|
-
refresh: string;
|
|
10
|
-
access: string;
|
|
11
|
-
expires: number;
|
|
12
|
-
enterpriseUrl?: string;
|
|
13
|
-
projectId?: string;
|
|
14
|
-
email?: string;
|
|
15
|
-
}
|
|
16
|
-
export interface OAuthStorage {
|
|
17
|
-
[provider: string]: OAuthCredentials;
|
|
18
|
-
}
|
|
19
|
-
export type OAuthProvider = "anthropic" | "github-copilot" | "google-gemini-cli" | "google-antigravity";
|
|
20
|
-
/**
|
|
21
|
-
* Storage backend interface.
|
|
22
|
-
* Implement this to use a custom storage location or backend.
|
|
23
|
-
*/
|
|
24
|
-
export interface OAuthStorageBackend {
|
|
25
|
-
/** Load all OAuth credentials. Return empty object if none exist. */
|
|
26
|
-
load(): OAuthStorage;
|
|
27
|
-
/** Save all OAuth credentials. */
|
|
28
|
-
save(storage: OAuthStorage): void;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Configure the OAuth storage backend.
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* // Custom file path
|
|
35
|
-
* setOAuthStorage({
|
|
36
|
-
* load: () => JSON.parse(readFileSync('/custom/path/oauth.json', 'utf-8')),
|
|
37
|
-
* save: (storage) => writeFileSync('/custom/path/oauth.json', JSON.stringify(storage))
|
|
38
|
-
* });
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* // In-memory storage (for testing)
|
|
42
|
-
* let memoryStorage = {};
|
|
43
|
-
* setOAuthStorage({
|
|
44
|
-
* load: () => memoryStorage,
|
|
45
|
-
* save: (storage) => { memoryStorage = storage; }
|
|
46
|
-
* });
|
|
47
|
-
*/
|
|
48
|
-
export declare function setOAuthStorage(backend: OAuthStorageBackend): void;
|
|
49
|
-
/**
|
|
50
|
-
* Reset to default filesystem storage (~/.pi/agent/oauth.json)
|
|
51
|
-
*/
|
|
52
|
-
export declare function resetOAuthStorage(): void;
|
|
53
|
-
/**
|
|
54
|
-
* Get the default OAuth path (for reference, may not be used if custom backend is set)
|
|
55
|
-
*/
|
|
56
|
-
export declare function getOAuthPath(): string;
|
|
57
|
-
/**
|
|
58
|
-
* Load all OAuth credentials
|
|
59
|
-
*/
|
|
60
|
-
export declare function loadOAuthStorage(): OAuthStorage;
|
|
61
|
-
/**
|
|
62
|
-
* Load OAuth credentials for a specific provider
|
|
63
|
-
*/
|
|
64
|
-
export declare function loadOAuthCredentials(provider: string): OAuthCredentials | null;
|
|
65
|
-
/**
|
|
66
|
-
* Save OAuth credentials for a specific provider
|
|
67
|
-
*/
|
|
68
|
-
export declare function saveOAuthCredentials(provider: string, creds: OAuthCredentials): void;
|
|
69
|
-
/**
|
|
70
|
-
* Remove OAuth credentials for a specific provider
|
|
71
|
-
*/
|
|
72
|
-
export declare function removeOAuthCredentials(provider: string): void;
|
|
73
|
-
/**
|
|
74
|
-
* Check if OAuth credentials exist for a provider
|
|
75
|
-
*/
|
|
76
|
-
export declare function hasOAuthCredentials(provider: string): boolean;
|
|
77
|
-
/**
|
|
78
|
-
* List all providers with OAuth credentials
|
|
79
|
-
*/
|
|
80
|
-
export declare function listOAuthProviders(): string[];
|
|
81
|
-
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/utils/oauth/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC5B,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAAC;CACrC;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;AAExG;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,qEAAqE;IACrE,IAAI,IAAI,YAAY,CAAC;IACrB,kCAAkC;IAClC,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CAClC;AAsCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAElE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAE/C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAG9E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAIpF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAI7D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAG7C","sourcesContent":["/**\n * OAuth credential storage with configurable backend.\n *\n * Default: ~/.pi/agent/oauth.json\n * Override with setOAuthStorage() for custom storage locations or backends.\n */\n\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join } from \"path\";\n\nexport interface OAuthCredentials {\n\ttype: \"oauth\";\n\trefresh: string;\n\taccess: string;\n\texpires: number;\n\tenterpriseUrl?: string;\n\tprojectId?: string;\n\temail?: string;\n}\n\nexport interface OAuthStorage {\n\t[provider: string]: OAuthCredentials;\n}\n\nexport type OAuthProvider = \"anthropic\" | \"github-copilot\" | \"google-gemini-cli\" | \"google-antigravity\";\n\n/**\n * Storage backend interface.\n * Implement this to use a custom storage location or backend.\n */\nexport interface OAuthStorageBackend {\n\t/** Load all OAuth credentials. Return empty object if none exist. */\n\tload(): OAuthStorage;\n\t/** Save all OAuth credentials. */\n\tsave(storage: OAuthStorage): void;\n}\n\n// ============================================================================\n// Default filesystem backend\n// ============================================================================\n\nconst DEFAULT_PATH = join(homedir(), \".pi\", \"agent\", \"oauth.json\");\n\nfunction defaultLoad(): OAuthStorage {\n\tif (!existsSync(DEFAULT_PATH)) {\n\t\treturn {};\n\t}\n\ttry {\n\t\tconst content = readFileSync(DEFAULT_PATH, \"utf-8\");\n\t\treturn JSON.parse(content);\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction defaultSave(storage: OAuthStorage): void {\n\tconst configDir = dirname(DEFAULT_PATH);\n\tif (!existsSync(configDir)) {\n\t\tmkdirSync(configDir, { recursive: true, mode: 0o700 });\n\t}\n\twriteFileSync(DEFAULT_PATH, JSON.stringify(storage, null, 2), \"utf-8\");\n\tchmodSync(DEFAULT_PATH, 0o600);\n}\n\n// ============================================================================\n// Configurable backend\n// ============================================================================\n\nlet currentBackend: OAuthStorageBackend = {\n\tload: defaultLoad,\n\tsave: defaultSave,\n};\n\n/**\n * Configure the OAuth storage backend.\n *\n * @example\n * // Custom file path\n * setOAuthStorage({\n * load: () => JSON.parse(readFileSync('/custom/path/oauth.json', 'utf-8')),\n * save: (storage) => writeFileSync('/custom/path/oauth.json', JSON.stringify(storage))\n * });\n *\n * @example\n * // In-memory storage (for testing)\n * let memoryStorage = {};\n * setOAuthStorage({\n * load: () => memoryStorage,\n * save: (storage) => { memoryStorage = storage; }\n * });\n */\nexport function setOAuthStorage(backend: OAuthStorageBackend): void {\n\tcurrentBackend = backend;\n}\n\n/**\n * Reset to default filesystem storage (~/.pi/agent/oauth.json)\n */\nexport function resetOAuthStorage(): void {\n\tcurrentBackend = { load: defaultLoad, save: defaultSave };\n}\n\n/**\n * Get the default OAuth path (for reference, may not be used if custom backend is set)\n */\nexport function getOAuthPath(): string {\n\treturn DEFAULT_PATH;\n}\n\n// ============================================================================\n// Public API (uses current backend)\n// ============================================================================\n\n/**\n * Load all OAuth credentials\n */\nexport function loadOAuthStorage(): OAuthStorage {\n\treturn currentBackend.load();\n}\n\n/**\n * Load OAuth credentials for a specific provider\n */\nexport function loadOAuthCredentials(provider: string): OAuthCredentials | null {\n\tconst storage = currentBackend.load();\n\treturn storage[provider] || null;\n}\n\n/**\n * Save OAuth credentials for a specific provider\n */\nexport function saveOAuthCredentials(provider: string, creds: OAuthCredentials): void {\n\tconst storage = currentBackend.load();\n\tstorage[provider] = creds;\n\tcurrentBackend.save(storage);\n}\n\n/**\n * Remove OAuth credentials for a specific provider\n */\nexport function removeOAuthCredentials(provider: string): void {\n\tconst storage = currentBackend.load();\n\tdelete storage[provider];\n\tcurrentBackend.save(storage);\n}\n\n/**\n * Check if OAuth credentials exist for a provider\n */\nexport function hasOAuthCredentials(provider: string): boolean {\n\treturn loadOAuthCredentials(provider) !== null;\n}\n\n/**\n * List all providers with OAuth credentials\n */\nexport function listOAuthProviders(): string[] {\n\tconst storage = currentBackend.load();\n\treturn Object.keys(storage);\n}\n"]}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OAuth credential storage with configurable backend.
|
|
3
|
-
*
|
|
4
|
-
* Default: ~/.pi/agent/oauth.json
|
|
5
|
-
* Override with setOAuthStorage() for custom storage locations or backends.
|
|
6
|
-
*/
|
|
7
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
8
|
-
import { homedir } from "os";
|
|
9
|
-
import { dirname, join } from "path";
|
|
10
|
-
// ============================================================================
|
|
11
|
-
// Default filesystem backend
|
|
12
|
-
// ============================================================================
|
|
13
|
-
const DEFAULT_PATH = join(homedir(), ".pi", "agent", "oauth.json");
|
|
14
|
-
function defaultLoad() {
|
|
15
|
-
if (!existsSync(DEFAULT_PATH)) {
|
|
16
|
-
return {};
|
|
17
|
-
}
|
|
18
|
-
try {
|
|
19
|
-
const content = readFileSync(DEFAULT_PATH, "utf-8");
|
|
20
|
-
return JSON.parse(content);
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return {};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function defaultSave(storage) {
|
|
27
|
-
const configDir = dirname(DEFAULT_PATH);
|
|
28
|
-
if (!existsSync(configDir)) {
|
|
29
|
-
mkdirSync(configDir, { recursive: true, mode: 0o700 });
|
|
30
|
-
}
|
|
31
|
-
writeFileSync(DEFAULT_PATH, JSON.stringify(storage, null, 2), "utf-8");
|
|
32
|
-
chmodSync(DEFAULT_PATH, 0o600);
|
|
33
|
-
}
|
|
34
|
-
// ============================================================================
|
|
35
|
-
// Configurable backend
|
|
36
|
-
// ============================================================================
|
|
37
|
-
let currentBackend = {
|
|
38
|
-
load: defaultLoad,
|
|
39
|
-
save: defaultSave,
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* Configure the OAuth storage backend.
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* // Custom file path
|
|
46
|
-
* setOAuthStorage({
|
|
47
|
-
* load: () => JSON.parse(readFileSync('/custom/path/oauth.json', 'utf-8')),
|
|
48
|
-
* save: (storage) => writeFileSync('/custom/path/oauth.json', JSON.stringify(storage))
|
|
49
|
-
* });
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* // In-memory storage (for testing)
|
|
53
|
-
* let memoryStorage = {};
|
|
54
|
-
* setOAuthStorage({
|
|
55
|
-
* load: () => memoryStorage,
|
|
56
|
-
* save: (storage) => { memoryStorage = storage; }
|
|
57
|
-
* });
|
|
58
|
-
*/
|
|
59
|
-
export function setOAuthStorage(backend) {
|
|
60
|
-
currentBackend = backend;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Reset to default filesystem storage (~/.pi/agent/oauth.json)
|
|
64
|
-
*/
|
|
65
|
-
export function resetOAuthStorage() {
|
|
66
|
-
currentBackend = { load: defaultLoad, save: defaultSave };
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Get the default OAuth path (for reference, may not be used if custom backend is set)
|
|
70
|
-
*/
|
|
71
|
-
export function getOAuthPath() {
|
|
72
|
-
return DEFAULT_PATH;
|
|
73
|
-
}
|
|
74
|
-
// ============================================================================
|
|
75
|
-
// Public API (uses current backend)
|
|
76
|
-
// ============================================================================
|
|
77
|
-
/**
|
|
78
|
-
* Load all OAuth credentials
|
|
79
|
-
*/
|
|
80
|
-
export function loadOAuthStorage() {
|
|
81
|
-
return currentBackend.load();
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Load OAuth credentials for a specific provider
|
|
85
|
-
*/
|
|
86
|
-
export function loadOAuthCredentials(provider) {
|
|
87
|
-
const storage = currentBackend.load();
|
|
88
|
-
return storage[provider] || null;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Save OAuth credentials for a specific provider
|
|
92
|
-
*/
|
|
93
|
-
export function saveOAuthCredentials(provider, creds) {
|
|
94
|
-
const storage = currentBackend.load();
|
|
95
|
-
storage[provider] = creds;
|
|
96
|
-
currentBackend.save(storage);
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Remove OAuth credentials for a specific provider
|
|
100
|
-
*/
|
|
101
|
-
export function removeOAuthCredentials(provider) {
|
|
102
|
-
const storage = currentBackend.load();
|
|
103
|
-
delete storage[provider];
|
|
104
|
-
currentBackend.save(storage);
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Check if OAuth credentials exist for a provider
|
|
108
|
-
*/
|
|
109
|
-
export function hasOAuthCredentials(provider) {
|
|
110
|
-
return loadOAuthCredentials(provider) !== null;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* List all providers with OAuth credentials
|
|
114
|
-
*/
|
|
115
|
-
export function listOAuthProviders() {
|
|
116
|
-
const storage = currentBackend.load();
|
|
117
|
-
return Object.keys(storage);
|
|
118
|
-
}
|
|
119
|
-
//# sourceMappingURL=storage.js.map
|