-
Notifications
You must be signed in to change notification settings - Fork 9
Modernizes the CRE CLI's user interface by integrating the Charm ecosystem #243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Create internal/ui/ package with centralized Lipgloss styles (styles.go) - Add output helpers for consistent styling: Title, Box, Success, Dim, etc. - Implement Bubble Tea spinner with reference counting for async operations - Add GlobalSpinner singleton for seamless spinner across CLI lifecycle - Update PersistentPreRunE to show spinner during initialization - Migrate cre init and cre whoami to use shared UI package
- Add spinner during file generation (copying, generating templates, contracts) - Show spinner during Go dependencies installation - Display dependencies in styled box after spinner completes - Fix Next steps box spacing and formatting - Refactor initializeGoModule to return deps instead of printing
- Add styled template functions (styleTitle, styleSection, styleCommand, styleDim, styleSuccess, styleCode) - Update help template to use Lipgloss styling - Style section headers, command names, tips, and URLs - Improve visual hierarchy and readability
- Add complete Blocks palette constants (Gray, Blue, Green, Red, Orange, Yellow, Teal, Purple) - Use high-contrast colors for dark terminal readability - Style titles/commands with Blue 400-500 for visibility - Style secondary info with Gray 500 (dimmed) - Create custom Huh theme with Blocks colors for forms - Update spinner to use Blue 500
- Add styled title and welcome message using Chainlink theme
- Add Bubble Tea spinner with progress states throughout auth flow:
- Preparing authentication
- Opening browser
- Waiting for authentication
- Exchanging authorization code
- Saving credentials
- Show styled URL fallback when browser cannot open automatically
- Display success message with next steps in branded box
- Update spinner message during org membership retry flow
- Update tests to include spinner in handler instantiations
- Add SilenceErrors: true to root command to disable Cobra's default error output - Display all user-facing errors with styled ui.Error() in Execute() - Errors now show with red color and ✗ prefix consistent with Chainlink theme - Internal debug logging via zerolog remains unchanged
- Add SilenceErrors: true to disable Cobra's default error output - Display errors with styled ui.Error() (red with ✗ prefix) - Set SilenceUsage in PersistentPreRunE to hide usage for runtime errors - Keep usage/suggestions visible for command typos and flag errors
consistent styling across the CLI
- Replaced prompt.YesNoPrompt with huh.NewConfirm forms
- Removed stdin io.Reader parameter
2. Updated cmd/creinit/creinit.go:
- Updated call sites to match new function signatures
3. Updated cmd/secrets/common/handler.go:
- Replaced ~25 fmt.Print* calls with ui.* functions
4. Updated cmd/workflow/simulate/telemetry_writer.go:
- Replaced fmt.Printf with ui.Printf
- Removed unused fmt import
5. Deleted internal/prompt/ directory:
- Removed entire old promptui-based package
6. Cleaned cmd/common/utils.go:
- Removed unused MustGetUserInputWithPrompt function
- Removed unused bufio and errors imports
7. Dependencies cleaned (go mod tidy):
- Removed github.com/manifoldco/promptui
- Removed github.com/chzyer/readline
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21673419475 Note: These are preview builds and are not signed. |
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21676241523 Note: These are preview builds and are not signed. |
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21676790323 Note: These are preview builds and are not signed. |
- Contracts generated in <contracts directory>
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21677123424 Note: These are preview builds and are not signed. |
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21677567395 Note: These are preview builds and are not signed. |
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21681149975 Note: These are preview builds and are not signed. |
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21685548327 Note: These are preview builds and are not signed. |
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21685548341 Note: These are preview builds and are not signed. |
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21689791006 Note: These are preview builds and are not signed. |
…flict and visual display issue in verbose mode
|
🚀 Preview Build Artifacts You can download the preview builds for this PR from the following URL: https://github.com/smartcontractkit/cre-cli/actions/runs/21716173381 Note: These are preview builds and are not signed. |
|
|
||
| func Exec(ctx *runtime.Context, in Inputs) error { | ||
| h := newHandler(ctx, os.Stdin) | ||
| h := newHandler(ctx, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we can clean this function up to remove this required param
| ui.Warning("Unlink is a destructive action that will wipe out all workflows registered under your owner address.") | ||
| ui.Line() | ||
| var confirm bool | ||
| confirmForm := huh.NewForm( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: Refactor using a ui.YesNoPrompt() for all yes/no prompt
| var confirm bool | ||
| confirmForm := huh.NewForm( | ||
| huh.NewGroup( | ||
| huh.NewConfirm(). | ||
| Title("Do you wish to proceed?"). | ||
| Value(&confirm), | ||
| ), | ||
| ).WithTheme(ui.ChainlinkTheme()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code quality: can we also abstract the huh form in ui library. something like ui.YesNoPrompt
| form := huh.NewForm( | ||
| huh.NewGroup( | ||
| huh.NewInput(). | ||
| Title("Provide a label for your owner address"). | ||
| Value(&in.WorkflowOwnerLabel), | ||
| ), | ||
| ).WithTheme(ui.ChainlinkTheme()) | ||
| if err := form.Run(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code quality: can we also abstract this in ui library. something like ui.simplePrompt
| return filepath.Base(wd), nil | ||
| } | ||
|
|
||
| func MustGetUserInputWithPrompt(l *zerolog.Logger, prompt string) (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Find where/how it was used before and what replaced it: MustGetUserInputWithPrompt()
| ) | ||
|
|
||
| // chainlinkTheme for all Huh forms in this package | ||
| var chainlinkTheme = ui.ChainlinkTheme() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: Logic should be moved so that commands doesn't need to know about the theme (ui or rootCmd)
| // Silence Cobra's default error display - we use styled ui.Error() instead | ||
| SilenceErrors: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @timothyF95 if you see any concerns with silencing these
| // Silence usage for runtime errors - at this point flag parsing succeeded, | ||
| // so any errors from here are runtime errors, not usage errors | ||
| cmd.SilenceUsage = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just want to highlight this for any concerns @timothyF95
| return !exists | ||
| } | ||
|
|
||
| func shouldShowSpinner(cmd *cobra.Command) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't fully follow this: doesn't every command have their own spinner logic? why do we need a spinner in root command?
Summary
This PR modernizes the CRE CLI's user interface by integrating the Charm ecosystem (Lipgloss, Huh, Bubble Tea). This is a view-layer only refactoring - no business logic or Cobra command structure was modified.
Why This Refactoring?
To build a world-class developer experience, we needed a better foundation. Our previous approach had limitations:
fmt.Printcalls can't handle async operations gracefullypromptuilibrary offered limited customization and no modern UX patternsThe Charm ecosystem solves these by owning the terminal - it manages the view layer as a proper UI framework, enabling:
Key Changes
1. New UI Package (
internal/ui/)Centralized styling and output functions:
2. Chainlink-Branded Theme
All interactive elements use the Chainlink color palette:
#375BD2): Primary actions, spinners, focused elements3. Spinner for Async Operations
Reference-counted spinner that handles concurrent operations:
4. Modern Form Inputs with Huh
Replaced
promptuiwithhuhforms featuring:5. Enhanced Error Handling
New helpers for actionable error messages:
6. Graceful Cancellation
Long-running operations (like
cre login) now support Escape/Ctrl+C with proper cleanup and user feedback.What's NOT Changed
Libraries
Removed Dependencies
promptui- Replaced entirely byhuhTesting