widget

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package widget provides shared Bubble Tea UI components for the AgentFactory and Rensei TUI applications.

Widgets

  • Dialog — a modal confirmation dialog with configurable buttons, keyboard navigation, and overlay support.
  • Progressbar — a themed progress bar wrapping charm.land/bubbles/v2/progress with deterministic (percent-driven) and indeterminate (animated sweep) modes, optional label, percent text, and ETA estimator.

Progressbar example

Construct a 60-cell-wide bar with a leading label, the right-aligned percentage, and an ETA estimator, then advance it as work completes:

bar := widget.NewProgressbar(
    widget.WithProgressbarWidth(60),
    widget.WithProgressbarLabel("Uploading"),
    widget.WithProgressbarShowPercent(true),
    widget.WithProgressbarShowETA(true),
)
bar.SetPercent(0.25)
// ... later ...
bar.IncrBy(0.25)
fmt.Println(bar.View().Content)

Package widget provides shared Bubble Tea UI components.

Example (LogViewer)

Example_logViewer demonstrates the minimal lifecycle of the LogViewer widget: construct, size, append, and render.

The rendered frame contains ANSI SGR escape sequences whose exact byte layout is environment-dependent (lipgloss downsamples colours according to the active profile), so the example asserts only the row count, which is a stable function of the widget height.

package main

import (
	"fmt"
	"strings"

	"github.com/RenseiAI/tui-components/widget"
)

func main() {
	lv := widget.NewLogViewer(widget.WithMaxLines(100))
	lv.SetSize(40, 6)
	lv.Append("hello", "world")

	view := lv.View()
	// Widget height is 6 rows (5 content + 1 footer), so the rendered
	// frame must contain exactly 6 rows — regardless of colour profile.
	rows := strings.Count(view.Content, "\n") + 1
	fmt.Printf("rows=%d\n", rows)

}
Output:
rows=6

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppendMsg

type AppendMsg struct {
	// Lines is the batch of raw log lines (may contain ANSI escapes)
	// to append to the buffer.
	Lines []string
}

AppendMsg is a tea.Msg form of Append. Dispatching this message through the program loop lets background producers push log lines without holding a reference to the widget.

type AttestationChip

type AttestationChip struct {
	// contains filtered or unexported fields
}

AttestationChip renders the signing / verification state of an artifact together with an optional truncated key fingerprint.

Example renderings:

✓ verified  ed25519:abc1234…d4f2
~ signed
✗ unsigned

In no-color mode the chip renders with plain ASCII and no color escapes.

Example (NoColor)

ExampleAttestationChip_noColor demonstrates AttestationChip rendering.

states := []AttestationState{AttestationVerified, AttestationSigned, AttestationUnsigned}
for _, s := range states {
	chip := NewAttestationChip(
		WithAttestationState(s),
		WithAttestationNoColor(true),
	)
	fmt.Println(chip.ViewString())
}
Output:
✓ verified
~ signed
✗ unsigned

func NewAttestationChip

func NewAttestationChip(opts ...AttestationChipOption) *AttestationChip

NewAttestationChip constructs an AttestationChip with default theme.

func (*AttestationChip) AccessibleLabel

func (c *AttestationChip) AccessibleLabel() string

AccessibleLabel returns the accessible label.

func (*AttestationChip) Blur

func (c *AttestationChip) Blur()

Blur is a no-op.

func (*AttestationChip) Focus

func (c *AttestationChip) Focus()

Focus is a no-op.

func (*AttestationChip) Init

func (c *AttestationChip) Init() tea.Cmd

Init satisfies tea.Model.

func (*AttestationChip) SetSize

func (c *AttestationChip) SetSize(width, height int)

SetSize is a no-op.

func (*AttestationChip) SetTheme

func (c *AttestationChip) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*AttestationChip) Update

func (c *AttestationChip) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*AttestationChip) View

func (c *AttestationChip) View() tea.View

View renders the chip as a tea.View.

func (*AttestationChip) ViewString

func (c *AttestationChip) ViewString() string

ViewString renders the chip as a plain string.

type AttestationChipOption

type AttestationChipOption func(*AttestationChip)

AttestationChipOption configures an AttestationChip during construction.

func WithAttestationAccessibleLabel

func WithAttestationAccessibleLabel(label string) AttestationChipOption

WithAttestationAccessibleLabel sets the accessible label.

func WithAttestationFingerprint

func WithAttestationFingerprint(fp string) AttestationChipOption

WithAttestationFingerprint sets the raw key fingerprint displayed in truncated form alongside the state. The format is expected to be "algo:hexbytes" (e.g. "ed25519:abcd1234..."). Truncation is applied by the widget; pass the full fingerprint.

func WithAttestationNoColor

func WithAttestationNoColor(nc bool) AttestationChipOption

WithAttestationNoColor forces symbol-first, no-ANSI rendering.

func WithAttestationState

func WithAttestationState(s AttestationState) AttestationChipOption

WithAttestationState sets the attestation state.

func WithAttestationTheme

func WithAttestationTheme(t theme.Theme) AttestationChipOption

WithAttestationTheme sets the Theme.

type AttestationState

type AttestationState string

AttestationState represents the attestation/signing state of a plugin, commit, or session artifact, per 002-provider-base-contract.md and 014-tui-operator-surfaces.md.

const (
	// AttestationSigned indicates the artifact carries a valid cryptographic
	// signature but the key has not been independently verified.
	AttestationSigned AttestationState = "signed"

	// AttestationUnsigned indicates the artifact has no signature.
	AttestationUnsigned AttestationState = "unsigned"

	// AttestationVerified indicates the signature has been verified against a
	// trusted key store (e.g. sigstore-equivalent verification).
	AttestationVerified AttestationState = "verified"
)

type AuditChain

type AuditChain struct {
	// contains filtered or unexported fields
}

AuditChain renders a composed list of AuditEntry rows along with a chain integrity indicator. Per Layer 6 / 014-tui-operator-surfaces.md.

Example rendering:

✓ Chain intact (3 events)
2026-04-28 14:23:01  session.start   worker-01  ✓ verified  ed25519:abc1…d4f2
2026-04-28 14:23:12  kit.detect      worker-01  ✓ verified  ed25519:abc1…d4f2
2026-04-28 14:45:30  session.end     worker-01  ✓ verified  ed25519:abc1…d4f2
Example (NoColor)

ExampleAuditChain_noColor demonstrates the AuditChain widget.

ts := time.Date(2026, 4, 28, 14, 23, 1, 0, time.UTC)
e := NewAuditEntry(
	WithAuditEventKind("session.start"),
	WithAuditActor("worker-01"),
	WithAuditTimestamp(ts),
	WithAuditAttestation(AttestationVerified),
	WithAuditNoColor(true),
)
chain := NewAuditChain(
	WithChainEntries(e),
	WithChainIntegrity(ChainIntegrityOK),
	WithAuditChainNoColor(true),
)
// Chain integrity header + entry; omit Output: since timestamp formatting
// and column alignment depends on entry count.
_ = chain.ViewString()

func NewAuditChain

func NewAuditChain(opts ...AuditChainOption) *AuditChain

NewAuditChain constructs an AuditChain with default theme.

func (*AuditChain) Blur

func (c *AuditChain) Blur()

Blur is a no-op.

func (*AuditChain) Focus

func (c *AuditChain) Focus()

Focus is a no-op.

func (*AuditChain) Init

func (c *AuditChain) Init() tea.Cmd

Init satisfies tea.Model.

func (*AuditChain) SetSize

func (c *AuditChain) SetSize(width, height int)

SetSize stores size hints.

func (*AuditChain) SetTheme

func (c *AuditChain) SetTheme(t theme.Theme)

SetTheme updates the theme for the chain and all entries.

func (*AuditChain) Update

func (c *AuditChain) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*AuditChain) View

func (c *AuditChain) View() tea.View

View renders the chain as a tea.View.

func (*AuditChain) ViewString

func (c *AuditChain) ViewString() string

ViewString renders the chain as a plain string.

type AuditChainOption

type AuditChainOption func(*AuditChain)

AuditChainOption configures an AuditChain during construction.

func WithAuditChainNoColor

func WithAuditChainNoColor(nc bool) AuditChainOption

WithAuditChainNoColor forces symbol-first, no-ANSI rendering.

func WithAuditChainTheme

func WithAuditChainTheme(t theme.Theme) AuditChainOption

WithAuditChainTheme sets the Theme.

func WithChainEntries

func WithChainEntries(entries ...*AuditEntry) AuditChainOption

WithChainEntries sets the AuditEntry rows.

func WithChainIntegrity

func WithChainIntegrity(i ChainIntegrity) AuditChainOption

WithChainIntegrity sets the chain integrity state.

type AuditEntry

type AuditEntry struct {
	// EventKind is the event type identifier (e.g. "session.start",
	// "commit.push", "kit.detect").
	EventKind string
	// Actor is the entity that triggered the event (worker ID, user ID, etc.).
	Actor string
	// Timestamp is when the event occurred.
	Timestamp time.Time
	// Attestation is the signing state of this event.
	Attestation AttestationState
	// Fingerprint is the optional key fingerprint for the attestation.
	Fingerprint string
	// AccessibleLabel provides a screen-reader-friendly description.
	AccessLabel string
	// contains filtered or unexported fields
}

AuditEntry renders a single signed audit event row with attestation state and timestamp. It is the building block for AuditChain. Per Layer 6 (Policy/Security/Observability) in 001 and 014-tui-operator-surfaces.md.

Example rendering:

✓  2026-04-28 14:23:01  session.start   worker-01  ed25519:abc1…d4f2

func NewAuditEntry

func NewAuditEntry(opts ...AuditEntryOption) *AuditEntry

NewAuditEntry constructs an AuditEntry with default theme.

func (*AuditEntry) AccessibleLabel

func (e *AuditEntry) AccessibleLabel() string

AccessibleLabel returns the accessible label.

func (*AuditEntry) Blur

func (e *AuditEntry) Blur()

Blur is a no-op.

func (*AuditEntry) Focus

func (e *AuditEntry) Focus()

Focus is a no-op.

func (*AuditEntry) Init

func (e *AuditEntry) Init() tea.Cmd

Init satisfies tea.Model.

func (*AuditEntry) SetSize

func (e *AuditEntry) SetSize(width, height int)

SetSize is a no-op.

func (*AuditEntry) SetTheme

func (e *AuditEntry) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*AuditEntry) Update

func (e *AuditEntry) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*AuditEntry) View

func (e *AuditEntry) View() tea.View

View renders the entry as a tea.View.

func (*AuditEntry) ViewString

func (e *AuditEntry) ViewString() string

ViewString renders the entry as a plain string.

type AuditEntryOption

type AuditEntryOption func(*AuditEntry)

AuditEntryOption configures an AuditEntry during construction.

func WithAuditAccessibleLabel

func WithAuditAccessibleLabel(label string) AuditEntryOption

WithAuditAccessibleLabel sets the accessible label.

func WithAuditActor

func WithAuditActor(actor string) AuditEntryOption

WithAuditActor sets the actor label.

func WithAuditAttestation

func WithAuditAttestation(a AttestationState) AuditEntryOption

WithAuditAttestation sets the attestation state.

func WithAuditEventKind

func WithAuditEventKind(kind string) AuditEntryOption

