@@ -49,8 +49,10 @@ import { AskDispatcher } from "./ask-dispatcher.js"
4949const cliLogger = new DebugLogger ( "CLI" )
5050
5151// Get the CLI package root directory (for finding node_modules/@vscode/ripgrep)
52+ // At runtime, this file is at apps/cli/dist/extension-host/extension-host.js
53+ // So we need to go up two levels to reach apps/cli (where node_modules is located)
5254const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) )
53- const CLI_PACKAGE_ROOT = path . resolve ( __dirname , ".." )
55+ const CLI_PACKAGE_ROOT = path . resolve ( __dirname , "../.. " )
5456
5557// =============================================================================
5658// Types
@@ -524,12 +526,14 @@ export class ExtensionHost extends EventEmitter {
524526 }
525527
526528 async runTask ( prompt : string ) : Promise < void > {
527- cliLogger . debug ( "runTask:start" , { prompt : prompt ?. substring ( 0 , 100 ) } )
528-
529529 if ( ! this . isWebviewReady ) {
530530 await new Promise < void > ( ( resolve ) => this . once ( "webviewReady" , resolve ) )
531531 }
532532
533+ // Send initial webview messages to trigger proper extension initialization
534+ // This is critical for the extension to start sending state updates properly
535+ this . sendToExtension ( { type : "webviewDidLaunch" } )
536+
533537 const baseSettings : RooCodeSettings = {
534538 commandExecutionTimeout : 30 ,
535539 browserToolEnabled : false ,
@@ -565,8 +569,10 @@ export class ExtensionHost extends EventEmitter {
565569 await this . waitForCompletion ( )
566570 }
567571
568- private waitForCompletion ( ) : Promise < void > {
572+ private waitForCompletion ( timeoutMs : number = 110000 ) : Promise < void > {
569573 return new Promise ( ( resolve , reject ) => {
574+ let timeoutId : NodeJS . Timeout | null = null
575+
570576 const completeHandler = ( ) => {
571577 cleanup ( )
572578 resolve ( )
@@ -575,11 +581,24 @@ export class ExtensionHost extends EventEmitter {
575581 cleanup ( )
576582 reject ( new Error ( error ) )
577583 }
584+ const timeoutHandler = ( ) => {
585+ cleanup ( )
586+ reject (
587+ new Error ( `Task completion timeout after ${ timeoutMs } ms - no completion or error event received` ) ,
588+ )
589+ }
578590 const cleanup = ( ) => {
591+ if ( timeoutId ) {
592+ clearTimeout ( timeoutId )
593+ timeoutId = null
594+ }
579595 this . off ( "taskComplete" , completeHandler )
580596 this . off ( "taskError" , errorHandler )
581597 }
582598
599+ // Set timeout to prevent indefinite hanging
600+ timeoutId = setTimeout ( timeoutHandler , timeoutMs )
601+
583602 this . once ( "taskComplete" , completeHandler )
584603 this . once ( "taskError" , errorHandler )
585604 } )
0 commit comments