Ship a working `gitflow tui` command: static scan result rendered as a lipgloss-styled table, with keyboard navigation and a detail pane. TUI package (internal/tui): - Model struct: holds scan result, cursor, detail/help toggles, loading state, error display, and injected app/AI/config dependencies - Update: handles WindowSizeMsg (resize), KeyMsg for navigation (j/↑/k/↓, Home/End, Enter/Space for detail, ? for help, q/Ctrl-C for quit), and async scanResultMsg/scanErrorMsg for the M3 periodic scan loop - View: repo list table (STATUS/REPOSITORY/BRANCH/AHEAD-BEHIND/CHGS/STASH) with cursor highlighting and dimmed error rows, expandable detail pane showing files, and a status bar (scan summary + keybinding hints) - styles.go: lipgloss Styles (Header/Row/CursorRow/StatusBar) with dark/light theme palettes that mirror the CLI's ThemeMode - Loading and empty states; help overlay with keybinding reference Presenter API surface (needed by the TUI): - ShortPath exported (home → ~ collapsing, reused by TUI and CLI) - StatusSymbolFor exported (✓ ✗ ↑ ↓ ⇄ ◉ ▢ ! symbols, reused) - ShortPath is kept as a wrapper so internal formatter callers are unaffected CLI (cmd/gitflow): - newTUICmd: resolves config, builds AI provider, calls tui.New() for the initial scan, and runs the bubbletea Program - Wired into root command under `gitflow tui` with full flag set (--dir, --interval, --exclude, etc.) Dependencies: bubbletea v1.3.10, lipgloss v1.1.0, a stable x/term tree Testing: - Model logic tests: cursor navigation (arrow + j/k), bottom/top clamping, detail toggle (Enter/Space), ? help, q/Ctrl-C quit, view renders repo names/branch/status columns, detail pane shows file lists, help overlay shows keybindings, loading/empty states Verified: go build, go vet, go test -race (12 packages), gofmt clean, `gitflow tui --help` prints command usage.
64 lines
1.4 KiB
Go
64 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"gitea.oblak.solutions/dimitar/gitFlow/internal/ai"
|
|
"gitea.oblak.solutions/dimitar/gitFlow/internal/app"
|
|
"gitea.oblak.solutions/dimitar/gitFlow/internal/config"
|
|
"gitea.oblak.solutions/dimitar/gitFlow/internal/presenter"
|
|
"gitea.oblak.solutions/dimitar/gitFlow/internal/tui"
|
|
)
|
|
|
|
// newTUICmd launches the interactive terminal UI.
|
|
func newTUICmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "tui",
|
|
Short: "Start the interactive terminal UI",
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
cfg, err := config.Load(cmd.Flags())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !cmd.Flags().Changed("dir") && isTerminal(os.Stdin) {
|
|
if d, err := promptDir(cfg.Dir); err == nil {
|
|
cfg.Dir = d
|
|
}
|
|
}
|
|
|
|
a, err := app.New(cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var aiProvider ai.Provider
|
|
if cfg.AI.Enabled {
|
|
aiProvider, err = ai.NewProvider(cfg.AI)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "warning: %v\n", err)
|
|
}
|
|
}
|
|
|
|
opts := presenter.Options{
|
|
Color: presenter.ParseColorMode(cfg.Color),
|
|
Theme: presenter.ParseTheme(cfg.Theme),
|
|
}
|
|
|
|
p, err := tui.New(cfg, a, aiProvider, opts)
|
|
if err != nil {
|
|
return fmt.Errorf("tui: %w", err)
|
|
}
|
|
if _, err := p.Run(); err != nil {
|
|
return fmt.Errorf("tui: %w", err)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
config.RegisterFlags(cmd.Flags())
|
|
return cmd
|
|
}
|