WithAuditEventKind sets the event kind label.

func WithAuditFingerprint

func WithAuditFingerprint(fp string) AuditEntryOption

WithAuditFingerprint sets the key fingerprint.

func WithAuditNoColor

func WithAuditNoColor(nc bool) AuditEntryOption

WithAuditNoColor forces symbol-first, no-ANSI rendering.

func WithAuditTheme

func WithAuditTheme(t theme.Theme) AuditEntryOption

WithAuditTheme sets the Theme.

func WithAuditTimestamp

func WithAuditTimestamp(t time.Time) AuditEntryOption

WithAuditTimestamp sets the event timestamp.

type Button

type Button struct {
	// Label is the text shown on the button.
	Label string
	// Result is the Result emitted when this button is activated.
	Result Result
}

Button describes a single selectable action in a Dialog.

type CapabilityChip

type CapabilityChip struct {
	// contains filtered or unexported fields
}

CapabilityChip renders a typed capability flag alongside its human-readable label. It is the canonical display primitive for any typed enum flag in the Rensei architecture (billing model, transport model, idle-cost model, etc.) as described in 002-provider-base-contract.md and 014-tui-operator-surfaces.md.

The chip renders as: ◆ <value> <humanLabel> In no-color mode: <symbol> <value> <humanLabel>

Example usage:

chip := widget.NewCapabilityChip(
    widget.WithCapabilityValue("active-cpu"),
    widget.WithCapabilityHumanLabel("Billed for active CPU only"),
)
fmt.Println(chip.ViewString())
Example (NoColor)

ExampleCapabilityChip_noColor demonstrates a CapabilityChip in no-color mode.

chip := NewCapabilityChip(
	WithCapabilityValue("active-cpu"),
	WithCapabilityHumanLabel("Billed for active CPU only"),
	WithCapabilityNoColor(true),
)
fmt.Println(chip.ViewString())
Output:
◆ active-cpu  Billed for active CPU only
Example (Themed)

ExampleCapabilityChip_themed demonstrates a CapabilityChip with the default theme.

chip := NewCapabilityChip(
	WithCapabilityValue("dial-in"),
	WithCapabilityHumanLabel("Dial-in transport"),
	WithCapabilityTheme(theme.DefaultTheme()),
)
// Lipgloss rendering contains ANSI sequences; omit Output:.
_ = chip.ViewString()

func NewCapabilityChip

func NewCapabilityChip(opts ...CapabilityChipOption) *CapabilityChip

NewCapabilityChip constructs a CapabilityChip with the default theme.

func (*CapabilityChip) AccessibleLabel

func (c *CapabilityChip) AccessibleLabel() string

AccessibleLabel returns the accessible label set on this chip. If no explicit accessible label was set, it falls back to "<value>: <humanLabel>".

func (*CapabilityChip) Blur

func (c *CapabilityChip) Blur()

Blur is a no-op; CapabilityChip is a display-only primitive.

func (*CapabilityChip) Focus

func (c *CapabilityChip) Focus()

Focus is a no-op; CapabilityChip is a display-only primitive.

func (*CapabilityChip) Init

func (c *CapabilityChip) Init() tea.Cmd

Init satisfies tea.Model; CapabilityChip is static — no commands needed.

func (*CapabilityChip) SetSize

func (c *CapabilityChip) SetSize(width, height int)

SetSize is a no-op for CapabilityChip; it renders its natural width.

func (*CapabilityChip) SetTheme

func (c *CapabilityChip) SetTheme(t theme.Theme)

SetTheme updates the theme used for rendering.

func (*CapabilityChip) Update

func (c *CapabilityChip) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model; CapabilityChip has no interactive state.

func (*CapabilityChip) View

func (c *CapabilityChip) View() tea.View

View renders the chip as a tea.View.

func (*CapabilityChip) ViewString

func (c *CapabilityChip) ViewString() string

ViewString renders the chip as a plain string (no tea.View wrapping).

type CapabilityChipOption

type CapabilityChipOption func(*CapabilityChip)

CapabilityChipOption configures a CapabilityChip during construction.

func WithCapabilityAccessibleLabel

func WithCapabilityAccessibleLabel(label string) CapabilityChipOption

WithCapabilityAccessibleLabel sets the accessible label used by screen-reader consumers (REN-1332 a11y opt-in).

func WithCapabilityHumanLabel

func WithCapabilityHumanLabel(label string) CapabilityChipOption

WithCapabilityHumanLabel sets the human-readable description rendered beside the flag value.

func WithCapabilityNoColor

func WithCapabilityNoColor(nc bool) CapabilityChipOption

WithCapabilityNoColor forces symbol-first, no-ANSI rendering. Equivalent to honoring the NO_COLOR env var at the widget level.

func WithCapabilitySymbol

func WithCapabilitySymbol(sym string) CapabilityChipOption

WithCapabilitySymbol overrides the default leading symbol ("◆").

func WithCapabilityTheme

func WithCapabilityTheme(t theme.Theme) CapabilityChipOption

WithCapabilityTheme sets the Theme used for rendering colors.

func WithCapabilityValue

func WithCapabilityValue(v string) CapabilityChipOption

WithCapabilityValue sets the raw capability flag value (e.g. "active-cpu", "wall-clock", "dial-in").

type ChainIntegrity

type ChainIntegrity string

ChainIntegrity represents whether the audit chain's hash chain is intact.

const (
	// ChainIntegrityOK means all entries hash-chain correctly.
	ChainIntegrityOK ChainIntegrity = "ok"
	// ChainIntegrityBroken means at least one hash-chain link is broken.
	ChainIntegrityBroken ChainIntegrity = "broken"
	// ChainIntegrityUnverified means chain integrity has not been checked.
	ChainIntegrityUnverified ChainIntegrity = "unverified"
)

type CostBreakdown

type CostBreakdown struct {
	// Label is the display name for this cost category.
	Label string
	// Amount is the cost in the smallest currency unit (e.g. USD cents).
	Amount float64
	// Currency is the currency code (e.g. "USD").
	Currency string
}

CostBreakdown represents a single cost line item in the panel.

type CostPanel

type CostPanel struct {
	// contains filtered or unexported fields
}

CostPanel renders a per-session / per-issue / per-tenant cost breakdown with an optional trend indicator. It taps idleCostModel and billingModel semantics from 006-cross-provider-interactions.md Seam 4.

Example rendering:

Cost summary
  Session     $0.42  USD
  Issue       $1.87  USD  ↑
  Tenant      $42.00 USD

func NewCostPanel

func NewCostPanel(opts ...CostPanelOption) *CostPanel

NewCostPanel constructs a CostPanel with default theme.

func (*CostPanel) AccessibleLabel

func (p *CostPanel) AccessibleLabel() string

AccessibleLabel returns the accessible label.

func (*CostPanel) Blur

func (p *CostPanel) Blur()

Blur is a no-op.

func (*CostPanel) Focus

func (p *CostPanel) Focus()

Focus is a no-op.

func (*CostPanel) Init

func (p *CostPanel) Init() tea.Cmd

Init satisfies tea.Model.

func (*CostPanel) SetSize

func (p *CostPanel) SetSize(width, height int)

SetSize stores the width hint.

func (*CostPanel) SetTheme

func (p *CostPanel) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*CostPanel) Update

func (p *CostPanel) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*CostPanel) View

func (p *CostPanel) View() tea.View

View renders the panel as a tea.View.

func (*CostPanel) ViewString

func (p *CostPanel) ViewString() string

ViewString renders the panel as a plain string.

type CostPanelOption

type CostPanelOption func(*CostPanel)

CostPanelOption configures a CostPanel during construction.

func WithCostBillingNote

func WithCostBillingNote(note string) CostPanelOption

WithCostBillingNote sets a billing model annotation (e.g. "active-cpu billing").

func WithCostItems

func WithCostItems(items ...CostBreakdown) CostPanelOption

WithCostItems sets the cost line items.

func WithCostPanelAccessibleLabel

func WithCostPanelAccessibleLabel(label string) CostPanelOption

WithCostPanelAccessibleLabel sets the accessible label.

func WithCostPanelNoColor

func WithCostPanelNoColor(nc bool) CostPanelOption

WithCostPanelNoColor forces symbol-first, no-ANSI rendering.

func WithCostPanelTheme

func WithCostPanelTheme(t theme.Theme) CostPanelOption

WithCostPanelTheme sets the Theme.

func WithCostTitle

func WithCostTitle(title string) CostPanelOption

WithCostTitle sets the panel title.

func WithCostTrend

func WithCostTrend(t CostTrend) CostPanelOption

WithCostTrend sets the trend indicator shown on the last item.

type CostTrend

type CostTrend string

CostTrend indicates whether costs are rising, falling, or flat.

const (
	// CostTrendUp indicates costs are increasing.
	CostTrendUp CostTrend = "up"
	// CostTrendDown indicates costs are decreasing.
	CostTrendDown CostTrend = "down"
	// CostTrendFlat indicates costs are unchanged.
	CostTrendFlat CostTrend = "flat"
)

type Dialog

type Dialog struct {
	// contains filtered or unexported fields
}

Dialog is a modal widget presenting a title, body text, and a row of buttons. It implements component.Component and can be rendered standalone via View. Composition onto a parent view is handled separately by the overlay helper.

func New

func New(opts ...Option) *Dialog

New constructs a Dialog with default Yes/No/Cancel buttons. Options may override labels, provide a custom button set, and set title/body text.

func (*Dialog) Blur

func (d *Dialog) Blur()

Blur marks the dialog as not focused.

func (*Dialog) Buttons

func (d *Dialog) Buttons() []Button

Buttons returns a copy of the dialog's configured buttons, in order.

func (*Dialog) Focus

func (d *Dialog) Focus()

Focus marks the dialog as focused. The dialog always consumes its own keys while visible; focus state is primarily informational.

func (*Dialog) Focused

func (d *Dialog) Focused() bool

Focused reports whether the dialog currently has focus.

func (*Dialog) FocusedIndex

func (d *Dialog) FocusedIndex() int

FocusedIndex returns the index of the currently focused button.

func (*Dialog) Init

func (d *Dialog) Init() tea.Cmd

Init implements tea.Model. Dialog has no startup work.

func (*Dialog) Overlay

func (d *Dialog) Overlay(background string) string

Overlay composes the dialog as a centered overlay on top of the given background string, with a dimmed backdrop. The background is expected to be a fully-rendered terminal view (may contain ANSI escape sequences).

If SetSize has not been called (width or height is 0), Overlay falls back to returning the dialog box alone without a backdrop.

Overlay is pure: it does not mutate any Dialog state.

func (*Dialog) Render

func (d *Dialog) Render() string

Render produces the dialog's content as a styled string without wrapping it in a tea.View. Useful for composition helpers such as Overlay.

func (*Dialog) Reset

func (d *Dialog) Reset()

Reset clears the Result back to ResultNone and restores initial focus to the first button. Title, body, and button configuration are preserved.

func (*Dialog) Result

func (d *Dialog) Result() Result

Result returns the Result currently set on the dialog. Before any button is activated the value is ResultNone.

func (*Dialog) SetSize

func (d *Dialog) SetSize(width, height int)

SetSize stores the outer dimensions used for centering and body wrapping. Re-wrapping happens lazily on the next View call.

