Documentation
¶
Overview ¶
Package overlay provides a terminal overlay system for agnt. It renders a status indicator bar and popup menus using ANSI escape sequences, while passing through input/output to the underlying PTY.
Index ¶
- Constants
- Variables
- func NeedsAggressiveMode() bool
- func NormalizeListenAddr(addr string) string
- func ScanWin32Input(r io.Reader) iter.Seq[byte]
- func StateColorCode(state string) string
- type Action
- type ActivityMonitor
- type ActivityMonitorConfig
- type ActivityState
- type AlertBatch
- type AlertMatch
- type AlertPattern
- type AlertScanner
- func (s *AlertScanner) AddPattern(p *AlertPattern)
- func (s *AlertScanner) DisablePattern(id string)
- func (s *AlertScanner) ProcessLine(line string, scriptID string)
- func (s *AlertScanner) RecentMatches(since time.Time) []*AlertMatch
- func (s *AlertScanner) SetEnabled(enabled bool)
- func (s *AlertScanner) Stop()
- type AlertScannerConfig
- type AlertSeverity
- type AuditData
- type AuditSummarizer
- type AuditSummarizerConfig
- type BashRunner
- type BrowserSession
- type Config
- type ConnectionStatus
- type DaemonBashRunner
- type DaemonConnector
- type DaemonConnectorImpl
- type DaemonOutputFetcher
- type ErrorInfo
- type EscapeSequenceReader
- type FilterConfig
- type InputRouter
- func (r *InputRouter) GetLastDaemonError() string
- func (r *InputRouter) Run() error
- func (r *InputRouter) SetBashRunner(runner BashRunner)
- func (r *InputRouter) SetDaemonConnector(connector DaemonConnector)
- func (r *InputRouter) SetOutputFetcher(fetcher ProcessOutputFetcher)
- func (r *InputRouter) SetStatusFetcher(fetcher *StatusFetcher)
- func (r *InputRouter) SetSummarizer(summarizer StatusSummarizer)
- func (r *InputRouter) Stop()
- type Menu
- type MenuItem
- type OutputGate
- type Overlay
- func (o *Overlay) DrawStatusBarMessage(message string)
- func (o *Overlay) GetStatus() Status
- func (o *Overlay) Hide()
- func (o *Overlay) IsActive() bool
- func (o *Overlay) Redraw()
- func (o *Overlay) RedrawIndicator()
- func (o *Overlay) SetAltScreenChecker(fn func() bool)
- func (o *Overlay) SetGate(gate *OutputGate)
- func (o *Overlay) SetRedrawPaused(paused bool)
- func (o *Overlay) SetSize(width, height int)
- func (o *Overlay) Show()
- func (o *Overlay) ShowIndicator() bool
- func (o *Overlay) State() State
- func (o *Overlay) Toggle()
- func (o *Overlay) ToggleIndicator()
- func (o *Overlay) UpdateStatus(status Status)
- type OverlayStack
- type PanelItem
- type ProcessInfo
- type ProcessOutputFetcher
- type ProcessSummary
- type ProtectedWriter
- type ProxyInfo
- type ProxySummary
- type PtyReadWriter
- type Renderer
- func (r *Renderer) ClearCurrentMenu()
- func (r *Renderer) ClearIndicator()
- func (r *Renderer) ClearMenu()
- func (r *Renderer) ClearScreen()
- func (r *Renderer) ClearStatusBarMessage()
- func (r *Renderer) ClearVisible()
- func (r *Renderer) DrawDashboard(menu Menu, selectedIndex int, status Status)
- func (r *Renderer) DrawIndicator(status Status)
- func (r *Renderer) DrawInput(prompt, value string)
- func (r *Renderer) DrawMenu(menu Menu, selectedIndex int)
- func (r *Renderer) DrawMenuWithProcesses(menu Menu, selectedIndex int, processes []ProcessInfo)
- func (r *Renderer) DrawPanelView(panels []PanelItem, activeIndex int, status Status)
- func (r *Renderer) DrawProcessOutput(processID, command, state, output string)
- func (r *Renderer) DrawStatusBarMessage(message string)
- func (r *Renderer) EnterAltScreen()
- func (r *Renderer) ExitAltScreen()
- func (r *Renderer) ResetMenuRegions()
- func (r *Renderer) SetOutput(out io.Writer)
- func (r *Renderer) SetSize(width, height int)
- func (r *Renderer) SetVersion(version string)
- type ScreenBuffer
- type ScreenManager
- func (sm *ScreenManager) ClearRegion(region ScreenRegion)
- func (sm *ScreenManager) DrawOverlay(name string, row, col, width, height int, ...) ScreenRegion
- func (sm *ScreenManager) ForceRedraw()
- func (sm *ScreenManager) RestoreRegion(name string)
- func (sm *ScreenManager) SaveRegion(name string, region ScreenRegion)
- func (sm *ScreenManager) SetOutput(out io.Writer)
- func (sm *ScreenManager) SetSize(width, height int)
- type ScreenRegion
- type ScriptInfo
- type StartupLogEntry
- type State
- type Status
- type StatusFetcher
- type StatusSummarizer
- type Summarizer
- type SummarizerConfig
- type SummaryResult
Constants ¶
const ( // Cursor control CursorHide = "\x1b[?25l" CursorShow = "\x1b[?25h" CursorSave = "\x1b[s" CursorRestore = "\x1b[u" CursorHome = "\x1b[H" CursorToFormat = "\x1b[%d;%dH" // row;col (1-indexed) // Screen control ClearScreen = "\x1b[2J" ClearLine = "\x1b[2K" ClearToEOL = "\x1b[K" ScrollRegion = "\x1b[%d;%dr" // top;bottom ResetScroll = "\x1b[r" EnterAltScreen = "\x1b[?1049h" ExitAltScreen = "\x1b[?1049l" // Text attributes Reset = "\x1b[0m" Bold = "\x1b[1m" Dim = "\x1b[2m" Italic = "\x1b[3m" Underline = "\x1b[4m" Blink = "\x1b[5m" Reverse = "\x1b[7m" // Foreground colors (basic) FgBlack = "\x1b[30m" FgRed = "\x1b[31m" FgGreen = "\x1b[32m" FgYellow = "\x1b[33m" FgBlue = "\x1b[34m" FgMagenta = "\x1b[35m" FgCyan = "\x1b[36m" FgWhite = "\x1b[37m" FgDefault = "\x1b[39m" // Bright foreground colors FgBrightBlack = "\x1b[90m" FgBrightRed = "\x1b[91m" FgBrightGreen = "\x1b[92m" FgBrightYellow = "\x1b[93m" FgBrightBlue = "\x1b[94m" FgBrightMagenta = "\x1b[95m" FgBrightCyan = "\x1b[96m" FgBrightWhite = "\x1b[97m" // Background colors (basic) BgBlack = "\x1b[40m" BgRed = "\x1b[41m" BgGreen = "\x1b[42m" BgYellow = "\x1b[43m" BgBlue = "\x1b[44m" BgMagenta = "\x1b[45m" BgCyan = "\x1b[46m" BgWhite = "\x1b[47m" BgDefault = "\x1b[49m" // Bright background colors BgBrightBlack = "\x1b[100m" )
ANSI escape sequences.
const ( BoxHorizontal = "─" BoxVertical = "│" BoxTopLeft = "┌" BoxTopRight = "┐" BoxBottomLeft = "└" BoxBottomRight = "┘" BoxVerticalRight = "├" BoxVerticalLeft = "┤" BoxHorizontalDown = "┬" BoxHorizontalUp = "┴" BoxCross = "┼" BoxDoubleHorizontal = "═" BoxDoubleVertical = "║" // Rounded box drawing characters (niri-style). RoundTopLeft = "╭" RoundTopRight = "╮" RoundBottomLeft = "╰" RoundBottomRight = "╯" )
Box drawing characters (Unicode).
const ( IconConnected = "●" IconDisconnected = "○" IconError = "✗" IconWarning = "⚠" IconProcess = "⚙" IconProxy = "⇄" IconOK = "✓" )
Status icons.
const ( RegionMenu = "menu" RegionInput = "input" )
Overlay region names for tracking.
Variables ¶
var DebugWin32Input = false
DebugWin32Input enables logging of win32-input-mode parsing
Functions ¶
func NeedsAggressiveMode ¶ added in v0.12.19
func NeedsAggressiveMode() bool
NeedsAggressiveMode detects whether the current terminal needs aggressive filtering. Returns true for ConPTY (Windows Terminal, VS Code terminal) where DECSTBM scroll regions are unreliable. Returns false for Unix PTYs, WSL, mintty, and other terminals with proper DECSTBM support.
func NormalizeListenAddr ¶ added in v0.12.0
NormalizeListenAddr converts wildcard and loopback addresses to localhost for clickable URLs. This is the most reliable option since LAN IPs can be unreliable in virtual environments (WSL2, Docker, etc.). Users who need LAN access can check the detailed proxy output.
func ScanWin32Input ¶ added in v0.6.3
ScanWin32Input returns an iterator that reads from r and yields parsed bytes. It handles Windows Terminal win32-input-mode escape sequences, extracting the unicode character values and yielding them as individual bytes. Buffer boundaries are handled internally - incomplete sequences at the end of a read are held and combined with the next read.
func StateColorCode ¶ added in v0.8.0
StateColorCode returns the ANSI color code for a process state.
Types ¶
type ActivityMonitor ¶
type ActivityMonitor struct {
// contains filtered or unexported fields
}
ActivityMonitor wraps an io.Writer to monitor output activity. It detects when data is being written (active) and when writing stops (idle). It can also broadcast output previews (recent lines) to connected browsers. It handles animated output (like Ink spinners) by detecting carriage returns and debouncing rapid updates to prevent scroll spam.
func NewActivityMonitor ¶
func NewActivityMonitor(w io.Writer, cfg ActivityMonitorConfig) *ActivityMonitor
NewActivityMonitor creates a new activity monitor wrapping the given writer.
func (*ActivityMonitor) IsActive ¶
func (am *ActivityMonitor) IsActive() bool
IsActive returns true if currently active.
func (*ActivityMonitor) State ¶
func (am *ActivityMonitor) State() ActivityState
State returns the current activity state.
type ActivityMonitorConfig ¶
type ActivityMonitorConfig struct {
// IdleTimeout is how long to wait with no output before transitioning to idle.
// Default: 2 seconds
IdleTimeout time.Duration
// OnStateChange is called when activity state changes.
OnStateChange func(ActivityState)
// MinActiveBytes is the minimum bytes written to trigger active state.
// This prevents brief flickers of activity for small outputs.
// Default: 10
MinActiveBytes int
// OnOutputPreview is called with recent output lines for browser display.
// Lines are debounced to avoid overwhelming the browser.
OnOutputPreview func(lines []string)
// PreviewMaxLines is the maximum number of lines to keep for preview.
// Default: 5
PreviewMaxLines int
// PreviewDebounce is the minimum time between output preview broadcasts.
// Default: 200ms
PreviewDebounce time.Duration
// AnimationDebounce is how long to wait after the last update to an animating
// line before flushing it. This prevents rapid updates (like Ink spinners)
// from appearing as scrolling lines. Default: 100ms
AnimationDebounce time.Duration
// ShowDoneMessage adds a persistent "Done" message when activity goes idle.
// Default: true
ShowDoneMessage bool
// DoneMessage is the message to show when activity goes idle.
// Default: "✓ Done"
DoneMessage string
// OnOutputLine is called with each complete, cleaned line of output.
// Used by AlertScanner to detect error/warning patterns.
OnOutputLine func(string)
}
ActivityMonitorConfig configures the activity monitor.
func DefaultActivityMonitorConfig ¶
func DefaultActivityMonitorConfig() ActivityMonitorConfig
DefaultActivityMonitorConfig returns the default configuration.
type ActivityState ¶
type ActivityState int
ActivityState represents the current activity state.
const ( ActivityIdle ActivityState = iota ActivityActive )
type AlertBatch ¶ added in v0.11.5
type AlertBatch struct {
Matches []*AlertMatch
ScriptID string
}
AlertBatch is a collection of alert matches to be delivered together.
func (*AlertBatch) Format ¶ added in v0.11.5
func (b *AlertBatch) Format() string
Format renders the batch as a human-readable message for the AI agent.
func (*AlertBatch) MaxSeverity ¶ added in v0.11.5
func (b *AlertBatch) MaxSeverity() AlertSeverity
MaxSeverity returns the highest severity in the batch.
type AlertMatch ¶ added in v0.11.5
type AlertMatch struct {
Pattern *AlertPattern
Line string
Timestamp time.Time
ScriptID string
}
AlertMatch represents a single matched alert from process output.
type AlertPattern ¶ added in v0.11.5
type AlertPattern struct {
ID string
Pattern *regexp.Regexp
Severity AlertSeverity
Category string // e.g. "dotnet", "webpack", "go", "generic"
Description string
}
AlertPattern defines a regex pattern to match against process output.
func DefaultAlertPatterns ¶ added in v0.11.5
func DefaultAlertPatterns() []*AlertPattern
DefaultAlertPatterns returns the built-in set of alert patterns for common dev server frameworks and languages.
type AlertScanner ¶ added in v0.11.5
type AlertScanner struct {
// contains filtered or unexported fields
}
AlertScanner matches process output lines against known error/warning patterns, deduplicates, batches, and delivers alerts through a callback.
func NewAlertScanner ¶ added in v0.11.5
func NewAlertScanner(cfg AlertScannerConfig) *AlertScanner
NewAlertScanner creates and starts a new AlertScanner with the given config.
func (*AlertScanner) AddPattern ¶ added in v0.11.5
func (s *AlertScanner) AddPattern(p *AlertPattern)
AddPattern registers an additional alert pattern.
func (*AlertScanner) DisablePattern ¶ added in v0.11.5
func (s *AlertScanner) DisablePattern(id string)
DisablePattern disables a pattern by ID.
func (*AlertScanner) ProcessLine ¶ added in v0.11.5
func (s *AlertScanner) ProcessLine(line string, scriptID string)
ProcessLine checks a single line of output against all enabled patterns.
func (*AlertScanner) RecentMatches ¶ added in v0.12.0
func (s *AlertScanner) RecentMatches(since time.Time) []*AlertMatch
RecentMatches returns matches from the ring buffer with timestamp >= since. If since is the zero time, all buffered matches are returned. Results are ordered oldest-to-newest.
func (*AlertScanner) SetEnabled ¶ added in v0.11.5
func (s *AlertScanner) SetEnabled(enabled bool)
SetEnabled enables or disables the scanner.
func (*AlertScanner) Stop ¶ added in v0.11.5
func (s *AlertScanner) Stop()
Stop stops the scanner and flushes any pending alerts.
type AlertScannerConfig ¶ added in v0.11.5
type AlertScannerConfig struct {
// Patterns are additional custom patterns to register.
Patterns []*AlertPattern
// DisabledIDs is a set of pattern IDs to disable.
DisabledIDs []string
// BatchWindow is how long to collect alerts before flushing.
// Default: 3 seconds.
BatchWindow time.Duration
// DedupeWindow is how long to suppress duplicate alerts.
// Default: 60 seconds.
DedupeWindow time.Duration
// ActivityState returns the current activity state of the AI agent.
// If non-nil and returns ActivityActive, flush is deferred.
ActivityState func() ActivityState
// OnAlert is called when a batch of alerts is ready for delivery.
OnAlert func(*AlertBatch)
}
AlertScannerConfig configures the AlertScanner.
type AlertSeverity ¶ added in v0.11.5
type AlertSeverity string
AlertSeverity indicates the severity of an alert match.
const ( AlertSeverityError AlertSeverity = "error" AlertSeverityWarning AlertSeverity = "warning" AlertSeverityInfo AlertSeverity = "info" )
type AuditData ¶ added in v0.8.0
type AuditData struct {
AuditType string `json:"auditType"`
Label string `json:"label"`
Summary string `json:"summary"`
Result json.RawMessage `json:"result"`
}
AuditData represents the audit data to summarize.
type AuditSummarizer ¶ added in v0.8.0
type AuditSummarizer struct {
// contains filtered or unexported fields
}
AuditSummarizer uses an AI channel to generate high-quality audit reports.
func NewAuditSummarizer ¶ added in v0.8.0
func NewAuditSummarizer(config AuditSummarizerConfig) *AuditSummarizer
NewAuditSummarizer creates a new audit summarizer.
func (*AuditSummarizer) IsAvailable ¶ added in v0.8.0
func (s *AuditSummarizer) IsAvailable() bool
IsAvailable returns true if the AI channel is available.
func (*AuditSummarizer) SummarizeAudit ¶ added in v0.8.0
func (s *AuditSummarizer) SummarizeAudit(ctx context.Context, audit AuditData, userMessage string) (string, error)
SummarizeAudit generates a high-quality report from audit data. It also saves the full audit data to .agnt/audit/ for later reference.
type AuditSummarizerConfig ¶ added in v0.8.0
type AuditSummarizerConfig struct {
// Agent type for AI summarization (default: uses API mode with Anthropic)
Agent aichannel.AgentType
// Optional custom command (overrides agent default)
Command string
// Optional additional args
Args []string
// Timeout for AI response (default 30 seconds)
Timeout time.Duration
// --- API Mode Configuration ---
// UseAPI forces API mode (default: true for audit summarization)
UseAPI bool
// LLMProvider specifies which provider to use (auto-detected if empty)
LLMProvider aichannel.LLMProvider
// APIKey overrides environment variable lookup
APIKey string
// Model overrides the provider's default model
Model string
}
AuditSummarizerConfig configures the audit summarizer.
type BashRunner ¶
BashRunner is an interface for running bash commands via the daemon.
type BrowserSession ¶
type BrowserSession struct {
ProxyID string
SessionID string
URL string
Interactions int
Mutations int
LastActivity time.Time
}
BrowserSession holds information about a connected browser.
type Config ¶
type Config struct {
// Hotkey to toggle overlay (default: Ctrl+L = 0x0C)
Hotkey byte
// Whether to show indicator bar by default
ShowIndicator bool
// Status refresh interval
StatusRefreshInterval time.Duration
// Version string to display in dashboard
Version string
// Action callback
OnAction func(Action) error
// Freeze/unfreeze callbacks for screen management
OnFreeze func() // Called when menu opens (freeze PTY output)
OnUnfreeze func() // Called when menu closes (send SIGWINCH to redraw)
}
Config holds overlay configuration.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns the default overlay configuration.
type ConnectionStatus ¶
type ConnectionStatus int
ConnectionStatus represents daemon connection state.
const ( ConnectionUnknown ConnectionStatus = iota ConnectionConnected ConnectionDisconnected ConnectionError )
type DaemonBashRunner ¶
type DaemonBashRunner struct {
// contains filtered or unexported fields
}
DaemonBashRunner implements BashRunner using a shared daemon connection.
func NewDaemonBashRunner ¶
func NewDaemonBashRunner(conn *daemon.Conn) *DaemonBashRunner
NewDaemonBashRunner creates a new DaemonBashRunner using a shared connection.
func (*DaemonBashRunner) RunBashCommand ¶
func (r *DaemonBashRunner) RunBashCommand(command string) (string, error)
RunBashCommand runs a bash command via the daemon and returns the process ID.
type DaemonConnector ¶
type DaemonConnector interface {
// Connect attempts to connect to the daemon, auto-starting it if needed.
// Returns nil on success, or an error describing why the connection failed.
Connect() error
// IsConnected returns true if currently connected to the daemon.
IsConnected() bool
}
DaemonConnector is an interface for connecting to and managing the daemon.
type DaemonConnectorImpl ¶
type DaemonConnectorImpl struct {
// contains filtered or unexported fields
}
DaemonConnectorImpl implements DaemonConnector using a shared connection.
func NewDaemonConnector ¶
func NewDaemonConnector(conn *daemon.Conn) *DaemonConnectorImpl
NewDaemonConnector creates a new DaemonConnector using a shared connection.
func (*DaemonConnectorImpl) Connect ¶
func (c *DaemonConnectorImpl) Connect() error
Connect attempts to connect to the daemon, auto-starting it if needed.
func (*DaemonConnectorImpl) IsConnected ¶
func (c *DaemonConnectorImpl) IsConnected() bool
IsConnected returns true if currently connected to the daemon.
type DaemonOutputFetcher ¶
type DaemonOutputFetcher struct {
// contains filtered or unexported fields
}
DaemonOutputFetcher implements ProcessOutputFetcher using a shared daemon connection.
func NewDaemonOutputFetcher ¶
func NewDaemonOutputFetcher(conn *daemon.Conn) *DaemonOutputFetcher
NewDaemonOutputFetcher creates a new DaemonOutputFetcher using a shared connection.
func (*DaemonOutputFetcher) GetProcessOutput ¶
func (f *DaemonOutputFetcher) GetProcessOutput(processID string, tailLines int) (string, error)
GetProcessOutput fetches the last N lines of output for a process.
func (*DaemonOutputFetcher) GetScriptOutput ¶ added in v0.12.16
func (f *DaemonOutputFetcher) GetScriptOutput(scriptName string, tailLines int) (string, error)
GetScriptOutput fetches the last N lines of output for a script by name.
type ErrorInfo ¶
type ErrorInfo struct {
Source string // "proxy", "process", "daemon"
Message string
Timestamp time.Time
}
ErrorInfo holds recent error information.
type EscapeSequenceReader ¶
type EscapeSequenceReader struct {
// contains filtered or unexported fields
}
EscapeSequenceReader helps parse escape sequences from input.
func NewEscapeSequenceReader ¶
func NewEscapeSequenceReader() *EscapeSequenceReader
NewEscapeSequenceReader creates a new escape sequence reader.
func (*EscapeSequenceReader) Feed ¶
func (r *EscapeSequenceReader) Feed(b byte) (key string, complete bool)
Feed feeds a byte into the reader and returns any recognized key.
func (*EscapeSequenceReader) IsPending ¶
func (r *EscapeSequenceReader) IsPending() bool
IsPending returns true if we're in the middle of parsing an escape sequence.
func (*EscapeSequenceReader) Reset ¶
func (r *EscapeSequenceReader) Reset()
Reset resets the reader state.
func (*EscapeSequenceReader) Timeout ¶
func (r *EscapeSequenceReader) Timeout() (key string, hadPending bool)
Timeout should be called when no more input arrives after starting an escape sequence. This allows treating a lone Escape key press as "Escape".
type FilterConfig ¶
type FilterConfig struct {
// ProtectBottomRows is the number of rows to protect at the bottom.
// Scroll region will be set to exclude these rows.
ProtectBottomRows int
// AggressiveMode enables full cursor clamping, manual scroll, and alt screen
// blocking. Required for terminals where DECSTBM is unreliable (ConPTY).
// When false (default), only scroll region enforcement and DA1 suppression
// are active — cursor positioning passes through unchanged.
// Use NeedsAggressiveMode() to detect automatically.
AggressiveMode bool
// RedrawInterval is how often to check if indicator needs redrawing.
// Set to 0 to disable periodic redraw.
RedrawInterval time.Duration
// OnRedraw is called when the indicator should be redrawn.
OnRedraw func()
}
FilterConfig configures the PTY output filter behavior.
type InputRouter ¶
type InputRouter struct {
// contains filtered or unexported fields
}
InputRouter routes input between the PTY and the overlay.
func NewInputRouter ¶
func NewInputRouter(ptmx PtyReadWriter, overlay *Overlay, hotkey byte) *InputRouter
NewInputRouter creates a new InputRouter.
func (*InputRouter) GetLastDaemonError ¶
func (r *InputRouter) GetLastDaemonError() string
GetLastDaemonError returns the last error from daemon connection attempt.
func (*InputRouter) Run ¶
func (r *InputRouter) Run() error
Run starts routing input from stdin to either the overlay or PTY. This blocks until stdin is closed or Stop is called.
func (*InputRouter) SetBashRunner ¶
func (r *InputRouter) SetBashRunner(runner BashRunner)
SetBashRunner sets the bash runner for executing bash commands via the daemon.
func (*InputRouter) SetDaemonConnector ¶
func (r *InputRouter) SetDaemonConnector(connector DaemonConnector)
SetDaemonConnector sets the daemon connector for connecting to the daemon.
func (*InputRouter) SetOutputFetcher ¶
func (r *InputRouter) SetOutputFetcher(fetcher ProcessOutputFetcher)
SetOutputFetcher sets the output fetcher for viewing process output.
func (*InputRouter) SetStatusFetcher ¶
func (r *InputRouter) SetStatusFetcher(fetcher *StatusFetcher)
SetStatusFetcher sets the status fetcher for refreshing after connection.
func (*InputRouter) SetSummarizer ¶
func (r *InputRouter) SetSummarizer(summarizer StatusSummarizer)
SetSummarizer sets the summarizer for generating AI summaries.
type Menu ¶
Menu represents a popup menu.
func DisconnectedMenu ¶
func DisconnectedMenu() Menu
DisconnectedMenu returns a menu for when the daemon is not connected.
func ProcessListMenu ¶
func ProcessListMenu(processes []ProcessInfo) Menu
ProcessListMenu creates a menu showing running processes.
func ProxyListMenu ¶
ProxyListMenu creates a menu showing running proxies.
func ScriptMenu ¶
ScriptMenu creates a menu of available scripts.
type MenuItem ¶
type MenuItem struct {
Label string
Shortcut rune // Single character shortcut (0 for none)
Action Action // Action to trigger
SubMenu *Menu // Sub-menu (nil if none)
}
MenuItem represents a single menu item.
type OutputGate ¶
type OutputGate struct {
// contains filtered or unexported fields
}
OutputGate wraps a writer and can freeze/unfreeze output. When frozen, all writes are discarded. When unfrozen, writes pass through. This is used to prevent PTY output from corrupting the overlay menu.
func NewOutputGate ¶
func NewOutputGate(out io.Writer) *OutputGate
NewOutputGate creates a new OutputGate.
func (*OutputGate) Freeze ¶
func (og *OutputGate) Freeze()
Freeze stops writing to the underlying writer (discards writes). Calls onFreeze callback if set and not already frozen. The callback runs after the lock is released to prevent deadlock when the callback writes to this gate.
func (*OutputGate) IsFrozen ¶
func (og *OutputGate) IsFrozen() bool
IsFrozen returns whether the gate is currently frozen.
func (*OutputGate) SetCallbacks ¶
func (og *OutputGate) SetCallbacks(onFreeze, onUnfreeze func())
SetCallbacks sets the freeze/unfreeze callbacks.
func (*OutputGate) Unfreeze ¶
func (og *OutputGate) Unfreeze()
Unfreeze resumes writing to the underlying writer. Calls onUnfreeze callback if set and was frozen. The callback runs after the lock is released to prevent deadlock when the callback writes to this gate (e.g. EnforceScrollRegion).
func (*OutputGate) Write ¶
func (og *OutputGate) Write(p []byte) (n int, err error)
Write writes to the underlying writer if not frozen. When frozen, writes are discarded but return success.
func (*OutputGate) WriteDirect ¶ added in v0.12.11
func (og *OutputGate) WriteDirect(p []byte) (n int, err error)
WriteDirect writes to the underlying writer regardless of freeze state, while holding the gate's mutex. This is used by the overlay renderer to write indicator/menu content without interleaving with PTY output.
type Overlay ¶
type Overlay struct {
// contains filtered or unexported fields
}
Overlay manages the terminal overlay display.
func New ¶
func New(ptmx PtyReadWriter, width, height int, cfg Config) *Overlay
New creates a new Overlay.
func (*Overlay) DrawStatusBarMessage ¶ added in v0.7.8
DrawStatusBarMessage draws a message on the status bar. This is used for transient messages like spinner updates. Note: The caller should call Redraw() or DrawIndicator() when done to restore the normal status bar.
func (*Overlay) RedrawIndicator ¶ added in v0.7.8
func (o *Overlay) RedrawIndicator()
RedrawIndicator redraws just the status bar indicator with current status.
func (*Overlay) SetAltScreenChecker ¶ added in v0.12.0
SetAltScreenChecker sets a callback that reports whether the child process is currently in the alternate screen buffer. Used to decide whether the overlay can safely use alt screen for menus (only when child is on main screen).
func (*Overlay) SetGate ¶
func (o *Overlay) SetGate(gate *OutputGate)
SetGate sets the output gate for freeze/unfreeze control.
func (*Overlay) SetRedrawPaused ¶ added in v0.12.0
SetRedrawPaused pauses or resumes indicator redraws. Status updates are still stored — just not rendered until unpaused.
func (*Overlay) ShowIndicator ¶
ShowIndicator returns whether the indicator bar is visible.
func (*Overlay) ToggleIndicator ¶
func (o *Overlay) ToggleIndicator()
ToggleIndicator toggles the indicator bar visibility.
func (*Overlay) UpdateStatus ¶
UpdateStatus updates the displayed status.
type OverlayStack ¶
type OverlayStack struct {
// contains filtered or unexported fields
}
OverlayStack manages a stack of overlays for proper z-order handling.
func NewOverlayStack ¶
func NewOverlayStack(sm *ScreenManager) *OverlayStack
NewOverlayStack creates a new overlay stack.
func (*OverlayStack) Clear ¶
func (os *OverlayStack) Clear()
Clear removes all overlays from the stack without clearing screen regions. Use this when relying on another mechanism (like SIGWINCH) to redraw.
func (*OverlayStack) Depth ¶
func (os *OverlayStack) Depth() int
Depth returns the number of overlays on the stack.
func (*OverlayStack) PopAll ¶
func (os *OverlayStack) PopAll()
PopAll removes and restores all overlays.
func (*OverlayStack) Push ¶
func (os *OverlayStack) Push(name string, region ScreenRegion)
Push adds an overlay to the stack.
type PanelItem ¶ added in v0.12.7
type PanelItem struct {
Type string // "overview", "process", "proxy"
ID string // process or proxy ID
Label string // short display label for tab bar
Content string // cached output content (accumulates across restarts)
ScrollOffset int // lines scrolled up from bottom (0 = pinned to bottom)
ProcessState string // last known process state ("running", "failed", "stopped", "")
// contains filtered or unexported fields
}
PanelItem represents a navigable panel in the horizontal panel view. Process panels persist until explicitly closed by the user.
func (*PanelItem) AppendContent ¶ added in v0.12.15
AppendContent appends text to the panel content with a separator and caps at maxLines.
func (*PanelItem) ContentLines ¶ added in v0.12.15
ContentLines returns the cached number of lines in the panel's content.
func (*PanelItem) IsDone ¶ added in v0.12.15
IsDone returns true if the process has stopped and the panel can be closed.
func (*PanelItem) SetContent ¶ added in v0.12.15
SetContent replaces the panel content and updates the cached line count.
type ProcessInfo ¶
type ProcessInfo struct {
ID string
Command string
State string
Runtime time.Duration
LastOutput string // Last line of output (trimmed)
URLs []string // URLs parsed from recent output
LinkedProxyID string // ID of proxy targeting this process (if any)
HasAlerts bool // Whether process has recent alerts/errors
}
ProcessInfo holds information about a running process.
type ProcessOutputFetcher ¶
type ProcessOutputFetcher interface {
// GetProcessOutput fetches the last N lines of output for a process.
GetProcessOutput(processID string, tailLines int) (string, error)
// GetScriptOutput fetches the last N lines of output for a script by name.
GetScriptOutput(scriptName string, tailLines int) (string, error)
}
ProcessOutputFetcher is an interface for fetching process output from the daemon.
type ProcessSummary ¶
type ProcessSummary struct {
ID string
Command string
State string
HasErrors bool
Output string // Last N lines
}
ProcessSummary contains summarized info about a process.
type ProtectedWriter ¶
type ProtectedWriter struct {
// contains filtered or unexported fields
}
ProtectedWriter filters PTY output to protect the status bar area. It intercepts ANSI sequences that could affect the protected region.
func NewProtectedWriter ¶
func NewProtectedWriter(out io.Writer, width, height int, config FilterConfig) *ProtectedWriter
NewProtectedWriter creates a new PTY output filter.
func (*ProtectedWriter) EnforceScrollRegion ¶
func (pw *ProtectedWriter) EnforceScrollRegion()
EnforceScrollRegion can be called externally to re-apply scroll region protection.
func (*ProtectedWriter) InAltScreen ¶ added in v0.12.0
func (pw *ProtectedWriter) InAltScreen() bool
InAltScreen returns whether the child process is currently in the alternate screen buffer.
func (*ProtectedWriter) RequestRedraw ¶
func (pw *ProtectedWriter) RequestRedraw()
RequestRedraw marks that a redraw is needed.
func (*ProtectedWriter) SetSize ¶
func (pw *ProtectedWriter) SetSize(width, height int)
SetSize updates the terminal dimensions.
func (*ProtectedWriter) Stop ¶
func (pw *ProtectedWriter) Stop()
Stop stops the periodic redraw goroutine.
type ProxyInfo ¶
type ProxyInfo struct {
ID string
TargetURL string
ListenAddr string
HasErrors bool
ErrorCount int
TunnelURL string
TunnelRunning bool
LinkedProcessID string // ID of process this proxy targets (if any)
TailscaleURL string // Tailscale DNS URL if available (e.g., http://machine.tailnet.ts.net:port)
}
ProxyInfo holds information about a running proxy.
type ProxySummary ¶
type ProxySummary struct {
ID string
TargetURL string
ListenAddr string
ErrorCount int
PageCount int
RecentLogs string // Recent log entries (errors, panel messages, etc.)
}
ProxySummary contains summarized info about a proxy.
type PtyReadWriter ¶ added in v0.6.3
PtyReadWriter is an interface for interacting with a PTY. This allows both Unix PTY (*os.File) and Windows ConPTY to be used.
type Renderer ¶
type Renderer struct {
// contains filtered or unexported fields
}
Renderer handles drawing to the terminal.
func NewRenderer ¶
NewRenderer creates a new Renderer.
func (*Renderer) ClearCurrentMenu ¶ added in v0.7.8
func (r *Renderer) ClearCurrentMenu()
ClearCurrentMenu clears the current menu from screen and resets the region. Use this before transitioning to a different menu type (e.g., Dashboard to submenu).
func (*Renderer) ClearIndicator ¶
func (r *Renderer) ClearIndicator()
ClearIndicator clears the indicator bar.
func (*Renderer) ClearMenu ¶
func (r *Renderer) ClearMenu()
ClearMenu clears all overlay regions (menu and input dialogs). This restores the screen by clearing the tracked regions.
func (*Renderer) ClearScreen ¶
func (r *Renderer) ClearScreen()
ClearScreen clears the entire screen and resets cursor to home.
func (*Renderer) ClearStatusBarMessage ¶ added in v0.7.8
func (r *Renderer) ClearStatusBarMessage()
ClearStatusBarMessage clears any message on the status bar. After clearing, the regular indicator should be redrawn.
func (*Renderer) ClearVisible ¶ added in v0.12.0
func (r *Renderer) ClearVisible()
ClearVisible clears the visible screen and moves cursor home. Unlike ClearScreen, this preserves the scroll region.
func (*Renderer) DrawDashboard ¶
DrawDashboard draws a niri-style dashboard with centered panels. Panels are stacked vertically in the center with rounded corners, gradient borders, and gaps between them (inspired by niri window manager).
func (*Renderer) DrawIndicator ¶
DrawIndicator draws the status indicator bar at the bottom of the screen.
func (*Renderer) DrawMenuWithProcesses ¶
func (r *Renderer) DrawMenuWithProcesses(menu Menu, selectedIndex int, processes []ProcessInfo)
DrawMenuWithProcesses draws a popup menu with a process list below it. Deprecated: Use DrawDashboard for a more comprehensive view.
func (*Renderer) DrawPanelView ¶ added in v0.12.7
DrawPanelView draws a full-screen panel view with a niri-style tab bar at top. Panels are arranged horizontally like niri columns: Ctrl+Left/Right to navigate.
func (*Renderer) DrawProcessOutput ¶
DrawProcessOutput draws the process output viewer on the alt screen using niri-style panel with rounded corners and gradient border.
func (*Renderer) DrawStatusBarMessage ¶ added in v0.7.8
DrawStatusBarMessage draws a message on the status bar at the bottom of the screen. Use this for transient status updates like spinners.
func (*Renderer) EnterAltScreen ¶
func (r *Renderer) EnterAltScreen()
EnterAltScreen switches to the alternate screen buffer. The main screen content is preserved and restored when ExitAltScreen is called.
func (*Renderer) ExitAltScreen ¶
func (r *Renderer) ExitAltScreen()
ExitAltScreen switches back to the main screen buffer. The main screen content that was preserved when EnterAltScreen was called is restored.
func (*Renderer) ResetMenuRegions ¶
func (r *Renderer) ResetMenuRegions()
ResetMenuRegions resets the tracked menu regions without clearing screen content. Use this when relying on SIGWINCH to trigger a full redraw by the child process.
func (*Renderer) SetOutput ¶ added in v0.12.11
SetOutput changes the writer used for rendering. This is used to route output through a synchronized writer (e.g. OutputGate.WriteDirect) to prevent interleaving with PTY output on the same stdout.
func (*Renderer) SetVersion ¶ added in v0.11.3
SetVersion sets the version displayed in the dashboard title.
type ScreenBuffer ¶
type ScreenBuffer struct {
Region ScreenRegion
Content [][]rune // [row][col] - stored content
Styles [][]string // [row][col] - ANSI style codes (if we track them)
}
ScreenBuffer stores saved screen content for restoration.
type ScreenManager ¶
type ScreenManager struct {
// contains filtered or unexported fields
}
ScreenManager handles saving and restoring screen regions. It uses ANSI escape sequences to query and restore terminal content.
func NewScreenManager ¶
func NewScreenManager(out io.Writer, width, height int) *ScreenManager
NewScreenManager creates a new ScreenManager.
func (*ScreenManager) ClearRegion ¶
func (sm *ScreenManager) ClearRegion(region ScreenRegion)
ClearRegion clears a rectangular region without saving.
func (*ScreenManager) DrawOverlay ¶
func (sm *ScreenManager) DrawOverlay(name string, row, col, width, height int, drawFunc func(row, col, width, height int)) ScreenRegion
DrawOverlay draws content at a specific region and tracks it for later clearing. Returns the region for use with RestoreRegion.
func (*ScreenManager) ForceRedraw ¶
func (sm *ScreenManager) ForceRedraw()
ForceRedraw sends a signal to force the underlying application to redraw. This works by simulating a resize event (SIGWINCH).
func (*ScreenManager) RestoreRegion ¶
func (sm *ScreenManager) RestoreRegion(name string)
RestoreRegion restores a previously saved region by overwriting with spaces. This visually clears the region. The underlying application will redraw when it receives SIGWINCH.
func (*ScreenManager) SaveRegion ¶
func (sm *ScreenManager) SaveRegion(name string, region ScreenRegion)
SaveRegion saves the screen content in a region. Since we can't actually read terminal content, we use the alternate screen buffer approach - save cursor, draw overlay, restore when done.
For terminals that don't support reading content, we'll use a different strategy: We'll track what we've drawn and clear it properly.
func (*ScreenManager) SetOutput ¶ added in v0.12.11
func (sm *ScreenManager) SetOutput(out io.Writer)
SetOutput changes the writer used for screen output.
func (*ScreenManager) SetSize ¶
func (sm *ScreenManager) SetSize(width, height int)
SetSize updates the terminal dimensions.
type ScreenRegion ¶
type ScreenRegion struct {
Row int // 1-indexed top row
Col int // 1-indexed left column
Width int
Height int
}
ScreenRegion represents a rectangular region of the terminal screen.
type ScriptInfo ¶ added in v0.12.16
type ScriptInfo struct {
Name string // Script name (e.g., "dev")
ProcessID string // Current process ID (empty if idle)
State string // "idle", "starting", "running", "failed", "stopped", "restarting"
Command string
StartCount int64
FailCount int64
LastError string
}
ScriptInfo holds information about a managed script from the ScriptRegistry. Scripts persist across process lifetimes, so their state is always available.
type StartupLogEntry ¶ added in v0.12.15
type StartupLogEntry struct {
ScriptName string
Level string // "info", "warning", "error"
EventType string
Message string
Timestamp time.Time
}
StartupLogEntry holds a startup log entry for display.
type Status ¶
type Status struct {
DaemonConnected ConnectionStatus
DaemonPingMs int64
Processes []ProcessInfo
Scripts []ScriptInfo
Proxies []ProxyInfo
BrowserSessions []BrowserSession
RecentErrors []ErrorInfo
StartupLog []StartupLogEntry
LastUpdate time.Time
}
Status holds the current system status for display.
type StatusFetcher ¶
type StatusFetcher struct {
// contains filtered or unexported fields
}
StatusFetcher fetches status from the daemon periodically. It uses a shared daemon.Conn for all requests. By default, it only fetches processes/proxies from the current project directory.
func NewStatusFetcher ¶
NewStatusFetcher creates a new StatusFetcher using a shared connection. It automatically detects the current working directory for scoping.
func (*StatusFetcher) Refresh ¶
func (f *StatusFetcher) Refresh()
Refresh triggers an immediate status refresh.
func (*StatusFetcher) Start ¶
func (f *StatusFetcher) Start(ctx context.Context)
Start starts the status fetcher.
type StatusSummarizer ¶
type StatusSummarizer interface {
// Summarize aggregates all system data and generates a summary.
Summarize(ctx context.Context) (*SummaryResult, error)
// IsAvailable returns true if the AI channel is available.
IsAvailable() bool
}
StatusSummarizer is an interface for summarizing system status.
type Summarizer ¶
type Summarizer struct {
// contains filtered or unexported fields
}
Summarizer aggregates system status and uses an AI channel to generate summaries. It uses a shared daemon.Conn for all requests.
func NewSummarizer ¶
func NewSummarizer(conn *daemon.Conn, config SummarizerConfig) *Summarizer
NewSummarizer creates a new Summarizer using a shared connection. For Claude agent, uses CLI mode (required for Claude Code Max plan). For all other agents, automatically uses Anthropic API mode as a fallback since those CLIs may not be available or may require their own subscriptions.
func (*Summarizer) AgentType ¶
func (s *Summarizer) AgentType() aichannel.AgentType
AgentType returns the configured agent type.
func (*Summarizer) IsAvailable ¶
func (s *Summarizer) IsAvailable() bool
IsAvailable returns true if the AI channel is available.
func (*Summarizer) Summarize ¶
func (s *Summarizer) Summarize(ctx context.Context) (*SummaryResult, error)
Summarize aggregates all system data and generates a summary.
type SummarizerConfig ¶
type SummarizerConfig struct {
// Agent type for AI summarization
Agent aichannel.AgentType
// Optional custom command (overrides agent default)
Command string
// Optional additional args
Args []string
// Timeout for AI response (default 2 minutes)
Timeout time.Duration
// DebugOutput is where debug messages are written (defaults to os.Stderr)
DebugOutput io.Writer
// ProjectPath is the current project directory for filtering processes/proxies
ProjectPath string
// --- API Mode Configuration ---
// UseAPI forces API mode. For non-Claude agents, API mode is enabled automatically
// since Claude Code Max plan only supports CLI, while other providers need API keys.
// Set to true to force API mode even for Claude agent.
UseAPI bool
// LLMProvider specifies which provider to use (auto-detected if empty)
LLMProvider aichannel.LLMProvider
// APIKey overrides environment variable lookup
APIKey string
// Model overrides the provider's default model
Model string
}
SummarizerConfig configures the Summarizer.
type SummaryResult ¶
type SummaryResult struct {
Summary string
ProcessData []ProcessSummary
ProxyData []ProxySummary
ErrorCount int
Duration time.Duration
}
SummaryResult contains the result of a summarization.