@@ -11,7 +11,12 @@ import { getCcsDir, getConfigPath, loadConfig, loadSettings } from '../utils/con
1111import { Config , Settings } from '../types/config' ;
1212import { expandPath } from '../utils/helpers' ;
1313import { runHealthChecks , fixHealthIssue } from './health-service' ;
14- import { getAllAuthStatus , getOAuthConfig , initializeAccounts } from '../cliproxy/auth-handler' ;
14+ import {
15+ getAllAuthStatus ,
16+ getOAuthConfig ,
17+ initializeAccounts ,
18+ triggerOAuth ,
19+ } from '../cliproxy/auth-handler' ;
1520import {
1621 fetchCliproxyStats ,
1722 fetchCliproxyModels ,
@@ -33,6 +38,7 @@ import {
3338 removeAccount as removeAccountFn ,
3439} from '../cliproxy/account-manager' ;
3540import type { CLIProxyProvider } from '../cliproxy/types' ;
41+ import { getClaudeEnvVars } from '../cliproxy/config-generator' ;
3642// Unified config imports
3743import {
3844 hasUnifiedConfig ,
@@ -200,12 +206,25 @@ function updateSettingsFile(
200206
201207/**
202208 * Helper: Create cliproxy variant settings
209+ * Includes base URL and auth token for proper Claude CLI integration
203210 */
204- function createCliproxySettings ( name : string , model ?: string ) : string {
211+ function createCliproxySettings ( name : string , provider : CLIProxyProvider , model ?: string ) : string {
205212 const settingsPath = path . join ( getCcsDir ( ) , `${ name } .settings.json` ) ;
206213
214+ // Get base env vars from provider config (includes BASE_URL, AUTH_TOKEN)
215+ const baseEnv = getClaudeEnvVars ( provider ) ;
216+
207217 const settings : Settings = {
208- env : model ? { ANTHROPIC_MODEL : model } : { } ,
218+ env : {
219+ ANTHROPIC_BASE_URL : baseEnv . ANTHROPIC_BASE_URL || '' ,
220+ ANTHROPIC_AUTH_TOKEN : baseEnv . ANTHROPIC_AUTH_TOKEN || '' ,
221+ ANTHROPIC_MODEL : model || ( baseEnv . ANTHROPIC_MODEL as string ) || '' ,
222+ ANTHROPIC_DEFAULT_OPUS_MODEL : model || ( baseEnv . ANTHROPIC_DEFAULT_OPUS_MODEL as string ) || '' ,
223+ ANTHROPIC_DEFAULT_SONNET_MODEL :
224+ model || ( baseEnv . ANTHROPIC_DEFAULT_SONNET_MODEL as string ) || '' ,
225+ ANTHROPIC_DEFAULT_HAIKU_MODEL :
226+ ( baseEnv . ANTHROPIC_DEFAULT_HAIKU_MODEL as string ) || model || '' ,
227+ } ,
209228 } ;
210229
211230 fs . writeFileSync ( settingsPath , JSON . stringify ( settings , null , 2 ) + '\n' ) ;
@@ -356,7 +375,7 @@ apiRoutes.post('/cliproxy', (req: Request, res: Response): void => {
356375 }
357376
358377 // Create settings file for variant
359- const settingsPath = createCliproxySettings ( name , model ) ;
378+ const settingsPath = createCliproxySettings ( name , provider as CLIProxyProvider , model ) ;
360379
361380 // Include account if specified (defaults to 'default' if not provided)
362381 config . cliproxy [ name ] = {
@@ -534,10 +553,34 @@ apiRoutes.post('/cliproxy/accounts/:provider/default', (req: Request, res: Respo
534553/**
535554 * DELETE /api/cliproxy/accounts/:provider/:accountId - Remove an account
536555 */
537- apiRoutes . delete (
538- '/api/cliproxy/accounts/:provider/:accountId' ,
539- ( req : Request , res : Response ) : void => {
540- const { provider, accountId } = req . params ;
556+ apiRoutes . delete ( '/cliproxy/accounts/:provider/:accountId' , ( req : Request , res : Response ) : void => {
557+ const { provider, accountId } = req . params ;
558+
559+ // Validate provider
560+ const validProviders : CLIProxyProvider [ ] = [ 'gemini' , 'codex' , 'agy' , 'qwen' , 'iflow' ] ;
561+ if ( ! validProviders . includes ( provider as CLIProxyProvider ) ) {
562+ res . status ( 400 ) . json ( { error : `Invalid provider: ${ provider } ` } ) ;
563+ return ;
564+ }
565+
566+ const success = removeAccountFn ( provider as CLIProxyProvider , accountId ) ;
567+
568+ if ( success ) {
569+ res . json ( { provider, accountId, deleted : true } ) ;
570+ } else {
571+ res . status ( 404 ) . json ( { error : 'Account not found' } ) ;
572+ }
573+ } ) ;
574+
575+ /**
576+ * POST /api/cliproxy/auth/:provider/start - Start OAuth flow for a provider
577+ * Opens browser for authentication and returns account info when complete
578+ */
579+ apiRoutes . post (
580+ '/cliproxy/auth/:provider/start' ,
581+ async ( req : Request , res : Response ) : Promise < void > => {
582+ const { provider } = req . params ;
583+ const { nickname } = req . body ;
541584
542585 // Validate provider
543586 const validProviders : CLIProxyProvider [ ] = [ 'gemini' , 'codex' , 'agy' , 'qwen' , 'iflow' ] ;
@@ -546,12 +589,30 @@ apiRoutes.delete(
546589 return ;
547590 }
548591
549- const success = removeAccountFn ( provider as CLIProxyProvider , accountId ) ;
592+ try {
593+ // Trigger OAuth flow - this opens browser and waits for completion
594+ const account = await triggerOAuth ( provider as CLIProxyProvider , {
595+ add : true , // Always add mode from UI
596+ headless : false , // Force interactive mode
597+ nickname : nickname || undefined ,
598+ } ) ;
550599
551- if ( success ) {
552- res . json ( { provider, accountId, deleted : true } ) ;
553- } else {
554- res . status ( 404 ) . json ( { error : 'Account not found' } ) ;
600+ if ( account ) {
601+ res . json ( {
602+ success : true ,
603+ account : {
604+ id : account . id ,
605+ email : account . email ,
606+ nickname : account . nickname ,
607+ provider : account . provider ,
608+ isDefault : account . isDefault ,
609+ } ,
610+ } ) ;
611+ } else {
612+ res . status ( 400 ) . json ( { error : 'Authentication failed or was cancelled' } ) ;
613+ }
614+ } catch ( error ) {
615+ res . status ( 500 ) . json ( { error : ( error as Error ) . message } ) ;
555616 }
556617 }
557618) ;
0 commit comments