ui

package
v1.1.1 Latest Latest
Warning

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

Go to latest
Published: Apr 6, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ColorBg           = "235" // #262626 - base background
	ColorSurface      = "237" // #3a3a3a - cards/panels
	ColorBorder       = "240" // #585858 - default borders
	ColorBorderActive = "74"  // #5fafd7 - focused border (slate blue)
	ColorText         = "252" // #d0d0d0 - primary text
	ColorTextMuted    = "244" // #808080 - secondary text
	ColorTextSubtle   = "240" // #585858 - hints, tree connectors
	ColorPrimary      = "74"  // #5fafd7 - app accent
	ColorSuccess      = "71"  // #5faf5f - latest/up to date
	ColorWarning      = "178" // #d7af00 - outdated
	ColorDanger       = "160" // #d70000 - vulnerable
	ColorSelected     = "24"  // #005f87 - selected row background
	ColorTabActive    = "74"  // same as Primary
	ColorTabInactive  = "244" // same as TextMuted
)

Color palette - dark slate/blue theme (256-color ANSI)

View Source
const (
	FixedChrome     = 3 // header (1) + tabbar (1) + statusbar (1)
	HeaderHeight    = 3
	TabBarHeight    = 1
	StatusBarHeight = 1
)

Layout constants

Variables

View Source
var AppHeaderStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorPrimary)).
	Bold(true).
	Background(lipgloss.Color(ColorSurface)).
	Padding(0, 2)
View Source
var AppVersionStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTextMuted))
View Source
var BadgeCriticalDotStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorDanger))
View Source
var BadgeErrorStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorDanger))
View Source
var BadgeHealthyDotStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorSuccess))
View Source
var BadgeLoadingStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTextMuted))
View Source
var BadgeOKStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorSuccess))
View Source
var BadgeOutdatedStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorWarning))
View Source
var BadgeVulnerableStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorDanger))
View Source
var BadgeWarningDotStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorWarning))
View Source
var ErrorBoxStyle = lipgloss.NewStyle().
	Border(lipgloss.RoundedBorder()).
	BorderForeground(lipgloss.Color(ColorDanger)).
	Foreground(lipgloss.Color(ColorDanger)).
	Bold(true).
	Padding(1, 2)
View Source
var ErrorMessageStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorText))
View Source
var ErrorTitleStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorDanger)).
	Bold(true)
View Source
var InputBoxStyle = lipgloss.NewStyle().
	Border(lipgloss.RoundedBorder()).
	BorderForeground(lipgloss.Color(ColorBorder)).
	Padding(0, 1)
View Source
var KeyHintDescStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTextMuted))
View Source
var KeyHintKeyStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorPrimary)).
	Bold(true)
View Source
var LoadingMessageStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTextMuted))
View Source
var PanelBorderActiveStyle = lipgloss.NewStyle().
	Border(lipgloss.RoundedBorder()).
	BorderForeground(lipgloss.Color(ColorBorderActive)).
	Padding(0, 1)
View Source
var PanelBorderStyle = lipgloss.NewStyle().
	Border(lipgloss.RoundedBorder()).
	BorderForeground(lipgloss.Color(ColorBorder)).
	Padding(0, 1)
View Source
var PanelTitleStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorPrimary)).
	Bold(true)
View Source
var ProjectPathStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTextMuted)).
	Padding(0, 2)
View Source
var RowMutedStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTextMuted))
View Source
var RowNormalStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorText))
View Source
var RowSelectedStyle = lipgloss.NewStyle().
	Background(lipgloss.Color(ColorSelected)).
	Foreground(lipgloss.Color(ColorText)).
	Bold(true)
View Source
var SearchBoxStyle = lipgloss.NewStyle().
	Border(lipgloss.RoundedBorder()).
	BorderForeground(lipgloss.Color(ColorBorderActive)).
	Padding(0, 1)
