@@ -115,18 +115,25 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
115115
116116 private async handleCredentialsChange ( ) : Promise < void > {
117117 try {
118+ this . log ( "[auth] Handling credentials change..." )
118119 const credentials = await this . loadCredentials ( )
119120
120121 if ( credentials ) {
122+ this . log ( "[auth] Credentials found, checking if they changed" )
121123 if (
122124 this . credentials === null ||
123125 this . credentials . clientToken !== credentials . clientToken ||
124126 this . credentials . sessionId !== credentials . sessionId
125127 ) {
128+ this . log ( "[auth] Credentials changed, transitioning to attempting session" )
126129 this . transitionToAttemptingSession ( credentials )
130+ } else {
131+ this . log ( "[auth] Credentials unchanged" )
127132 }
128133 } else {
134+ this . log ( "[auth] No credentials found" )
129135 if ( this . state !== "logged-out" ) {
136+ this . log ( "[auth] Transitioning to logged-out state" )
130137 this . transitionToLoggedOut ( )
131138 }
132139 }
@@ -135,6 +142,15 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
135142 }
136143 }
137144
145+ /**
146+ * Manually check for credential changes - used as fallback for Windsurf
147+ * where secrets.onDidChange might not work reliably
148+ */
149+ private async checkCredentialsManually ( ) : Promise < void > {
150+ this . log ( "[auth] Manually checking credentials..." )
151+ await this . handleCredentialsChange ( )
152+ }
153+
138154 private transitionToLoggedOut ( ) : void {
139155 this . timer . stop ( )
140156
@@ -191,26 +207,64 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
191207 return
192208 }
193209
210+ this . log ( "[auth] Initializing WebAuthService..." )
211+
194212 await this . handleCredentialsChange ( )
195213
196- this . context . subscriptions . push (
197- this . context . secrets . onDidChange ( ( e ) => {
198- if ( e . key === this . authCredentialsKey ) {
199- this . handleCredentialsChange ( )
200- }
201- } ) ,
202- )
214+ // Set up secrets change listener with error handling for Windsurf compatibility
215+ try {
216+ this . context . subscriptions . push (
217+ this . context . secrets . onDidChange ( ( e ) => {
218+ if ( e . key === this . authCredentialsKey ) {
219+ this . log ( "[auth] Secrets changed, handling credentials change" )
220+ this . handleCredentialsChange ( )
221+ }
222+ } ) ,
223+ )
224+ this . log ( "[auth] Secrets change listener registered successfully" )
225+ } catch ( error ) {
226+ this . log ( "[auth] Warning: Failed to register secrets change listener:" , error )
227+ // Continue without the listener - we'll rely on manual credential checks
228+ }
229+
230+ // Set up periodic credential check as fallback for Windsurf
231+ const credentialCheckInterval = setInterval ( async ( ) => {
232+ if ( this . state === "initializing" ) {
233+ return // Don't check during initialization
234+ }
235+ await this . checkCredentialsManually ( )
236+ } , 5000 ) // Check every 5 seconds
237+
238+ // Clean up interval when context is disposed
239+ this . context . subscriptions . push ( {
240+ dispose : ( ) => {
241+ clearInterval ( credentialCheckInterval )
242+ this . log ( "[auth] Credential check interval cleared" )
243+ }
244+ } )
245+
246+ this . log ( "[auth] WebAuthService initialization complete" )
203247 }
204248
205249 private async storeCredentials ( credentials : AuthCredentials ) : Promise < void > {
206- await this . context . secrets . store ( this . authCredentialsKey , JSON . stringify ( credentials ) )
250+ try {
251+ await this . context . secrets . store ( this . authCredentialsKey , JSON . stringify ( credentials ) )
252+ this . log ( "[auth] Credentials stored successfully" )
253+ } catch ( error ) {
254+ this . log ( "[auth] Error storing credentials:" , error )
255+ throw new Error ( `Failed to store authentication credentials: ${ error } ` )
256+ }
207257 }
208258
209259 private async loadCredentials ( ) : Promise < AuthCredentials | null > {
210- const credentialsJson = await this . context . secrets . get ( this . authCredentialsKey )
211- if ( ! credentialsJson ) return null
212-
213260 try {
261+ const credentialsJson = await this . context . secrets . get ( this . authCredentialsKey )
262+ if ( ! credentialsJson ) {
263+ this . log ( "[auth] No credentials found in storage" )
264+ return null
265+ }
266+
267+ this . log ( "[auth] Loading credentials from storage" )
214268 const parsedJson = JSON . parse ( credentialsJson )
215269 const credentials = authCredentialsSchema . parse ( parsedJson )
216270
@@ -221,12 +275,13 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
221275 this . log ( "[auth] Migrated credentials with organizationId" )
222276 }
223277
278+ this . log ( "[auth] Credentials loaded successfully" )
224279 return credentials
225280 } catch ( error ) {
226281 if ( error instanceof z . ZodError ) {
227282 this . log ( "[auth] Invalid credentials format:" , error . errors )
228283 } else {
229- this . log ( "[auth] Failed to parse stored credentials:" , error )
284+ this . log ( "[auth] Failed to load or parse stored credentials:" , error )
230285 }
231286 return null
232287 }
@@ -298,6 +353,14 @@ export class WebAuthService extends EventEmitter<AuthServiceEvents> implements A
298353
299354 await this . storeCredentials ( credentials )
300355
356+ // Force credential reload and state transition for Windsurf compatibility
357+ await this . handleCredentialsChange ( )
358+
359+ // Additional manual check after a short delay to ensure state transition
360+ setTimeout ( async ( ) => {
361+ await this . checkCredentialsManually ( )
362+ } , 1000 )
363+
301364 vscode . window . showInformationMessage ( "Successfully authenticated with Roo Code Cloud" )
302365 this . log ( "[auth] Successfully authenticated with Roo Code Cloud" )
303366 } catch ( error ) {
0 commit comments