theme

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 5 Imported by: 0

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.

const (
	Border      Role = "border"
	Overlay     Role = "overlay"
	Selection   Role = "selection"
	Placeholder Role = "placeholder"
	PasteChip   Role = "paste.chip"
	QueuedChip  Role = "queued.chip"
)

The chrome roles: borders, overlays, selection, and the composer's affordances.

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) IsZero

func (s Style) IsZero() bool

IsZero reports whether the style changes nothing.

func (Style) Over

func (s Style) Over(base Style) Style

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

func (s Style) Render(text string) string

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 Builtin

func Builtin(name string) *Theme

Builtin returns the built-in theme with the given name, or nil.

func Default

func Default() *Theme

Default returns the standard theme.

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

func Load(r io.Reader) (*Theme, error)

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 Mono

func Mono() *Theme

Mono returns the attribute-only theme for monochrome output.

func (*Theme) Name

func (t *Theme) Name() string

Name identifies the theme (shown by the theme picker).

func (*Theme) Render

func (t *Theme) Render(r Role, s string) string

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.

func (*Theme) Style

func (t *Theme) Style(r Role) Style

Style returns the style for a role (the zero style when undefined).

Jump to

Keyboard shortcuts

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