mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-05 12:16:46 +00:00
feat(dashboard): add project_id display for Antigravity accounts
Display GCP project_id for Antigravity (agy) accounts in the Dashboard: - Add projectId field to AccountInfo interface (account-manager.ts) - Read project_id from auth files when discovering/registering accounts - Pass projectId through token-manager when registering new accounts - Add projectId to OAuthAccount type (api-client.ts) - Add projectId to AccountRow type (auth-monitor/types.ts) - Display project_id in account-item.tsx with FolderCode icon - Show N/A warning with amber tooltip if project_id is missing suggesting user remove and re-add account to fetch it Note: project_id is read-only and respects privacy mode blur.
This commit is contained in:
@@ -47,6 +47,8 @@ export interface AccountInfo {
|
||||
pausedAt?: string;
|
||||
/** Account tier: free or paid (Pro/Ultra combined) */
|
||||
tier?: AccountTier;
|
||||
/** GCP Project ID (Antigravity only) - read-only, fetched from auth token */
|
||||
projectId?: string;
|
||||
}
|
||||
|
||||
/** Provider accounts configuration */
|
||||
@@ -293,7 +295,8 @@ export function registerAccount(
|
||||
provider: CLIProxyProvider,
|
||||
tokenFile: string,
|
||||
email?: string,
|
||||
nickname?: string
|
||||
nickname?: string,
|
||||
projectId?: string
|
||||
): AccountInfo {
|
||||
const registry = loadAccountsRegistry();
|
||||
|
||||
@@ -350,7 +353,7 @@ export function registerAccount(
|
||||
const isFirstAccount = Object.keys(providerAccounts.accounts).length === 0;
|
||||
|
||||
// Create or update account
|
||||
providerAccounts.accounts[accountId] = {
|
||||
const accountMeta: Omit<AccountInfo, 'id' | 'provider' | 'isDefault'> = {
|
||||
email,
|
||||
nickname: accountNickname,
|
||||
tokenFile,
|
||||
@@ -358,6 +361,13 @@ export function registerAccount(
|
||||
lastUsedAt: new Date().toISOString(),
|
||||
};
|
||||
|
||||
// Include projectId for Antigravity accounts
|
||||
if (provider === 'agy' && projectId) {
|
||||
accountMeta.projectId = projectId;
|
||||
}
|
||||
|
||||
providerAccounts.accounts[accountId] = accountMeta;
|
||||
|
||||
// Set as default if first account
|
||||
if (isFirstAccount) {
|
||||
providerAccounts.default = accountId;
|
||||
@@ -671,13 +681,20 @@ export function discoverExistingAccounts(): void {
|
||||
// Register account with auto-generated nickname
|
||||
// Use mtime as lastUsedAt (when token was last modified = last auth/refresh)
|
||||
const lastModified = stats.mtime || stats.birthtime || new Date();
|
||||
providerAccounts.accounts[accountId] = {
|
||||
const accountMeta: Omit<AccountInfo, 'id' | 'provider' | 'isDefault'> = {
|
||||
email,
|
||||
nickname: generateNickname(email),
|
||||
tokenFile: file,
|
||||
createdAt: stats.birthtime?.toISOString() || new Date().toISOString(),
|
||||
lastUsedAt: lastModified.toISOString(),
|
||||
};
|
||||
|
||||
// Read project_id for Antigravity accounts (read-only field from auth token)
|
||||
if (provider === 'agy' && data.project_id) {
|
||||
accountMeta.projectId = data.project_id;
|
||||
}
|
||||
|
||||
providerAccounts.accounts[accountId] = accountMeta;
|
||||
} catch {
|
||||
// Skip invalid files
|
||||
continue;
|
||||
|
||||
@@ -229,8 +229,15 @@ export function registerAccountFromToken(
|
||||
const content = fs.readFileSync(tokenPath, 'utf-8');
|
||||
const data = JSON.parse(content);
|
||||
const email = data.email || undefined;
|
||||
const projectId = data.project_id || undefined;
|
||||
|
||||
return registerAccount(provider, newestFile, email, nickname || generateNickname(email));
|
||||
return registerAccount(
|
||||
provider,
|
||||
newestFile,
|
||||
email,
|
||||
nickname || generateNickname(email),
|
||||
projectId
|
||||
);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user