ui

package
v0.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	HexPrimary = theme.HexPrimary
	HexAccent  = theme.HexAccent
	HexPass    = theme.HexPass
	HexWarn    = theme.HexWarn
	HexFail    = theme.HexFail
	HexMuted   = theme.HexMuted
	HexText    = theme.HexText
	HexTextDim = theme.HexTextDim
	HexBgDark  = theme.HexBgDark
	HexBgCode  = theme.HexBgCode
	HexPublic  = theme.HexPublic
	HexPrivate = theme.HexPrivate
)

Re-export hex constants for backward compatibility and glamour integration

View Source
const (
	IconPass  = "✓"
	IconWarn  = "⚠"
	IconFail  = "✖" // heavier icon for better visibility
	IconSkip  = "-"
	IconInfo  = "ℹ"
	IconAgent = "★" // agent-required indicator (star for special attention)
)

Status icons

View Source
const (
	TreeChild  = "⎿ "  // child indicator
	TreeLast   = "└─ " // last child / detail line
	TreeIndent = "  "  // 2-space indent per level
)

Tree characters for hierarchical display

View Source
const (
	SeparatorLight = "" /* 126-byte string literal not displayed */
	SeparatorHeavy = "" /* 126-byte string literal not displayed */
)

Separators

View Source
const (
	TimelineBar    = "│"
	TimelineDot    = "●"
	TimelineCircle = "○"
)

Timeline characters (circles - OpenClaw bubble style)

Variables

View Source
var (
	// Brand primary - the core SageOx identity color
	ColorPrimary = lipgloss.Color(HexPrimary) // sage green - brand identity

	// Semantic status colors (aligned with brand)
	ColorPass   = lipgloss.Color(HexPass)   // sage green - brand success
	ColorWarn   = lipgloss.Color(HexWarn)   // copper gold - brand warning
	ColorFail   = lipgloss.Color(HexFail)   // ox red - brand error
	ColorMuted  = lipgloss.Color(HexMuted)  // charcoal gray - recessive
	ColorAccent = lipgloss.Color(HexAccent) // info blue - brand accent

	// Text colors
	ColorText    = lipgloss.Color(HexText)    // soft gray-white - dark terminal optimized
	ColorTextDim = lipgloss.Color(HexTextDim) // dim text - pairs with sage/charcoal

	// Visibility colors (from sageox-mono public/private semantic tokens)
	ColorPublic  = lipgloss.Color(HexPublic)  // teal - public visibility
	ColorPrivate = lipgloss.Color(HexPrivate) // amber - private visibility
)
View Source
var (
	PassStyle   = lipgloss.NewStyle().Foreground(ColorPass)
	WarnStyle   = lipgloss.NewStyle().Foreground(ColorWarn)
	FailStyle   = lipgloss.NewStyle().Foreground(ColorFail)
	MutedStyle  = lipgloss.NewStyle().Foreground(ColorMuted)
	AccentStyle = lipgloss.NewStyle().Foreground(ColorAccent)
)

Status styles - consistent across all commands

View Source
var (
	PublicStyle  = lipgloss.NewStyle().Foreground(ColorPublic)
	PrivateStyle = lipgloss.NewStyle().Foreground(ColorPrivate)
)

Visibility styles

View Source
var CategoryStyle = lipgloss.NewStyle().Bold(true).Foreground(ColorAccent)

Category header style - using accent color for brand identity

