cli: add Frame — live compositional AppShell for TUI #15
Labels
No labels
needs-review
needs-review
needs-review
needs-review
needs-review
needs-review
needs-review
athena
athena-gemini
audit
clotho
clotho-gemini
codex
darbs-claude
security
wiki
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: core/go#15
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
pkg/cli has good individual components (Table, Spinner, ProgressBar, Viewport, InteractiveList) and a static layout system (HLCRF
Layout("HCF")). But they can't compose at runtime:tea.NewProgram()independently — they can't share the screen\033[2K\r— can't coexist with a table above itLayout("HCF")renders once to a string — no live updates, no region swappingEvery dashboard command (
core dev health,core dev work,lem gen distill) wants a persistent shell with independently-updating regions. Today they can't have one.Proposal:
cli.FrameA live layout frame — like Angular's AppShell but for TUI. One
bubbletea.Programowns the terminal, regions update independently, components slot in without managing their own stdout.Mental Model
API Sketch
Frame Responsibilities
tea.Program, manages resize, alt-screenNavigate(model)replaces content region,Back()popsLayout.Render()(existing code)cli.Modelcan slot into any regionBuilt-in Region Components
Small composable pieces that slot into Frame regions:
cli.StatusLine(title string, pairs ...string)— key:value bar for Header/Footercli.KeyHints(hints ...string)— keybinding help for Footercli.Breadcrumb(parts ...string)— navigation path for Headercli.TaskTracker()— multi-line parallel task display (N spinners)How Existing Components Fit
t.Render()prints\033[2K\rRunTUI(viewport)tea.NewProgram\033[2K\rComponents need a
Resize(width, height int)message so the frame can tell them their allocated space. This is already how bubbletea'sWindowSizeMsgworks — just needs plumbing.Variant Reuse
Frame reuses the existing HLCRF variant parser (
ParseVariant). The live frame is the runtime version of the static layout:Same variant strings, same region model, different execution mode.
Priority
This is the architectural piece that unlocks #14 (rich table, parallel tasks, streaming, tree). Without Frame, each component is standalone. With Frame, they compose.
Constraints
forge.lthn.ai/core/go/pkg/clionly — no bubbletea imports in domain code!term.IsTerminal(CI, pipes, redirects)cli.Modelinterface (already defined intui.go)References
layout.go(HLCRF parser),render.go(static rendering),tui.go(Model/RunTUI)JoinVertical/JoinHorizontalfor region compositionCompleted by Charon in
core/cli(e360115). CLI package now lives atforge.lthn.ai/core/cli/pkg/cli, notcore/go/pkg/cli.