Skip to content

feat: migrate CLI rendering to Bubble Tea TUI#24

Merged
xfiive merged 50 commits intodevfrom
feat/bubble-ui
Mar 9, 2026
Merged

feat: migrate CLI rendering to Bubble Tea TUI#24
xfiive merged 50 commits intodevfrom
feat/bubble-ui

Conversation

@xfiive
Copy link
Member

@xfiive xfiive commented Mar 9, 2026

Summary

  • Rewrite interactive rendering from pterm to Bubble Tea/lipgloss across login, connect, dbinfo, seed commands
  • Add TUI framework with phase-based architecture (plan, prompt, seeding, completion phases)
  • Add reusable TUI components: selector, spinner, text input, summary box, info banner
  • Wire TUI prompt and scope display into production orchestrator
  • Remove dead code, deduplicate API calls, extract shared helpers
  • Optimize CLI startup with parallel HTTP calls and 24-hour update check throttle
  • Migrate gRPC client to grpc.NewClient from deprecated DialContext
  • Fix MCP connection test to use real database connections
  • Fix subscription limit display on every scope arrival

xfiive and others added 30 commits February 22, 2026 20:13
Lightweight standalone package for login and connect TUI flows,
separate from the seed TUI. Reuses existing spinner and text
input components from the TUI framework.
Replace goroutine spinners and manual ANSI in login and connect
with configtui Bubble Tea models. Replace pterm in dbinfo with
dbheader + fmt. All error messages and output preserved.
refactor: replace pterm with lipgloss in subscription display
refactor: rewrite config commands to Bubble Tea
Legacy compatibility layer for keychain operations that was
never imported anywhere in the codebase. All callers use
`internal/keychain` directly.
Remove `DSNResolver.GetDatabaseName()` (orchestrator uses
`dsn.ExtractDatabaseName()` directly), `EventHandler.logVerboseHumanPrompt()`,
`AuthValidator.IsAuthenticated()` (all callers use `Validate()`),
`DatabaseConnector.ConnectWithTimeout()` (only `Connect()` is used),
and unused `SeedState.Area` and `SeedState.Frames` fields.
Remove `auth.IsLoggedIn`, `auth.SetLoggedIn`, `auth.SetLoggedOut`
(never called from anywhere) and `keychain.MustGetManager()` (dead
code with dangerous panic pattern).
Single `auth.Service` instance shared across the orchestrator
instead of 4 separate instantiations. `Validate()` now returns
the access token directly, eliminating `getAccessToken()` and
the redundant `WhoAmI` call. Saves 1-2 HTTP round-trips per run.
`FetchLatestVersion()` previously made an HTTP call on every CLI invocation.
Now the cache stores `LastCheckTime` and skips the HTTP call when within
`checkInterval` (24 hours), using the cached `LatestVersion` instead.
The PersistentPreRun context timeout is increased from 2s to 5s to
accommodate the 3-second HTTP timeout when a fetch does occur.
`GetVersion` and `GetCLIVersion` are now fetched concurrently using
goroutines after the manifest is resolved, reducing `--version` latency
by running both HTTP calls in parallel instead of sequentially.
Replaces 4 identical private `isVerbose()` functions across
backend, manifest, auth, and keychain packages with a single
exported function in the logging package.
Centralizes DSN priority logic (SEEDFAST_DSN > DATABASE_URL >
keychain) into a shared function. Both dbinfo command and
DSNResolver now delegate to it instead of reimplementing.
Consolidates the email > user_id > id fallback pattern into
a single function. Replaces 4 inline copies across auth service
and me command.
The `TokenManager` struct was stateless, holding only a constant 2-minute
threshold, yet required a heap allocation on every token validation call.
Replace the struct and methods with package-level functions and a constant.
Replace the if-chain with string() casts in ProcessEvents with a labeled
switch statement. Use a labeled break to exit the for loop from within
the switch for terminal events. Delete dead no-op line and unused
strings import in ui_helpers.go.
Shrink MCP server initial scan buffer from 10MB to 64KB while keeping
the 10MB max for large messages. Replace map-based output mode validation
in `validateFlags` with a switch statement to avoid allocation.
Replaces per-call http.Client creation with a package-level
shared client. Enables TCP connection pooling across manifest
fetch calls.
Replaces grpc.DialContext + WithBlock with grpc.NewClient which
is non-blocking and the recommended API going forward.
The `seedfast_connections_test` tool now verifies connectivity using `pgxpool` instead of returning a static success message.
refactor: remove dead code and unused exports
…duplicate-api-calls

# Conflicts:
#	cmd/dbinfo.go
xfiive and others added 20 commits February 24, 2026 18:25
refactor: deduplicate API calls and reduce code duplication
perf: optimize CLI startup performance
refactor: clean up minor inefficiencies
…gement

refactor: improve connection management
…nections-test

# Conflicts:
#	internal/mcpserver/handlers.go
fix: real database connection test in MCP server
Add ScopeIssues field to AskHumanMsg for structured scope issue
passthrough from proto. Add PromptWarnings and PromptOption types
to bridge orchestration warning data to TUI PromptPhase. Update
convertAskHuman to populate ScopeIssues from proto UserQuestion.
Arrow-key navigation selector following the TextInputComponent
pattern. Supports PromptOption items with Label/Answer pairs,
keyboard navigation, and cancel via Ctrl+C/Esc.
Accept optional PromptWarnings in constructor. When warnings with
options are present, show styled warning lines and selector instead
of text input. Selector "describe" option falls through to text
input mode. Factory passes nil to preserve existing TUI behavior.
Add RunPrompt standalone Bubble Tea program that wraps PromptPhase
with promptActions to capture results without gRPC. Add
buildPromptWarnings to convert warningFormatResult to TUI types.
Replace pterm prompt rendering and runScopeInput/runScopeSelector
calls in handleAskHuman with single RunPrompt call.
Cover SelectorComponent navigation, PromptPhase warning mode,
promptActions channel behavior, buildPromptWarnings option building,
helper functions, promptApp delegation, and EventBridge ScopeIssues.
docs: add plan for TUI prompt wiring in production
Replace pterm-based scope rendering in handlePlanProposed and
handleAskHuman with the TUI PlanPhase component via a new
RunScopeDisplay function. Add configurable header support to
PlanPhase for replan mode ("Previous seeding scope").
feat: migrate scope display from pterm to TUI
Remove .claude/ and .mcp.json from git tracking and add
.claude/, .mcp.json, docs/ to .gitignore. Public repo must
not contain internal documentation, skills, or config.
Re-register OS signal handlers after Bubble Tea exits raw mode
to ensure CTRL+C continues working. Add MarkComplete to prompt
phase to prevent stale spinner on final render. Send cancellation
to backend when user interrupts during ask_human.
@xfiive xfiive added ✨ Refactoring Refactoring request 🛠️ Enhancement New feature or request labels Mar 9, 2026
@xfiive xfiive self-assigned this Mar 9, 2026
@xfiive xfiive added ✨ Refactoring Refactoring request 🛠️ Enhancement New feature or request labels Mar 9, 2026
@xfiive xfiive merged commit 43e5161 into dev Mar 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠️ Enhancement New feature or request ✨ Refactoring Refactoring request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant