@@ -9,6 +9,8 @@ class CommanderPanel {
99 this . orchestrator = orchestrator ;
1010 this . isVisible = false ;
1111 this . isRunning = false ;
12+ this . isStarting = false ;
13+ this . startCommanderPromise = null ;
1214 // Always use same-origin API requests; the dev server proxies `/api` to the backend.
1315 this . serverUrl = window . location . origin ;
1416 this . terminal = null ;
@@ -114,7 +116,7 @@ class CommanderPanel {
114116 <div class="commander-terminal" id="commander-terminal">
115117 <div class="commander-placeholder">
116118 <p>Commander is a Claude Code terminal for orchestrating your sessions.</p>
117- <p>Click <strong>▶️ Start</strong> to launch the terminal, then <strong>Start Claude</strong> to begin .</p>
119+ <p>Opening Commander starts it automatically. Claude will launch as soon as the terminal is ready .</p>
118120 </div>
119121 </div>
120122 ` ;
@@ -139,6 +141,29 @@ class CommanderPanel {
139141 this . orchestrator ?. applyUiVisibility ?. ( ) ;
140142 }
141143
144+ setPlaceholderMessages ( lines = [ ] ) {
145+ if ( this . terminal ) return ;
146+
147+ const container = document . getElementById ( 'commander-terminal' ) ;
148+ if ( ! container ) return ;
149+
150+ const messages = Array . isArray ( lines ) && lines . length
151+ ? lines
152+ : [
153+ 'Commander is a Claude Code terminal for orchestrating your sessions.' ,
154+ 'Opening Commander starts it automatically. Claude will launch as soon as the terminal is ready.'
155+ ] ;
156+
157+ const placeholder = document . createElement ( 'div' ) ;
158+ placeholder . className = 'commander-placeholder' ;
159+ messages . forEach ( ( message ) => {
160+ const paragraph = document . createElement ( 'p' ) ;
161+ paragraph . textContent = message ;
162+ placeholder . appendChild ( paragraph ) ;
163+ } ) ;
164+ container . replaceChildren ( placeholder ) ;
165+ }
166+
142167 /**
143168 * Initialize XTerm.js terminal
144169 */
@@ -545,7 +570,10 @@ class CommanderPanel {
545570 updateStatusBadge ( ) {
546571 const badge = document . getElementById ( 'commander-status-badge' ) ;
547572 if ( badge ) {
548- if ( this . isRunning ) {
573+ if ( this . isStarting ) {
574+ badge . textContent = 'Starting' ;
575+ badge . className = 'commander-status starting' ;
576+ } else if ( this . isRunning ) {
549577 badge . textContent = 'Running' ;
550578 badge . className = 'commander-status online' ;
551579 } else {
@@ -581,11 +609,14 @@ class CommanderPanel {
581609 const status = await this . checkStatus ( ) ;
582610
583611 if ( ! status . running ) {
584- // Commander terminal not running - start everything
612+ this . isStarting = true ;
613+ this . updateStatusBadge ( ) ;
614+ this . setPlaceholderMessages ( [
615+ 'Commander is starting.' ,
616+ 'Claude will launch automatically as soon as the terminal is ready.'
617+ ] ) ;
618+
585619 await this . startCommander ( ) ;
586- setTimeout ( ( ) => {
587- this . startClaude ( 'fresh' ) ;
588- } , 1500 ) ;
589620 } else if ( ! this . terminal ) {
590621 // Terminal not initialized locally - set it up
591622 this . initTerminal ( ) ;
@@ -615,22 +646,50 @@ class CommanderPanel {
615646 * Start the Commander terminal
616647 */
617648 async startCommander ( ) {
618- try {
619- const response = await fetch ( `${ this . serverUrl } /api/commander/start` , {
620- method : 'POST'
621- } ) ;
649+ if ( this . startCommanderPromise ) {
650+ return this . startCommanderPromise ;
651+ }
622652
623- if ( response . ok ) {
624- const result = await response . json ( ) ;
625- if ( result . success ) {
653+ this . isStarting = true ;
654+ this . updateStatusBadge ( ) ;
655+
656+ this . startCommanderPromise = ( async ( ) => {
657+ try {
658+ const response = await fetch ( `${ this . serverUrl } /api/commander/start` , {
659+ method : 'POST'
660+ } ) ;
661+ const result = response . ok
662+ ? await response . json ( )
663+ : { success : false , error : `Request failed (${ response . status } )` } ;
664+
665+ if ( result . success || result . error === 'Already running' ) {
626666 this . isRunning = true ;
627- this . updateStatusBadge ( ) ;
628667 this . initTerminal ( ) ;
668+ return result ;
629669 }
670+
671+ this . isRunning = false ;
672+ this . setPlaceholderMessages ( [
673+ 'Commander could not be started.' ,
674+ String ( result . error || 'Close and reopen the panel to try again.' )
675+ ] ) ;
676+ return result ;
677+ } catch ( error ) {
678+ console . error ( 'Failed to start commander:' , error ) ;
679+ this . isRunning = false ;
680+ this . setPlaceholderMessages ( [
681+ 'Commander could not be started.' ,
682+ 'Close and reopen the panel to try again.'
683+ ] ) ;
684+ return { success : false , error : error . message } ;
685+ } finally {
686+ this . isStarting = false ;
687+ this . updateStatusBadge ( ) ;
688+ this . startCommanderPromise = null ;
630689 }
631- } catch ( error ) {
632- console . error ( 'Failed to start commander:' , error ) ;
633- }
690+ } ) ( ) ;
691+
692+ return this . startCommanderPromise ;
634693 }
635694
636695 /**
0 commit comments