when-does-my-quota-refresh 1.0.0 → 1.1.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/dist/{auth-S43EEJYA.js → auth-XYJBJA2Q.js} +2 -2
- package/dist/{chunk-YZVX5QIP.js → chunk-ST6OOHQI.js} +11 -9
- package/dist/chunk-ST6OOHQI.js.map +1 -0
- package/dist/cli/index.js +3 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/sdk/index.d.ts +12 -5
- package/dist/sdk/index.js +11 -9
- package/dist/sdk/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-YZVX5QIP.js.map +0 -1
- /package/dist/{auth-S43EEJYA.js.map → auth-XYJBJA2Q.js.map} +0 -0
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
completeManualLogin,
|
|
4
4
|
getManualLoginUrl,
|
|
5
5
|
loginAccount
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ST6OOHQI.js";
|
|
7
7
|
export {
|
|
8
8
|
completeManualLogin,
|
|
9
9
|
getManualLoginUrl,
|
|
10
10
|
loginAccount
|
|
11
11
|
};
|
|
12
|
-
//# sourceMappingURL=auth-
|
|
12
|
+
//# sourceMappingURL=auth-XYJBJA2Q.js.map
|
|
@@ -28,9 +28,9 @@ var CLOUD_CODE_DEFAULT_BODY = {
|
|
|
28
28
|
var OAUTH_CLIENT_ID = "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com";
|
|
29
29
|
var OAUTH_CLIENT_SECRET = "d-FL95Q19q7MQmFpd7hHD0Ty";
|
|
30
30
|
var OAUTH_SCOPES = [
|
|
31
|
-
"https://www.googleapis.com/auth/cloud-platform"
|
|
32
|
-
"https://www.googleapis.com/auth/cloudcode"
|
|
31
|
+
"https://www.googleapis.com/auth/cloud-platform"
|
|
33
32
|
].join(" ");
|
|
33
|
+
var OAUTH_REDIRECT_URI = "http://127.0.0.1:0/callback";
|
|
34
34
|
|
|
35
35
|
// src/sources/oauth/client.ts
|
|
36
36
|
var OAuthClient = class {
|
|
@@ -41,10 +41,10 @@ var OAuthClient = class {
|
|
|
41
41
|
/**
|
|
42
42
|
* Generate the OAuth authorization URL for user login
|
|
43
43
|
*/
|
|
44
|
-
getAuthUrl() {
|
|
44
|
+
getAuthUrl(redirectUri) {
|
|
45
45
|
const params = new URLSearchParams({
|
|
46
46
|
client_id: OAUTH_CLIENT_ID,
|
|
47
|
-
redirect_uri:
|
|
47
|
+
redirect_uri: redirectUri || OAUTH_REDIRECT_URI,
|
|
48
48
|
response_type: "code",
|
|
49
49
|
scope: OAUTH_SCOPES,
|
|
50
50
|
access_type: "offline",
|
|
@@ -55,12 +55,12 @@ var OAuthClient = class {
|
|
|
55
55
|
/**
|
|
56
56
|
* Exchange an authorization code for tokens
|
|
57
57
|
*/
|
|
58
|
-
async exchangeCode(code) {
|
|
58
|
+
async exchangeCode(code, redirectUri) {
|
|
59
59
|
const body = new URLSearchParams({
|
|
60
60
|
code,
|
|
61
61
|
client_id: OAUTH_CLIENT_ID,
|
|
62
62
|
client_secret: OAUTH_CLIENT_SECRET,
|
|
63
|
-
redirect_uri:
|
|
63
|
+
redirect_uri: redirectUri || OAUTH_REDIRECT_URI,
|
|
64
64
|
grant_type: "authorization_code"
|
|
65
65
|
});
|
|
66
66
|
const response = await this.postUrlEncoded("https://oauth2.googleapis.com/token", body);
|
|
@@ -396,8 +396,8 @@ import http from "http";
|
|
|
396
396
|
import { URL as URL2 } from "url";
|
|
397
397
|
async function loginAccount() {
|
|
398
398
|
const client = new OAuthClient();
|
|
399
|
-
const authUrl = client.getAuthUrl();
|
|
400
399
|
debug("auth", "Starting OAuth login flow");
|
|
400
|
+
let capturedRedirectUri = "http://127.0.0.1:0/callback";
|
|
401
401
|
const code = await new Promise((resolve, reject) => {
|
|
402
402
|
const server = http.createServer(async (req, res) => {
|
|
403
403
|
const url = new URL2(req.url || "/", `http://127.0.0.1`);
|
|
@@ -428,7 +428,9 @@ async function loginAccount() {
|
|
|
428
428
|
server.listen(0, "127.0.0.1", () => {
|
|
429
429
|
const addr = server.address();
|
|
430
430
|
if (typeof addr === "object" && addr) {
|
|
431
|
+
capturedRedirectUri = `http://127.0.0.1:${addr.port}/callback`;
|
|
431
432
|
debug("auth", `Callback server on port ${addr.port}`);
|
|
433
|
+
const authUrl = client.getAuthUrl(capturedRedirectUri);
|
|
432
434
|
open(authUrl).catch(() => {
|
|
433
435
|
console.log(`
|
|
434
436
|
Open this URL in your browser:
|
|
@@ -443,7 +445,7 @@ ${authUrl}
|
|
|
443
445
|
reject(new AuthError("Login timed out after 5 minutes"));
|
|
444
446
|
}, 5 * 60 * 1e3);
|
|
445
447
|
});
|
|
446
|
-
const tokens = await client.exchangeCode(code);
|
|
448
|
+
const tokens = await client.exchangeCode(code, capturedRedirectUri);
|
|
447
449
|
const email = tokens.email || "unknown@gmail.com";
|
|
448
450
|
tokens.email = email;
|
|
449
451
|
saveAccountTokens(email, tokens);
|
|
@@ -484,4 +486,4 @@ export {
|
|
|
484
486
|
getManualLoginUrl,
|
|
485
487
|
completeManualLogin
|
|
486
488
|
};
|
|
487
|
-
//# sourceMappingURL=chunk-
|
|
489
|
+
//# sourceMappingURL=chunk-ST6OOHQI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sources/oauth/client.ts","../src/sources/cloud-code-api.ts","../src/sdk/accounts/storage.ts","../src/core/config.ts","../src/core/logger.ts","../src/core/errors.ts","../src/sdk/accounts/auth.ts"],"sourcesContent":["/**\n * Google OAuth client for Cloud Code API\n *\n * Handles the OAuth2 flow for remote quota fetching.\n */\n\nimport https from 'https'\nimport { URL } from 'url'\nimport { debug } from '../../core/logger.js'\nimport type { OAuthTokenResponse, StoredTokens } from '../../sdk/types.js'\nimport {\n CLOUD_CODE_ENDPOINTS,\n CLOUD_CODE_DEFAULT_BODY,\n OAUTH_CLIENT_ID,\n OAUTH_CLIENT_SECRET,\n OAUTH_SCOPES,\n OAUTH_REDIRECT_URI,\n} from '../cloud-code-api.js'\n\nexport class OAuthClient {\n private tokens: StoredTokens | null = null\n\n constructor(tokens?: StoredTokens) {\n this.tokens = tokens || null\n }\n\n /**\n * Generate the OAuth authorization URL for user login\n */\n getAuthUrl(redirectUri?: string): string {\n const params = new URLSearchParams({\n client_id: OAUTH_CLIENT_ID,\n redirect_uri: redirectUri || OAUTH_REDIRECT_URI,\n response_type: 'code',\n scope: OAUTH_SCOPES,\n access_type: 'offline',\n prompt: 'consent',\n })\n return `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`\n }\n\n /**\n * Exchange an authorization code for tokens\n */\n async exchangeCode(code: string, redirectUri?: string): Promise<StoredTokens> {\n const body = new URLSearchParams({\n code,\n client_id: OAUTH_CLIENT_ID,\n client_secret: OAUTH_CLIENT_SECRET,\n redirect_uri: redirectUri || OAUTH_REDIRECT_URI,\n grant_type: 'authorization_code',\n })\n\n const response = await this.postUrlEncoded('https://oauth2.googleapis.com/token', body)\n const data = response as OAuthTokenResponse\n\n this.tokens = {\n accessToken: data.access_token,\n refreshToken: data.refresh_token || '',\n expiresAt: Date.now() + data.expires_in * 1000,\n }\n\n return this.tokens\n }\n\n /**\n * Refresh the access token\n */\n async refreshAccessToken(): Promise<StoredTokens> {\n if (!this.tokens?.refreshToken) {\n throw new Error('No refresh token available')\n }\n\n const body = new URLSearchParams({\n client_id: OAUTH_CLIENT_ID,\n client_secret: OAUTH_CLIENT_SECRET,\n refresh_token: this.tokens.refreshToken,\n grant_type: 'refresh_token',\n })\n\n const response = await this.postUrlEncoded('https://oauth2.googleapis.com/token', body)\n const data = response as OAuthTokenResponse\n\n this.tokens = {\n ...this.tokens,\n accessToken: data.access_token,\n expiresAt: Date.now() + data.expires_in * 1000,\n }\n\n return this.tokens\n }\n\n /**\n * Get a valid access token, refreshing if necessary\n */\n async getAccessToken(): Promise<string> {\n if (!this.tokens) throw new Error('Not authenticated')\n if (Date.now() >= this.tokens.expiresAt - 60000) {\n await this.refreshAccessToken()\n }\n return this.tokens.accessToken!\n }\n\n /**\n * Get stored tokens\n */\n getTokens(): StoredTokens | null {\n return this.tokens\n }\n\n /**\n * Make an authenticated POST request to the Cloud Code API\n */\n async fetchQuotaSummary(): Promise<unknown> {\n const token = await this.getAccessToken()\n return this.authenticatedPost(\n CLOUD_CODE_ENDPOINTS.retrieveUserQuotaSummary,\n CLOUD_CODE_DEFAULT_BODY,\n token\n )\n }\n\n async fetchUserStatus(): Promise<unknown> {\n const token = await this.getAccessToken()\n return this.authenticatedPost(\n CLOUD_CODE_ENDPOINTS.loadCodeAssist,\n CLOUD_CODE_DEFAULT_BODY,\n token\n )\n }\n\n async fetchAvailableModels(): Promise<unknown> {\n const token = await this.getAccessToken()\n return this.authenticatedPost(\n CLOUD_CODE_ENDPOINTS.fetchAvailableModels,\n CLOUD_CODE_DEFAULT_BODY,\n token\n )\n }\n\n // ── HTTP Helpers ────────────────────────────────────────────────\n\n private authenticatedPost(url: string, body: unknown, token: string): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const parsed = new URL(url)\n const data = JSON.stringify(body)\n const options: https.RequestOptions = {\n hostname: parsed.hostname,\n path: parsed.pathname,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`,\n 'Content-Length': Buffer.byteLength(data),\n },\n timeout: 10000,\n }\n\n const req = https.request(options, (res) => {\n let responseData = ''\n res.on('data', (chunk: Buffer) => { responseData += chunk })\n res.on('end', () => {\n try {\n resolve(JSON.parse(responseData))\n } catch {\n reject(new Error(`Invalid JSON: ${responseData.slice(0, 200)}`))\n }\n })\n })\n req.on('error', reject)\n req.on('timeout', () => { req.destroy(); reject(new Error('Timeout')) })\n req.write(data)\n req.end()\n })\n }\n\n private postUrlEncoded(url: string, body: URLSearchParams): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const parsed = new URL(url)\n const data = body.toString()\n const options: https.RequestOptions = {\n hostname: parsed.hostname,\n path: parsed.pathname,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'Content-Length': Buffer.byteLength(data),\n },\n timeout: 10000,\n }\n\n const req = https.request(options, (res) => {\n let responseData = ''\n res.on('data', (chunk: Buffer) => { responseData += chunk })\n res.on('end', () => {\n try {\n resolve(JSON.parse(responseData))\n } catch {\n reject(new Error(`Invalid JSON: ${responseData.slice(0, 200)}`))\n }\n })\n })\n req.on('error', reject)\n req.on('timeout', () => { req.destroy(); reject(new Error('Timeout')) })\n req.write(data)\n req.end()\n })\n }\n}\n","/**\n * Google Cloud Code API endpoints for remote quota fetching\n *\n * Used as fallback when local sources are unavailable.\n * Requires OAuth authentication.\n */\n\nexport const CLOUD_CODE_ENDPOINTS = {\n /** Load code assist configuration */\n loadCodeAssist: 'https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist',\n\n /** Onboard a new user */\n onboardUser: 'https://cloudcode-pa.googleapis.com/v1internal:onboardUser',\n\n /** Fetch available models for the account */\n fetchAvailableModels: 'https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels',\n\n /** Fetch raw quota data */\n retrieveUserQuota: 'https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota',\n\n /** Fetch quota summary with weekly + session buckets */\n retrieveUserQuotaSummary: 'https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuotaSummary',\n} as const\n\nexport const CLOUD_CODE_DEFAULT_BODY = {\n metadata: {\n ideName: 'antigravity',\n extensionName: 'antigravity',\n locale: 'en',\n ideVersion: 'unknown',\n },\n}\n\nexport const OAUTH_CLIENT_ID = '764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com'\nexport const OAUTH_CLIENT_SECRET = 'd-FL95Q19q7MQmFpd7hHD0Ty'\nexport const OAUTH_SCOPES = [\n 'https://www.googleapis.com/auth/cloud-platform',\n].join(' ')\nexport const OAUTH_REDIRECT_URI = 'http://127.0.0.1:0/callback'\n","/**\n * Token storage for account credentials\n *\n * Stores OAuth tokens locally in the config directory.\n * Tokens are stored as plain JSON (local machine only).\n */\n\nimport { readFileSync, writeFileSync, existsSync, unlinkSync } from 'fs'\nimport { join } from 'path'\nimport type { StoredTokens } from '../types.js'\nimport { getConfigDirPath, ensureDirs } from '../../core/config.js'\nimport { debug } from '../../core/logger.js'\n\nconst TOKENS_DIR = 'accounts'\n\ninterface TokenAccount {\n email: string\n tokens: StoredTokens\n addedAt: string\n}\n\ninterface TokenStore {\n accounts: TokenAccount[]\n activeEmail?: string\n}\n\nfunction getStorePath(): string {\n return join(getConfigDirPath(), TOKENS_DIR, 'tokens.json')\n}\n\nfunction loadStore(): TokenStore {\n const path = getStorePath()\n if (!existsSync(path)) return { accounts: [] }\n try {\n return JSON.parse(readFileSync(path, 'utf-8'))\n } catch {\n return { accounts: [] }\n }\n}\n\nfunction saveStore(store: TokenStore): void {\n ensureDirs()\n writeFileSync(getStorePath(), JSON.stringify(store, null, 2))\n debug('account-storage', `Saved ${store.accounts.length} account(s)`)\n}\n\n/**\n * Save tokens for an account\n */\nexport function saveAccountTokens(email: string, tokens: StoredTokens): void {\n const store = loadStore()\n const existing = store.accounts.findIndex(a => a.email === email)\n const account: TokenAccount = {\n email,\n tokens,\n addedAt: new Date().toISOString(),\n }\n\n if (existing >= 0) {\n store.accounts[existing] = account\n } else {\n store.accounts.push(account)\n }\n\n // Set as active if it's the only one\n if (store.accounts.length === 1) {\n store.activeEmail = email\n }\n\n saveStore(store)\n}\n\n/**\n * Get tokens for a specific account\n */\nexport function getAccountTokens(email: string): StoredTokens | null {\n const store = loadStore()\n const account = store.accounts.find(a => a.email === email)\n return account?.tokens || null\n}\n\n/**\n * Get the active account's tokens\n */\nexport function getActiveAccountTokens(): StoredTokens | null {\n const store = loadStore()\n if (!store.activeEmail) return null\n const account = store.accounts.find(a => a.email === store.activeEmail)\n return account?.tokens || null\n}\n\n/**\n * Set the active account\n */\nexport function setActiveAccount(email: string): boolean {\n const store = loadStore()\n if (!store.accounts.find(a => a.email === email)) return false\n store.activeEmail = email\n saveStore(store)\n return true\n}\n\n/**\n * Remove an account\n */\nexport function removeAccount(email: string): boolean {\n const store = loadStore()\n const idx = store.accounts.findIndex(a => a.email === email)\n if (idx < 0) return false\n store.accounts.splice(idx, 1)\n if (store.activeEmail === email) {\n store.activeEmail = store.accounts[0]?.email\n }\n saveStore(store)\n return true\n}\n\n/**\n * List all stored accounts\n */\nexport function listAccounts(): Array<{ email: string; isActive: boolean; addedAt: string }> {\n const store = loadStore()\n return store.accounts.map(a => ({\n email: a.email,\n isActive: a.email === store.activeEmail,\n addedAt: a.addedAt,\n }))\n}\n\n/**\n * Get all stored tokens (for multi-account fetch)\n */\nexport function getAllAccountTokens(): StoredTokens[] {\n const store = loadStore()\n return store.accounts.map(a => a.tokens)\n}\n","/**\n * Config file management — reads/writes app configuration\n */\n\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'\nimport { join } from 'path'\nimport { homedir } from 'os'\nimport type { AppConfig } from '../sdk/types.js'\nimport { debug } from './logger.js'\n\nconst CONFIG_DIR_NAME = 'when-does-my-quota-refresh'\n\nconst DEFAULT_CONFIG: AppConfig = {\n defaultMode: 'local',\n cacheTtlMs: 5 * 60 * 1000, // 5 minutes\n refreshIntervalMs: 5 * 60 * 1000,\n wakeupModels: ['claude-sonnet-4-5', 'gemini-3-flash', 'gemini-3-pro-low'],\n wakeupAccounts: [],\n notifications: true,\n plugins: [],\n daemon: {\n pollIntervalMs: 60 * 1000,\n enabled: false,\n },\n}\n\nfunction getConfigDir(): string {\n const home = homedir()\n switch (process.platform) {\n case 'darwin':\n return join(home, 'Library', 'Application Support', CONFIG_DIR_NAME)\n case 'win32':\n return join(process.env.APPDATA || join(home, 'AppData', 'Roaming'), CONFIG_DIR_NAME)\n default:\n return join(home, '.config', CONFIG_DIR_NAME)\n }\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), 'config.json')\n}\n\nfunction getDataDir(): string {\n return join(getConfigDir(), 'data')\n}\n\nexport function ensureDirs(): void {\n const configDir = getConfigDir()\n const dataDir = getDataDir()\n if (!existsSync(configDir)) mkdirSync(configDir, { recursive: true })\n if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true })\n}\n\nexport function loadConfig(): AppConfig {\n try {\n const path = getConfigPath()\n if (!existsSync(path)) return DEFAULT_CONFIG\n const raw = readFileSync(path, 'utf-8')\n const parsed = JSON.parse(raw)\n debug('config', `Loaded config from ${path}`)\n return { ...DEFAULT_CONFIG, ...parsed }\n } catch (err) {\n debug('config', 'Failed to load config, using defaults', err)\n return DEFAULT_CONFIG\n }\n}\n\nexport function saveConfig(config: AppConfig): void {\n ensureDirs()\n const path = getConfigPath()\n writeFileSync(path, JSON.stringify(config, null, 2))\n debug('config', `Saved config to ${path}`)\n}\n\nexport function getConfigDirPath(): string {\n return getConfigDir()\n}\n\nexport function getDataDirPath(): string {\n return getDataDir()\n}\n\nexport { DEFAULT_CONFIG }\n","/**\n * Simple logger with debug flag\n */\n\nlet _verbose = false\n\nexport function setVerbose(verbose: boolean): void {\n _verbose = verbose\n}\n\nexport function debug(module: string, msg: string, data?: unknown): void {\n if (!_verbose) return\n const prefix = `[${module}]`\n if (data !== undefined) {\n console.error(`${prefix} ${msg}`, data)\n } else {\n console.error(`${prefix} ${msg}`)\n }\n}\n\nexport function info(msg: string): void {\n console.error(msg)\n}\n\nexport function warn(msg: string): void {\n console.error(`⚠ ${msg}`)\n}\n","/**\n * Custom error types for when-does-my-quota-refresh\n */\n\nexport class SourceUnavailableError extends Error {\n constructor(source: string, reason?: string) {\n super(`Source \"${source}\" unavailable${reason ? `: ${reason}` : ''}`)\n this.name = 'SourceUnavailableError'\n }\n}\n\nexport class AuthError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'AuthError'\n }\n}\n\nexport class QuotaFetchError extends Error {\n constructor(source: string, reason?: string) {\n super(`Failed to fetch quota from \"${source}\"${reason ? `: ${reason}` : ''}`)\n this.name = 'QuotaFetchError'\n }\n}\n\nexport class ProcessNotFoundError extends Error {\n constructor() {\n super('Antigravity language server process not found')\n this.name = 'ProcessNotFoundError'\n }\n}\n\nexport class PortDiscoveryError extends Error {\n constructor(pid: number, platform: string) {\n super(`Failed to discover ports for PID ${pid} on ${platform}`)\n this.name = 'PortDiscoveryError'\n }\n}\n","/**\n * OAuth authentication flow for Google accounts\n */\n\nimport { OAuthClient } from '../../sources/oauth/client.js'\nimport { saveAccountTokens, setActiveAccount } from './storage.js'\nimport { debug } from '../../core/logger.js'\nimport { AuthError } from '../../core/errors.js'\nimport open from 'open'\nimport http from 'http'\nimport { URL } from 'url'\n\n/**\n * Start an interactive OAuth login flow\n *\n * Opens the browser for Google login, then captures the redirect\n * to exchange the authorization code for tokens.\n */\nexport async function loginAccount(): Promise<string> {\n const client = new OAuthClient()\n\n debug('auth', 'Starting OAuth login flow')\n\n // Start a temporary local server to catch the redirect\n let capturedRedirectUri = 'http://127.0.0.1:0/callback'\n const code = await new Promise<string>((resolve, reject) => {\n const server = http.createServer(async (req, res) => {\n const url = new URL(req.url || '/', `http://127.0.0.1`)\n const code = url.searchParams.get('code')\n\n if (code) {\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end(`\n <html><body style=\"font-family: sans-serif; text-align: center; padding: 50px;\">\n <h1>✅ Login successful!</h1>\n <p>You can close this tab and return to the terminal.</p>\n </body></html>\n `)\n server.close()\n resolve(code)\n } else {\n const error = url.searchParams.get('error')\n if (error) {\n res.writeHead(400, { 'Content-Type': 'text/html' })\n res.end(`<h1>Login failed: ${error}</h1>`)\n server.close()\n reject(new AuthError(`OAuth error: ${error}`))\n } else {\n res.writeHead(404)\n res.end('Waiting for OAuth callback...')\n }\n }\n })\n\n server.listen(0, '127.0.0.1', () => {\n const addr = server.address()\n if (typeof addr === 'object' && addr) {\n capturedRedirectUri = `http://127.0.0.1:${addr.port}/callback`\n debug('auth', `Callback server on port ${addr.port}`)\n\n // Build auth URL with the actual port\n const authUrl = client.getAuthUrl(capturedRedirectUri)\n\n // Open browser\n open(authUrl).catch(() => {\n console.log(`\\nOpen this URL in your browser:\\n\\n${authUrl}\\n`)\n })\n }\n })\n\n // Timeout after 5 minutes\n setTimeout(() => {\n server.close()\n reject(new AuthError('Login timed out after 5 minutes'))\n }, 5 * 60 * 1000)\n })\n\n // Exchange code for tokens (use same redirect URI as the auth URL)\n const tokens = await client.exchangeCode(code, capturedRedirectUri)\n\n // Get user email\n const email = tokens.email || 'unknown@gmail.com'\n tokens.email = email\n\n // Store tokens\n saveAccountTokens(email, tokens)\n setActiveAccount(email)\n\n debug('auth', `Logged in as ${email}`)\n return email\n}\n\n/**\n * Perform a manual login (headless/SSH mode)\n * Returns the auth URL for the user to open manually\n */\nexport function getManualLoginUrl(): string {\n const client = new OAuthClient()\n return client.getAuthUrl()\n}\n\n/**\n * Complete manual login with an authorization code\n */\nexport async function completeManualLogin(code: string): Promise<string> {\n const client = new OAuthClient()\n const tokens = await client.exchangeCode(code)\n const email = tokens.email || 'unknown@gmail.com'\n tokens.email = email\n saveAccountTokens(email, tokens)\n setActiveAccount(email)\n return email\n}\n"],"mappings":"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","names":["readFileSync","writeFileSync","existsSync","join","join","existsSync","readFileSync","writeFileSync","URL","code"]}
|
package/dist/cli/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
saveConfig,
|
|
16
16
|
setActiveAccount,
|
|
17
17
|
setVerbose
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-ST6OOHQI.js";
|
|
19
19
|
|
|
20
20
|
// src/cli/index.ts
|
|
21
21
|
import { Command } from "commander";
|
|
@@ -423,7 +423,7 @@ var ConnectClient = class {
|
|
|
423
423
|
* Fetch model configs (last-resort fallback)
|
|
424
424
|
*/
|
|
425
425
|
async fetchModelConfigs() {
|
|
426
|
-
debug("connect-client", "Fetching
|
|
426
|
+
debug("connect-client", "Fetching GetCommandModelConfigs");
|
|
427
427
|
try {
|
|
428
428
|
return await this.request("POST", ENDPOINTS.modelConfigs, {
|
|
429
429
|
metadata: {
|
|
@@ -1659,7 +1659,7 @@ function registerAccountsCommand(program2) {
|
|
|
1659
1659
|
accounts.command("add").description("Login a new Google account").option("--manual", "Manual login for headless/SSH (get URL instead of browser)").action(async (opts) => {
|
|
1660
1660
|
try {
|
|
1661
1661
|
if (opts.manual) {
|
|
1662
|
-
const { getManualLoginUrl: getManualLoginUrl2, completeManualLogin: completeManualLogin2 } = await import("../auth-
|
|
1662
|
+
const { getManualLoginUrl: getManualLoginUrl2, completeManualLogin: completeManualLogin2 } = await import("../auth-XYJBJA2Q.js");
|
|
1663
1663
|
const url = getManualLoginUrl2();
|
|
1664
1664
|
console.log(chalk6.bold("\nOpen this URL in your browser:\n"));
|
|
1665
1665
|
console.log(chalk6.cyan(url));
|