func (*Dialog) Update

func (d *Dialog) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update implements tea.Model. It handles focus navigation between buttons, activation via Enter, quick-activation via y/n, and cancellation via Esc.

func (*Dialog) View

func (d *Dialog) View() tea.View

View implements tea.Model. It renders a bordered, centered dialog box with a title, wrapped body text, and a row of buttons. An empty view is returned when the dialog has no content and no configured buttons.

type DialogDoneMsg

type DialogDoneMsg struct {
	// Result is the Result that was selected.
	Result Result
}

DialogDoneMsg is emitted as a tea.Cmd payload when a Dialog is dismissed by activating a button or by pressing escape.

type FleetGrid

type FleetGrid struct {
	// contains filtered or unexported fields
}

FleetGrid renders a multi-worker fleet view grouped by machine/daemon as described in 013-orchestrator-and-governor.md and 014-tui-operator-surfaces.md.

Example rendering:

machine-01
  ● busy   iad1   ████████  99%   active-cpu
  ◌ idle   iad1   ░░░░░░░░   0%   active-cpu
machine-02
  ◌ idle   sfo3   ░░░░░░░░   0%   wall-clock
Example (NoColor)

ExampleFleetGrid_noColor demonstrates FleetGrid rendering.

g := NewFleetGrid(
	WithFleetWorkers(
		FleetWorker{
			ID:           "w-1",
			MachineGroup: "mac-01",
			Status:       WorkerStatusBusy,
			Region:       "iad1",
			LoadFraction: 0.75,
			BillingModel: "active-cpu",
		},
	),
	WithFleetNoColor(true),
)
// Output contains ANSI-free text; omit Output: due to bar character width.
_ = g.ViewString()

func NewFleetGrid

func NewFleetGrid(opts ...FleetGridOption) *FleetGrid

NewFleetGrid constructs a FleetGrid with default theme.

func (*FleetGrid) Blur

func (g *FleetGrid) Blur()

Blur is a no-op.

func (*FleetGrid) Focus

func (g *FleetGrid) Focus()

Focus is a no-op.

func (*FleetGrid) Init

func (g *FleetGrid) Init() tea.Cmd

Init satisfies tea.Model.

func (*FleetGrid) SetSize

func (g *FleetGrid) SetSize(width, height int)

SetSize stores size hints.

func (*FleetGrid) SetTheme

func (g *FleetGrid) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*FleetGrid) SetWorkers

func (g *FleetGrid) SetWorkers(workers []FleetWorker)

SetWorkers replaces the current worker list.

func (*FleetGrid) Update

func (g *FleetGrid) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*FleetGrid) View

func (g *FleetGrid) View() tea.View

View renders the grid as a tea.View.

func (*FleetGrid) ViewString

func (g *FleetGrid) ViewString() string

ViewString renders the grid as a plain string.

type FleetGridOption

type FleetGridOption func(*FleetGrid)

FleetGridOption configures a FleetGrid during construction.

func WithFleetNoColor

func WithFleetNoColor(nc bool) FleetGridOption

WithFleetNoColor forces symbol-first, no-ANSI rendering.

func WithFleetTheme

func WithFleetTheme(t theme.Theme) FleetGridOption

WithFleetTheme sets the Theme.

func WithFleetWorkers

func WithFleetWorkers(workers ...FleetWorker) FleetGridOption

WithFleetWorkers sets the list of workers to display.

type FleetWorker

type FleetWorker struct {
	ID           string
	MachineGroup string // machine/daemon grouping label
	Status       WorkerStatus
	Region       string
	LoadFraction float64
	BillingModel string
}

FleetWorker is the data record for a single worker entry in the FleetGrid. It mirrors the fields of WorkerRow to allow callers to build a grid from data without constructing individual WorkerRow instances first.

type KeyMap

type KeyMap struct {
	// LineUp scrolls the viewport up by one line and pauses follow.
	LineUp key.Binding
	// LineDown scrolls the viewport down by one line.
	LineDown key.Binding
	// PageUp scrolls the viewport up by one page and pauses follow.
	PageUp key.Binding
	// PageDown scrolls the viewport down by one page.
	PageDown key.Binding
	// Home jumps to the top of the buffer and pauses follow.
	Home key.Binding
	// End jumps to the tail and re-engages follow.
	End key.Binding
	// ToggleFollow flips follow mode. Turning follow on jumps to the
	// tail.
	ToggleFollow key.Binding
	// ToggleWrap flips soft-wrap rendering.
	ToggleWrap key.Binding
	// Clear drops every retained line and resets the SGR parser.
	Clear key.Binding
}

KeyMap defines the key bindings used by LogViewer. Consumers can rebind any action by constructing a new KeyMap and passing it via WithLogViewerKeyMap.

Each binding carries its own help text (see key.WithHelp) so a future help-bar integration can surface the active bindings without needing a separate metadata table.

func DefaultKeyMap

func DefaultKeyMap() KeyMap

DefaultKeyMap returns the default key bindings for LogViewer:

LineUp:       up, k
LineDown:     down, j
PageUp:       pgup
PageDown:     pgdn
Home:         home, g
End:          end, G
ToggleFollow: f
ToggleWrap:   w
Clear:        c

type KitDetectResult

type KitDetectResult struct {
	// contains filtered or unexported fields
}

KitDetectResult renders the list of kits that matched detection for a given session, with ordering and conflict indicators. Per 005-kit-manifest-spec.md and 014-tui-operator-surfaces.md.

Example rendering:

Kits detected (2)
  1  spring-java  v1.2.0
  2  nextjs       v0.9.1  ⚠ conflicts with spring-java: conflicting MCP servers
Example (NoColor)

ExampleKitDetectResult_noColor demonstrates kit detection output.

r := NewKitDetectResult(
	WithKitMatches(
		KitMatch{Name: "spring-java", Version: "v1.2.0", Order: 1},
	),
	WithKitDetectNoColor(true),
)
// Omit Output: due to column padding variability.
_ = r.ViewString()

func NewKitDetectResult

func NewKitDetectResult(opts ...KitDetectResultOption) *KitDetectResult

NewKitDetectResult constructs a KitDetectResult with default theme.

func (*KitDetectResult) AccessibleLabel

func (r *KitDetectResult) AccessibleLabel() string

AccessibleLabel returns the accessible label.

func (*KitDetectResult) Blur

func (r *KitDetectResult) Blur()

Blur is a no-op.

func (*KitDetectResult) Focus

func (r *KitDetectResult) Focus()

Focus is a no-op.

func (*KitDetectResult) Init

func (r *KitDetectResult) Init() tea.Cmd

Init satisfies tea.Model.

func (*KitDetectResult) SetSize

func (r *KitDetectResult) SetSize(width, height int)

SetSize is a no-op.

func (*KitDetectResult) SetTheme

func (r *KitDetectResult) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*KitDetectResult) Update

func (r *KitDetectResult) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*KitDetectResult) View

func (r *KitDetectResult) View() tea.View

View renders the result as a tea.View.

func (*KitDetectResult) ViewString

func (r *KitDetectResult) ViewString() string

ViewString renders the result as a plain string.

type KitDetectResultOption

type KitDetectResultOption func(*KitDetectResult)

KitDetectResultOption configures a KitDetectResult during construction.

func WithKitDetectAccessibleLabel

func WithKitDetectAccessibleLabel(label string) KitDetectResultOption

WithKitDetectAccessibleLabel sets the accessible label.

func WithKitDetectNoColor

func WithKitDetectNoColor(nc bool) KitDetectResultOption

WithKitDetectNoColor forces symbol-first, no-ANSI rendering.

func WithKitDetectTheme

func WithKitDetectTheme(t theme.Theme) KitDetectResultOption

WithKitDetectTheme sets the Theme.

func WithKitMatches

func WithKitMatches(matches ...KitMatch) KitDetectResultOption

WithKitMatches sets the list of detected kit matches.

type KitMatch

type KitMatch struct {
	// Name is the kit name (e.g. "spring-java", "nextjs", "go-module").
	Name string
	// Version is the matched kit version.
	Version string
	// Order is the composition order (lower = applied first).
	Order int
	// Conflict is true when this kit has a composition conflict with another.
	Conflict bool
	// ConflictReason describes the conflict if Conflict is true.
	ConflictReason string
}

KitMatch describes a single Kit that matched during the detection phase, per 005-kit-manifest-spec.md and 014-tui-operator-surfaces.md.

type LogViewer

type LogViewer struct {
	// contains filtered or unexported fields
}

LogViewer is a Bubble Tea widget that renders a stream of log lines inside a scrollable viewport. Lines are retained in a ring buffer (bounded by WithMaxLines) and rendered with ANSI SGR styling via the parser in widget/ansi.go.

LogViewer implements the follow / scroll-lock state machine: while Following() is true, each LogViewer.Append auto-scrolls the viewport to the tail; otherwise the viewport offset is preserved so the user can read history without being yanked forward by new output. The bindings in KeyMap drive the transitions (LineUp / PageUp / Home pause follow; End re-engages; ToggleFollow toggles); a mouse-wheel-up event also pauses follow.

Key dispatch is gated on focus: a blurred LogViewer drops tea.KeyPressMsg messages but still processes AppendMsg, mouse events, and tea.WindowSizeMsg so background producers keep delivering data regardless of which widget currently owns the focus ring.

The footer row below the viewport shows a short indicator rendered via theme.LogFollow / theme.LogPaused. The viewport itself is sized to height-1 so the footer always has a row.

LogViewer is not safe for concurrent use. Drive it from a single goroutine (typically the tea.Program loop) using Append or AppendMsg.

func NewLogViewer

func NewLogViewer(opts ...LogViewerOption) *LogViewer

New constructs a LogViewer with the given options applied on top of the defaults (maxLines=10_000, wrap=true, follow=true, KeyMap=DefaultKeyMap).

func (*LogViewer) Append

func (m *LogViewer) Append(lines ...string)

Append adds one or more lines to the buffer. Overflow drops from the head. If Following() is true, the viewport is scrolled to the bottom after the append and re-render.

func (*LogViewer) Blur

func (m *LogViewer) Blur()

Blur clears the focus flag. Subsequent tea.KeyPressMsg messages are dropped until Focus is called again. Non-key messages (appends, resizes, mouse wheel) are still processed.

func (*LogViewer) Clear

func (m *LogViewer) Clear()

Clear drops all retained lines and resets the SGR parser state.

func (*LogViewer) Focus

func (m *LogViewer) Focus()

Focus marks the widget as owning the focus ring. Subsequent tea.KeyPressMsg messages will be dispatched through the configured KeyMap; non-key messages are unaffected by focus.

func (*LogViewer) Focused

func (m *LogViewer) Focused() bool

Focused reports whether the widget currently owns the focus ring.

func (*LogViewer) Following

func (m *LogViewer) Following() bool

Following reports whether the viewport is currently tailing the log.

func (*LogViewer) Init

func (m *LogViewer) Init() tea.Cmd

Init satisfies tea.Model. LogViewer produces no initial commands.

func (*LogViewer) KeyMap

func (m *LogViewer) KeyMap() KeyMap

KeyMap returns a copy of the widget's active key bindings. Useful for help-bar integrations that want to enumerate what's currently bound.

func (*LogViewer) SetFollowing

