Design: the Charm v2 stack, liberally and tastefully — what we use, what we measured and removed, and the menu of what's left on the table
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Owner direction: cobra plus the Charm v2 family should give this CLI everything it needs for a genuinely beautiful terminal experience, used liberally — and the house taste rules are what keep liberal from becoming loud. This issue is the design record: the current inventory, the decisions already made (including one removal with numbers attached), and the adoption menu with the bar each candidate has to clear.
In the tree today
- lipgloss v2 — all styling, exclusively through
cmd/flow/internal/ui/theme.go's role palette (charmtone pairs per role, light/dark per stream). No raw ANSI anywhere else; adherence is currently clean. - bubbletea v2 —
flow watch/flow run's live view (watchmodel.go), drawing to stderr so stdout stays pipeable. - colorprofile — the entire NO_COLOR/CLICOLOR_FORCE/TERM/tmux decision, deliberately not reimplemented (
ui.go:64-67). - x/term, x/exp/charmtone — TTY detection per stream; the named palette.
Decided, with reasons that still hold
- fang: removed, measured. Its
mustColorschemequeries the terminal background before any option can prevent it, which cost 4.05s on a pty answering nothing — on the help and error paths, the two surfaces a person reaches when something already went wrong (cmd/flow/help.go:16-34). Re-adopting fang requires that upstream behavior to change first; until then the custom help/error renderers are the design, not a stopgap. Any future Charm adoption inherits the same test: no library gets to ask the terminal a question this repo's ui package hasn't already answered. - No spinners/progress-percent in watch — by design (
watch.go:42-47); a durable run's progress isn't a fraction, and pretending otherwise is the kind of flash the charter rules out.
The menu — each with its bar
- vhs for transcripts. The mirror tests already require that output quoted in README/docs regenerate when output changes (#327's constraint). vhs makes that mechanical and visual:
.tapefiles checked in, GIFs/text rendered in CI, drift caught the same wayflow docs generatecatches prose drift. This is the highest-leverage item because it turns "beautiful in form" into something CI can hold — every styled surface gets a recorded, reviewed appearance. Bar: deterministic output (fixed width,FLOWSTATE_BACKGROUNDpinned, fake clock where elapsed time shows). - bubbles components where the watch view grows real interaction (a run picker for bare
flow watch, filterableflow liston a TTY). Bar: every interactive surface remains optional — the flag/plain path stays first-class, TTY-only enhancement never gates function (#327's degrade-cleanly rule; the MCP/agent path never sees a prompt it can't answer). - glamour for exactly one job: rendering the generated markdown under
docs/reference/in-terminal (flow docs view <topic>or similar), where the source really is markdown. Not for help prose — that's one backtick construct, handled in-house (#375), and importing a markdown engine to style help would invert that decision. - ultraviolet — bubbletea v2's renderer substrate; tracked, not acted on. When the watch view needs finer redraw control it's the sanctioned path; nothing today does.
- harmonica — physics animation. The honest answer is probably never, and writing that down is the point of a taste record: motion in a CLI for durable workflows communicates nothing the status pills don't. If a use ever appears (smooth scroll in a long watch view), it rides bubbletea, not a new surface.
The taste rules, restated once
Already in force and worth naming as the charter for all of the above: nothing padded to a width a pipe cannot see; every heading survives losing its color; color is an accelerator, never the carrier; symbols not emoji, ASCII fallback always (symbols.go:3-16); stdout is the answer, stderr is the account; and one style token per concept, defined in the ui package, never per command.
Related: #327 (applying the language to informational output), #375 (inline code spans), #370/#372 (the sad paths adopting the same next-command element), docs/CLI_DESIGN.md (the charter this extends).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read docs/CLI_DESIGN.md and the current UI entry points in cmd/flow/internal/ui/theme.go, ui.go, watchmodel.go, watch.go, and symbols.go. Review the measured fang removal and the adoption menu, then identify a concrete candidate whose stated bar can be tested. Done requires an agreed design decision and evidence that it preserves the charter and degrade-cleanly behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli, design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100