@@ -126,7 +126,7 @@ impl IdeClient {
126126 // Try to read connection config from file
127127 if let Some ( config) = self . read_connection_config ( ) . await {
128128 self . port = Some ( config. port ) ;
129- self . auth_token = config. auth_token ;
129+ self . auth_token = config. auth_token . clone ( ) ;
130130
131131 // Try to establish connection
132132 if self . establish_connection ( ) . await . is_ok ( ) {
@@ -157,43 +157,31 @@ impl IdeClient {
157157 /// Read connection config from port file
158158 /// Supports both Syncable and Gemini CLI companion extensions
159159 async fn read_connection_config ( & self ) -> Option < ConnectionConfig > {
160- let process_info = self . process_info . as_ref ( ) ?;
161- let pid = process_info. pid ;
162160 let temp_dir = env:: temp_dir ( ) ;
163161
164- // Try Syncable extension first
162+ // Try Syncable extension first - scan all port files, match by workspace
165163 let syncable_port_dir = temp_dir. join ( "syncable" ) . join ( "ide" ) ;
166- if let Some ( config) = self . find_port_file ( & syncable_port_dir, "syncable-ide-server" , pid ) {
164+ if let Some ( config) = self . find_port_file_by_workspace ( & syncable_port_dir, "syncable-ide-server" ) {
167165 return Some ( config) ;
168166 }
169167
170168 // Try Gemini CLI extension (for compatibility)
171169 let gemini_port_dir = temp_dir. join ( "gemini" ) . join ( "ide" ) ;
172- if let Some ( config) = self . find_port_file ( & gemini_port_dir, "gemini-ide-server" , pid ) {
170+ if let Some ( config) = self . find_port_file_by_workspace ( & gemini_port_dir, "gemini-ide-server" ) {
173171 return Some ( config) ;
174172 }
175173
176- // Legacy Gemini format (single file in temp dir)
177- let legacy_gemini = temp_dir. join ( format ! ( "gemini-ide-server-{}.json" , pid) ) ;
178- if let Ok ( content) = fs:: read_to_string ( & legacy_gemini) {
179- if let Ok ( config) = serde_json:: from_str :: < ConnectionConfig > ( & content) {
180- if self . validate_workspace_path ( & config. workspace_path ) {
181- return Some ( config) ;
182- }
183- }
184- }
185-
186174 None
187175 }
188176
189- /// Find a port file in a directory matching the given prefix and PID
190- fn find_port_file ( & self , dir : & PathBuf , prefix : & str , pid : u32 ) -> Option < ConnectionConfig > {
177+ /// Find a port file in a directory by scanning all files and matching workspace path
178+ fn find_port_file_by_workspace ( & self , dir : & PathBuf , prefix : & str ) -> Option < ConnectionConfig > {
191179 let entries = fs:: read_dir ( dir) . ok ( ) ?;
192- let file_prefix = format ! ( "{}-{}-" , prefix, pid) ;
193180
194181 for entry in entries. flatten ( ) {
195182 let filename = entry. file_name ( ) . to_string_lossy ( ) . to_string ( ) ;
196- if filename. starts_with ( & file_prefix) && filename. ends_with ( ".json" ) {
183+ // Match any file starting with the prefix and ending with .json
184+ if filename. starts_with ( prefix) && filename. ends_with ( ".json" ) {
197185 if let Ok ( content) = fs:: read_to_string ( entry. path ( ) ) {
198186 if let Ok ( config) = serde_json:: from_str :: < ConnectionConfig > ( & content) {
199187 if self . validate_workspace_path ( & config. workspace_path ) {
@@ -253,7 +241,10 @@ impl IdeClient {
253241 ) ;
254242
255243 // Send initialize request
256- let mut request = self . http_client . post ( & url) . json ( & init_request) ;
244+ let mut request = self . http_client
245+ . post ( & url)
246+ . header ( "Accept" , "application/json, text/event-stream" )
247+ . json ( & init_request) ;
257248
258249 if let Some ( token) = & self . auth_token {
259250 request = request. header ( "Authorization" , format ! ( "Bearer {}" , token) ) ;
@@ -271,12 +262,15 @@ impl IdeClient {
271262 }
272263 }
273264
274- // Parse response
275- let response_data : JsonRpcResponse = response
276- . json ( )
265+ // Parse response (SSE format: "event: message\ndata: {json}")
266+ let response_text = response
267+ . text ( )
277268 . await
278269 . map_err ( |e| IdeError :: ConnectionFailed ( e. to_string ( ) ) ) ?;
279270
271+ let response_data: JsonRpcResponse = Self :: parse_sse_response ( & response_text)
272+ . map_err ( IdeError :: ConnectionFailed ) ?;
273+
280274 if response_data. error . is_some ( ) {
281275 return Err ( IdeError :: ConnectionFailed (
282276 response_data
@@ -289,6 +283,20 @@ impl IdeClient {
289283 Ok ( ( ) )
290284 }
291285
286+ /// Parse SSE response format to extract JSON
287+ fn parse_sse_response ( text : & str ) -> Result < JsonRpcResponse , String > {
288+ // SSE format: "event: message\ndata: {json}\n\n"
289+ for line in text. lines ( ) {
290+ if let Some ( json_str) = line. strip_prefix ( "data: " ) {
291+ return serde_json:: from_str ( json_str)
292+ . map_err ( |e| format ! ( "Failed to parse JSON: {}" , e) ) ;
293+ }
294+ }
295+ // Fallback: try parsing entire response as JSON (for non-SSE responses)
296+ serde_json:: from_str ( text)
297+ . map_err ( |e| format ! ( "Failed to parse response: {}" , e) )
298+ }
299+
292300 /// Get next request ID
293301 fn next_request_id ( & self ) -> u64 {
294302 let mut id = self . request_id . lock ( ) . unwrap ( ) ;
@@ -307,7 +315,10 @@ impl IdeClient {
307315
308316 let request = JsonRpcRequest :: new ( self . next_request_id ( ) , method, params) ;
309317
310- let mut http_request = self . http_client . post ( & url) . json ( & request) ;
318+ let mut http_request = self . http_client
319+ . post ( & url)
320+ . header ( "Accept" , "application/json, text/event-stream" )
321+ . json ( & request) ;
311322
312323 if let Some ( token) = & self . auth_token {
313324 http_request = http_request. header ( "Authorization" , format ! ( "Bearer {}" , token) ) ;
@@ -322,10 +333,13 @@ impl IdeClient {
322333 . await
323334 . map_err ( |e| IdeError :: RequestFailed ( e. to_string ( ) ) ) ?;
324335
325- response
326- . json ( )
336+ let response_text = response
337+ . text ( )
327338 . await
328- . map_err ( |e| IdeError :: RequestFailed ( e. to_string ( ) ) )
339+ . map_err ( |e| IdeError :: RequestFailed ( e. to_string ( ) ) ) ?;
340+
341+ Self :: parse_sse_response ( & response_text)
342+ . map_err ( IdeError :: RequestFailed )
329343 }
330344
331345 /// Open a diff view in the IDE
0 commit comments