@@ -60,12 +60,18 @@ const detectAuthResult = (output: string): GeminiAuthResult => {
6060 return "pending"
6161}
6262
63+ // Fixed port for Gemini CLI OAuth callback server
64+ // WHY: Using a fixed port allows Docker port forwarding to work
65+ // SOURCE: https://github.com/google-gemini/gemini-cli/issues/2040
66+ const geminiOauthCallbackPort = 38_751
67+
6368type DockerGeminiAuthSpec = {
6469 readonly cwd : string
6570 readonly image : string
6671 readonly hostPath : string
6772 readonly containerPath : string
6873 readonly env : ReadonlyArray < string >
74+ readonly callbackPort : number
6975}
7076
7177const buildDockerGeminiAuthSpec = (
@@ -78,15 +84,27 @@ const buildDockerGeminiAuthSpec = (
7884 image,
7985 hostPath : accountPath ,
8086 containerPath,
87+ callbackPort : geminiOauthCallbackPort ,
8188 env : [
8289 `HOME=${ containerPath } ` ,
8390 "NO_BROWSER=true" ,
84- "GEMINI_CLI_NONINTERACTIVE=false"
91+ "GEMINI_CLI_NONINTERACTIVE=false" ,
92+ `OAUTH_CALLBACK_PORT=${ geminiOauthCallbackPort } ` ,
93+ "OAUTH_CALLBACK_HOST=0.0.0.0"
8594 ]
8695} )
8796
8897const buildDockerGeminiAuthArgs = ( spec : DockerGeminiAuthSpec ) : ReadonlyArray < string > => {
89- const base : Array < string > = [ "run" , "--rm" , "-i" , "-t" , "-v" , `${ spec . hostPath } :${ spec . containerPath } ` ]
98+ const base : Array < string > = [
99+ "run" ,
100+ "--rm" ,
101+ "-i" ,
102+ "-t" ,
103+ "-v" ,
104+ `${ spec . hostPath } :${ spec . containerPath } ` ,
105+ "-p" ,
106+ `${ spec . callbackPort } :${ spec . callbackPort } `
107+ ]
90108 const dockerUser = resolveDefaultDockerUser ( )
91109 if ( dockerUser !== null ) {
92110 base . push ( "--user" , dockerUser )
@@ -98,8 +116,10 @@ const buildDockerGeminiAuthArgs = (spec: DockerGeminiAuthSpec): ReadonlyArray<st
98116 }
99117 base . push ( "-e" , trimmed )
100118 }
101- // Run gemini CLI - it will prompt for OAuth authentication with NO_BROWSER=true
102- return [ ...base , spec . image , "gemini" ]
119+ // Run gemini CLI with --debug flag to ensure auth URL is shown
120+ // WHY: In some Gemini CLI versions, auth URL is only shown with --debug flag
121+ // SOURCE: https://github.com/google-gemini/gemini-cli/issues/13853
122+ return [ ...base , spec . image , "gemini" , "--debug" ]
103123}
104124
105125const startDockerProcess = (
@@ -179,8 +199,30 @@ const resolveGeminiLoginResult = (
179199 // (user may have completed auth flow successfully)
180200 } )
181201
182- // CHANGE: run Gemini CLI OAuth login with interactive prompt
183- // WHY: Gemini CLI with NO_BROWSER=true shows auth URL and waits for user to paste authorization code
202+ // CHANGE: print OAuth instructions before starting the flow
203+ // WHY: help users understand how to complete OAuth in Docker environment
204+ // QUOTE(ТЗ): "Мне надо что бы он её умел принимать, типо ждал пока мы вставим ссылку"
205+ // REF: issue-146, PR-147 comment from skulidropek
206+ // SOURCE: https://github.com/google-gemini/gemini-cli
207+ // PURITY: SHELL
208+ // COMPLEXITY: O(1)
209+ const printOauthInstructions = ( ) : Effect . Effect < void > =>
210+ Effect . sync ( ( ) => {
211+ const port = geminiOauthCallbackPort
212+ process . stderr . write ( "\n" )
213+ process . stderr . write ( "╔═══════════════════════════════════════════════════════════════════════════╗\n" )
214+ process . stderr . write ( "║ Gemini CLI OAuth Authentication ║\n" )
215+ process . stderr . write ( "╠═══════════════════════════════════════════════════════════════════════════╣\n" )
216+ process . stderr . write ( "║ 1. Copy the auth URL shown below and open it in your browser ║\n" )
217+ process . stderr . write ( "║ 2. Sign in with your Google account ║\n" )
218+ process . stderr . write ( `║ 3. After authentication, the browser will redirect to localhost:${ port } ║\n` )
219+ process . stderr . write ( "║ 4. The callback will be captured automatically (port is forwarded) ║\n" )
220+ process . stderr . write ( "╚═══════════════════════════════════════════════════════════════════════════╝\n" )
221+ process . stderr . write ( "\n" )
222+ } )
223+
224+ // CHANGE: run Gemini CLI OAuth login with interactive prompt and port forwarding
225+ // WHY: Gemini CLI OAuth callback now works in Docker via fixed port forwarding
184226// QUOTE(ТЗ): "Типо ждал пока мы вставим ссылку"
185227// REF: issue-146, PR-147 comment
186228// SOURCE: https://github.com/google-gemini/gemini-cli
@@ -199,6 +241,8 @@ export const runGeminiOauthLoginWithPrompt = (
199241) : Effect . Effect < void , AuthError | CommandFailedError | PlatformError , CommandExecutor . CommandExecutor > =>
200242 Effect . scoped (
201243 Effect . gen ( function * ( _ ) {
244+ yield * _ ( printOauthInstructions ( ) )
245+
202246 const executor = yield * _ ( CommandExecutor . CommandExecutor )
203247 const hostPath = yield * _ ( resolveDockerVolumeHostPath ( cwd , accountPath ) )
204248 const spec = buildDockerGeminiAuthSpec ( cwd , hostPath , options . image , options . containerPath )
0 commit comments