func (m *LogViewer) SetFollowing(enabled bool)

SetFollowing toggles follow mode. Turning follow on re-scrolls the viewport to the bottom immediately so the caller doesn't need to issue a separate Append to catch up.

func (*LogViewer) SetSize

func (m *LogViewer) SetSize(width, height int)

SetSize propagates new dimensions to the embedded viewport and re-renders (wrap width changed). The viewport receives height-footerRows rows so the footer fits on the last row.

Follow state is preserved across a resize: if follow is on the viewport is pinned to the bottom; if follow is off, the viewport keeps its prior Y-offset (clamped against the new content height, which the viewport handles internally). This is important so a paused reader is not yanked back to the tail on a terminal resize.

func (*LogViewer) SetWrap

func (m *LogViewer) SetWrap(enabled bool)

SetWrap toggles soft-wrap rendering and re-renders so the new wrapping takes effect on the current buffer.

func (*LogViewer) Update

func (m *LogViewer) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update handles AppendMsg, WindowSizeMsg, focus-gated KeyPressMsg via the configured KeyMap, and MouseWheelMsg. All other messages are dropped.

Key dispatch is gated on focus: when the widget is blurred, a tea.KeyPressMsg is dropped without effect. Non-key messages (AppendMsg, WindowSizeMsg, MouseWheelMsg) are always processed so background producers and the program loop keep working regardless of which widget currently owns the focus ring.

func (*LogViewer) View

func (m *LogViewer) View() tea.View

View renders the viewport plus the footer indicator as a tea.View. The viewport occupies height-footerRows rows; the footer takes the last row.

func (*LogViewer) Wrap

func (m *LogViewer) Wrap() bool

Wrap reports whether soft-wrap rendering is currently enabled.

type LogViewerOption

type LogViewerOption func(*LogViewer)

LogViewerOption configures a LogViewer at construction time.

func WithFollow

func WithFollow(enabled bool) LogViewerOption

WithFollow sets the initial follow state. When follow is on (default), each append auto-scrolls the viewport to the bottom.

func WithLogViewerKeyMap

func WithLogViewerKeyMap(km KeyMap) LogViewerOption

WithLogViewerKeyMap overrides the default key bindings. Any unset fields on the supplied map disable the corresponding action (an empty key.Binding matches nothing).

func WithMaxLines

func WithMaxLines(n int) LogViewerOption

WithMaxLines caps the number of retained lines. Once the buffer is full, the oldest line is discarded on each append. Passing 0 disables the cap (unbounded retention). Negative values are ignored with a warning logged to stderr and the default (10_000) is retained.

func WithWrap

func WithWrap(enabled bool) LogViewerOption

WithWrap toggles soft-wrap rendering. When true (default), lines longer than the viewport width are wrapped to subsequent rows. When false, lines overflow horizontally and the viewport exposes horizontal scrolling.

type MachinePivot

type MachinePivot struct {
	// contains filtered or unexported fields
}

MachinePivot renders a multi-machine breakdown suitable for the SaaS operator surface. Each machine is shown as a summary row with worker counts, region, and aggregate health dot.

Example rendering:

ID               Region  Workers  Active  Health
machine-01       iad1    4        3       ● ready
machine-02       sfo3    2        0       ◌ idle

func NewMachinePivot

func NewMachinePivot(opts ...MachinePivotOption) *MachinePivot

NewMachinePivot constructs a MachinePivot with default theme.

func (*MachinePivot) Blur

func (p *MachinePivot) Blur()

Blur is a no-op.

func (*MachinePivot) Focus

func (p *MachinePivot) Focus()

Focus is a no-op.

func (*MachinePivot) Init

func (p *MachinePivot) Init() tea.Cmd

Init satisfies tea.Model.

func (*MachinePivot) SetMachines

func (p *MachinePivot) SetMachines(machines []MachineSummary)

SetMachines replaces the current machine list.

func (*MachinePivot) SetSize

func (p *MachinePivot) SetSize(width, height int)

SetSize stores the width hint.

func (*MachinePivot) SetTheme

func (p *MachinePivot) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*MachinePivot) Update

func (p *MachinePivot) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*MachinePivot) View

func (p *MachinePivot) View() tea.View

View renders the pivot as a tea.View.

func (*MachinePivot) ViewString

func (p *MachinePivot) ViewString() string

ViewString renders the pivot table as a plain string.

type MachinePivotOption

type MachinePivotOption func(*MachinePivot)

MachinePivotOption configures a MachinePivot during construction.

func WithMachinePivotNoColor

func WithMachinePivotNoColor(nc bool) MachinePivotOption

WithMachinePivotNoColor forces symbol-first, no-ANSI rendering.

func WithMachinePivotTheme

func WithMachinePivotTheme(t theme.Theme) MachinePivotOption

WithMachinePivotTheme sets the Theme.

func WithMachines

func WithMachines(machines ...MachineSummary) MachinePivotOption

WithMachines sets the machines to display.

type MachineSummary

type MachineSummary struct {
	// ID is the machine or daemon identifier.
	ID string
	// Workers is the total number of workers registered on this machine.
	Workers int
	// ActiveWorkers is the number currently executing a session.
	ActiveWorkers int
	// Region is the geographic region or datacenter label.
	Region string
	// Health is the aggregate health of this machine's workers.
	Health ProviderHealth
}

MachineSummary represents an aggregated snapshot of a single machine (daemon) in a multi-machine SaaS fleet, per 013-orchestrator-and-governor.md and 014-tui-operator-surfaces.md.

type Option

type Option func(*Dialog)

Option configures a Dialog in the functional-options style.

func WithBody

func WithBody(body string) Option

WithBody sets the body text displayed inside the Dialog.

func WithButtons

func WithButtons(buttons ...Button) Option

WithButtons replaces the default Yes/No/Cancel button set with a custom sequence of buttons. The first button is focused initially.

func WithCancelLabel

func WithCancelLabel(label string) Option

WithCancelLabel overrides the label of the default Cancel button.

func WithDialogTheme

func WithDialogTheme(t theme.Theme) Option

WithDialogTheme sets the theme.Theme used by the dialog for colors and styles. The default is theme.DefaultTheme.

func WithNoLabel

func WithNoLabel(label string) Option

WithNoLabel overrides the label of the default No button.

func WithTitle

func WithTitle(title string) Option

WithTitle sets the title shown at the top of the Dialog box.

func WithYesLabel

func WithYesLabel(label string) Option

WithYesLabel overrides the label of the default Yes button.

type PolicyDecision

type PolicyDecision string

PolicyDecision represents the outcome of a policy evaluation. Per Layer 6 / 014-tui-operator-surfaces.md.

const (
	// PolicyAllowed indicates the action is permitted by policy.
	PolicyAllowed PolicyDecision = "allowed"
	// PolicyBlocked indicates the action is denied by policy.
	PolicyBlocked PolicyDecision = "blocked"
	// PolicyNeedsApproval indicates the action requires explicit approval.
	PolicyNeedsApproval PolicyDecision = "needs-approval"
)

type PolicyDecisionBanner

type PolicyDecisionBanner struct {
	// contains filtered or unexported fields
}

PolicyDecisionBanner renders a prominent banner conveying the outcome of a policy evaluation — allowed, blocked, or needs-approval — with an optional override actor and reason.

Example renderings:

✓ ALLOWED    deploy to production
✗ BLOCKED    agent cannot write to /etc/  [policy: path-allowlist]
⚑ APPROVAL   deployment requires QA sign-off  [requested from: qa-team]
Example (NoColor)

ExamplePolicyDecisionBanner_noColor demonstrates policy decision banners.

b := NewPolicyDecisionBanner(
	WithPolicyDecision(PolicyBlocked),
	WithPolicyDescription("agent cannot write to /etc/"),
	WithPolicyReason("path-allowlist"),
	WithPolicyBannerNoColor(true),
)
fmt.Println(b.ViewString())
Output:
✗ BLOCKED    agent cannot write to /etc/  [path-allowlist]

func NewPolicyDecisionBanner

func NewPolicyDecisionBanner(opts ...PolicyDecisionBannerOption) *PolicyDecisionBanner

NewPolicyDecisionBanner constructs a PolicyDecisionBanner with default theme.

func (*PolicyDecisionBanner) AccessibleLabel

func (b *PolicyDecisionBanner) AccessibleLabel() string

AccessibleLabel returns the accessible label.

func (*PolicyDecisionBanner) Blur

func (b *PolicyDecisionBanner) Blur()

Blur is a no-op.

func (*PolicyDecisionBanner) Focus

func (b *PolicyDecisionBanner) Focus()

Focus is a no-op.

func (*PolicyDecisionBanner) Init

func (b *PolicyDecisionBanner) Init() tea.Cmd

Init satisfies tea.Model.

func (*PolicyDecisionBanner) SetSize

func (b *PolicyDecisionBanner) SetSize(width, height int)

SetSize stores width hint.

func (*PolicyDecisionBanner) SetTheme

func (b *PolicyDecisionBanner) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*PolicyDecisionBanner) Update

func (b *PolicyDecisionBanner) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*PolicyDecisionBanner) View

func (b *PolicyDecisionBanner) View() tea.View

View renders the banner as a tea.View.

func (*PolicyDecisionBanner) ViewString

func (b *PolicyDecisionBanner) ViewString() string

ViewString renders the banner as a plain string.

type PolicyDecisionBannerOption

type PolicyDecisionBannerOption func(*PolicyDecisionBanner)

PolicyDecisionBannerOption configures a PolicyDecisionBanner.

func WithPolicyActor

func WithPolicyActor(actor string) PolicyDecisionBannerOption

WithPolicyActor sets the actor label (override actor, approver, etc.).

func WithPolicyBannerAccessibleLabel

func WithPolicyBannerAccessibleLabel(label string) PolicyDecisionBannerOption

WithPolicyBannerAccessibleLabel sets the accessible label.

func WithPolicyBannerNoColor

func WithPolicyBannerNoColor(nc bool) PolicyDecisionBannerOption

WithPolicyBannerNoColor forces symbol-first, no-ANSI rendering.

func WithPolicyBannerTheme

func WithPolicyBannerTheme(t theme.Theme) PolicyDecisionBannerOption

WithPolicyBannerTheme sets the Theme.

func WithPolicyDecision

func WithPolicyDecision(d PolicyDecision) PolicyDecisionBannerOption

WithPolicyDecision sets the decision outcome.

func WithPolicyDescription

func WithPolicyDescription(desc string) PolicyDecisionBannerOption

WithPolicyDescription sets the human-readable action description.

func WithPolicyReason

func WithPolicyReason(reason string) PolicyDecisionBannerOption

WithPolicyReason sets the policy rule or override reason.

type Progressbar

type Progressbar struct {
	// contains filtered or unexported fields
}

Progressbar is a themed progress bar widget wrapping charm.land/bubbles/v2/progress.

The widget renders the most recent percent set via SetPercent immediately; the smooth spring animation built into the inner Bubbles model is bypassed in favor of deterministic, snapshot-friendly output. Callers that need animated transitions should use the inner Bubbles progress model directly.

Progressbar implements component.Component: it satisfies tea.Model and exposes SetSize, Focus, and Blur. Focus and Blur are intentionally inert because progress bars are non-interactive; they exist solely to satisfy the Component interface.

