Bubble Tea TUI for tailing Claude Code subagent JSONL logs. Features: - Tabbed interface with one tab per agent, sorted by most recent activity - Markdown rendering via glamour (Dracula theme) - Session discovery and filtering with -s flag - Auto-discovers subagents dir from session ID prefix - Live tailing with follow mode, mouse scroll support - Agent name resolution from team config files - Tail-from-bottom: only reads last 200 lines per file on startup
77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
package main
|
|
|
|
import "github.com/charmbracelet/lipgloss"
|
|
|
|
// Agent color palette — each agent gets assigned the next color.
|
|
var agentColors = []lipgloss.Color{
|
|
lipgloss.Color("#61AFEF"), // blue
|
|
lipgloss.Color("#98C379"), // green
|
|
lipgloss.Color("#E5C07B"), // yellow
|
|
lipgloss.Color("#C678DD"), // magenta
|
|
lipgloss.Color("#56B6C2"), // cyan
|
|
lipgloss.Color("#E06C75"), // red
|
|
lipgloss.Color("#D19A66"), // orange
|
|
lipgloss.Color("#ABB2BF"), // gray
|
|
}
|
|
|
|
var (
|
|
// Dim text (timestamps, results, secondary info)
|
|
dimStyle = lipgloss.NewStyle().Faint(true)
|
|
|
|
// Bold text
|
|
boldStyle = lipgloss.NewStyle().Bold(true)
|
|
|
|
// Tab styles
|
|
activeTabStyle = lipgloss.NewStyle().
|
|
Bold(true).
|
|
Foreground(lipgloss.Color("#282C34")).
|
|
Background(lipgloss.Color("#61AFEF")).
|
|
Padding(0, 1)
|
|
|
|
inactiveTabStyle = lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("#ABB2BF")).
|
|
Padding(0, 1)
|
|
|
|
// Session bar
|
|
sessionBarStyle = lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("#E5C07B")).
|
|
Background(lipgloss.Color("#2C323C")).
|
|
Padding(0, 0)
|
|
|
|
// Status bar
|
|
statusBarStyle = lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("#ABB2BF")).
|
|
Background(lipgloss.Color("#3E4451")).
|
|
Padding(0, 1)
|
|
|
|
statusKeyStyle = lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("#E5C07B")).
|
|
Background(lipgloss.Color("#3E4451"))
|
|
|
|
// Tool use prefix (yellow)
|
|
toolStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#E5C07B"))
|
|
|
|
// Assistant text prefix (green)
|
|
textStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#98C379"))
|
|
|
|
// User/task prefix (blue)
|
|
taskStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#61AFEF"))
|
|
|
|
// Error style
|
|
errorStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#E06C75"))
|
|
|
|
// Follow mode indicator
|
|
followOnStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#98C379")).Bold(true)
|
|
followOffStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#E06C75"))
|
|
)
|
|
|
|
func agentStyle(colorIdx int) lipgloss.Style {
|
|
c := agentColors[colorIdx%len(agentColors)]
|
|
return lipgloss.NewStyle().Foreground(c).Bold(true)
|
|
}
|
|
|
|
func agentDimStyle(colorIdx int) lipgloss.Style {
|
|
c := agentColors[colorIdx%len(agentColors)]
|
|
return lipgloss.NewStyle().Foreground(c).Faint(true)
|
|
}
|