View Source
var SageOxDarkStyleJSON = `{
	"document": {
		"block_prefix": "",
		"block_suffix": "",
		"margin": 0
	},
	"block_quote": {
		"indent": 2,
		"color": "` + theme.HexMuted + `",
		"indent_token": "│ "
	},
	"paragraph": {},
	"list": {
		"level_indent": 2
	},
	"heading": {
		"block_suffix": "\n",
		"color": "` + theme.HexAccent + `",
		"bold": true
	},
	"h1": {
		"prefix": "# ",
		"color": "` + theme.HexAccent + `",
		"bold": true
	},
	"h2": {
		"prefix": "## ",
		"color": "` + theme.HexAccent + `",
		"bold": true
	},
	"h3": {
		"prefix": "### ",
		"color": "` + theme.HexAccent + `"
	},
	"h4": {
		"prefix": "#### ",
		"color": "` + theme.HexAccent + `"
	},
	"h5": {
		"prefix": "##### ",
		"color": "` + theme.HexMuted + `"
	},
	"h6": {
		"prefix": "###### ",
		"color": "` + theme.HexMuted + `"
	},
	"text": {},
	"strikethrough": {
		"crossed_out": true
	},
	"emph": {
		"italic": true,
		"color": "` + theme.HexWarn + `"
	},
	"strong": {
		"bold": true,
		"color": "` + theme.HexText + `"
	},
	"hr": {
		"color": "` + theme.HexMuted + `",
		"format": "──────────────────────────────────────────"
	},
	"item": {
		"block_prefix": "• "
	},
	"enumeration": {
		"block_prefix": ". "
	},
	"task": {
		"ticked": "[✓] ",
		"unticked": "[ ] "
	},
	"link": {
		"color": "` + theme.HexAccent + `",
		"underline": true
	},
	"link_text": {
		"color": "` + theme.HexAccent + `"
	},
	"image": {
		"color": "` + theme.HexAccent + `"
	},
	"image_text": {
		"color": "` + theme.HexWarn + `"
	},
	"code": {
		"color": "` + theme.HexWarn + `",
		"background_color": "` + theme.HexBgCode + `"
	},
	"code_block": {
		"color": "` + theme.HexText + `",
		"margin": 2,
		"chroma": {
			"text": { "color": "` + theme.HexText + `" },
			"error": { "color": "` + theme.HexFail + `" },
			"comment": { "color": "` + theme.HexMuted + `" },
			"comment_preproc": { "color": "` + theme.HexMuted + `" },
			"keyword": { "color": "` + theme.HexAccent + `" },
			"keyword_reserved": { "color": "` + theme.HexAccent + `" },
			"keyword_namespace": { "color": "` + theme.HexAccent + `" },
			"keyword_type": { "color": "` + theme.HexAccent + `" },
			"operator": { "color": "` + theme.HexText + `" },
			"punctuation": { "color": "` + theme.HexMuted + `" },
			"name": { "color": "` + theme.HexText + `" },
			"name_builtin": { "color": "` + theme.HexAccent + `" },
			"name_tag": { "color": "` + theme.HexAccent + `" },
			"name_attribute": { "color": "` + theme.HexPrimary + `" },
			"name_class": { "color": "` + theme.HexPrimary + `", "bold": true },
			"name_constant": { "color": "` + theme.HexWarn + `" },
			"name_decorator": { "color": "` + theme.HexWarn + `" },
			"name_exception": { "color": "` + theme.HexFail + `" },
			"name_function": { "color": "` + theme.HexPrimary + `" },
			"name_other": { "color": "` + theme.HexText + `" },
			"literal": { "color": "` + theme.HexWarn + `" },
			"literal_number": { "color": "` + theme.HexWarn + `" },
			"literal_date": { "color": "` + theme.HexWarn + `" },
			"literal_string": { "color": "` + theme.HexPrimary + `" },
			"literal_string_escape": { "color": "` + theme.HexWarn + `" },
			"generic_deleted": { "color": "` + theme.HexFail + `" },
			"generic_emph": { "italic": true },
			"generic_inserted": { "color": "` + theme.HexPrimary + `" },
			"generic_strong": { "bold": true },
			"generic_subheading": { "color": "` + theme.HexAccent + `" },
			"background": { "background_color": "` + theme.HexBgDark + `" }
		}
	},
	"table": {
		"center_separator": "┼",
		"column_separator": "│",
		"row_separator": "─"
	},
	"definition_list": {},
	"definition_term": {
		"color": "` + theme.HexAccent + `",
		"bold": true
	},
	"definition_description": {
		"block_prefix": "  "
	},
	"html_block": {},
	"html_span": {}
}`

SageOxDarkStyleJSON defines a glamour style for dark terminals using SageOx brand colors. Colors reference the theme package constants for consistency.

