Documentation
¶
Index ¶
- Constants
- func CleanupOrphanedLogs() (removed int, freedBytes int64, err error)
- func DetectTerminal() string
- func IsTmuxAvailable() error
- func LogDir() string
- func RefreshExistingSessions()
- func RefreshSessionCache()
- func RotateLog(sessionName string, maxSize int64) error
- func RunLogMaintenance(maxSizeMB int, maxLines int, removeOrphans bool)
- func StripANSI(content string) string
- func SupportsHyperlinks() bool
- func TruncateLargeLogFiles(maxSizeMB int, maxLines int) (truncated int, err error)
- func TruncateLogFile(logPath string, maxLines int) error
- type LogWatcher
- type PromptDetector
- type Session
- func DiscoverAllTmuxSessions() ([]*Session, error)
- func ListAllSessions() ([]*Session, error)
- func NewSession(name, workDir string) *Session
- func ReconnectSession(tmuxName, displayName, workDir, command string) *Session
- func ReconnectSessionWithStatus(tmuxName, displayName, workDir, command string, previousStatus string) *Session
- func (s *Session) Acknowledge()
- func (s *Session) AcknowledgeWithSnapshot()
- func (s *Session) Attach(ctx context.Context) error
- func (s *Session) AttachReadOnly(ctx context.Context) error
- func (s *Session) CaptureFullHistory() (string, error)
- func (s *Session) CapturePane() (string, error)
- func (s *Session) ConfigureStatusBar()
- func (s *Session) DetectTool() string
- func (s *Session) DisablePipePane() error
- func (s *Session) EnableMouseMode() error
- func (s *Session) EnablePipePane() error
- func (s *Session) Exists() bool
- func (s *Session) ForceDetectTool() string
- func (s *Session) GetEnvironment(key string) (string, error)
- func (s *Session) GetLastActivityTime() time.Time
- func (s *Session) GetStatus() (string, error)
- func (s *Session) GetWindowActivity() (int64, error)
- func (s *Session) GetWorkDir() string
- func (s *Session) HasUpdated() (bool, error)
- func (s *Session) IsClaudeRunning() bool
- func (s *Session) Kill() error
- func (s *Session) LogFile() string
- func (s *Session) ResetAcknowledged()
- func (s *Session) Resize(cols, rows int) error
- func (s *Session) RespawnPane(command string) error
- func (s *Session) SendCommand(command string) error
- func (s *Session) SendCtrlC() error
- func (s *Session) SendCtrlU() error
- func (s *Session) SendEnter() error
- func (s *Session) SendKeys(keys string) error
- func (s *Session) SetEnvironment(key, value string) error
- func (s *Session) SignalFileActivity()
- func (s *Session) Start(command string) error
- func (s *Session) StreamOutput(ctx context.Context, w io.Writer) error
- func (s *Session) WaitForReady(timeout time.Duration) bool
- func (s *Session) WaitForShellPrompt(timeout time.Duration) bool
- type SessionState
- type StateTracker
- type TerminalInfo
Constants ¶
const SessionPrefix = "agentdeck_"
Variables ¶
This section is empty.
Functions ¶
func CleanupOrphanedLogs ¶ added in v0.5.3
CleanupOrphanedLogs removes log files for sessions that no longer exist A log is considered orphaned if: 1. No tmux session with matching name exists 2. The log file is older than 1 hour (to avoid race conditions during session creation)
func DetectTerminal ¶ added in v0.3.0
func DetectTerminal() string
DetectTerminal identifies the current terminal emulator from environment variables Returns terminal name: "warp", "iterm2", "kitty", "alacritty", "vscode", "windows-terminal", or "unknown"
func IsTmuxAvailable ¶
func IsTmuxAvailable() error
IsTmuxAvailable checks if tmux is installed and accessible Returns nil if tmux is available, otherwise returns an error with details
func LogDir ¶ added in v0.3.0
func LogDir() string
LogDir returns the directory containing all session logs
func RefreshExistingSessions ¶ added in v0.6.0
func RefreshExistingSessions()
RefreshExistingSessions is an alias for RefreshSessionCache for backwards compatibility
func RefreshSessionCache ¶ added in v0.6.0
func RefreshSessionCache()
RefreshSessionCache updates the cache of existing tmux sessions and their activity Call this ONCE per tick, then use Session.Exists() and Session.GetWindowActivity() which read from cache. This reduces 30+ subprocess spawns to just 1 per tick cycle.
func RunLogMaintenance ¶ added in v0.5.3
RunLogMaintenance performs all log maintenance tasks based on settings This should be called once at startup and optionally periodically
func StripANSI ¶
StripANSI removes ANSI escape codes from content This is important because terminal output contains color codes
func SupportsHyperlinks ¶ added in v0.3.0
func SupportsHyperlinks() bool
SupportsHyperlinks returns true if the current terminal supports OSC 8 hyperlinks
func TruncateLargeLogFiles ¶ added in v0.5.3
TruncateLargeLogFiles checks all log files and truncates any that exceed maxSizeMB
func TruncateLogFile ¶ added in v0.5.3
TruncateLogFile truncates a log file to keep only the last maxLines lines This is called when a log file exceeds maxSizeBytes
Types ¶
type LogWatcher ¶ added in v0.3.0
type LogWatcher struct {
// contains filtered or unexported fields
}
LogWatcher watches session log files for changes using fsnotify When a log file is modified, it triggers a callback with the session name
func NewLogWatcher ¶ added in v0.3.0
func NewLogWatcher(logDir string, callback func(sessionName string)) (*LogWatcher, error)
NewLogWatcher creates a new log file watcher callback is called with the session name when its log file changes
func (*LogWatcher) Close ¶ added in v0.3.0
func (lw *LogWatcher) Close() error
Close stops the watcher
func (*LogWatcher) Start ¶ added in v0.3.0
func (lw *LogWatcher) Start()
Start begins watching for file changes (blocking) Call this in a goroutine
type PromptDetector ¶
type PromptDetector struct {
// contains filtered or unexported fields
}
PromptDetector checks for tool-specific prompts in terminal content Based on Claude Squad's exact implementation: https://github.com/smtg-ai/claude-squad/blob/main/session/tmux/tmux.go
func NewPromptDetector ¶
func NewPromptDetector(tool string) *PromptDetector
NewPromptDetector creates a detector for the specified tool
func (*PromptDetector) HasPrompt ¶
func (d *PromptDetector) HasPrompt(content string) bool
HasPrompt checks if the terminal content contains a prompt waiting for input These patterns are derived from Claude Squad + additional research for edge cases
type Session ¶
type Session struct {
Name string
DisplayName string
WorkDir string
Command string
Created time.Time
// contains filtered or unexported fields
}
Session represents a tmux session NOTE: All mutable fields are protected by mu. The Bubble Tea event loop is single-threaded, but we use mutex protection for defensive programming and future-proofing.
func DiscoverAllTmuxSessions ¶
DiscoverAllTmuxSessions returns all tmux sessions (including non-Agent Deck ones)
func ListAllSessions ¶
ListAllSessions returns all Agent Deck tmux sessions
func NewSession ¶
NewSession creates a new Session instance with a unique name
func ReconnectSession ¶
ReconnectSession creates a Session object for an existing tmux session This is used when loading sessions from storage - it properly initializes all fields needed for status detection to work correctly
func ReconnectSessionWithStatus ¶
func ReconnectSessionWithStatus(tmuxName, displayName, workDir, command string, previousStatus string) *Session
ReconnectSessionWithStatus creates a Session with pre-initialized state based on previous status This restores the exact status state across app restarts:
- "idle" (gray): acknowledged=true, cooldown expired
- "waiting" (yellow): acknowledged=false, cooldown expired
- "active" (green): will be recalculated based on actual content changes
func (*Session) Acknowledge ¶
func (s *Session) Acknowledge()
Acknowledge marks the session as "seen" by the user Call this when user attaches to the session
func (*Session) AcknowledgeWithSnapshot ¶
func (s *Session) AcknowledgeWithSnapshot()
AcknowledgeWithSnapshot marks the session as seen and baselines the current content hash. Called when user detaches from session.
func (*Session) Attach ¶
Attach attaches to the tmux session with full PTY support Ctrl+Q will detach and return to the caller
func (*Session) AttachReadOnly ¶
AttachReadOnly attaches to the session in read-only mode
func (*Session) CaptureFullHistory ¶
CaptureFullHistory captures the scrollback history (limited to last 2000 lines for performance)
func (*Session) CapturePane ¶
CapturePane captures the visible pane content
func (*Session) ConfigureStatusBar ¶ added in v0.3.0
func (s *Session) ConfigureStatusBar()
ConfigureStatusBar sets up the tmux status bar with session info Shows: session title on left, project folder on right Uses a compact, informative layout that helps developers know where they are
func (*Session) DetectTool ¶
DetectTool detects which AI coding tool is running in the session Uses caching to avoid re-detection on every call
func (*Session) DisablePipePane ¶ added in v0.3.0
DisablePipePane disables pipe-pane logging
func (*Session) EnableMouseMode ¶
EnableMouseMode enables mouse scrolling, clipboard integration, and optimal settings Safe to call multiple times - just sets the options again
Enables: - mouse on: Mouse wheel scrolling, text selection, pane resizing - set-clipboard on: OSC 52 clipboard integration (works with modern terminals) - allow-passthrough on: OSC 8 hyperlinks, advanced escape sequences (tmux 3.2+) - history-limit 10000: Large scrollback buffer for AI agent output - escape-time 10: Fast Vim/editor responsiveness (default 500ms is too slow)
Terminal compatibility: - Warp, iTerm2, kitty, Alacritty, WezTerm: Full support (hyperlinks, clipboard, true color) - Windows Terminal, VS Code: Full support - Apple Terminal.app: Limited (no hyperlinks or clipboard)
Note: With mouse mode on, hold Shift while selecting to use native terminal selection instead of tmux's selection (useful for copying to system clipboard in some terminals)
func (*Session) EnablePipePane ¶ added in v0.3.0
EnablePipePane enables tmux pipe-pane to stream output to a log file This is used for event-driven status detection via fsnotify
func (*Session) Exists ¶
Exists checks if the tmux session exists Uses cached session list when available (refreshed by RefreshExistingSessions) Falls back to direct tmux call if cache is stale
func (*Session) ForceDetectTool ¶
ForceDetectTool forces a re-detection of the tool, ignoring cache
func (*Session) GetEnvironment ¶ added in v0.5.0
GetEnvironment gets an environment variable from this tmux session Returns the value or error if not found
func (*Session) GetLastActivityTime ¶ added in v0.5.6
GetLastActivityTime returns when the session content last changed Returns zero time if no activity has been tracked
func (*Session) GetStatus ¶
GetStatus returns the current status of the session
Activity-based 3-state model with spike filtering:
GREEN (active) = Sustained activity (2+ changes in 1s) within cooldown YELLOW (waiting) = Cooldown expired, NOT acknowledged (needs attention) GRAY (idle) = Cooldown expired, acknowledged (user has seen it)
Key insight: Status bar updates cause single timestamp changes (spikes). Real AI work causes multiple timestamp changes over 1 second (sustained). This filters spikes to prevent false GREEN flashes.
Logic: 1. Check busy indicator (immediate GREEN if present) 2. Get activity timestamp (fast ~4ms) 3. If timestamp changed → check if sustained or spike
- Sustained (1+ more changes in 1s) → GREEN
- Spike (no more changes) → filtered (no state change)
4. Check cooldown → GREEN if within 5. Cooldown expired → YELLOW or GRAY based on acknowledged
func (*Session) GetWindowActivity ¶ added in v0.3.0
GetWindowActivity returns Unix timestamp of last tmux window activity Uses cached data when available (refreshed by RefreshSessionCache) Falls back to direct tmux call if cache is stale
func (*Session) GetWorkDir ¶
GetWorkDir returns the current working directory of the tmux pane This is the live directory from the pane, not the initial WorkDir
func (*Session) HasUpdated ¶
HasUpdated checks if the pane content has changed since last check
func (*Session) IsClaudeRunning ¶ added in v0.5.3
IsClaudeRunning checks if Claude appears to be running in the session Returns true if Claude indicators are found
func (*Session) LogFile ¶ added in v0.3.0
LogFile returns the path to this session's pipe-pane log file Logs are stored in ~/.agent-deck/logs/<session-name>.log
func (*Session) ResetAcknowledged ¶
func (s *Session) ResetAcknowledged()
ResetAcknowledged marks the session as needing attention Call this when a hook event indicates the agent finished (Stop, AfterAgent) This ensures the session shows yellow (waiting) instead of gray (idle)
func (*Session) RespawnPane ¶ added in v0.5.4
RespawnPane kills the current process in the pane and starts a new command This is more reliable than sending Ctrl+C and waiting for shell prompt The -k flag kills the current process before respawning
func (*Session) SendCommand ¶ added in v0.5.1
SendCommand sends a command to the tmux session and presses Enter
func (*Session) SendCtrlC ¶ added in v0.5.1
SendCtrlC sends Ctrl+C (interrupt signal) to the tmux session
func (*Session) SendKeys ¶
SendKeys sends keys to the tmux session Uses -l flag to treat keys as literal text, preventing tmux special key interpretation
func (*Session) SetEnvironment ¶ added in v0.5.0
SetEnvironment sets an environment variable for this tmux session
func (*Session) SignalFileActivity ¶ added in v0.3.0
func (s *Session) SignalFileActivity()
SignalFileActivity signals that file output was detected (from LogWatcher) This directly triggers GREEN status by updating the cooldown timer Call this when pipe-pane log file is written to
func (*Session) StreamOutput ¶
StreamOutput streams the session output to the provided writer
func (*Session) WaitForReady ¶ added in v0.7.0
WaitForReady polls the terminal until the agent is ready for input Ready state = NO busy indicator AND prompt visible This works for Claude ("> "), Gemini, and other agents
type SessionState ¶
type SessionState string
SessionState represents the detected state of a session
const ( StateIdle SessionState = "idle" // No activity, waiting for user StateBusy SessionState = "busy" // Actively working (output changing) StateWaiting SessionState = "waiting" // Showing a prompt, needs input )
type StateTracker ¶
type StateTracker struct {
// contains filtered or unexported fields
}
StateTracker tracks content changes for notification-style status detection
StateTracker implements a simple 3-state model:
GREEN (active) = Content changed within 2 seconds YELLOW (waiting) = Content stable, user hasn't seen it GRAY (idle) = Content stable, user has seen it
type TerminalInfo ¶ added in v0.3.0
type TerminalInfo struct {
Name string // Terminal name (warp, iterm2, kitty, alacritty, etc.)
SupportsOSC8 bool // Supports OSC 8 hyperlinks
SupportsOSC52 bool // Supports OSC 52 clipboard
SupportsTrueColor bool // Supports 24-bit color
}
TerminalInfo contains detected terminal information
func GetTerminalInfo ¶ added in v0.3.0
func GetTerminalInfo() TerminalInfo
GetTerminalInfo returns detailed terminal capabilities