agent
import "github.com/thesimonho/warden/agent"Package agent defines interfaces and types for extracting status data from CLI agents running inside project containers. The abstraction allows supporting different agent backends (Claude Code, Aider, etc.) without coupling the dashboard to any single agent’s data format.
- Constants
- Variables
- func ShortLabel(agentType constants.AgentType) string
- func TruncateString(s string, maxLen int) string
- func VersionForType(agentType constants.AgentType) string
- func WorktreeIDFromCWD(cwd string) string
- type FormatPromptResult
- type ModelInfo
- type ParsedEvent
- type ParsedEventType
- type ProjectInfo
- type PromptSource
- type Registry
- func NewRegistry() *Registry
- func (r *Registry) Default() StatusProvider
- func (r *Registry) Get(agentType constants.AgentType) (StatusProvider, bool)
- func (r *Registry) Register(agentType constants.AgentType, provider StatusProvider)
- func (r *Registry) Resolve(agentType constants.AgentType) StatusProvider
- type SessionParser
- type SessionWatcher
- type Status
- type StatusProvider
- type TokenUsage
- type ValidationResult
Constants
Section titled “Constants”Type aliases for convenience — re-export from constants so existing callers (agent.ClaudeCode, agent.DefaultType, etc.) still work.
const ( ClaudeCode = constants.AgentClaudeCode Codex = constants.AgentCodex DefaultType = constants.DefaultAgentType)const ( // ClaudeCodeVersion is the pinned Claude Code CLI version. // Query latest: curl -sfL "https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases/latest" ClaudeCodeVersion = "2.1.92"
// CodexVersion is the pinned OpenAI Codex CLI version. // Query latest: npm view @openai/codex version CodexVersion = "0.118.0")MaxPromptLength is the maximum length of user prompt text included in events. Matches the truncation in container event scripts for consistency.
const MaxPromptLength = 500MaxToolInputLength is the maximum length of tool input included in events.
const MaxToolInputLength = 1000Variables
Section titled “Variables”AllTypes lists all supported agent type identifiers in display order.
var AllTypes = constants.AllAgentTypesDisplayLabels maps agent type identifiers to human-readable labels.
var DisplayLabels = map[constants.AgentType]string{ ClaudeCode: "Claude Code", Codex: "OpenAI Codex",}func ShortLabel
Section titled “func ShortLabel”func ShortLabel(agentType constants.AgentType) stringShortLabel returns a compact display label for the given agent type, falling back to the type string itself when no mapping exists.
func TruncateString
Section titled “func TruncateString”func TruncateString(s string, maxLen int) stringTruncateString caps a string at maxLen runes, appending ”…” if truncated. Uses rune count to avoid splitting multi-byte UTF-8 characters.
func VersionForType
Section titled “func VersionForType”func VersionForType(agentType constants.AgentType) stringVersionForType returns the pinned CLI version for the given agent type.
func WorktreeIDFromCWD
Section titled “func WorktreeIDFromCWD”func WorktreeIDFromCWD(cwd string) stringWorktreeIDFromCWD extracts the worktree ID from a container-side working directory. Returns “main” for the workspace root or unrecognized paths.
Patterns:
- .claude/worktrees/<id> → <id> (Claude Code native worktrees)
- .warden/worktrees/<id> → <id> (Warden-managed worktrees for Codex)
type FormatPromptResult
Section titled “type FormatPromptResult”FormatPromptResult holds the cleaned prompt text and its classified source.
type FormatPromptResult struct { Text string Source PromptSource}func FormatPromptText
Section titled “func FormatPromptText”func FormatPromptText(text string) FormatPromptResultFormatPromptText cleans up raw prompt text from agent session files and classifies the prompt source. Claude Code’s ! bash mode and /slash commands wrap content in XML-like tags that are not useful for audit display.
Returns empty Text for prompts that contain only stripped tags (e.g. local-command-caveat instructions). Source is classified as:
- “bash” for <bash-input> commands
- “bash_output” for <bash-stdout>/<bash-stderr> output
- “user” for plain text prompts
type ModelInfo
Section titled “type ModelInfo”ModelInfo identifies the model being used by the agent.
type ModelInfo struct { ID string DisplayName string}type ParsedEvent
Section titled “type ParsedEvent”ParsedEvent is an agent-agnostic event produced by parsing a session JSONL line. The parser converts agent-specific JSONL formats into these uniform events, which are then converted to [event.ContainerEvent] for SSE broadcast and audit logging.
type ParsedEvent struct { // Type identifies what kind of event this is. Type ParsedEventType
// SessionID is the agent's session identifier. SessionID string // Timestamp is when the event occurred (ISO 8601). Timestamp string
// Model is the AI model used (populated on assistant events). Model string // ToolName is the tool invoked (populated on ToolUse events). ToolName string // ToolInput is a summary of the tool input (populated on ToolUse events, truncated). ToolInput string // Prompt is the user's message text (populated on UserPrompt events). Prompt string // PromptSource classifies the origin of the prompt (populated on UserPrompt events). // Values: "user" (normal text), "bash" (! command), "bash_output" (! stdout/stderr). PromptSource PromptSource // ErrorContent is the error message (populated on ToolUseFailure and StopFailure events). ErrorContent string // ServerName is the MCP server name (populated on Elicitation events). ServerName string
// DurationMs is the turn duration in milliseconds (populated on TurnDuration events). DurationMs int64
// Tokens holds cumulative token usage (populated on TokenUpdate events). Tokens TokenUsage // EstimatedCostUSD is the estimated cost from tokens (populated on TokenUpdate events). EstimatedCostUSD float64
// GitBranch is the current git branch (populated on SessionStart). GitBranch string // WorktreeID is the worktree identifier (populated on SessionStart if available). WorktreeID string
// Subtype is the system message subtype (populated on SystemInfo events). Subtype string // Content is the message text (populated on SystemInfo, SubagentStop, PermissionGrant, ContextCompact events). Content string // Commands holds allowed commands (populated on PermissionGrant events). Commands []string // TTFTMs is time to first token in milliseconds (populated on ApiMetrics events). TTFTMs float64 // OutputTokensPerSec is output tokens per second (populated on ApiMetrics events). OutputTokensPerSec float64 // CompactTrigger is what triggered context compaction (populated on ContextCompact events). CompactTrigger string // PreCompactTokens is the token count before compaction (populated on ContextCompact events). PreCompactTokens int64
// SourceLine is the raw JSONL line bytes that produced this event. // Used to compute a content hash for deduplication in the audit DB. // Set by the session watcher; empty for hook-sourced events. SourceLine []byte // SourceIndex disambiguates multiple events parsed from the same JSONL line. SourceIndex int}func ParseAllEvents
Section titled “func ParseAllEvents”func ParseAllEvents(parser SessionParser, r io.Reader) ([]ParsedEvent, error)ParseAllEvents reads a JSONL stream line-by-line and returns all parsed events. Used by test helpers to collect events for detailed assertions.
type ParsedEventType
Section titled “type ParsedEventType”ParsedEventType is an alias for [event.ContainerEventType]. Parsers use the same constants as the event pipeline directly. The only exception is [event.EventTokenUpdate], which the session bridge remaps to [event.EventCostUpdate] before entering the store.
type ParsedEventType = event.ContainerEventTypetype ProjectInfo
Section titled “type ProjectInfo”ProjectInfo provides project metadata for session file discovery.
type ProjectInfo struct { // ProjectID is the deterministic 12-char hex project identifier. ProjectID string // AgentType identifies the agent (e.g. "claude-code", "codex"). AgentType string // WorkspaceDir is the container-side workspace directory. WorkspaceDir string // ProjectName is the user-chosen project name. ProjectName string}type PromptSource
Section titled “type PromptSource”PromptSource identifies the origin of a user prompt for display purposes.
type PromptSource stringconst ( // PromptSourceUser is a normal text prompt typed by the user. PromptSourceUser PromptSource = "user" // PromptSourceBash is a command run via Claude Code's ! bash mode. PromptSourceBash PromptSource = "bash" // PromptSourceBashOutput is stdout/stderr output from a ! bash command. PromptSourceBashOutput PromptSource = "bash_output")func (PromptSource) IsBash
Section titled “func (PromptSource) IsBash”func (s PromptSource) IsBash() boolIsBash returns true if the prompt originated from a ! bash command (either the command itself or its stdout/stderr output).
type Registry
Section titled “type Registry”Registry holds StatusProvider instances keyed by agent type. It allows the engine to resolve the correct provider for a container based on its WARDEN_AGENT_TYPE env var.
type Registry struct { // contains filtered or unexported fields}func NewRegistry
Section titled “func NewRegistry”func NewRegistry() *RegistryNewRegistry creates an empty agent registry.
func (*Registry) Default
Section titled “func (*Registry) Default”func (r *Registry) Default() StatusProviderDefault returns the StatusProvider for the default agent type (claude-code). Returns nil if the default provider is not registered.
func (*Registry) Get
Section titled “func (*Registry) Get”func (r *Registry) Get(agentType constants.AgentType) (StatusProvider, bool)Get returns the StatusProvider for the given agent type. Returns nil and false if no provider is registered for that type.
func (*Registry) Register
Section titled “func (*Registry) Register”func (r *Registry) Register(agentType constants.AgentType, provider StatusProvider)Register adds a StatusProvider for the given agent type.
func (*Registry) Resolve
Section titled “func (*Registry) Resolve”func (r *Registry) Resolve(agentType constants.AgentType) StatusProviderResolve returns the StatusProvider for the given agent type, falling back to the default provider if the type is empty or unregistered.
type SessionParser
Section titled “type SessionParser”SessionParser parses agent-specific JSONL session files into agent-agnostic ParsedEvents. Each agent implementation (Claude Code, Codex) provides its own parser that knows the JSONL schema.
Parsers are stateful — they accumulate token counts across lines within a session. Create a new parser per session file.
type SessionParser interface { // ParseLine parses a single JSONL line into zero or more Warden events. // Returns nil for lines that don't produce events (e.g. file-history-snapshot). ParseLine(line []byte) []ParsedEvent
// SessionDir returns the host-side directory to watch for session files. // The directory path is constructed from the host home dir and project metadata. SessionDir(homeDir string, project ProjectInfo) string
// FindSessionFiles returns the absolute paths of active JSONL session // files belonging to the given project. Returns nil when no files are // found or the directory does not exist. FindSessionFiles(homeDir string, project ProjectInfo) []string}type SessionWatcher
Section titled “type SessionWatcher”SessionWatcher monitors a directory for JSONL session files and tails them line-by-line, feeding parsed events to a callback. It handles session file rotation (new session → new .jsonl file appears).
Lifecycle: one watcher per project, created when a container starts, stopped when the container stops.
type SessionWatcher struct { // contains filtered or unexported fields}func NewSessionWatcher
Section titled “func NewSessionWatcher”func NewSessionWatcher(parser SessionParser, homeDir string, project ProjectInfo, callback func(ParsedEvent), offsetStore watcher.OffsetStore) *SessionWatcherNewSessionWatcher creates a watcher for JSONL session files. The parser converts lines into ParsedEvents. The callback receives each event (typically wired to the eventbus). The homeDir and project are passed to the parser’s FindSessionFiles for file discovery. The offsetStore (optional, may be nil) persists byte offsets so the tailer resumes from where it left off after a restart.
func (*SessionWatcher) Start
Section titled “func (*SessionWatcher) Start”func (sw *SessionWatcher) Start(ctx context.Context) errorStart begins watching for session files. It discovers existing session files via the parser’s FindSessionFiles and tails them. Periodically re-discovers to pick up new sessions.
func (*SessionWatcher) Stop
Section titled “func (*SessionWatcher) Stop”func (sw *SessionWatcher) Stop()Stop signals the watcher to stop and waits for goroutines to finish.
type Status
Section titled “type Status”Status holds agent-reported data for a single session/project directory. Fields are optional — not all agents report all fields.
type Status struct { // CostUSD is the total session cost in US dollars. CostUSD float64
// DurationMs is the total wall-clock time since the session started. DurationMs int64
// APIDurationMs is the time spent waiting for API responses. APIDurationMs int64
// LinesAdded is the total number of lines added during the session. LinesAdded int
// LinesRemoved is the total number of lines removed during the session. LinesRemoved int
// Model holds the agent model information. Model ModelInfo
// Tokens holds token usage counters. Tokens TokenUsage
// AgentSessionID is the agent's own session identifier (not the dashboard's). AgentSessionID string}type StatusProvider
Section titled “type StatusProvider”StatusProvider extracts agent status data from a config file that the agent writes inside the container. Each agent implementation knows where its data lives and how to parse it.
The Docker layer reads the file via exec and passes raw bytes here. The provider returns status data keyed by working directory path, which the caller uses to match against dashboard sessions.
type StatusProvider interface { // Name returns a human-readable agent identifier (e.g. "claude-code"). Name() string
// ProcessName returns the CLI binary name used for pgrep process detection // (e.g. "claude", "codex"). This is the executable name, not the agent type. ProcessName() string
// ConfigFilePath returns the absolute path to the agent's config file // inside the container (e.g. "/home/warden/.claude.json"). ConfigFilePath() string
// ExtractStatus parses the config file contents and returns status data // keyed by the working directory path that the agent was running in. // // For agents that use worktrees, the key is the worktree path // (e.g. "/project/.claude/worktrees/abc-123"). For non-worktree sessions, // the key is the project root (e.g. "/project"). // // Returns nil for keys where no status data is available. // Returns an empty map if the config data is empty or unparseable. ExtractStatus(configData []byte) map[string]*Status
// NewSessionParser creates a new stateful parser for JSONL session files. // Each parser instance accumulates state (e.g. token counts) across lines, // so a new parser should be created per session file. Returns nil if the // provider does not support JSONL parsing. NewSessionParser() SessionParser}type TokenUsage
Section titled “type TokenUsage”TokenUsage holds token consumption counters.
type TokenUsage struct { InputTokens int64 OutputTokens int64 CacheReadTokens int64 CacheWriteTokens int64}type ValidationResult
Section titled “type ValidationResult”ValidationResult holds the outcome of parsing a JSONL session file.
type ValidationResult struct { // TotalEvents is the total number of parsed events. TotalEvents int // Counts maps each event type to how many times it appeared. Counts map[ParsedEventType]int // Errors collects any requirement failures from [Require]. Errors []string}func ValidateJSONL
Section titled “func ValidateJSONL”func ValidateJSONL(parser SessionParser, r io.Reader) (*ValidationResult, error)ValidateJSONL reads a JSONL session file line-by-line, parses each line with the given parser, and returns a ValidationResult with event counts. This is the shared validation logic used by both unit tests (against test fixtures) and CI (against live CLI output).
func (*ValidationResult) Check
Section titled “func (*ValidationResult) Check”func (v *ValidationResult) Check() errorCheck returns an error if any [Require] calls failed, or if no events were parsed at all. Returns nil on success.
func (*ValidationResult) Require
Section titled “func (*ValidationResult) Require”func (v *ValidationResult) Require(eventType ParsedEventType, minCount int)Require asserts that at least minCount events of the given type were parsed. Failures are accumulated in Errors and surfaced by [Check].
Generated by gomarkdoc