The zero value is not usable; construct with NewProgressbar.

func NewProgressbar

func NewProgressbar(opts ...ProgressbarOption) *Progressbar

NewProgressbar constructs a Progressbar. By default the bar is 40 cells wide, fills with a theme.Default().Teal -> theme.Default().Accent gradient, starts at 0% progress, and renders no label, percentage, or ETA. Apply ProgressbarOptions to customize width, gradient, label, percentage, and ETA display.

func (*Progressbar) Blur

func (p *Progressbar) Blur()

Blur marks the bar as blurred. It is intentionally inert: the bar is non-interactive and ignores focus state for rendering. The method exists to satisfy component.Component.

func (*Progressbar) Focus

func (p *Progressbar) Focus()

Focus marks the bar as focused. It is intentionally inert: the bar is non-interactive and ignores focus state for rendering. The method exists to satisfy component.Component.

func (*Progressbar) IncrBy

func (p *Progressbar) IncrBy(d float64) tea.Cmd

IncrBy advances the displayed progress by d, clamped to [0, 1]. The returned tea.Cmd is reserved for future animated transitions and is currently always nil; callers may safely discard it.

func (*Progressbar) Init

func (p *Progressbar) Init() tea.Cmd

Init implements tea.Model. In deterministic mode it returns nil. In indeterminate mode it returns the first tick command so the animation begins as soon as the Bubble Tea program starts.

func (*Progressbar) Percent

func (p *Progressbar) Percent() float64

Percent returns the current progress in the range [0, 1].

func (*Progressbar) SetIndeterminate

func (p *Progressbar) SetIndeterminate(b bool) tea.Cmd

SetIndeterminate switches the bar between deterministic and indeterminate rendering. When entering indeterminate mode, the returned tea.Cmd starts the sweep tick loop; pass it back through your Bubble Tea program. When leaving indeterminate mode, the returned cmd is nil. Switching modes increments an internal generation counter so any in-flight tickMsgs scheduled before the switch are discarded by Update — this prevents double-ticking when a paused bar resumes. A no-op call (mode unchanged) returns nil and does not increment the generation.

func (*Progressbar) SetPercent

func (p *Progressbar) SetPercent(v float64) tea.Cmd

SetPercent sets the displayed progress to v, clamped to [0, 1]. NaN inputs are treated as 0. The first call that produces a non-zero target records the ETA start time, used by WithProgressbarShowETA to estimate remaining time. The returned tea.Cmd is reserved for future animated transitions and is currently always nil; callers may safely discard it.

func (*Progressbar) SetSize

func (p *Progressbar) SetSize(width, height int)

SetSize sets the rendered width and records the height. Negative width is clamped to zero. The height is stored but not used because the bar is always one line tall.

func (*Progressbar) SetTheme

func (p *Progressbar) SetTheme(t theme.Theme)

SetTheme updates the theme used for rendering. The change takes effect on the next call to View.

func (*Progressbar) Update

func (p *Progressbar) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update implements tea.Model. Indeterminate-mode tickMsgs whose generation matches the current SetIndeterminate generation advance the sweep and schedule the next tick; stale tickMsgs are silently dropped. All other messages are forwarded to the inner Bubbles progress model.

func (*Progressbar) View

func (p *Progressbar) View() tea.View

View renders the bar at the current percent. When width is non-positive the view is empty.

type ProgressbarOption

type ProgressbarOption func(*Progressbar)

ProgressbarOption configures a Progressbar at construction time.

func WithProgressbarClock

func WithProgressbarClock(now func() time.Time) ProgressbarOption

WithProgressbarClock injects a clock function used by the ETA estimator. Pass time.Now (the default) for production; tests use this to make ETA output deterministic. Passing nil restores the default.

func WithProgressbarGradient

func WithProgressbarGradient(from, to color.Color) ProgressbarOption

WithProgressbarGradient overrides the default gradient. The default is theme.Default().Teal to theme.Default().Accent; pass any two lipgloss-compatible colors to customize. The gradient is applied across the full bar width.

func WithProgressbarIndeterminate

func WithProgressbarIndeterminate(b bool) ProgressbarOption

WithProgressbarIndeterminate constructs the bar in indeterminate mode, where rendering is an animated sweep instead of a percent-driven fill. Use this when the total work is unknown (waiting on a stream or indeterminate network operation). When the total becomes known, SetIndeterminate(false) switches the bar back to deterministic mode.

Indeterminate is preferred over a spinner when the operation occupies a progress slot in a layout (so the visual cell does not jump in width) and when emphasizing "work is happening, duration unknown" rather than "thinking, soon to return".

func WithProgressbarLabel

func WithProgressbarLabel(s string) ProgressbarOption

WithProgressbarLabel sets a leading label rendered to the left of the bar (e.g. "Uploading"). Empty labels are not rendered. Long labels are truncated with an ellipsis when the combined render would exceed the widget width; the bar, percent, and ETA segments are preferred over label width.

func WithProgressbarShowETA

func WithProgressbarShowETA(b bool) ProgressbarOption

WithProgressbarShowETA enables the right-aligned estimated time remaining segment, e.g. "~12s". The estimate is derived from the wall-clock rate observed since the first non-zero SetPercent call, formatted via the format package. The segment is suppressed before progress begins, when the rate is undefined, and at 100%.

func WithProgressbarShowPercent

func WithProgressbarShowPercent(b bool) ProgressbarOption

WithProgressbarShowPercent enables the right-aligned numeric percentage segment formatted as "XX.X%" with stable 6-column width.

func WithProgressbarTheme

func WithProgressbarTheme(t theme.Theme) ProgressbarOption

WithProgressbarTheme sets the theme.Theme used by the bar for colors and styles. Calling this option mid-render updates the internal theme; the next View call uses the new theme. The default is theme.DefaultTheme.

func WithProgressbarWidth

func WithProgressbarWidth(w int) ProgressbarOption

WithProgressbarWidth sets the rendered width in cells. Negative values are clamped to zero, in which case the bar renders an empty string until SetSize or another option provides a positive width.

type ProviderHealth

type ProviderHealth string

ProviderHealth represents the operational health state of a provider (SandboxProvider, WorkareaProvider, AgentRuntimeProvider, etc.) as referenced in 002-provider-base-contract.md.

const (
	// ProviderHealthReady indicates the provider is operational.
	ProviderHealthReady ProviderHealth = "ready"
	// ProviderHealthDegraded indicates the provider is partially operational
	// or experiencing elevated latency/errors.
	ProviderHealthDegraded ProviderHealth = "degraded"
	// ProviderHealthUnhealthy indicates the provider is not operational.
	ProviderHealthUnhealthy ProviderHealth = "unhealthy"
)

type ProviderHealthDot

type ProviderHealthDot struct {
	// contains filtered or unexported fields
}

ProviderHealthDot renders a compact single-rune health indicator dot for a provider. The dot pairs a Unicode symbol with a color so that the status is unambiguous in both color and symbol-only (NO_COLOR) modes.

● ready        (green)
◐ degraded     (yellow)
✗ unhealthy    (red)
Example (NoColor)

ExampleProviderHealthDot_noColor demonstrates ProviderHealthDot rendering.

for _, h := range []ProviderHealth{ProviderHealthReady, ProviderHealthDegraded, ProviderHealthUnhealthy} {
	d := NewProviderHealthDot(
		WithProviderHealth(h),
		WithProviderHealthShowLabel(true),
		WithProviderHealthNoColor(true),
	)
	fmt.Println(d.ViewString())
}
Output:
● ready
◐ degraded
✗ unhealthy

func NewProviderHealthDot

func NewProviderHealthDot(opts ...ProviderHealthDotOption) *ProviderHealthDot

NewProviderHealthDot constructs a ProviderHealthDot with default theme.

func (*ProviderHealthDot) AccessibleLabel

func (d *ProviderHealthDot) AccessibleLabel() string

AccessibleLabel returns the accessible label or a fallback.

func (*ProviderHealthDot) Blur

func (d *ProviderHealthDot) Blur()

Blur is a no-op.

func (*ProviderHealthDot) Focus

func (d *ProviderHealthDot) Focus()

Focus is a no-op.

func (*ProviderHealthDot) Init

func (d *ProviderHealthDot) Init() tea.Cmd

Init satisfies tea.Model.

func (*ProviderHealthDot) SetSize

func (d *ProviderHealthDot) SetSize(width, height int)

SetSize is a no-op.

func (*ProviderHealthDot) SetTheme

func (d *ProviderHealthDot) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*ProviderHealthDot) Update

func (d *ProviderHealthDot) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*ProviderHealthDot) View

func (d *ProviderHealthDot) View() tea.View

View renders the dot as a tea.View.

func (*ProviderHealthDot) ViewString

func (d *ProviderHealthDot) ViewString() string

ViewString renders the dot as a plain string.

type ProviderHealthDotOption

type ProviderHealthDotOption func(*ProviderHealthDot)

ProviderHealthDotOption configures a ProviderHealthDot during construction.

func WithProviderHealth

func WithProviderHealth(h ProviderHealth) ProviderHealthDotOption

WithProviderHealth sets the health state.

func WithProviderHealthAccessibleLabel

func WithProviderHealthAccessibleLabel(label string) ProviderHealthDotOption

WithProviderHealthAccessibleLabel sets the accessible label.

func WithProviderHealthNoColor

func WithProviderHealthNoColor(nc bool) ProviderHealthDotOption

WithProviderHealthNoColor forces symbol-only, no-ANSI rendering.

func WithProviderHealthShowLabel

func WithProviderHealthShowLabel(show bool) ProviderHealthDotOption

WithProviderHealthShowLabel includes the state label after the dot symbol.

func WithProviderHealthTheme

func WithProviderHealthTheme(t theme.Theme) ProviderHealthDotOption

WithProviderHealthTheme sets the Theme.

type Result

type Result int

Result represents the outcome of a dialog interaction.

const (
	// ResultNone indicates that the dialog has not produced a result yet.
	ResultNone Result = iota
	// ResultYes indicates that the user selected the affirmative button.
	ResultYes
	// ResultNo indicates that the user selected the negative button.
	ResultNo
	// ResultCancel indicates that the user cancelled the dialog.
	ResultCancel
)

func (Result) String

func (r Result) String() string

String returns a human-readable name for the Result.

type SandboxCapacityGauge

type SandboxCapacityGauge struct {
	// contains filtered or unexported fields
}

SandboxCapacityGauge renders a SandboxProvider's concurrent / max capacity as a utilization bar. When maxConcurrent is 0 (nil in the architecture), the gauge degenerates to "X / ∞" with no bar. Per 004-sandbox-capability-matrix.md and 014-tui-operator-surfaces.md.

Example renderings:

████████░░  5 / 8  (62%)
0 / ∞
Example (Unlimited)

ExampleSandboxCapacityGauge_unlimited demonstrates the unlimited capacity gauge.

g := NewSandboxCapacityGauge(
	WithGaugeCurrent(3),
	WithGaugeMax(0), // unlimited
	WithGaugeNoColor(true),
)
fmt.Println(g.ViewString())
Output:
3 / ∞

func NewSandboxCapacityGauge

func NewSandboxCapacityGauge(opts ...SandboxCapacityGaugeOption) *SandboxCapacityGauge

