feat: standardize CLI output on charmbracelet/bubbles + bubbletea - #47
Open
ChristoPy wants to merge 1 commit into
Open
feat: standardize CLI output on charmbracelet/bubbles + bubbletea#47ChristoPy wants to merge 1 commit into
ChristoPy wants to merge 1 commit into
Conversation
Adopts bubbletea/bubbles (already indirect deps via huh) as the consistent rendering layer for the CLI's dynamic output, replacing a mix of ad-hoc fmt.Print*, a non-Charm spinner, and boxed lipgloss output. - internal/tui: bubbletea-driven spinner-to-result flow (output.RunTask) used by login, logout, upgrade, and payments simulate - one continuous render instead of a spinner followed by a separately-printed result - plus a full interactive dashboard for `listen` (scrollable event feed, connection status, key bindings), degrading to today's plain sequential lines when stdout isn't a terminal or -o isn't text. - internal/webhook: listener display logic decoupled from the network loop via an optional Emit hook, so the dashboard and the plain fallback share one source of data instead of duplicating it. - internal/logger: console handler now only surfaces diagnostics under --verbose (routine Info/Warn logs were leaking as raw `level=INFO msg=...` text alongside the styled output); file logging is unaffected. - internal/clierr: marks errors already shown to the user (by RunTask, or by a handler that prints before returning) so the top-level runner doesn't print them a second time - fixes a real duplicate-error-box bug in login/payments/ws, not just a cosmetic one. - Dropped the bordered box around success/error output in favor of flat styled text, and standardized `upgrade` on English to match every other command. - Replaced briandowns/spinner with bubbles/spinner; go.mod/go.sum updated accordingly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G4MKBc9TASEspQuCnsqZLf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The CLI already lived in the Charm ecosystem (
huhfor forms,lipglossfor styling) but its dynamic/async output was inconsistent: a non-Charm spinner (briandowns/spinner), plain sequential prints inlisten, rawfmt.Printfinupgrade, and no progress indication at all inpayments simulate. This adoptsbubbletea/bubbles(already indirect deps viahuh) as the single rendering layer for that dynamic output, and fixes a couple of real bugs found along the way.internal/tui: a bubbletea spinner-to-result flow (output.RunTask) used bylogin,logout,upgrade, andpayments simulate— the spinner's final frame becomes the result, one continuous render instead of abubbleteaanimation followed by a separately-printed box (which, forpayments simulate, actually raced the still-running spinner and corrupted output). Also a full interactive dashboard forlisten: scrollable event feed, connection status, key bindings (bubbles/viewport+key+help). Both fall back to today's plain sequential-line output when stdout isn't a terminal or-oisn'ttext, so piped/scripted/CI use is unaffected.internal/webhook: listener display logic decoupled from the network loop via an optionalEmithook, so the interactive dashboard and the plain fallback share one source of truth instead of duplicating it.internal/logger: the console handler now only surfaces diagnostics under--verbose. RoutineInfo/Warnlogs ("Signed out","WebSocket connected", ...) were leaking as rawlevel=INFO msg=...text right next to the styled output — file logging is unaffected,--verbosestill shows everything.internal/clierr: marks errors already displayed to the user (byRunTask, or by any handler that prints before returning) so the top-level command runner doesn't print them a second time. This was a real bug, not just cosmetic —login/payments/the websocket retry path could each show the same error box twice.upgradeon English (it was the only command in Portuguese).briandowns/spinnerwithbubbles/spinner.Test plan
go build ./...,go vet ./...,go test ./...all passupgrade(spinner → result, single continuous render),loginvia both--keyand the real device-flow path (confirmed the duplicate-error-box fix against a real 400 response),logout,payments simulate(including--verboseand-o json)| cat) still produces plain sequential output forlistenlisten's interactive dashboard against a real forwarded webhook (spinner/connection-status/event-feed rendering was verified via the same bubbletea primitives proven out in theupgrade/loginpty tests, but not the full dashboard end-to-end with live traffic)