Documentation
¶
Overview ¶
Package theme is the semantic styling layer for the terminal session. Components never emit colors: they style text by role (what the text IS, not how it looks), and a Theme maps each role to a concrete style. Swapping the theme restyles the whole session without touching a component, which is what makes user theme files and the accessibility variants possible at all.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Color ¶
type Color string
Color names a terminal color: empty for the terminal default, one of the sixteen base names ("red", "bright-blue"), a 256-palette index ("213"), or a hex value ("#ff5f87"). Named and indexed colors respect the user's terminal palette; hex is exact where supported.
type Role ¶
type Role string
Role names one kind of content the session renders. The set is the UI's styling vocabulary: a new visual element gets a role here, never an inline color at the call site.
const ( UserText Role = "user.text" UserPrefix Role = "user.prefix" AssistantText Role = "assistant.text" Code Role = "code" Quote Role = "quote" Link Role = "link" Emphasis Role = "emphasis" Strong Role = "strong" Heading Role = "heading" )
The transcript roles: the conversation's own text and its markdown constructs.
const ( ToolName Role = "tool.name" ToolDetail Role = "tool.detail" ToolOutput Role = "tool.output" Admitted Role = "governance.admitted" Rejected Role = "governance.rejected" Trust Role = "governance.trust" DiffAdded Role = "diff.added" DiffRemoved Role = "diff.removed" DiffContext Role = "diff.context" DiffLocation Role = "diff.location" )
The tool and governance roles: action blocks, admission outcomes, and diffs.
const ( Status Role = "status" StatusBusy Role = "status.busy" RecordRecording Role = "record.recording" RecordSealed Role = "record.sealed" RecordVerified Role = "record.verified" RecordFailed Role = "record.failed" Success Role = "success" Warning Role = "warning" Error Role = "error" Muted Role = "muted" )
The status and record roles: the status line, the record badge states, and the outcome accents.
const ( SyntaxKeyword Role = "syntax.keyword" SyntaxString Role = "syntax.string" SyntaxNumber Role = "syntax.number" SyntaxComment Role = "syntax.comment" SyntaxFunction Role = "syntax.function" SyntaxType Role = "syntax.type" )
The syntax roles: token classes inside highlighted code blocks. The set is deliberately small; a highlighter buckets its lexer's fine-grained token types into these, and anything unbucketed falls back to Code.
type Style ¶
type Style struct {
Foreground Color `json:"fg,omitempty"`
Background Color `json:"bg,omitempty"`
Bold bool `json:"bold,omitempty"`
Faint bool `json:"faint,omitempty"`
Italic bool `json:"italic,omitempty"`
Underline bool `json:"underline,omitempty"`
Reverse bool `json:"reverse,omitempty"`
Strike bool `json:"strike,omitempty"`
}
Style is one role's appearance.
func (Style) Over ¶
Over layers s onto base: s's colors win where set, and attribute flags accumulate. This is how nested markdown styles compose (emphasis inside a quote keeps the quote's color and gains italics) without any renderer keeping escape state.
func (Style) Render ¶
Render styles text with s directly, for callers that compose styles themselves (the markdown and syntax renderers merge several roles into one effective style per span). Same contract as Theme.Render: an attribute-free style passes the text through untouched, and every styled span is self-contained (prefix, text, reset), so lines never leak escape state into each other.
type Theme ¶
type Theme struct {
// contains filtered or unexported fields
}
Theme maps roles to styles. A role a theme does not define renders unstyled, never as an error: a sparse user theme degrades to plain text, not a broken session.
func HighContrast ¶
func HighContrast() *Theme
HighContrast returns the accessibility theme: no faint text, and every state distinction doubled onto a non-color channel.
func Load ¶
Load reads a JSON theme and returns it layered over its declared base (default when unset), so a user theme starts from a complete, coherent palette and only overrides what it names. Unknown roles are refused rather than ignored: a misspelled role in a theme file would otherwise silently style nothing, which is the kind of failure a user cannot debug.
func (*Theme) Render ¶
Render styles s for the role: the role's SGR attributes, the text, then a reset. Text whose style contributes no attributes passes through untouched. That covers the zero style (an unthemed role costs nothing and adds no escape noise) and a style whose only content is an invalid color: the color is muted, so there is no prefix, and there must be no dangling reset either.