NewSandboxCapacityGauge constructs a SandboxCapacityGauge with default theme.

func (*SandboxCapacityGauge) AccessibleLabel

func (g *SandboxCapacityGauge) AccessibleLabel() string

AccessibleLabel returns the accessible label.

func (*SandboxCapacityGauge) Blur

func (g *SandboxCapacityGauge) Blur()

Blur is a no-op.

func (*SandboxCapacityGauge) Focus

func (g *SandboxCapacityGauge) Focus()

Focus is a no-op.

func (*SandboxCapacityGauge) Init

func (g *SandboxCapacityGauge) Init() tea.Cmd

Init satisfies tea.Model.

func (*SandboxCapacityGauge) SetSize

func (g *SandboxCapacityGauge) SetSize(width, height int)

SetSize is a no-op.

func (*SandboxCapacityGauge) SetTheme

func (g *SandboxCapacityGauge) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*SandboxCapacityGauge) Update

func (g *SandboxCapacityGauge) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*SandboxCapacityGauge) View

func (g *SandboxCapacityGauge) View() tea.View

View renders the gauge as a tea.View.

func (*SandboxCapacityGauge) ViewString

func (g *SandboxCapacityGauge) ViewString() string

ViewString renders the gauge as a plain string.

type SandboxCapacityGaugeOption

type SandboxCapacityGaugeOption func(*SandboxCapacityGauge)

SandboxCapacityGaugeOption configures a SandboxCapacityGauge.

func WithGaugeAccessibleLabel

func WithGaugeAccessibleLabel(label string) SandboxCapacityGaugeOption

WithGaugeAccessibleLabel sets the accessible label.

func WithGaugeBarWidth

func WithGaugeBarWidth(w int) SandboxCapacityGaugeOption

WithGaugeBarWidth sets the pixel/cell width of the utilization bar. Default is 10.

func WithGaugeCurrent

func WithGaugeCurrent(n int) SandboxCapacityGaugeOption

WithGaugeCurrent sets the current concurrent session count.

func WithGaugeMax

func WithGaugeMax(n int) SandboxCapacityGaugeOption

WithGaugeMax sets the maximum concurrent session count. Pass 0 to indicate unlimited (maxConcurrent: null).

func WithGaugeNoColor

func WithGaugeNoColor(nc bool) SandboxCapacityGaugeOption

WithGaugeNoColor forces symbol-first, no-ANSI rendering.

func WithGaugeTheme

func WithGaugeTheme(t theme.Theme) SandboxCapacityGaugeOption

WithGaugeTheme sets the Theme.

type Scope

type Scope string

Scope represents the resolution scope of a provider or plugin as defined in 002-provider-base-contract.md (project → org → tenant → global).

const (
	// ScopeProject is the narrowest scope — applies to a single project.
	ScopeProject Scope = "project"
	// ScopeOrg applies across all projects within an organization.
	ScopeOrg Scope = "org"
	// ScopeTenant applies across all orgs within a tenant.
	ScopeTenant Scope = "tenant"
	// ScopeGlobal is the widest scope — platform-wide.
	ScopeGlobal Scope = "global"
)

type ScopePill

type ScopePill struct {
	// contains filtered or unexported fields
}

ScopePill renders a provider or plugin resolution scope as a small colored pill badge. The pill uses distinct colors for each scope level:

  • project → blue (narrowest)
  • org → teal
  • tenant → accent/orange
  • global → yellow (widest)

In no-color mode the pill renders as plain bracketed text: [project].

Example (NoColor)

ExampleScopePill_noColor demonstrates ScopePill in no-color mode for all scopes.

for _, scope := range []Scope{ScopeProject, ScopeOrg, ScopeTenant, ScopeGlobal} {
	p := NewScopePill(WithScopeValue(scope), WithScopeNoColor(true))
	fmt.Println(p.ViewString())
}
Output:
[project]
[org]
[tenant]
[global]

func NewScopePill

func NewScopePill(opts ...ScopePillOption) *ScopePill

NewScopePill constructs a ScopePill with the default theme.

func (*ScopePill) AccessibleLabel

func (p *ScopePill) AccessibleLabel() string

AccessibleLabel returns the accessible label. Falls back to the scope string if no explicit label was set.

func (*ScopePill) Blur

func (p *ScopePill) Blur()

Blur is a no-op.

func (*ScopePill) Focus

func (p *ScopePill) Focus()

Focus is a no-op.

func (*ScopePill) Init

func (p *ScopePill) Init() tea.Cmd

Init satisfies tea.Model.

func (*ScopePill) SetSize

func (p *ScopePill) SetSize(width, height int)

SetSize is a no-op.

func (*ScopePill) SetTheme

func (p *ScopePill) SetTheme(t theme.Theme)

SetTheme updates the theme used for rendering.

func (*ScopePill) Update

func (p *ScopePill) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*ScopePill) View

func (p *ScopePill) View() tea.View

View renders the pill as a tea.View.

func (*ScopePill) ViewString

func (p *ScopePill) ViewString() string

ViewString renders the pill as a plain string.

type ScopePillOption

type ScopePillOption func(*ScopePill)

ScopePillOption configures a ScopePill during construction.

func WithScopeAccessibleLabel

func WithScopeAccessibleLabel(label string) ScopePillOption

WithScopeAccessibleLabel sets the accessible label for screen-reader consumers.

func WithScopeNoColor

func WithScopeNoColor(nc bool) ScopePillOption

WithScopeNoColor forces symbol-first, no-ANSI rendering.

func WithScopeTheme

func WithScopeTheme(t theme.Theme) ScopePillOption

WithScopeTheme sets the Theme used for rendering.

func WithScopeValue

func WithScopeValue(s Scope) ScopePillOption

WithScopeValue sets the Scope value to display.

type Select

type Select struct {
	// contains filtered or unexported fields
}

Select is a list widget backed by bubbles/v2 list.Model that supports both single-select and multi-select modes. It implements the component.Component interface.

func NewSelect

func NewSelect(items []SelectItem, opts ...SelectOption) *Select

NewSelect creates a new Select widget from the given items and options. By default, filtering is enabled and the default key map is used.

func (*Select) Blur

func (s *Select) Blur()

Blur implements component.Component.

func (*Select) Focus

func (s *Select) Focus()

Focus implements component.Component.

func (*Select) Highlighted

func (s *Select) Highlighted() SelectItem

Highlighted returns the item under the cursor, or nil if the list is empty.

func (*Select) Init

func (s *Select) Init() tea.Cmd

Init implements tea.Model.

func (*Select) IsSelected

func (s *Select) IsSelected(id string) bool

IsSelected reports whether the item with the given ID is in the selection set.

func (*Select) Selected

func (s *Select) Selected() []SelectItem

Selected returns the currently selected items. In multi-select mode it returns all toggled items in insertion order. In single-select mode it returns the highlighted item as a single-element slice. Returns nil if nothing is selected.

func (*Select) SetDelegate

func (s *Select) SetDelegate(d list.ItemDelegate)

SetDelegate replaces the item delegate on the underlying list.

func (*Select) SetMultiSelect

func (s *Select) SetMultiSelect(v bool)

SetMultiSelect enables or disables multi-select mode. When switching to single-select mode the selection set is cleared. When enabling multi-select the internal map is initialized if needed.

func (*Select) SetSize

func (s *Select) SetSize(width, height int)

SetSize implements component.Component.

func (*Select) ShowMultiSelectIndicators

func (s *Select) ShowMultiSelectIndicators(v bool)

ShowMultiSelectIndicators controls whether the default themed delegate renders checkbox-style prefix indicators for multi-select mode. The default is true. When a custom delegate is provided via WithDelegate, this flag has no effect — custom delegates are responsible for their own rendering.

func (*Select) Update

func (s *Select) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update implements tea.Model.

func (*Select) View

func (s *Select) View() tea.View

View implements tea.Model.

type SelectItem

type SelectItem interface {
	list.Item
	// ID returns a stable, unique identifier for the item.
	ID() string
}

SelectItem extends list.Item with a stable identity. Delegates receive a SelectItem and may type-assert to a richer concrete type for custom rendering. See theme/worktype.go, theme/status.go, and theme/activity.go for the canonical icon and color palettes that consumer-side delegates should use.

type SelectKeyMap

type SelectKeyMap = list.KeyMap

SelectKeyMap defines key bindings for the Select widget.

type SelectOption

type SelectOption func(*Select)

SelectOption is a functional option for configuring a Select widget.

func WithDelegate

func WithDelegate(d list.ItemDelegate) SelectOption

WithDelegate sets a custom list.ItemDelegate that overrides the default themed delegate. The delegate's Render method receives items that satisfy SelectItem; callers may type-assert to a richer concrete type for custom rendering. When using a custom delegate, multi-select prefix indicators are the delegate's responsibility — see Select.ShowMultiSelectIndicators.

func WithFilter

func WithFilter(enabled bool) SelectOption

WithFilter enables or disables fuzzy filtering on the select list.

func WithKeyMap

func WithKeyMap(km SelectKeyMap) SelectOption

WithKeyMap sets custom key bindings on the select list.

func WithMultiSelect

func WithMultiSelect(enabled bool) SelectOption

WithMultiSelect enables multi-select mode, allowing the user to toggle multiple items in the list via the space key.

type SelectToggleKeyMap

type SelectToggleKeyMap struct {
	// Toggle toggles the highlighted item's selection state.
	Toggle key.Binding
}

SelectToggleKeyMap holds the key binding used to toggle item selection in multi-select mode.

func DefaultSelectToggleKeyMap

func DefaultSelectToggleKeyMap() SelectToggleKeyMap

DefaultSelectToggleKeyMap returns the default toggle key binding (space).

type Spinner

type Spinner struct {
	// contains filtered or unexported fields
}

Spinner is a themed animated spinner widget wrapping charm.land/bubbles/v2/spinner. It implements component.Component and renders the current frame using the accent color from the active theme. When a label is set, the output is "<frame> <label>".

func NewSpinner

func NewSpinner(opts ...SpinnerOption) *Spinner

NewSpinner constructs a Spinner. By default the spinner uses spinner.Line, has no label, is focused (animating), and its frame is styled with the accent color from the active theme.

Pass WithSpinnerTheme to override the theme, or WithTheme (the universal widget option) — both are accepted.

func (*Spinner) Blur

func (s *Spinner) Blur()

Blur pauses the spinner animation. While blurred, the current frame is still rendered but spinner.TickMsg messages are ignored so the animation does not advance.

func (*Spinner) Focus

func (s *Spinner) Focus()

Focus resumes the spinner animation. While focused, spinner.TickMsg messages advance the frame. A Spinner is focused by default after construction.

func (*Spinner) Init

func (s *Spinner) Init() tea.Cmd

Init returns the initial command that starts the spinner animation. It forwards to the inner spinner's tick command so that the spinner begins advancing frames as soon as the Bubble Tea program starts.

func (*Spinner) SetLabel

func (s *Spinner) SetLabel(label string)

SetLabel updates the label rendered next to the spinner frame.

func (*Spinner) SetSize

func (s *Spinner) SetSize(width, height int)

SetSize is a no-op. The Spinner renders a single short line whose width is determined by the current frame and optional label, so external size hints are ignored.

func (*Spinner) SetStyle

func (s *Spinner) SetStyle(style spinner.Spinner)

