Documentation
¶
Overview ¶
Package tui is a placeholder for a future Bubble Tea TUI.
Index ¶
- Constants
- Variables
- func ClampFloat(value, min, max float64) float64
- func CountLines(content string) int
- func EaseOutCubic(t float64) float64
- func NewAdvancedSettings(sourceType string, config sources.Config) *advancedSettingsModel
- func NewCaptureTabs() tea.Model
- func NewConfigEditor() tea.Model
- func NewDefaultProgress(width int) progress.Model
- func NewDefaultSpinner() spinner.Model
- func NewListPorts() tea.Model
- func NewMetadataEditor(repo MetadataPort, meta MetadataValues, path string, loadErr error) tea.Model
- func NewRouterForTest(cfg RouterConfig) *router
- func NewRunsViewer(cacheRoot string) tea.Model
- func NewSourceInfo(sourceType string, width, height int) *sourceInfoModel
- func NewUploadModel(client UploadPort, runIDs []string) tea.Model
- func NewWelcome(status *StatusMessage) tea.Model
- func RunTUI(cfg RouterConfig) error
- type App
- type CaptureConfig
- type CaptureSession
- type CaptureSessionPort
- type CaptureSessionResult
- type LineBuffer
- type LineWrapper
- type MetadataPort
- type MetadataValues
- type NavigateMsg
- type RouterConfig
- type ScreenContext
- type ScreenFactory
- type ScreenID
- type ScrollInfo
- type SpotlightEffect
- type StatusKind
- type StatusMessage
- type UploadPort
Constants ¶
const ( TabIndexSerial = 0 TabIndexTCP = 1 TabIndexSCPI = 2 TabCount = 3 )
Tab indices
const ( SerialFieldPort = 0 SerialFieldBaud = 1 SerialFieldCount = 2 )
Field indices for Serial tab
const ( TCPFieldHost = 0 TCPFieldPort = 1 TCPFieldCount = 2 )
Field indices for TCP tab
const ( SCPIFieldAddress = 0 SCPIFieldCount = 1 )
Field indices for SCPI/VISA tab
const ( ButtonIndexConfirm = 0 ButtonIndexReset = 1 )
Button indices
const ( FocusModeTabs = "tabs" FocusModeFields = "fields" FocusModeButtons = "buttons" FocusModeAdvanced = "advanced" FocusModeInfo = "info" )
Focus modes
const ( SourceTypeSerial = "serial" SourceTypeTCP = "tcp" SourceTypeSCPI = "scpi" )
Source type identifiers
const ( HelpSeparator = "•" HelpEnterEditMode = " (Enter to edit)" HelpArrowsChange = " ←/→" WarnNoPortsFound = "No ports found" PlaceholderNotSet = "(not set)" )
UI text constants TODO: Centralize all Help Warn and Placholder strings for app-wide consistency
const ( LabelWidth = 14 CursorPadding = " " )
Field formatting
const ( // SpotlightMinIntensity is the minimum brightness for faded lines SpotlightMinIntensity = 0.3 // SpotlightFocusRadius controls how wide the bright area is SpotlightFocusRadius = 0.4 // ANSIEscapePrefix is the start of ANSI escape sequences ANSIEscapePrefix = "\x1b[" )
const ( IconStatusInfo = " " // nf-fa-info_circle IconStatusSuccess = " " // nf-fa-check IconStatusWarning = " " // nf-fa-exclamation_triangle IconStatusError = " " // nf-fa-times IconMenuCapture = " " // nf-fa-bar_chart IconMenuTCP = " " // nf-md-ethernet IconMenuListPorts = " " // nf-fa-usb IconMenuMetadata = " " // nf-fa-id_badge IconMenuViewRuns = " " // nf-fa-database IconMenuUpload = " " // nf-fa-upload IconMenuConfig = " " // nf-fa-cog IconMenuConnection = " " // nf-md-connection IconMenuNewFile = " " // nf-fa-file_text IconSelectedItem = "❯ " IconMenuSeparator = "\ue621" // nf-indentation line IconTitlePorts = IconMenuListPorts )
Icon Palette - Nerd Font glyphs Update these values as needed
const ( // Status indicators IconAlchemyComplete = "🜏 " IconAlchemyUpload = "🜍 " IconAlchemySuccess = "" IconAlchemyWarning = "⌽ " IconAlchemyError = "⊗ " IconAlchemySettings = "⚖ " // Operational states IconAlchemyActive = "🜃 " // Fire - operations in progress IconAlchemyProcess = "⚗ " // Alembic - data transformation IconAlchemyCached = "🜄 " // Earth - stored locally IconAlchemyStreaming = "🜂 " // Water - live data flow IconAlchemyInfo = "🜔 " // Quintessence - information/knowledge IconAlchemyDownload = "🝱 " // Precipitate - download operations IconAlchemyConnected = "🜁 " // Air - connection active IconAlchemyValidation = "🜨 " // Retort - validation/verification )
const MaxBufferedLines = 1000
MaxBufferedLines defines the maximum number of lines to keep in the buffer
Variables ¶
var ( ColorPrimary = lipgloss.Color("#c6a664") // Celestial Gold - main highlights, cursor ColorSecondary = lipgloss.Color("#7fa4b5") // Starlight - headers, info ColorSuccess = lipgloss.Color("#5e8570") // Verdigris - selected items, success states ColorWarning = lipgloss.Color("#d4a843") // Bright gold - warnings, active states ColorError = lipgloss.Color("#c4523f") // Rust-red - errors ColorMuted = lipgloss.Color("#5a5040") // Warm gray - unselected, help text ColorText = lipgloss.Color("#f0e6d3") // Parchment - normal text ColorHighlight = lipgloss.Color("#1f160a") // Obsidian-brown - highlight background )
Color Palette - centralized color definitions
var ( // Text styles StyleBold = lipgloss.NewStyle(). Bold(true) StyleItalic = lipgloss.NewStyle(). Italic(true) StyleDim = lipgloss.NewStyle(). Faint(true) StyleSelected = lipgloss.NewStyle().Bold(true).Italic(true).Foreground(ColorWarning).Background(ColorHighlight) // Component styles StyleBorder = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). Padding(0, 1) StyleTitle = lipgloss.NewStyle(). Foreground(ColorPrimary). Bold(true). MarginTop(marginSize). MarginBottom(marginSize) StyleHeader = lipgloss.NewStyle(). Foreground(ColorSecondary). Bold(true). MarginTop(marginSize) StyleSubheader = lipgloss.NewStyle(). Foreground(ColorText). Bold(true) // Interactive element styles StyleCursor = lipgloss.NewStyle(). Foreground(ColorPrimary). Bold(true) StyleUnselected = lipgloss.NewStyle(). Foreground(ColorMuted). PaddingLeft(marginSize) StyleHighlight = lipgloss.NewStyle(). Foreground(ColorWarning). Bold(true) // Status styles StyleSuccess = lipgloss.NewStyle(). Foreground(ColorSuccess). Bold(true) StyleError = lipgloss.NewStyle(). Foreground(ColorError). Bold(true). MarginTop(marginSize) StyleWarning = lipgloss.NewStyle(). Foreground(ColorWarning). Bold(true) StyleMuted = lipgloss.NewStyle(). Foreground(ColorMuted) StyleMenuItem = lipgloss.NewStyle(). Foreground(ColorText). Padding(0, 2). Width(menuWidth) StyleMenuSelected = lipgloss.NewStyle(). Background(ColorHighlight). Foreground(ColorWarning). Bold(true). Width(menuWidth) StyleHelp = lipgloss.NewStyle(). Foreground(ColorMuted). MarginTop(marginSize). Italic(true) // Key-value display StyleKey = lipgloss.NewStyle(). Foreground(ColorMuted) StyleValue = lipgloss.NewStyle(). Foreground(ColorPrimary). Bold(true) // Icon styles StyleIcon = lipgloss.NewStyle(). Foreground(ColorPrimary). Bold(true) )
Common Styles - reusable across all TUI components
var ( ProgressGradientStart = lipgloss.Color("#c6a664") // Celestial Gold ProgressGradientEnd = lipgloss.Color("#5e8570") // Verdigris DefaultProgressGradient = progress.WithGradient(string(ProgressGradientStart), string(ProgressGradientEnd)) )
Progress bar configuration Custom gradient that matches our color palette (cyan → purple)
var ( // Status indicators StyledAlchemySuccess = lipgloss.NewStyle().Foreground(ColorSuccess).SetString(IconAlchemySuccess) StyledAlchemyError = lipgloss.NewStyle().Foreground(ColorError).SetString(IconAlchemyError) StyledAlchemyWarning = lipgloss.NewStyle().Foreground(ColorWarning).SetString(IconAlchemyWarning) // Operational states StyledAlchemyActive = lipgloss.NewStyle().Foreground(ColorWarning).SetString(IconAlchemyActive) // Yellow for active ops StyledAlchemyProcess = lipgloss.NewStyle().Foreground(ColorPrimary).SetString(IconAlchemyProcess) // Cyan for processing StyledAlchemyCached = lipgloss.NewStyle().Foreground(ColorMuted).SetString(IconAlchemyCached) // Gray for cached StyledAlchemyStreaming = lipgloss.NewStyle().Foreground(ColorPrimary).SetString(IconAlchemyStreaming) // Cyan for streaming StyledAlchemyInfo = lipgloss.NewStyle().Foreground(ColorSecondary).SetString(IconAlchemyInfo) // Purple for info StyledAlchemyConnected = lipgloss.NewStyle().Foreground(ColorSuccess).SetString(IconAlchemyConnected) // Green for connected StyledAlchemyValidation = lipgloss.NewStyle().Foreground(ColorPrimary).SetString(IconAlchemyValidation) // Cyan for validation )
Styled alchemy symbols for status display
Functions ¶
func ClampFloat ¶
ClampFloat constrains a float64 value between min and max
func CountLines ¶
CountLines returns the number of lines in a string
func EaseOutCubic ¶
EaseOutCubic applies cubic easing to a value (0-1)
func NewAdvancedSettings ¶
func NewCaptureTabs ¶
func NewConfigEditor ¶
NewConfigEditor constructs the config TUI model pre-populated with existing values.
func NewDefaultProgress ¶
NewDefaultProgress creates a progress bar with consistent styling across the application.
func NewDefaultSpinner ¶
NewDefaultSpinner creates a spinner with consistent styling across the application.
func NewListPorts ¶
func NewMetadataEditor ¶
func NewMetadataEditor(repo MetadataPort, meta MetadataValues, path string, loadErr error) tea.Model
NewMetadataEditor constructs the metadata TUI model pre-populated with existing values.
func NewRouterForTest ¶
func NewRouterForTest(cfg RouterConfig) *router
NewRouterForTest exposes router construction for white-box tests.
func NewRunsViewer ¶
NewRunsViewer constructs the runs viewer TUI model.
func NewSourceInfo ¶
NewSourceInfo builds the contextual diagnostics dialog for the given source type.
func NewUploadModel ¶
func NewUploadModel(client UploadPort, runIDs []string) tea.Model
NewUploadModel constructs an upload screen model for use with the router.
func NewWelcome ¶
func NewWelcome(status *StatusMessage) tea.Model
func RunTUI ¶
func RunTUI(cfg RouterConfig) error
RunTUI launches the single Bubble Tea program for the entire application lifetime.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App represents the live capture TUI application
func (*App) SaveRequested ¶
SaveRequested returns true if the user requested to save the run
type CaptureConfig ¶
type CaptureConfig struct {
SourceType string // SourceTypeSerial, SourceTypeTCP, or SourceTypeSCPI
SerialConfig *sources.Config
TCPHost string
TCPPort string
SCPIAddress string // For future SCPI/VISA implementation
}
CaptureConfig holds the configuration for any capture source
type CaptureSession ¶
type CaptureSession interface {
Feed() <-chan string
// Stop cancels the session, waits for finalization, and returns the outcome.
Stop() CaptureSessionResult
// RequestSave marks the session so that Stop promotes artifacts instead of discarding them.
RequestSave()
}
CaptureSession represents an active capture session from the TUI's perspective.
type CaptureSessionPort ¶
type CaptureSessionPort interface {
Start(ctx context.Context, cfg CaptureConfig) (CaptureSession, error)
}
CaptureSessionPort abstracts the live capture subsystem so the router can start sessions without importing concrete source implementations.
type CaptureSessionResult ¶
CaptureSessionResult holds the outcome after a capture session ends.
type LineBuffer ¶
type LineBuffer struct {
// contains filtered or unexported fields
}
LineBuffer manages buffering and processing of incoming text data
func (*LineBuffer) AddData ¶
func (lb *LineBuffer) AddData(data string)
AddData adds raw data to the buffer, processing complete lines
func (*LineBuffer) GetDisplayLines ¶
func (lb *LineBuffer) GetDisplayLines() []string
GetDisplayLines returns all complete lines plus any partial line
func (*LineBuffer) LineCount ¶
func (lb *LineBuffer) LineCount() int
LineCount returns the number of complete lines
type LineWrapper ¶
type LineWrapper struct {
// contains filtered or unexported fields
}
LineWrapper handles text wrapping logic
func NewLineWrapper ¶
func NewLineWrapper(width int) *LineWrapper
NewLineWrapper creates a new line wrapper with the given width
func (*LineWrapper) Wrap ¶
func (lw *LineWrapper) Wrap(lines []string) string
Wrap wraps lines to fit within the configured width
type MetadataPort ¶
type MetadataPort interface {
Load() (MetadataValues, error)
Save(MetadataValues) (string, error)
Path() (string, error)
}
MetadataPort abstracts loading and saving run metadata for the TUI.
type MetadataValues ¶
type MetadataValues struct {
Operator string
Location string
Device core.DeviceInfo
Test core.TestInfo
Tags []string
Attributes map[string]string
}
MetadataValues is the TUI-owned representation of editable metadata.
type NavigateMsg ¶
type NavigateMsg struct {
}
NavigateMsg is emitted by screens to request a transition.
type RouterConfig ¶
type RouterConfig struct {
InitialScreen ScreenID
InitialStatus *StatusMessage
CapturePort CaptureSessionPort
MetadataPort MetadataPort
UploadPort UploadPort
RunsCacheRoot string
}
RouterConfig holds router dependencies.
type ScreenContext ¶
type ScreenContext struct {
Status *StatusMessage
Args any
}
ScreenContext is passed to every ScreenFactory at construction time.
type ScreenFactory ¶
type ScreenFactory func(ctx ScreenContext) (tea.Model, func(), error)
ScreenFactory constructs a screen on demand. The returned func() is a cleanup hook called when the router navigates away. Return nil for the func() if no cleanup is needed. Return a non-nil error to navigate back to welcome with a StatusError.
type ScrollInfo ¶
ScrollInfo contains information about the viewport's scroll position
type SpotlightEffect ¶
type SpotlightEffect struct {
// contains filtered or unexported fields
}
SpotlightEffect applies a gradient fade effect to content based on scroll position
func NewSpotlightEffect ¶
func NewSpotlightEffect() *SpotlightEffect
NewSpotlightEffect creates a new spotlight effect with default settings
func NewSpotlightEffectCustom ¶
func NewSpotlightEffectCustom(minIntensity, focusRadius float64) *SpotlightEffect
NewSpotlightEffectCustom creates a new spotlight effect with custom settings
func (*SpotlightEffect) ApplyFade ¶
func (s *SpotlightEffect) ApplyFade(content string, scroll ScrollInfo) string
ApplyFade applies a gradient fade to the visible content based on scroll position
type StatusKind ¶
type StatusKind int
StatusKind determines the styling applied to a status message.
const ( StatusInfo StatusKind = iota StatusSuccess StatusWarning StatusError )
type StatusMessage ¶
type StatusMessage struct {
Kind StatusKind
Title string
Body string
}
StatusMessage represents a bordered notification rendered inside the TUI.
func NewStatusMessage ¶
func NewStatusMessage(kind StatusKind, title, body string) *StatusMessage
NewStatusMessage constructs a new status message.
func (*StatusMessage) Render ¶
func (m *StatusMessage) Render(width int) string
Render draws the status message within the provided width.