View Source
var SageOxLightStyleJSON = `{
	"document": {
		"block_prefix": "",
		"block_suffix": "",
		"margin": 0
	},
	"block_quote": {
		"indent": 2,
		"color": "` + theme.HexLightMuted + `",
		"indent_token": "│ "
	},
	"paragraph": {},
	"list": {
		"level_indent": 2
	},
	"heading": {
		"block_suffix": "\n",
		"color": "` + theme.HexLightAccent + `",
		"bold": true
	},
	"h1": {
		"prefix": "# ",
		"color": "` + theme.HexLightAccent + `",
		"bold": true
	},
	"h2": {
		"prefix": "## ",
		"color": "` + theme.HexLightAccent + `",
		"bold": true
	},
	"h3": {
		"prefix": "### ",
		"color": "` + theme.HexLightAccent + `"
	},
	"h4": {
		"prefix": "#### ",
		"color": "` + theme.HexLightAccent + `"
	},
	"h5": {
		"prefix": "##### ",
		"color": "` + theme.HexLightMuted + `"
	},
	"h6": {
		"prefix": "###### ",
		"color": "` + theme.HexLightMuted + `"
	},
	"text": {},
	"strikethrough": {
		"crossed_out": true
	},
	"emph": {
		"italic": true,
		"color": "` + theme.HexLightWarn + `"
	},
	"strong": {
		"bold": true,
		"color": "` + theme.HexLightText + `"
	},
	"hr": {
		"color": "` + theme.HexLightMuted + `",
		"format": "──────────────────────────────────────────"
	},
	"item": {
		"block_prefix": "• "
	},
	"enumeration": {
		"block_prefix": ". "
	},
	"task": {
		"ticked": "[✓] ",
		"unticked": "[ ] "
	},
	"link": {
		"color": "` + theme.HexLightAccent + `",
		"underline": true
	},
	"link_text": {
		"color": "` + theme.HexLightAccent + `"
	},
	"image": {
		"color": "` + theme.HexLightAccent + `"
	},
	"image_text": {
		"color": "` + theme.HexLightWarn + `"
	},
	"code": {
		"color": "` + theme.HexLightWarn + `",
		"background_color": "` + theme.HexLightBgCode + `"
	},
	"code_block": {
		"color": "` + theme.HexLightText + `",
		"margin": 2,
		"chroma": {
			"text": { "color": "` + theme.HexLightText + `" },
			"error": { "color": "` + theme.HexLightFail + `" },
			"comment": { "color": "` + theme.HexLightMuted + `" },
			"comment_preproc": { "color": "` + theme.HexLightMuted + `" },
			"keyword": { "color": "` + theme.HexLightAccent + `" },
			"keyword_reserved": { "color": "` + theme.HexLightAccent + `" },
			"keyword_namespace": { "color": "` + theme.HexLightAccent + `" },
			"keyword_type": { "color": "` + theme.HexLightAccent + `" },
			"operator": { "color": "` + theme.HexLightText + `" },
			"punctuation": { "color": "` + theme.HexLightMuted + `" },
			"name": { "color": "` + theme.HexLightText + `" },
			"name_builtin": { "color": "` + theme.HexLightAccent + `" },
			"name_tag": { "color": "` + theme.HexLightAccent + `" },
			"name_attribute": { "color": "` + theme.HexLightPrimary + `" },
			"name_class": { "color": "` + theme.HexLightPrimary + `", "bold": true },
			"name_constant": { "color": "` + theme.HexLightWarn + `" },
			"name_decorator": { "color": "` + theme.HexLightWarn + `" },
			"name_exception": { "color": "` + theme.HexLightFail + `" },
			"name_function": { "color": "` + theme.HexLightPrimary + `" },
			"name_other": { "color": "` + theme.HexLightText + `" },
			"literal": { "color": "` + theme.HexLightWarn + `" },
			"literal_number": { "color": "` + theme.HexLightWarn + `" },
			"literal_date": { "color": "` + theme.HexLightWarn + `" },
			"literal_string": { "color": "` + theme.HexLightPrimary + `" },
			"literal_string_escape": { "color": "` + theme.HexLightWarn + `" },
			"generic_deleted": { "color": "` + theme.HexLightFail + `" },
			"generic_emph": { "italic": true },
			"generic_inserted": { "color": "` + theme.HexLightPrimary + `" },
			"generic_strong": { "bold": true },
			"generic_subheading": { "color": "` + theme.HexLightAccent + `" },
			"background": { "background_color": "` + theme.HexLightBgLight + `" }
		}
	},
	"table": {
		"center_separator": "┼",
		"column_separator": "│",
		"row_separator": "─"
	},
	"definition_list": {},
	"definition_term": {
		"color": "` + theme.HexLightAccent + `",
		"bold": true
	},
	"definition_description": {
		"block_prefix": "  "
	},
	"html_block": {},
	"html_span": {}
}`

SageOxLightStyleJSON defines a glamour style for light terminals using SageOx brand colors. Adjusted for light backgrounds with appropriate contrast.

Functions

func GetSageOxDarkStyle

func GetSageOxDarkStyle() ansi.StyleConfig

GetSageOxDarkStyle returns the SageOx dark theme style configuration

func GetSageOxLightStyle

func GetSageOxLightStyle() ansi.StyleConfig

GetSageOxLightStyle returns the SageOx light theme style configuration

func GetSageOxStyle

func GetSageOxStyle() ansi.StyleConfig

GetSageOxStyle returns the appropriate SageOx style based on terminal background. Uses lipgloss to detect if the terminal has a dark or light background.