SetStyle updates the Bubbles spinner animation style.

func (*Spinner) SetTheme

func (s *Spinner) SetTheme(t theme.Theme)

SetTheme updates the theme used for rendering. The change takes effect on the next call to View.

func (*Spinner) Update

func (s *Spinner) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update forwards messages to the inner spinner model. When the Spinner is blurred, spinner.TickMsg messages are dropped so that the animation freezes on the current frame. All other messages pass through unchanged. Update always returns the receiver itself (as tea.Model) so that consumers can continue treating *Spinner as the component.

func (*Spinner) View

func (s *Spinner) View() tea.View

View renders the spinner. The current frame is styled with the accent color from the active theme. When a label is set, the output is "<styled-frame> <styled-label>" where the label uses the theme's TextPrimary; otherwise only the styled frame is rendered.

type SpinnerOption

type SpinnerOption func(*Spinner)

SpinnerOption configures a Spinner during construction.

func WithSpinnerLabel

func WithSpinnerLabel(label string) SpinnerOption

WithSpinnerLabel sets the label rendered next to the spinner frame. An empty label causes only the frame to be rendered.

func WithSpinnerStyle

func WithSpinnerStyle(s spinner.Spinner) SpinnerOption

WithSpinnerStyle sets the Bubbles spinner animation style (e.g. spinner.Line, spinner.Dot, spinner.MiniDot, spinner.Jump, spinner.Pulse, spinner.Points, spinner.Globe, spinner.Moon, spinner.Monkey, spinner.Meter, spinner.Hamburger, spinner.Ellipsis).

func WithSpinnerTheme

func WithSpinnerTheme(t theme.Theme) SpinnerOption

WithSpinnerTheme sets the Theme used by the spinner for colors and styles. Calling this option mid-render updates the internal theme; the next View call uses the new theme. The default is theme.DefaultTheme.

type Tabs

type Tabs struct {
	// contains filtered or unexported fields
}

Tabs is a horizontal tab-bar widget. It implements component.Component and emits TabsSelectedMsg when the active tab changes via Tabs.Update key handling.

Example

ExampleTabs demonstrates constructing a small widget.Tabs widget, fixing its size, and rendering the resulting tab bar. The example uses a narrow fixed width and ASCII-only titles so the expected output is stable across terminals.

tabs := widget.NewTabs(
	[]widget.TabsItem{
		{ID: "home", Title: "Home"},
		{ID: "work", Title: "Work"},
		{ID: "help", Title: "Help"},
	},
	widget.WithActive(1),
)
tabs.SetSize(24, 1)

rendered := tabs.View().Content
fmt.Println(lipgloss.Width(rendered))
Output:
24

func NewTabs

func NewTabs(items []TabsItem, opts ...TabsOption) *Tabs

NewTabs constructs a Tabs widget with the given items and options. The active index is clamped to the valid range and defaults to 0.

func (*Tabs) Active

func (t *Tabs) Active() int

Active returns the currently-active tab index. When the item list is empty the returned value is 0 and has no associated tab.

func (*Tabs) Blur

func (t *Tabs) Blur()

Blur disables key handling in Tabs.Update.

func (*Tabs) Focus

func (t *Tabs) Focus()

Focus enables key handling in Tabs.Update.

func (*Tabs) Init

func (t *Tabs) Init() tea.Cmd

Init satisfies tea.Model. The tab bar has no startup work.

func (*Tabs) SetActive

func (t *Tabs) SetActive(idx int)

SetActive sets the active tab index. Out-of-range values are clamped to the valid range. This method is for direct programmatic updates; it does not emit a TabsSelectedMsg. Messages are only emitted for navigation performed through Tabs.Update.

func (*Tabs) SetItems

func (t *Tabs) SetItems(items []TabsItem)

SetItems replaces the tab items. The active index is clamped to the new range so it remains valid.

func (*Tabs) SetSize

func (t *Tabs) SetSize(w, h int)

SetSize records the available width and height for the tab bar. Non-positive values are coerced to zero. A positive width causes Tabs.View to apply width-aware truncation; a zero width renders the bar at its natural size.

func (*Tabs) SetTheme

func (t *Tabs) SetTheme(th theme.Theme)

SetTheme updates the theme used for rendering. The change takes effect on the next call to View.

func (*Tabs) Update

func (t *Tabs) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update handles navigation key events. Input is ignored when the widget is not focused. When navigation changes the active index a TabsSelectedMsg command is returned.

In addition to sequential navigation via the configured TabsKeyMap, any [TabsItem.KeyHint] that matches the key event's string form activates that tab directly. Shortcut activation on a disabled tab or on the already-active tab is a no-op.

func (*Tabs) View

func (t *Tabs) View() tea.View

View renders the tab bar as a single horizontal line. When a positive width has been recorded via Tabs.SetSize the bar is fit to that width by truncating titles, removing separators from the outer edges, or, as a last resort, dropping tabs and appending a trailing ellipsis marker while keeping the active tab visible.

type TabsItem

type TabsItem struct {
	// ID is a stable identifier emitted with [TabsSelectedMsg] when the
	// tab becomes active. Callers use it to route view changes without
	// depending on the slice index.
	ID string

	// Title is the human-readable label rendered in the tab bar.
	Title string

	// KeyHint is an optional keystroke shown alongside the title and
	// used to activate the tab directly. It is matched against the
	// [tea.KeyPressMsg] string representation via exact equality.
	KeyHint string

	// Disabled marks a tab as non-interactive. Disabled tabs are
	// skipped during sequential navigation (left/right, tab/shift+tab)
	// and cannot be activated via [KeyHint] shortcuts.
	Disabled bool
}

TabsItem is a single entry in a Tabs widget.

type TabsKeyMap

type TabsKeyMap struct {
	// Left moves the active tab one position toward the start of the list.
	Left key.Binding

	// Right moves the active tab one position toward the end of the list.
	Right key.Binding

	// Next moves the active tab one position toward the end of the list
	// (conventionally bound to the tab key).
	Next key.Binding

	// Prev moves the active tab one position toward the start of the list
	// (conventionally bound to shift+tab).
	Prev key.Binding
}

TabsKeyMap is the set of key bindings that drive Tabs navigation.

func DefaultTabsKeyMap

func DefaultTabsKeyMap() TabsKeyMap

DefaultTabsKeyMap returns the default TabsKeyMap binding left/right for horizontal navigation and tab/shift+tab as alternate shortcuts.

type TabsOption

type TabsOption func(*Tabs)

TabsOption configures a Tabs widget via the functional-options pattern.

func WithActive

func WithActive(idx int) TabsOption

WithActive sets the initial active tab index. Out-of-range values are clamped to the valid range at construction time.

func WithTabsKeyMap

func WithTabsKeyMap(km TabsKeyMap) TabsOption

WithTabsKeyMap overrides the default TabsKeyMap used by the widget.

func WithTabsTheme

func WithTabsTheme(th theme.Theme) TabsOption

WithTabsTheme sets the theme.Theme used by the tab bar for colors and styles. The default is theme.DefaultTheme.

func WithWraparound

func WithWraparound(enabled bool) TabsOption

WithWraparound enables (or disables) wraparound navigation. When enabled, moving left from the first tab wraps to the last valid tab and moving right from the last tab wraps to the first. The default is false — sequential navigation clamps at the ends.

type TabsSelectedMsg

type TabsSelectedMsg struct {
	// Index is the new active tab index.
	Index int

	// ID is the [TabsItem.ID] of the newly-active tab.
	ID string
}

TabsSelectedMsg is emitted by Tabs when the active tab changes. It is never emitted for no-op navigation that leaves the active index unchanged (for example, pressing left while already at index 0).

type TextInput

type TextInput struct {
	// contains filtered or unexported fields
}

TextInput is a styled wrapper around bubbles/v2/textinput that implements component.Component and surfaces a validation error below the field.

The zero value is not usable; construct with NewTextInput.

func NewTextInput

func NewTextInput(opts ...TextInputOption) TextInput

NewTextInput constructs a TextInput. Apply options for placeholder, validation, etc.

func (*TextInput) Blur

func (t *TextInput) Blur()

Blur deactivates the input so it stops receiving keyboard events and hides its cursor.

func (TextInput) Err

func (t TextInput) Err() error

Err returns the last validation error, or nil if the input is valid or no ValidateFunc was configured.

func (*TextInput) Focus

func (t *TextInput) Focus()

Focus activates the input so it receives keyboard events and shows a cursor. The cursor-blink command from the embedded model is intentionally discarded to keep the Component interface void-returning; consumers that want blinking can drive it via Init on the returned model.

func (TextInput) Init

func (t TextInput) Init() tea.Cmd

Init implements tea.Model. It returns no initial command.

func (*TextInput) Reset

func (t *TextInput) Reset()

Reset clears the input value and any cached validation error.

func (*TextInput) SetSize

func (t *TextInput) SetSize(width, _ int)

SetSize sets the widget width in cells. The height argument is ignored because the input is always single-line.

func (*TextInput) SetValue

func (t *TextInput) SetValue(s string)

SetValue replaces the current input value and re-runs validation.

func (TextInput) Update

func (t TextInput) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update implements tea.Model. It forwards the message to the embedded textinput and, on key presses, runs the configured ValidateFunc against the resulting value, caching the error for later retrieval via Err.

func (TextInput) Value

func (t TextInput) Value() string

Value returns the current input value.

func (TextInput) View

func (t TextInput) View() tea.View

View implements tea.Model. It renders the bordered input field and, when the value is non-empty and the validation callback has reported an error, an inline error message on the line below.

type TextInputOption

type TextInputOption func(*TextInput)

TextInputOption configures a TextInput at construction time.

func WithCharLimit

func WithCharLimit(n int) TextInputOption

WithCharLimit caps the maximum number of characters accepted. A value of 0 or less disables the limit.

func WithPlaceholder

func WithPlaceholder(s string) TextInputOption

WithPlaceholder sets the placeholder text shown when the input is empty.

func WithValidate

func WithValidate(fn ValidateFunc) TextInputOption

WithValidate sets the validation callback invoked on every change. The most recent error is exposed via Err and rendered below the input.

func WithWidth

func WithWidth(n int) TextInputOption

WithWidth sets the display width in cells. Panics on negative values.

type ThemeOption

type ThemeOption struct {
	// contains filtered or unexported fields
}

ThemeOption is the universal theme-carrying option accepted by every widget constructor in this package. Construct one with WithTheme.

Widget constructors that accept a variadic typed-option slice cannot directly accept a heterogeneous option type in idiomatic Go. Instead, each widget exposes a thin helper — WithSpinnerTheme, WithProgressbarTheme, etc. — and the universal WithTheme helper constructs that per-widget option for you:

t := theme.DarkTheme()
sp  := widget.NewSpinner(widget.WithTheme(t).Spinner())
bar := widget.NewProgressbar(widget.WithTheme(t).Progressbar())

Alternatively, use the per-widget helpers directly:

sp  := widget.NewSpinner(widget.WithSpinnerTheme(t))
bar := widget.NewProgressbar(widget.WithProgressbarTheme(t))

Theme hot-swap: call SetTheme on any widget instance to update the theme mid-render; the next View call uses the new theme.

func WithTheme

func WithTheme(t theme.Theme) ThemeOption

