@@ -460,7 +460,12 @@ function detectTools() {
460460 category : "prerequisite" ,
461461 displayName : "Docker" ,
462462 cmd : "docker" ,
463- installMethod : null ,
463+ installMethod : "native" ,
464+ installCmd : {
465+ darwin : [ "bash" , [ "-c" , "brew install --cask docker" ] ] ,
466+ linux : [ "bash" , [ "-c" , "curl -fsSL https://get.docker.com | sudo sh" ] ] ,
467+ win32 : null ,
468+ } ,
464469 installHint : {
465470 darwin : "brew install --cask docker OR https://docs.docker.com/get-docker/" ,
466471 linux : "https://docs.docker.com/engine/install/" ,
@@ -591,16 +596,62 @@ async function handleSetup(args) {
591596 // Print current status
592597 printSetupStatus ( tools ) ;
593598
594- // For prerequisites that are missing, print install hints
599+ // Handle missing prerequisites — offer to install those we can auto-install
595600 const missingPrereqs = tools . filter ( ( t ) => t . category === "prerequisite" && ! t . installed ) ;
596601 if ( missingPrereqs . length > 0 ) {
597602 const platform = process . platform ;
598- console . log ( " \x1b[1mMissing prerequisites\x1b[0m (install manually):" ) ;
599- for ( const t of missingPrereqs ) {
600- const hint = t . installHint [ platform ] || t . installHint . linux ;
601- console . log ( ` ${ t . displayName } : ${ hint } ` ) ;
603+ const autoInstallable = missingPrereqs . filter (
604+ ( t ) => t . installCmd && t . installCmd [ platform ]
605+ ) ;
606+ const manualOnly = missingPrereqs . filter (
607+ ( t ) => ! t . installCmd || ! t . installCmd [ platform ]
608+ ) ;
609+
610+ if ( manualOnly . length > 0 ) {
611+ console . log ( " \x1b[1mMissing prerequisites\x1b[0m (install manually):" ) ;
612+ for ( const t of manualOnly ) {
613+ const hint = t . installHint [ platform ] || t . installHint . linux ;
614+ console . log ( ` ${ t . displayName } : ${ hint } ` ) ;
615+ }
616+ console . log ( "" ) ;
617+ }
618+
619+ if ( ! checkOnly && autoInstallable . length > 0 ) {
620+ for ( const t of autoInstallable ) {
621+ const confirmed = await askConfirm ( ` Install ${ t . displayName } ?` ) ;
622+ if ( confirmed ) {
623+ console . log ( `\n Installing ${ t . displayName } ...` ) ;
624+ const ok = installTool ( t ) ;
625+ if ( ok ) {
626+ console . log ( ` \x1b[32m✓\x1b[0m ${ t . displayName } installed successfully` ) ;
627+ t . installed = true ;
628+ // Docker post-install: add user to docker group and start service
629+ if ( t . name === "docker" && platform === "linux" ) {
630+ const user = process . env . USER || process . env . LOGNAME ;
631+ if ( user ) {
632+ console . log ( ` Adding ${ user } to docker group...` ) ;
633+ spawnSync ( "sudo" , [ "usermod" , "-aG" , "docker" , user ] , { stdio : "inherit" } ) ;
634+ }
635+ console . log ( " Starting Docker service..." ) ;
636+ const svcResult = spawnSync ( "sudo" , [ "service" , "docker" , "start" ] , { stdio : "inherit" } ) ;
637+ if ( svcResult . status !== 0 ) {
638+ // WSL without systemd — try dockerd directly
639+ console . log ( " \x1b[33m!\x1b[0m Could not start Docker service." ) ;
640+ console . log ( " Try: sudo dockerd &" ) ;
641+ }
642+ console . log ( "" ) ;
643+ console . log ( " \x1b[33mNote:\x1b[0m Log out and back in for docker group to take effect." ) ;
644+ console . log ( " Or run: newgrp docker" ) ;
645+ }
646+ } else {
647+ console . log ( ` \x1b[31m✗\x1b[0m ${ t . displayName } installation failed` ) ;
648+ const hint = t . installHint [ platform ] || t . installHint . linux ;
649+ console . log ( ` Install manually: ${ hint } ` ) ;
650+ }
651+ console . log ( "" ) ;
652+ }
653+ }
602654 }
603- console . log ( "" ) ;
604655 }
605656
606657 if ( checkOnly ) {
0 commit comments