View Source
var SearchPromptStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorPrimary)).
	Bold(true)
View Source
var SpinnerStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorPrimary)).
	Bold(true)
View Source
var StatusBarStyle = lipgloss.NewStyle().
	Background(lipgloss.Color(ColorSurface)).
	Foreground(lipgloss.Color(ColorTextMuted)).
	Padding(0, 2)
View Source
var TabActiveStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTabActive)).
	Bold(true).
	Padding(0, 2).
	Background(lipgloss.Color(ColorSurface)).
	Underline(true)
View Source
var TabStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTabInactive)).
	Padding(0, 2).
	Background(lipgloss.Color(ColorSurface))
View Source
var TableHeaderStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTextMuted)).
	Bold(true).
	BorderBottom(true).
	BorderStyle(lipgloss.NormalBorder()).
	BorderForeground(lipgloss.Color(ColorBorder))
View Source
var TreeConnectorStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTextSubtle))
View Source
var TreeGemNameStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorText))
View Source
var TreeVersionStyle = lipgloss.NewStyle().
	Foreground(lipgloss.Color(ColorTextMuted))
View Source
var UpdateBarStyle = lipgloss.NewStyle().
	Background(lipgloss.Color(ColorSurface)).
	Foreground(lipgloss.Color(ColorWarning)).
	Padding(0, 2)

Functions

This section is empty.

Types

type AnalysisCompleteMsg

type AnalysisCompleteMsg struct {
	Result          *gemfile.AnalysisResult
	Error           error
	OutdatedChecker *gemfile.OutdatedChecker
}

type DependencyCompleteMsg

type DependencyCompleteMsg struct {
	Result *gemfile.DependencyResult
	Error  error
}

type HealthCompleteMsg added in v1.1.0

type HealthCompleteMsg struct{}

type HealthItemMsg added in v1.1.0

type HealthItemMsg struct {
	GemName string
	Health  *gemfile.GemHealth
	Error   error
}

type HealthRateLimitedMsg added in v1.1.0

type HealthRateLimitedMsg struct {
	StoppedAt string // gem name where rate limiting occurred
}

type Model

