@@ -7,10 +7,12 @@ import (
77 "io"
88 "os"
99 "path/filepath"
10+ "runtime"
1011 "strings"
1112
1213 "github.com/jongio/dispatch/internal/config"
1314 "github.com/jongio/dispatch/internal/data"
15+ "github.com/jongio/dispatch/internal/platform"
1416 "github.com/jongio/dispatch/internal/update"
1517 "github.com/jongio/dispatch/internal/version"
1618)
@@ -50,6 +52,11 @@ func handleArgs(args []string, origStderr io.Writer, updateCh <-chan *update.Upd
5052 }
5153 return true , cleanup , nil
5254
55+ case "doctor" :
56+ runDoctor (os .Stdout )
57+ showUpdateNotification (origStderr , updateCh )
58+ return true , cleanup , nil
59+
5360 case "--demo" :
5461 c , demoErr := setupDemo ()
5562 if demoErr != nil {
@@ -99,6 +106,58 @@ func handleArgs(args []string, origStderr io.Writer, updateCh <-chan *update.Upd
99106 return false , cleanup , nil
100107}
101108
109+ func runDoctor (w io.Writer ) {
110+ if w == nil {
111+ w = io .Discard
112+ }
113+
114+ fmt .Fprintf (w , "Dispatch doctor\n " )
115+ fmt .Fprintf (w , "Version: %s\n " , version .Version )
116+ fmt .Fprintf (w , "OS: %s/%s\n " , runtime .GOOS , runtime .GOARCH )
117+ fmt .Fprintf (w , "\n " )
118+
119+ if p , err := config .ConfigPath (); err != nil {
120+ fmt .Fprintf (w , "Config: error: %v\n " , err )
121+ } else {
122+ printPathStatus (w , "Config" , p , false )
123+ }
124+
125+ if p , err := platform .SessionStorePath (); err != nil {
126+ fmt .Fprintf (w , "Session store: error: %v\n " , err )
127+ } else {
128+ printPathStatus (w , "Session store" , p , false )
129+ }
130+
131+ if p := data .SessionStatePath (); p == "" {
132+ fmt .Fprintf (w , "Session state: missing\n " )
133+ } else {
134+ printPathStatus (w , "Session state" , p , true )
135+ }
136+
137+ if p := platform .FindCLIBinary (); p == "" {
138+ fmt .Fprintf (w , "Copilot CLI: missing\n " )
139+ } else {
140+ fmt .Fprintf (w , "Copilot CLI: found (%s)\n " , p )
141+ }
142+ }
143+
144+ func printPathStatus (w io.Writer , label , path string , wantDir bool ) {
145+ info , err := os .Stat (path )
146+ if err != nil {
147+ fmt .Fprintf (w , "%s: missing (%s)\n " , label , path )
148+ return
149+ }
150+ if wantDir && ! info .IsDir () {
151+ fmt .Fprintf (w , "%s: wrong type, expected directory (%s)\n " , label , path )
152+ return
153+ }
154+ if ! wantDir && info .IsDir () {
155+ fmt .Fprintf (w , "%s: wrong type, expected file (%s)\n " , label , path )
156+ return
157+ }
158+ fmt .Fprintf (w , "%s: found (%s)\n " , label , path )
159+ }
160+
102161// setupLogRedirect opens the log file (if configured via DISPATCH_LOG) and
103162// redirects stderr to it. When no log file is configured, stderr is sent to
104163// os.DevNull to keep Bubble Tea's alt-screen clean. Returns the writer for
0 commit comments