func NewMarkdownRenderer

func NewMarkdownRenderer() (*glamour.TermRenderer, error)

NewMarkdownRenderer creates a glamour renderer with SageOx branding. Automatically selects dark or light theme based on terminal background.

func RenderAccent

func RenderAccent(s string) string

RenderAccent renders text with accent (blue) styling

func RenderAgentIcon

func RenderAgentIcon() string

RenderAgentIcon renders the agent icon with styling

func RenderBox added in v0.2.0

func RenderBox(title, content string, variant BoxVariant) string

RenderBox renders content in a bordered box with an optional title. Uses lipgloss.RoundedBorder() for rounded corners.

func RenderCategory

func RenderCategory(s string) string

RenderCategory renders a category header in uppercase with accent color

func RenderFail

func RenderFail(s string) string

RenderFail renders text with fail (red) styling

func RenderFailIcon

func RenderFailIcon() string

RenderFailIcon renders the fail icon with styling

func RenderInfoIcon

func RenderInfoIcon() string

RenderInfoIcon renders the info icon with styling

func RenderMarkdown

func RenderMarkdown(text string) string

RenderMarkdown renders markdown text with SageOx branding. Automatically selects dark or light theme based on terminal background. Returns the original text if rendering fails (graceful degradation).

func RenderMuted

func RenderMuted(s string) string

RenderMuted renders muted/dimmed text

func RenderPass

func RenderPass(s string) string

RenderPass renders text with pass (green) styling

func RenderPassIcon

func RenderPassIcon() string

RenderPassIcon renders the pass icon with styling

func RenderPrivate

func RenderPrivate(s string) string

RenderPrivate renders text with private (amber) styling

func RenderPublic

func RenderPublic(s string) string

RenderPublic renders text with public (teal) styling

func RenderSeparator

func RenderSeparator() string

RenderSeparator renders the light separator line

func RenderSkipIcon

func RenderSkipIcon() string

RenderSkipIcon renders the skip icon with styling

func RenderSummaryBox added in v0.2.0

func RenderSummaryBox(passCount, warnCount, failCount, skipCount int, hint string) string

RenderSummaryBox renders a summary box for doctor-style output. Shows pass/warn/fail counts with colored icons and an optional hint line.

func RenderTimeline added in v0.2.0

func RenderTimeline(nodes []TimelineNode, endLabel string) string

RenderTimeline renders a complete timeline as a string. endLabel is the text for the final hollow circle node (e.g., "Done").

func RenderTimelineConnector added in v0.2.0

func RenderTimelineConnector() string

RenderTimelineConnector renders just the "│" connector line.

func RenderTimelineEnd added in v0.2.0

func RenderTimelineEnd(label string) string

RenderTimelineEnd renders the closing hollow circle node.

func RenderTimelineNode added in v0.2.0

func RenderTimelineNode(node TimelineNode) string

RenderTimelineNode renders a single node with its items. Used for streaming output in --fix mode.

func RenderVisibility

func RenderVisibility(visibility string) string

RenderVisibility renders a visibility value with semantic color

func RenderWarn

func RenderWarn(s string) string

RenderWarn renders text with warning (yellow) styling

func RenderWarnIcon

func RenderWarnIcon() string

RenderWarnIcon renders the warning icon with styling

Types

type BoxVariant added in v0.2.0

type BoxVariant int

BoxVariant determines the border color of a box.

const (
	BoxDefault BoxVariant = iota // border: theme.ColorDim
	BoxInfo                      // border: theme.ColorInfo
	BoxWarning                   // border: theme.ColorWarning
	BoxError                     // border: theme.ColorError
	BoxSuccess                   // border: theme.ColorSuccess
)

type TimelineItem added in v0.2.0

type TimelineItem struct {
	Icon      string         // one of IconPass, IconWarn, IconFail, IconSkip, IconInfo, IconAgent
	Style     lipgloss.Style // color for the icon
	Text      string         // check name
	Detail    string         // action hint (rendered dim, indented below)
	DetailRaw bool           // if true, detail is pre-styled; skip MutedStyle wrapping
	Badge     string         // e.g., "[auto-fix]", "[--fix]"
}

TimelineItem represents a single check within a timeline node

type TimelineNode added in v0.2.0

type TimelineNode struct {
	Title   string         // section name
	Style   lipgloss.Style // node circle color
	Items   []TimelineItem
	Summary string // optional collapsed summary like "2 passed"
	Box     string // optional: render a bordered box instead of items (set by caller)
}

TimelineNode represents a section on the vertical timeline

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL