feat(ux): visual improvements for list tree, graph, and show commands
bd list --tree: - Use actual parent-child dependencies instead of dotted ID hierarchy - Treat epic dependencies as parent-child relationships - Sort children by priority (P0 first) - Fix tree display in daemon mode with read-only store access bd graph: - Add --all flag to show dependency graph of all open issues - Add --compact flag for tree-style rendering (reduces 44+ lines to 13) - Fix "needs:N" cognitive noise by using semantic colors - Add blocks:N indicator with semantic red coloring bd show: - Tufte-aligned header with status icon, priority, and type badges - Add glamour markdown rendering with auto light/dark mode detection - Cap markdown line width at 100 chars for readability - Mute entire row for closed dependencies (work done, no attention needed) Design system: - Add shared status icons (○ ◐ ● ✓ ❄) with semantic colors - Implement priority colors: P0 red, P1 orange, P2 muted gold, P3-P4 neutral - Add TrueColor profile for distinct hex color rendering - Type badges for epic (purple) and bug (red) Design principles: - Semantic colors only for actionable items - Closed items fade (muted gray) - Icons > text labels for better scanability Co-Authored-By: SageOx <ox@sageox.ai>
This commit is contained in:
54
internal/ui/markdown.go
Normal file
54
internal/ui/markdown.go
Normal file
@@ -0,0 +1,54 @@
|
||||
// Package ui provides terminal styling for beads CLI output.
|
||||
package ui
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/charmbracelet/glamour"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
// RenderMarkdown renders markdown text using glamour with beads theme colors.
|
||||
// Returns the rendered markdown or the original text if rendering fails.
|
||||
// Word wraps at terminal width (or 80 columns if width can't be detected).
|
||||
func RenderMarkdown(markdown string) string {
|
||||
// Skip glamour in agent mode to keep output clean for parsing
|
||||
if IsAgentMode() {
|
||||
return markdown
|
||||
}
|
||||
|
||||
// Skip glamour if colors are disabled
|
||||
if !ShouldUseColor() {
|
||||
return markdown
|
||||
}
|
||||
|
||||
// Detect terminal width for word wrap
|
||||
// Cap at 100 chars for readability - wider lines cause eye-tracking fatigue
|
||||
// Typography research suggests 50-75 chars optimal, 80-100 comfortable max
|
||||
const maxReadableWidth = 100
|
||||
wrapWidth := 80 // default if terminal size unavailable
|
||||
if w, _, err := term.GetSize(int(os.Stdout.Fd())); err == nil && w > 0 {
|
||||
wrapWidth = w
|
||||
}
|
||||
if wrapWidth > maxReadableWidth {
|
||||
wrapWidth = maxReadableWidth
|
||||
}
|
||||
|
||||
// Create renderer with auto-detected style (respects terminal light/dark mode)
|
||||
renderer, err := glamour.NewTermRenderer(
|
||||
glamour.WithAutoStyle(),
|
||||
glamour.WithWordWrap(wrapWidth),
|
||||
)
|
||||
if err != nil {
|
||||
// fallback to raw markdown on error
|
||||
return markdown
|
||||
}
|
||||
|
||||
rendered, err := renderer.Render(markdown)
|
||||
if err != nil {
|
||||
// fallback to raw markdown on error
|
||||
return markdown
|
||||
}
|
||||
|
||||
return rendered
|
||||
}
|
||||
Reference in New Issue
Block a user