Documentation
¶
Index ¶
- Constants
- Variables
- func BucketTimestamps(timestamps []time.Time, window time.Duration, width int) []int
- func Clamp(lo, hi, v int) int
- func ConfigDir() string
- func ConfigPath() string
- func EffectiveCost(model string, costUSD float64, ...) float64
- func EstimateCost(model string, inputTokens, outputTokens, cacheCreation, cacheRead int) float64
- func FormatCost(usd float64) string
- func FormatDuration(d time.Duration) string
- func FormatTokens(n int) string
- func IsActiveActivity(a ActivityKind) bool
- func PadRight(s string, n int) string
- func RenderSparkline(timestamps []time.Time, window time.Duration, width int) string
- func SaveConfig(cfg Config) error
- func ShortName(path string, maxLen int) string
- func SortSessions(sessions []*model.Session)
- type ActivityEntry
- type ActivityKind
- type ActivityTracker
- type Config
- type CursorProvider
- type LiveProvider
- type MultiProvider
- type OpenCodeProvider
- type PiProvider
- type ProjectWatcher
- type SessionDetailView
- type SessionManager
- func (m *SessionManager) ActivityFilter() ActivityKind
- func (m *SessionManager) ActivityFor(sessionID string) ActivityKind
- func (m *SessionManager) QuerySessions(search string, filter ActivityKind) []*model.Session
- func (m *SessionManager) Reload() error
- func (m *SessionManager) SessionDetail(id string) *SessionDetailView
- func (m *SessionManager) SessionName(sessionID string) string
- func (m *SessionManager) Sessions() []*model.Session
- func (m *SessionManager) SetActivityFilter(filter ActivityKind)
- func (m *SessionManager) SetSearchQuery(query string)
- func (m *SessionManager) SetSessionName(sessionID, name string) error
- func (m *SessionManager) SetWindowMinutes(minutes int)
- func (m *SessionManager) StartWatcher() error
- func (m *SessionManager) StopWatcher()
- func (m *SessionManager) UpdateActivities() bool
- func (m *SessionManager) VisibleSessions() []*model.Session
- func (m *SessionManager) WatcherEvents() <-chan struct{}
- func (m *SessionManager) WindowMinutes() int
- type SessionNames
- type SessionProvider
Constants ¶
const ( MinWindowMinutes = 10 MaxWindowMinutes = 480 )
Window minutes bounds.
const ActivityTimeout = 30 * time.Second
ActivityTimeout is the duration a tool-based activity stays visible after the tool finishes, unless replaced by a newer activity.
const WaitingGrace = 10 * time.Second
WaitingGrace is the minimum time StatusWaitingForUser must be stable before displaying ActivityWaiting. Claude sometimes writes a text-only assistant message before immediately continuing with a tool_use message (~2s later), which would otherwise cause a brief false "waiting" flash.
const WaitingTimeout = 2 * time.Minute
WaitingTimeout is how long "waiting" stays visible before falling back to idle.
Variables ¶
var AllActivities = []ActivityKind{ "", ActivityIdle, ActivityWaiting, ActivityThinking, ActivityCompacting, ActivityReading, ActivityWriting, ActivityRunning, ActivitySearching, ActivityBrowsing, ActivitySpawning, }
AllActivities returns all ActivityKind values in display order (empty = all).
var SpinnerFrames = []rune{'⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'}
SpinnerFrames contains the Braille spinner animation frames.
Functions ¶
func BucketTimestamps ¶
BucketTimestamps groups timestamps into fixed-width buckets for sparkline display. Returns a slice of counts per bucket.
func ConfigDir ¶
func ConfigDir() string
ConfigDir returns the config directory path (~/.config/lazyagent).
func EffectiveCost ¶
func EffectiveCost(model string, costUSD float64, inputTokens, outputTokens, cacheCreation, cacheRead int) float64
EffectiveCost returns CostUSD if non-zero, otherwise estimates from tokens.
func EstimateCost ¶
EstimateCost estimates API cost based on model and token counts. Supports Anthropic (Claude), Google (Gemini), and OpenAI (GPT) model families.
func FormatDuration ¶
FormatDuration converts a duration to a human-readable "Xs ago" string.
func FormatTokens ¶
FormatTokens formats a token count for display (e.g., 1200 → "1.2k").
func IsActiveActivity ¶
func IsActiveActivity(a ActivityKind) bool
IsActiveActivity returns true for any activity that represents ongoing work (i.e. everything except idle and waiting).
func PadRight ¶
PadRight pads a string with spaces to reach visual width n (rune count), or truncates if longer.
func RenderSparkline ¶
RenderSparkline renders bucketed data as a Unicode sparkline string.
func ShortName ¶
ShortName truncates a file path intelligently, showing "…/parent/child" when needed. maxLen is measured in runes (visual width for monospace display).
func SortSessions ¶
SortSessions sorts sessions by last activity (most recent first).
Types ¶
type ActivityEntry ¶
type ActivityEntry struct {
Kind ActivityKind
LastSeen time.Time
}
ActivityEntry holds a session's current sticky activity state.
type ActivityKind ¶
type ActivityKind string
ActivityKind is the human-readable label shown in the session list.
const ( ActivityIdle ActivityKind = "idle" ActivityWaiting ActivityKind = "waiting" ActivityThinking ActivityKind = "thinking" ActivityCompacting ActivityKind = "compacting" ActivityReading ActivityKind = "reading" ActivityWriting ActivityKind = "writing" ActivityRunning ActivityKind = "running" ActivitySearching ActivityKind = "searching" ActivityBrowsing ActivityKind = "browsing" ActivitySpawning ActivityKind = "spawning" )
func NextActivityFilter ¶
func NextActivityFilter(current ActivityKind) ActivityKind
NextActivityFilter cycles to the next activity filter in AllActivities.
func ResolveActivity ¶
func ResolveActivity(s *model.Session, now time.Time) ActivityKind
ResolveActivity determines the display activity for a session.
Priority:
- Compacting (summary entry written recently).
- Most recent tool in RecentTools within ActivityTimeout.
- StatusWaitingForUser within WaitingTimeout (with grace period).
- LastActivity older than ActivityTimeout → idle.
- Current JSONL status → thinking if Claude is processing, idle otherwise.
func ToolActivity ¶
func ToolActivity(tool string) ActivityKind
ToolActivity maps a tool name to an activity kind. Supports both Claude Code (PascalCase) and pi (snake_case) tool names.
type ActivityTracker ¶
type ActivityTracker struct {
// contains filtered or unexported fields
}
ActivityTracker manages sticky activity states with grace period logic.
func NewActivityTracker ¶
func NewActivityTracker() *ActivityTracker
NewActivityTracker creates a new ActivityTracker.
func (*ActivityTracker) Get ¶
func (t *ActivityTracker) Get(sessionID string) ActivityKind
Get returns the current sticky activity for a session.
type Config ¶
type Config struct {
WindowMinutes int `json:"window_minutes"`
DefaultFilter string `json:"default_filter"`
Editor string `json:"editor"`
LaunchAtLogin bool `json:"launch_at_login"`
Notifications bool `json:"notifications"`
NotifyAfterSec int `json:"notify_after_sec"`
Agents map[string]bool `json:"agents"`
}
Config holds application settings shared by TUI and GUI.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a Config with sensible defaults.
func LoadConfig ¶
func LoadConfig() Config
LoadConfig reads the config file, creating it with defaults if missing.
func (Config) AgentEnabled ¶
AgentEnabled returns whether an agent is enabled in config. Defaults to true if the agent key is missing from the map.
type CursorProvider ¶
type CursorProvider struct {
// contains filtered or unexported fields
}
CursorProvider discovers Cursor sessions from store.db files.
func NewCursorProvider ¶
func NewCursorProvider() *CursorProvider
NewCursorProvider creates a CursorProvider.
func (*CursorProvider) DiscoverSessions ¶
func (p *CursorProvider) DiscoverSessions() ([]*model.Session, error)
func (*CursorProvider) RefreshInterval ¶
func (p *CursorProvider) RefreshInterval() time.Duration
func (*CursorProvider) UseWatcher ¶
func (p *CursorProvider) UseWatcher() bool
func (*CursorProvider) WatchDirs ¶
func (p *CursorProvider) WatchDirs() []string
type LiveProvider ¶
type LiveProvider struct {
// contains filtered or unexported fields
}
LiveProvider discovers real Claude Code sessions from disk.
func NewLiveProvider ¶
func NewLiveProvider() *LiveProvider
NewLiveProvider creates a LiveProvider with mtime-based caches.
func (*LiveProvider) DiscoverSessions ¶
func (p *LiveProvider) DiscoverSessions() ([]*model.Session, error)
func (*LiveProvider) RefreshInterval ¶
func (p *LiveProvider) RefreshInterval() time.Duration
func (*LiveProvider) UseWatcher ¶
func (p *LiveProvider) UseWatcher() bool
func (*LiveProvider) WatchDirs ¶
func (p *LiveProvider) WatchDirs() []string
type MultiProvider ¶
type MultiProvider struct {
Providers []SessionProvider
}
MultiProvider merges sessions from multiple providers.
func (MultiProvider) DiscoverSessions ¶
func (m MultiProvider) DiscoverSessions() ([]*model.Session, error)
func (MultiProvider) RefreshInterval ¶
func (m MultiProvider) RefreshInterval() time.Duration
func (MultiProvider) UseWatcher ¶
func (m MultiProvider) UseWatcher() bool
func (MultiProvider) WatchDirs ¶
func (m MultiProvider) WatchDirs() []string
type OpenCodeProvider ¶
type OpenCodeProvider struct {
// contains filtered or unexported fields
}
OpenCodeProvider discovers OpenCode sessions from SQLite.
func NewOpenCodeProvider ¶
func NewOpenCodeProvider() *OpenCodeProvider
NewOpenCodeProvider creates an OpenCodeProvider.
func (*OpenCodeProvider) DiscoverSessions ¶
func (p *OpenCodeProvider) DiscoverSessions() ([]*model.Session, error)
func (*OpenCodeProvider) RefreshInterval ¶
func (p *OpenCodeProvider) RefreshInterval() time.Duration
func (*OpenCodeProvider) UseWatcher ¶
func (p *OpenCodeProvider) UseWatcher() bool
func (*OpenCodeProvider) WatchDirs ¶
func (p *OpenCodeProvider) WatchDirs() []string
type PiProvider ¶
type PiProvider struct {
// contains filtered or unexported fields
}
PiProvider discovers pi coding agent sessions from disk.
func NewPiProvider ¶
func NewPiProvider() *PiProvider
NewPiProvider creates a PiProvider with an mtime-based cache.
func (*PiProvider) DiscoverSessions ¶
func (p *PiProvider) DiscoverSessions() ([]*model.Session, error)
func (*PiProvider) RefreshInterval ¶
func (p *PiProvider) RefreshInterval() time.Duration
func (*PiProvider) UseWatcher ¶
func (p *PiProvider) UseWatcher() bool
func (*PiProvider) WatchDirs ¶
func (p *PiProvider) WatchDirs() []string
type ProjectWatcher ¶
type ProjectWatcher struct {
Events <-chan struct{}
// contains filtered or unexported fields
}
ProjectWatcher watches ~/.claude/projects for JSONL changes using FSEvents. It debounces rapid writes so that a burst of JSONL lines triggers one reload.
func NewProjectWatcher ¶
func NewProjectWatcher(dirs ...string) (*ProjectWatcher, error)
NewProjectWatcher starts an FSEvents watcher on the given directories. Returns nil (no error) if none of the directories exist.
func (*ProjectWatcher) Close ¶
func (w *ProjectWatcher) Close()
Close signals the watcher goroutine to stop and releases resources.
type SessionDetailView ¶
type SessionDetailView struct {
model.Session
Activity ActivityKind
}
SessionDetailView is the full struct for a detail panel.
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager manages session discovery, file watching, and activity tracking.
func NewSessionManager ¶
func NewSessionManager(windowMinutes int, provider SessionProvider) *SessionManager
NewSessionManager creates a new SessionManager with the given provider.
func (*SessionManager) ActivityFilter ¶
func (m *SessionManager) ActivityFilter() ActivityKind
ActivityFilter returns the current activity filter.
func (*SessionManager) ActivityFor ¶
func (m *SessionManager) ActivityFor(sessionID string) ActivityKind
ActivityFor returns the current activity for a session.
func (*SessionManager) QuerySessions ¶
func (m *SessionManager) QuerySessions(search string, filter ActivityKind) []*model.Session
QuerySessions returns sessions filtered by explicit parameters without using the manager's internal filter/search state. Safe for concurrent API use. Empty search/filter means no filtering.
func (*SessionManager) Reload ¶
func (m *SessionManager) Reload() error
Reload discovers sessions via the provider and updates activity states.
func (*SessionManager) SessionDetail ¶
func (m *SessionManager) SessionDetail(id string) *SessionDetailView
SessionDetail returns the full detail view for a session.
func (*SessionManager) SessionName ¶
func (m *SessionManager) SessionName(sessionID string) string
SessionName returns the custom name for a session, or empty string.
func (*SessionManager) Sessions ¶
func (m *SessionManager) Sessions() []*model.Session
Sessions returns all raw sessions (unfiltered).
func (*SessionManager) SetActivityFilter ¶
func (m *SessionManager) SetActivityFilter(filter ActivityKind)
SetActivityFilter sets the activity filter.
func (*SessionManager) SetSearchQuery ¶
func (m *SessionManager) SetSearchQuery(query string)
SetSearchQuery sets the search query.
func (*SessionManager) SetSessionName ¶
func (m *SessionManager) SetSessionName(sessionID, name string) error
SetSessionName stores a custom name for a session.
func (*SessionManager) SetWindowMinutes ¶
func (m *SessionManager) SetWindowMinutes(minutes int)
SetWindowMinutes sets the time window filter, clamped to [MinWindowMinutes, MaxWindowMinutes].
func (*SessionManager) StartWatcher ¶
func (m *SessionManager) StartWatcher() error
StartWatcher starts the file system watcher if the provider supports it.
func (*SessionManager) StopWatcher ¶
func (m *SessionManager) StopWatcher()
StopWatcher stops the file system watcher.
func (*SessionManager) UpdateActivities ¶
func (m *SessionManager) UpdateActivities() bool
UpdateActivities refreshes activity states without reloading from disk. Returns true if any activity state changed. If the provider specifies a RefreshInterval, sessions are re-discovered periodically. Also refreshes session names from disk if modified externally.
func (*SessionManager) VisibleSessions ¶
func (m *SessionManager) VisibleSessions() []*model.Session
VisibleSessions returns sessions filtered by the manager's internal state (time window, activity filter, search query). Used by TUI and tray.
func (*SessionManager) WatcherEvents ¶
func (m *SessionManager) WatcherEvents() <-chan struct{}
WatcherEvents returns the channel for file change notifications, or nil.
func (*SessionManager) WindowMinutes ¶
func (m *SessionManager) WindowMinutes() int
WindowMinutes returns the current time window.
type SessionNames ¶
type SessionNames struct {
// contains filtered or unexported fields
}
SessionNames manages user-defined aliases for sessions. Stored in ~/.config/lazyagent/session-names.json.
func NewSessionNames ¶
func NewSessionNames() *SessionNames
NewSessionNames creates a new SessionNames and loads from disk.
func (*SessionNames) Get ¶
func (sn *SessionNames) Get(sessionID string) string
Get returns the custom name for a session, or empty string.
func (*SessionNames) Refresh ¶
func (sn *SessionNames) Refresh() bool
Refresh re-reads the file from disk if it was modified externally. Returns true if the file was actually reloaded.
func (*SessionNames) Set ¶
func (sn *SessionNames) Set(sessionID, name string) error
Set stores a custom name for a session and persists to disk. Empty name removes the alias.
type SessionProvider ¶
type SessionProvider interface {
// DiscoverSessions returns all available sessions.
DiscoverSessions() ([]*model.Session, error)
// UseWatcher returns whether a file system watcher should be started.
UseWatcher() bool
// RefreshInterval returns how often UpdateActivities should re-discover sessions,
// or 0 to never re-discover (only on explicit Reload or watcher events).
RefreshInterval() time.Duration
// WatchDirs returns directories to watch for file system changes.
WatchDirs() []string
}
SessionProvider abstracts how sessions are discovered.
func BuildProvider ¶
func BuildProvider(agentMode string, cfg Config) SessionProvider
BuildProvider creates a SessionProvider based on agent mode and config. When agentMode is "all", it reads the agents config to decide which providers to include. A specific agentMode (e.g. "claude") overrides the config.