@@ -17,6 +17,7 @@ const previewWatchers: Map<string, vscode.FileSystemWatcher> = new Map();
1717// Local HTTP server for receiving session notifications from SDK
1818let httpServer : http . Server | undefined ;
1919let serverPort : number | undefined ;
20+ let registrationHeartbeat : ReturnType < typeof setInterval > | undefined ;
2021
2122// Path to the TestDriver directory (used for IPC between SDK and extension)
2223const SESSION_DIR = path . join ( os . homedir ( ) , '.testdriver' ) ;
@@ -201,6 +202,9 @@ function startHttpServer(context: vscode.ExtensionContext) {
201202 serverPort = address . port ;
202203 console . log ( `TestDriver extension server listening on port ${ serverPort } ` ) ;
203204 registerInstance ( ) ;
205+ // Refresh the registration timestamp every 30 seconds so the SDK
206+ // never considers this instance stale (SDK threshold is 60 seconds).
207+ registrationHeartbeat = setInterval ( registerInstance , 30000 ) ;
204208 }
205209 } ) ;
206210
@@ -291,17 +295,26 @@ function setupPreviewWatchers(context: vscode.ExtensionContext) {
291295 previewWatchers . set ( folder . uri . fsPath , watcher ) ;
292296 context . subscriptions . push ( watcher ) ;
293297
294- cleanupStalePreviewFiles ( previewsDir ) ;
298+ processOrCleanupPreviewFiles ( context , previewsDir ) ;
295299 }
296300}
297301
298- function cleanupStalePreviewFiles ( previewsDir : string ) {
302+ // Process recent preview files (written within the last 30 seconds) and delete stale ones.
303+ // This handles the race condition where a file is written before the watcher is fully active.
304+ function processOrCleanupPreviewFiles ( context : vscode . ExtensionContext , previewsDir : string ) {
305+ const RECENT_THRESHOLD_MS = 30000 ;
299306 try {
300307 const files = fs . readdirSync ( previewsDir ) ;
301308 for ( const file of files ) {
302309 if ( file . endsWith ( '.json' ) ) {
310+ const filePath = path . join ( previewsDir , file ) ;
303311 try {
304- fs . unlinkSync ( path . join ( previewsDir , file ) ) ;
312+ const stats = fs . statSync ( filePath ) ;
313+ if ( Date . now ( ) - stats . mtimeMs < RECENT_THRESHOLD_MS ) {
314+ handlePreviewFile ( context , vscode . Uri . file ( filePath ) ) ;
315+ } else {
316+ fs . unlinkSync ( filePath ) ;
317+ }
305318 } catch { /* ignore */ }
306319 }
307320 }
@@ -425,7 +438,8 @@ function connectToWebSocket(debuggerUrl: string, panel: vscode.WebviewPanel, ses
425438
426439 try {
427440 const url = new URL ( debuggerUrl ) ;
428- const wsUrl = `ws://${ url . host } ` ;
441+ const wsProtocol = url . protocol === 'https:' ? 'wss:' : 'ws:' ;
442+ const wsUrl = `${ wsProtocol } //${ url . host } ` ;
429443 const ws = new WebSocket ( wsUrl ) ;
430444 websocketConnections . set ( sessionId , ws ) ;
431445
@@ -706,6 +720,11 @@ function getDebuggerHtml(debuggerUrl: string, encodedData: string): string {
706720export function deactivate ( ) {
707721 closeAllDebuggerPanels ( ) ;
708722
723+ if ( registrationHeartbeat ) {
724+ clearInterval ( registrationHeartbeat ) ;
725+ registrationHeartbeat = undefined ;
726+ }
727+
709728 if ( httpServer ) {
710729 httpServer . close ( ) ;
711730 httpServer = undefined ;
0 commit comments