diff --git a/src/web-server/routes/account-routes.ts b/src/web-server/routes/account-routes.ts index 848383f5..6b512b3f 100644 --- a/src/web-server/routes/account-routes.ts +++ b/src/web-server/routes/account-routes.ts @@ -1,38 +1,57 @@ /** - * Account Routes - CRUD operations for Claude accounts (profiles.json) + * Account Routes - CRUD operations for Claude accounts * - * Separated from profile-routes.ts to avoid dual-mounting conflicts. + * Uses ProfileRegistry to read from both legacy (profiles.json) + * and unified config (config.yaml) for consistent data with CLI. */ import { Router, Request, Response } from 'express'; -import * as fs from 'fs'; -import * as path from 'path'; -import { getCcsDir } from '../../utils/config-manager'; +import ProfileRegistry from '../../auth/profile-registry'; +import { isUnifiedMode } from '../../config/unified-config-loader'; const router = Router(); +const registry = new ProfileRegistry(); /** - * GET /api/accounts - List accounts from profiles.json + * GET /api/accounts - List accounts from both profiles.json and config.yaml */ router.get('/', (_req: Request, res: Response): void => { try { - const profilesPath = path.join(getCcsDir(), 'profiles.json'); + // Get profiles from both legacy and unified config (same logic as CLI) + const legacyProfiles = registry.getAllProfiles(); + const unifiedAccounts = registry.getAllAccountsUnified(); - if (!fs.existsSync(profilesPath)) { - res.json({ accounts: [], default: null }); - return; + // Merge profiles: unified config takes precedence + const merged: Record = {}; + + // Add legacy profiles first + for (const [name, meta] of Object.entries(legacyProfiles)) { + merged[name] = { + type: meta.type || 'account', + created: meta.created, + last_used: meta.last_used || null, + }; } - const data = JSON.parse(fs.readFileSync(profilesPath, 'utf8')); - const accounts = Object.entries(data.profiles || {}).map(([name, meta]) => { - const metadata = meta as Record; - return { - name, - ...metadata, + // Override with unified config accounts (takes precedence) + for (const [name, account] of Object.entries(unifiedAccounts)) { + merged[name] = { + type: 'account', + created: account.created, + last_used: account.last_used, }; - }); + } - res.json({ accounts, default: data.default || null }); + // Convert to array format + const accounts = Object.entries(merged).map(([name, meta]) => ({ + name, + ...meta, + })); + + // Get default from unified config first, fallback to legacy + const defaultProfile = registry.getDefaultUnified() ?? registry.getDefaultProfile() ?? null; + + res.json({ accounts, default: defaultProfile }); } catch (error) { res.status(500).json({ error: (error as Error).message }); } @@ -50,14 +69,12 @@ router.post('/default', (req: Request, res: Response): void => { return; } - const profilesPath = path.join(getCcsDir(), 'profiles.json'); - - const data = fs.existsSync(profilesPath) - ? JSON.parse(fs.readFileSync(profilesPath, 'utf8')) - : { profiles: {} }; - - data.default = name; - fs.writeFileSync(profilesPath, JSON.stringify(data, null, 2) + '\n'); + // Use unified config if in unified mode, otherwise use legacy + if (isUnifiedMode()) { + registry.setDefaultUnified(name); + } else { + registry.setDefaultProfile(name); + } res.json({ default: name }); } catch (error) {