Skip to content

feat(tui): TUI personality — Tier 1 (window title, spinner indicators, status bar, gradient logo)#44

Merged
danielxxomg merged 4 commits into
mainfrom
feat/tui-personality-tier1
Jun 27, 2026
Merged

feat(tui): TUI personality — Tier 1 (window title, spinner indicators, status bar, gradient logo)#44
danielxxomg merged 4 commits into
mainfrom
feat/tui-personality-tier1

Conversation

@danielxxomg

Copy link
Copy Markdown
Owner

Part 1 of 3 of the tui-personality SDD change. This is the foundational, render-only personality layer (~150 lines of behavior) — no state-machine or architectural changes. All additive, testable as pure Update/View functions per AGENTS.md TUI rules.

What's in this PR (Tier 1)

Phase 1 — Window title + spinning step indicators

  • Contextual window title (REQ-TP-001): every screen sets tea.View.WindowTitle declaratively — bak — Main Menu, bak — Backup 3/7 (live step counter on running progress), bak — Restore:abc1234 (selected id), plus Wizard/Settings/Cloud/Health/Profiles/Backups/Welcome/Shortcuts. Uses the v2 View.WindowTitle field, not the removed tea.SetWindowTitle command.
  • Live spinner step indicators (REQ-TP-002): the running step row on the progress and health screens now renders m.spinner.View() (the live rotating frame) instead of the static / glyph. Health gained its own spinner.Model (mirrors progress). Done = , pending = unchanged.

Phase 2 — Status bar + gradient logo

  • Persistent status bar (REQ-TP-003): new stateless components.RenderStatusBar(width, version, preset, path) appended at the bottom of every screen. Hidden below 40 cols; backup path truncated with ellipsis to fit. Styled with a package-level StatusBarStyle. Deps gained Preset/BackupPath; cmd/root.go populates them best-effort.
  • Gradient logo (REQ-TP-004): styles/logo.go now uses lipgloss.Blend1D (Love→Gold→Rose→Pine→Lavender) and falls back to plain text (no ANSI) on no-color profiles.

Verification

  • Strict TDD red/green throughout (evidence in commits).
  • go test ./... green; go vet ./... clean; golangci-lint run 0 issues.
  • Per-package coverage: tui 90.3%, components 93.5%, screens 83.0%, styles 95.7% (all ≥80%).

Notes / deviations

  • Blend1D + color profile (resolves a design open question): verified lipgloss.Blend1D(steps, stops...) and that Style.Render does not downsample at render time — downsampling is renderer-level. So RenderLogo consults a settable package-level colorProfile (default TrueColor) for an explicit, unit-testable no-color branch; the bubbletea renderer remains the production safety net.
  • tea.SetWindowTitle does not exist in bubbletea v2.0.7 — used the View.WindowTitle field instead (design Decision 1).
  • Wizard runs as a separate flow (no ScreenWizard in the main Model); its WizardModel.View sets WindowTitle = "bak — Wizard" directly.
  • GGA pre-commit hit Argument list too long (ARG_MAX) on both feat commits — a documented GGA limitation. Bypassed with --no-verify + NO-VERIFY: reason per AGENTS.md; go test, go vet, and golangci-lint all pass clean.

Stacked-PR plan

Per tasks.md (stacked-to-main): PR 1 (this — Tier 1) → PR 2 (Tier 2: viewport dry-run, mouse nav, styled empty states) → PR 3 (Tier 3: paste support). PR 2 will base on main after this merges.

Spec

SDD change artifacts (proposal, spec, design, tasks, delta specs) are included in this PR under openspec/changes/tui-personality/.

danielxxomg added 4 commits June 26, 2026 17:58
Phase 1 of tui-personality (Tier 1a):

- model.go: add titleForScreen(m) pure helper mapping each screen to a
  'bak — {Screen}' title; set v.WindowTitle (declarative tea.View field,
  v2 API) in View(). Progress appends the live step counter ('bak — Backup
  3/7'); Restore appends the selected backup id.
- progress.go: the running step row now renders m.spinner.View() (live
  rotating frame) instead of the static '⠹' glyph; done=✓, pending=○
  unchanged. Store Current/Total for the window title counter.
- health.go: add a spinner.Model field; Init() returns spinner.Tick;
  propagate spinner.TickMsg (animate while running, stop when idle);
  running check row uses m.spinner.View().
- wizard.go: set v.WindowTitle = 'bak — Wizard' on every View branch.

REQ-TP-001, REQ-TP-002. All TDD red/green; full TUI suite green.

NO-VERIFY: GGA pre-commit failed with 'Argument list too long' (ARG_MAX,
exit 126) on the 8-file diff — a documented GGA technical limitation per
AGENTS.md. Code reviewed against AGENTS.md rules manually (Go idioms, error
wrapping, package-level styles, v2 API, table-driven tests). Tests + go vet
pass. Follow-up: re-run GGA on smaller slices if needed.
Phase 2 of tui-personality (Tier 1b):
- components/statusbar.go: stateless RenderStatusBar(width, version, preset,
  path) hidden below 40 cols; path truncated with ellipsis. Styled with
  package-level StatusBarStyle (Rose Pine ColorSubtle).
- styles/screens.go: add StatusBarStyle package-level var.
- styles/logo.go: 5 fixed Foreground styles -> lipgloss.Blend1D gradient
  (Love->Gold->Rose->Pine->Lavender); settable colorProfile var falls back
  to plain text (no ANSI) on NoTTY/Ascii profiles.
- model.go: renderContent appends the status bar at the bottom of every
  screen; deps.go adds Preset/BackupPath; cmd/root.go populates them
  best-effort (config.DefaultPreset + backup.BakDir).
- wizard.go: extract wizardView helper (funlen). model.go: extract
  progressTitle/restoreTitle (gocyclo).

REQ-TP-003, REQ-TP-004. TDD red/green; coverage 83-96% per TUI package;
golangci-lint clean.

NO-VERIFY: GGA pre-commit failed with 'Argument list too long' (ARG_MAX,
exit 126) on the 10-file diff -- a documented GGA technical limitation per
AGENTS.md. Code reviewed against AGENTS.md rules manually. go test ./...,
go vet, and golangci-lint run all pass clean.
@danielxxomg danielxxomg merged commit fee9b86 into main Jun 27, 2026
6 of 7 checks passed
@danielxxomg danielxxomg deleted the feat/tui-personality-tier1 branch June 27, 2026 17:37
danielxxomg pushed a commit that referenced this pull request Jun 27, 2026
3 PRs merged (#44, #45, #46):
- Tier 1: window title, spinner indicators, status bar, gradient logo
- Tier 2: viewport dry-run, mouse nav, styled empty states
- Tier 3: paste support in wizard
Personality: 4/10 → 8/10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant