7575 errorStyle = lipgloss .NewStyle ().
7676 Foreground (lipgloss .Color ("#FF0000" )).
7777 Bold (true )
78+
79+ asciiArtStyle = lipgloss .NewStyle ().
80+ Foreground (lipgloss .Color ("#7D56F4" )).
81+ Bold (true )
82+
83+ welcomeTextStyle = lipgloss .NewStyle ().
84+ Foreground (lipgloss .Color ("#FFFFFF" )).
85+ MarginTop (1 ).
86+ MarginBottom (1 )
87+
88+ accentStyle = lipgloss .NewStyle ().
89+ Foreground (lipgloss .Color ("#00D7FF" )).
90+ Bold (true )
7891)
7992
93+ const asciiArt = `
94+ _____ _ _ _ _ _ __ __ _____ _____
95+ / ____(_) | | | | | | | | \/ |/ ____| __ \
96+ | | __ _| |_| |__| |_ _| |__ | \ / | | | |__) |
97+ | | |_ | | __| __ | | | | '_ \ | |\/| | | | ___/
98+ | |__| | | |_| | | | |_| | |_) | | | | | |____| |
99+ \_____|_|\__|_| |_|\__,_|_.__/ |_| |_|\_____|_|
100+
101+ 🧙 Configuration Wizard 🔧
102+ `
103+
80104type toolInfo struct {
81105 name string
82106 description string
@@ -103,15 +127,14 @@ type wizardModel struct {
103127 quitting bool
104128 confirmed bool
105129 viewportOffset int
130+ showWelcome bool
106131}
107132
108133func initialWizardModel (toolsets []toolsetInfo ) wizardModel {
109134 // Flatten all tools
110135 var allTools []toolInfo
111136 for _ , ts := range toolsets {
112- for _ , tool := range ts .tools {
113- allTools = append (allTools , tool )
114- }
137+ allTools = append (allTools , ts .tools ... )
115138 }
116139
117140 return wizardModel {
@@ -121,6 +144,7 @@ func initialWizardModel(toolsets []toolsetInfo) wizardModel {
121144 selected : make (map [int ]bool ),
122145 width : 80 ,
123146 height : 24 ,
147+ showWelcome : true , // Start with welcome screen
124148 }
125149}
126150
@@ -136,6 +160,20 @@ func (m wizardModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
136160 return m , nil
137161
138162 case tea.KeyMsg :
163+ // Welcome screen - only Enter or Space continues
164+ if m .showWelcome {
165+ switch msg .String () {
166+ case "ctrl+c" , "q" , "esc" :
167+ m .quitting = true
168+ return m , tea .Quit
169+ case "enter" , " " :
170+ m .showWelcome = false
171+ return m , nil
172+ }
173+ // Ignore all other keys on welcome screen
174+ return m , nil
175+ }
176+
139177 switch msg .String () {
140178 case "ctrl+c" , "q" :
141179 if m .filterActive {
@@ -276,7 +314,13 @@ func (m wizardModel) View() string {
276314 }
277315
278316 if m .confirmed {
279- return m .renderConfirmation ()
317+ // Show a brief "saving" message before exiting
318+ return successStyle .Render ("\n ✓ Generating configuration...\n " )
319+ }
320+
321+ // Show welcome screen first
322+ if m .showWelcome {
323+ return m .renderWelcome ()
280324 }
281325
282326 var s strings.Builder
@@ -388,6 +432,90 @@ func (m wizardModel) View() string {
388432 return s .String ()
389433}
390434
435+ func (m wizardModel ) renderWelcome () string {
436+ var s strings.Builder
437+
438+ // Center the content vertically
439+ totalLines := strings .Count (asciiArt , "\n " ) + 20 // ASCII art + text
440+ topPadding := (m .height - totalLines ) / 2
441+ if topPadding < 0 {
442+ topPadding = 0
443+ }
444+
445+ for i := 0 ; i < topPadding ; i ++ {
446+ s .WriteString ("\n " )
447+ }
448+
449+ // ASCII art
450+ s .WriteString (asciiArtStyle .Render (asciiArt ))
451+ s .WriteString ("\n \n " )
452+
453+ // Welcome message
454+ welcomeMsg := lipgloss .NewStyle ().
455+ Width (70 ).
456+ Align (lipgloss .Center ).
457+ Foreground (lipgloss .Color ("#FFFFFF" )).
458+ Render ("Welcome to the GitHub MCP Server Configuration Wizard!" )
459+ s .WriteString (welcomeMsg )
460+ s .WriteString ("\n \n " )
461+
462+ // Description
463+ description := []string {
464+ "This interactive tool helps you customize your MCP server by selecting" ,
465+ "which tools you want to enable. You'll be able to:" ,
466+ "" ,
467+ }
468+
469+ for _ , line := range description {
470+ centered := lipgloss .NewStyle ().
471+ Width (70 ).
472+ Align (lipgloss .Center ).
473+ Foreground (lipgloss .Color ("#888888" )).
474+ Render (line )
475+ s .WriteString (centered )
476+ s .WriteString ("\n " )
477+ }
478+
479+ // Features
480+ features := []string {
481+ accentStyle .Render (" ✓" ) + " Browse all available GitHub tools" ,
482+ accentStyle .Render (" ✓" ) + " Search and filter by name or category" ,
483+ accentStyle .Render (" ✓" ) + " Select only the tools you need" ,
484+ accentStyle .Render (" ✓" ) + " Generate ready-to-use configuration" ,
485+ }
486+
487+ for _ , feature := range features {
488+ centered := lipgloss .NewStyle ().
489+ Width (70 ).
490+ Align (lipgloss .Center ).
491+ Render (feature )
492+ s .WriteString (centered )
493+ s .WriteString ("\n " )
494+ }
495+
496+ s .WriteString ("\n \n " )
497+
498+ // Call to action with a pulsing effect
499+ ctaMain := lipgloss .NewStyle ().
500+ Width (70 ).
501+ Align (lipgloss .Center ).
502+ Foreground (lipgloss .Color ("#7D56F4" )).
503+ Bold (true ).
504+ Render ("Press ENTER or SPACE to continue" )
505+ s .WriteString (ctaMain )
506+ s .WriteString ("\n " )
507+
508+ ctaQuit := lipgloss .NewStyle ().
509+ Width (70 ).
510+ Align (lipgloss .Center ).
511+ Foreground (lipgloss .Color ("#888888" )).
512+ Render ("(or press 'q' to quit)" )
513+ s .WriteString (ctaQuit )
514+ s .WriteString ("\n " )
515+
516+ return s .String ()
517+ }
518+
391519func (m wizardModel ) renderConfirmation () string {
392520 var s strings.Builder
393521
@@ -439,11 +567,10 @@ func (m wizardModel) renderConfirmation() string {
439567 }
440568 }
441569
442- // Build command args
570+ // Build command args - use package path instead of individual files
443571 cmdArgs := []string {
444572 "run" ,
445- "cmd/github-mcp-server/main.go" ,
446- "cmd/github-mcp-server/wizard.go" ,
573+ "./cmd/github-mcp-server" ,
447574 "stdio" ,
448575 }
449576
@@ -560,9 +687,18 @@ func runWizard(cmd *cobra.Command, args []string) error {
560687 tea .WithAltScreen (),
561688 )
562689
563- if _ , err := p .Run (); err != nil {
690+ finalModel , err := p .Run ()
691+ if err != nil {
564692 return fmt .Errorf ("error running wizard: %w" , err )
565693 }
566694
695+ // Cast the final model and print confirmation if needed
696+ if m , ok := finalModel .(wizardModel ); ok {
697+ if m .confirmed {
698+ // Print the confirmation output after exiting alt screen
699+ fmt .Print (m .renderConfirmation ())
700+ }
701+ }
702+
567703 return nil
568704}
0 commit comments