WithTheme constructs a ThemeOption carrying t. Use the receiver methods (.Spinner(), .Progressbar(), .Dialog(), .Tabs(), .Select(), .TextInput()) to convert it to the appropriate widget-level option type.

func (ThemeOption) Dialog

func (o ThemeOption) Dialog() Option

Dialog returns an Option (Dialog option) that applies this theme to a Dialog.

func (ThemeOption) Progressbar

func (o ThemeOption) Progressbar() ProgressbarOption

Progressbar returns a ProgressbarOption that applies this theme to a Progressbar.

func (ThemeOption) Spinner

func (o ThemeOption) Spinner() SpinnerOption

Spinner returns a SpinnerOption that applies this theme to a Spinner.

func (ThemeOption) Tabs

func (o ThemeOption) Tabs() TabsOption

Tabs returns a TabsOption that applies this theme to a Tabs widget.

type ToolchainChip

type ToolchainChip struct {
	// contains filtered or unexported fields
}

ToolchainChip renders one or more ToolchainSpec values as a compact chip. It is the canonical display primitive for Kit toolchain demands and Workarea pool state per 014-tui-operator-surfaces.md.

Single spec: ⚙ java=17 Multi spec: ⚙ java=17, node=20.x

Example (NoColor)

ExampleToolchainChip_noColor demonstrates ToolchainChip for multi-toolchain demands.

chip := NewToolchainChip(
	WithToolchainSpecs(
		ToolchainSpec{"java", "17"},
		ToolchainSpec{"node", "20.x"},
	),
	WithToolchainNoColor(true),
)
fmt.Println(chip.ViewString())
Output:
⚙ java=17, node=20.x

func NewToolchainChip

func NewToolchainChip(opts ...ToolchainChipOption) *ToolchainChip

NewToolchainChip constructs a ToolchainChip with the default theme.

func (*ToolchainChip) AccessibleLabel

func (c *ToolchainChip) AccessibleLabel() string

AccessibleLabel returns the accessible label.

func (*ToolchainChip) Blur

func (c *ToolchainChip) Blur()

Blur is a no-op.

func (*ToolchainChip) Focus

func (c *ToolchainChip) Focus()

Focus is a no-op.

func (*ToolchainChip) Init

func (c *ToolchainChip) Init() tea.Cmd

Init satisfies tea.Model.

func (*ToolchainChip) SetSize

func (c *ToolchainChip) SetSize(width, height int)

SetSize is a no-op.

func (*ToolchainChip) SetTheme

func (c *ToolchainChip) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*ToolchainChip) Update

func (c *ToolchainChip) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*ToolchainChip) View

func (c *ToolchainChip) View() tea.View

View renders the chip as a tea.View.

func (*ToolchainChip) ViewString

func (c *ToolchainChip) ViewString() string

ViewString renders the chip as a plain string.

type ToolchainChipOption

type ToolchainChipOption func(*ToolchainChip)

ToolchainChipOption configures a ToolchainChip during construction.

func WithToolchainAccessibleLabel

func WithToolchainAccessibleLabel(label string) ToolchainChipOption

WithToolchainAccessibleLabel sets the accessible label.

func WithToolchainNoColor

func WithToolchainNoColor(nc bool) ToolchainChipOption

WithToolchainNoColor forces symbol-first, no-ANSI rendering.

func WithToolchainSpecs

func WithToolchainSpecs(specs ...ToolchainSpec) ToolchainChipOption

WithToolchainSpecs sets the toolchain specs to display.

func WithToolchainTheme

func WithToolchainTheme(t theme.Theme) ToolchainChipOption

WithToolchainTheme sets the Theme.

type ToolchainSpec

type ToolchainSpec struct {
	// Name is the toolchain name (e.g. "java", "node", "go", "python").
	Name string
	// Version is the required version or range (e.g. "17", "20.x", ">=3.11").
	Version string
}

ToolchainSpec represents a single toolchain demand in "name=version" form as declared by a Kit or consumed by a WorkareaProvider. Per 004-sandbox-capability-matrix.md and 005-kit-manifest-spec.md.

func (ToolchainSpec) String

func (s ToolchainSpec) String() string

String formats the spec as "name=version".

type ValidateFunc

type ValidateFunc func(string) error

ValidateFunc reports an error for an invalid input value, or nil if valid.

type WorkareaPoolEntry

type WorkareaPoolEntry struct {
	// Repo is the repository identifier (e.g. "github.com/org/repo").
	Repo string
	// Toolchain is the toolchain spec satisfied by this pool slot.
	Toolchain string
	// Warm is the number of pre-warmed, ready-to-use slots.
	Warm int
	// Cold is the number of un-warmed slots available.
	Cold int
	// InUse is the number of slots currently acquired by active sessions.
	InUse int
}

WorkareaPoolEntry represents a single pool slot entry keyed by repo and toolchain, per 003-workarea-provider.md and 014-tui-operator-surfaces.md.

type WorkareaPoolPanel

type WorkareaPoolPanel struct {
	// contains filtered or unexported fields
}

WorkareaPoolPanel renders the warm / cold / in-use workarea pool breakdown per (repo, toolchain) key. It is the primary display primitive for WorkareaProvider pool status as described in 014-tui-operator-surfaces.md.

Example rendering:

Repo                         Toolchain    Warm  Cold  In-Use
github.com/org/api           java=17      3     1     2
github.com/org/web           node=20.x    2     0     1

func NewWorkareaPoolPanel

func NewWorkareaPoolPanel(opts ...WorkareaPoolPanelOption) *WorkareaPoolPanel

NewWorkareaPoolPanel constructs a WorkareaPoolPanel with default theme.

func (*WorkareaPoolPanel) Blur

func (p *WorkareaPoolPanel) Blur()

Blur is a no-op.

func (*WorkareaPoolPanel) Focus

func (p *WorkareaPoolPanel) Focus()

Focus is a no-op.

func (*WorkareaPoolPanel) Init

func (p *WorkareaPoolPanel) Init() tea.Cmd

Init satisfies tea.Model.

func (*WorkareaPoolPanel) SetEntries

func (p *WorkareaPoolPanel) SetEntries(entries []WorkareaPoolEntry)

SetEntries replaces the current pool entries.

func (*WorkareaPoolPanel) SetSize

func (p *WorkareaPoolPanel) SetSize(width, height int)

SetSize stores the width hint.

func (*WorkareaPoolPanel) SetTheme

func (p *WorkareaPoolPanel) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*WorkareaPoolPanel) Update

func (p *WorkareaPoolPanel) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*WorkareaPoolPanel) View

func (p *WorkareaPoolPanel) View() tea.View

View renders the panel as a tea.View.

func (*WorkareaPoolPanel) ViewString

func (p *WorkareaPoolPanel) ViewString() string

ViewString renders the panel as a plain string.

type WorkareaPoolPanelOption

type WorkareaPoolPanelOption func(*WorkareaPoolPanel)

WorkareaPoolPanelOption configures a WorkareaPoolPanel during construction.

func WithPoolEntries

func WithPoolEntries(entries ...WorkareaPoolEntry) WorkareaPoolPanelOption

WithPoolEntries sets the pool entries to display.

func WithPoolNoColor

func WithPoolNoColor(nc bool) WorkareaPoolPanelOption

WithPoolNoColor forces symbol-first, no-ANSI rendering.

func WithPoolTheme

func WithPoolTheme(t theme.Theme) WorkareaPoolPanelOption

WithPoolTheme sets the Theme.

type WorkerRow

type WorkerRow struct {
	// contains filtered or unexported fields
}

WorkerRow renders a single worker's status, region, load fraction, and billing model in a compact single-line format suitable for use inside a FleetGrid. Per 013-orchestrator-and-governor.md and 014-tui-operator-surfaces.md.

Example rendering:

● busy   iad1   ████░░░░  75%   active-cpu

func NewWorkerRow

func NewWorkerRow(opts ...WorkerRowOption) *WorkerRow

NewWorkerRow constructs a WorkerRow with default theme.

func (*WorkerRow) AccessibleLabel

func (r *WorkerRow) AccessibleLabel() string

AccessibleLabel returns the accessible label.

func (*WorkerRow) Blur

func (r *WorkerRow) Blur()

Blur is a no-op.

func (*WorkerRow) Focus

func (r *WorkerRow) Focus()

Focus is a no-op.

func (*WorkerRow) Init

func (r *WorkerRow) Init() tea.Cmd

Init satisfies tea.Model.

func (*WorkerRow) SetSize

func (r *WorkerRow) SetSize(width, height int)

SetSize stores the width hint.

func (*WorkerRow) SetTheme

func (r *WorkerRow) SetTheme(t theme.Theme)

SetTheme updates the theme.

func (*WorkerRow) Update

func (r *WorkerRow) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update satisfies tea.Model.

func (*WorkerRow) View

func (r *WorkerRow) View() tea.View

View renders the row as a tea.View.

func (*WorkerRow) ViewString

func (r *WorkerRow) ViewString() string

ViewString renders the row as a plain string.

type WorkerRowOption

type WorkerRowOption func(*WorkerRow)

WorkerRowOption configures a WorkerRow during construction.

func WithWorkerAccessibleLabel

func WithWorkerAccessibleLabel(label string) WorkerRowOption

WithWorkerAccessibleLabel sets the accessible label.

func WithWorkerBillingModel

func WithWorkerBillingModel(bm string) WorkerRowOption

WithWorkerBillingModel sets the billing model label (e.g. "active-cpu").

func WithWorkerID

func WithWorkerID(id string) WorkerRowOption

WithWorkerID sets the worker ID displayed at the start of the row.

func WithWorkerLoadFraction

func WithWorkerLoadFraction(f float64) WorkerRowOption

WithWorkerLoadFraction sets the current load as a fraction [0.0, 1.0].

func WithWorkerNoColor

func WithWorkerNoColor(nc bool) WorkerRowOption

WithWorkerNoColor forces symbol-first, no-ANSI rendering.

func WithWorkerRegion

func WithWorkerRegion(region string) WorkerRowOption

WithWorkerRegion sets the region label (e.g. "iad1", "sfo3").

func WithWorkerStatus

func WithWorkerStatus(s WorkerStatus) WorkerRowOption

WithWorkerStatus sets the worker operational status.

func WithWorkerTheme

func WithWorkerTheme(t theme.Theme) WorkerRowOption

WithWorkerTheme sets the Theme.

type WorkerStatus

type WorkerStatus string

WorkerStatus represents the operational status of a worker process as described in 013-orchestrator-and-governor.md.

const (
	// WorkerStatusIdle indicates the worker is connected and waiting for work.
	WorkerStatusIdle WorkerStatus = "idle"
	// WorkerStatusBusy indicates the worker is executing a session.
	WorkerStatusBusy WorkerStatus = "busy"
	// WorkerStatusDraining indicates the worker is finishing its current
	// session and will not accept new work.
	WorkerStatusDraining WorkerStatus = "draining"
	// WorkerStatusOffline indicates the worker is not reachable.
	WorkerStatusOffline WorkerStatus = "offline"
)

Directories

Path Synopsis
Package notification provides a transient toast widget for the AgentFactory and Rensei TUI applications.
Package notification provides a transient toast widget for the AgentFactory and Rensei TUI applications.

Jump to

Keyboard shortcuts

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