type Model struct {
	// Window dimensions
	Width  int
	Height int

	// Current view and navigation
	CurrentView ViewMode
	ActiveTab   ViewMode // Persists across ViewLoading/ViewGemDetail

	// Data
	AnalysisResult   *gemfile.AnalysisResult
	DependencyResult *gemfile.DependencyResult

	// Gem List screen state
	FirstLevelGems     []*gemfile.GemStatus
	GemListCursor      int
	GemListOffset      int
	UnfilteredGems     []*gemfile.GemStatus // All first-level gems (for filter operations)
	SelectedGroups     map[string]bool      // Groups to filter by (if empty, show all)
	ShowOnlyUpgradable bool                 // Filter to show only gems with updates
	AvailableGroups    []string             // All unique groups found in gems

	// Filter Menu screen state
	FilterMenuCursor int // Position in the filter menu (0 = upgradable, 1+ = groups)

	// Gem Detail screen state
	SelectedGem             *gemfile.GemStatus
	DetailSection           int // 0 = forward deps, 1 = reverse deps
	DetailForwardOffset     int
	DetailReverseOffset     int
	DetailTreeCursor        int                     // Selected line in current tree panel
	DetailForwardLines      []string                // Gem names at each line in forward tree
	DetailReverseLines      []string                // Gem names at each line in reverse tree
	DetailCurrentlyViewing  *gemfile.GemStatus      // The gem currently being viewed in detail (may differ from SelectedGem)
	DetailCurrentReverseDep *gemfile.DependencyInfo // Current gem's reverse dependencies

	// Search screen state
	SearchInput   textinput.Model
	SearchQuery   string
	SearchResults []*gemfile.GemStatus
	SearchCursor  int
	SearchOffset  int

	// Upgradeable screen state
	UpgradeableGems           []*gemfile.GemStatus
	UpgradeableFrameworkGems  []*gemfile.GemStatus
	UpgradeableTransitiveDeps []*gemfile.GemStatus // Transitive dependency gems that can be upgraded
	UpgradeableCursor         int
	UpgradeableOffset         int

	// CVE screen state
	VulnerableGems []*gemfile.GemStatus
	CVECursor      int
	CVEOffset      int

	// Project Info screen state
	RubyVersion       string
	RailsVersion      string
	BundleVersion     string
	OtherFramework    string // For non-Rails projects
	TotalGems         int
	FirstLevelCount   int
	TransitiveDeps    int
	FrameworkDetected string // The name of the framework detected

	// Path selection modal
	PathInput textinput.Model

	// Loading state
	Loading              bool
	LoadingMessage       string
	AnimationFrame       int
	AnalysisStage        string // "parsing", "checking-updates", "scanning-cves"
	AnalysisPercentage   int    // 0-100
	AnalysisCurrentCount int    // Current item in stage
	AnalysisTotalCount   int    // Total items for stage

	// Health loading state
	HealthLoading     bool
	HealthRateLimited bool
	HealthLoadedCount int
	HealthTotalCount  int
	HealthPending     []*gemfile.GemStatus // Queue for sequential fetching
	HealthChecker     *gemfile.HealthChecker
	OutdatedChecker   *gemfile.OutdatedChecker // Reused for health data extraction

	// Outdated checking state
	OutdatedLoading     bool
	OutdatedPending     []*gemfile.GemStatus // Queue for sequential fetching
	OutdatedErrorCount  int
	OutdatedRateLimited bool

	// Error state
	ErrorMessage string

	// Project state
	ProjectPath     string
	GemfileLockPath string

	// App metadata
	Version             string
	Commit              string
	Date                string
	NewVersionAvailable string // empty = no update, otherwise holds latest version tag
	Quitting            bool
	NoCache             bool // Skip cache and force fresh analysis
}

func NewModel

func NewModel(version, commit, date, projectPath string, noCache bool) *Model

func (*Model) Init

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

func (*Model) Update

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

func (*Model) View

func (m *Model) View() string

type OutdatedCompleteMsg added in v1.1.0

type OutdatedCompleteMsg struct{}

type OutdatedItemMsg added in v1.1.0

type OutdatedItemMsg struct {
	GemName       string
	IsOutdated    bool
	LatestVersion string
	HomepageURL   string
	Description   string
	Error         error
}

type ProgressMsg added in v1.0.6

type ProgressMsg struct {
	Stage      string // "parsing", "checking-updates", "scanning-cves", "complete"
	Percentage int    // 0-100
	Message    string // Status message
}

type ProgressTickMsg added in v1.0.6

type ProgressTickMsg struct{}

type SpinnerTickMsg

type SpinnerTickMsg struct{}

type StageUpdateMsg added in v1.0.6

type StageUpdateMsg struct {
	Stage          string                  // "parsing", "checking-updates", "scanning-cves"
	CurrentCount   int                     // Current gems processed
	TotalCount     int                     // Total gems to process
	Percentage     int                     // 0-100
	Result         *gemfile.AnalysisResult // Accumulated results so far
	OutdatedGems   []*gemfile.GemStatus    // Updated gems with version info
	VulnerableGems []*gemfile.GemStatus    // Updated with CVE info
}

type VersionCheckMsg added in v1.0.3

type VersionCheckMsg struct {
	LatestVersion string
	HasUpdate     bool
}

type ViewMode

type ViewMode int
const (
	ViewLoading ViewMode = iota
	ViewGemList
	ViewGemDetail
	ViewSearch
	ViewUpgradeable
	ViewCVE
	ViewProjectInfo
	ViewFilterMenu
	ViewSelectPath
	ViewError
)

Jump to

Keyboard shortcuts

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