Skip to content

agent/claudecode

View on pkg.go.dev

import "github.com/thesimonho/warden/agent/claudecode"

Package claudecode implements the agent.StatusProvider interface for Claude Code CLI. It reads session data from Claude Code’s global config file (~/.claude.json) which stores per-project usage metrics.

func EstimateCost(model string, tokens agent.TokenUsage) float64

EstimateCost computes an estimated cost in USD from cumulative token usage. This is a fallback — the preferred cost source is actual cost from .claude.json via StatusProvider. Returns 0 for unknown models.

func ParseConfig(data []byte) map[string]*agent.Status

ParseConfig parses Claude Code’s .claude.json and extracts per-project status data. Exported for testing.

CompactMetadata holds details about a context compaction event.

type CompactMetadata struct {
Trigger string `json:"trigger"`
PreTokens int64 `json:"preTokens"`
MessagesSummarized int `json:"messagesSummarized,omitempty"`
}

ContentBlock represents a single block within a message’s content array. The Type field determines which other fields are populated.

type ContentBlock struct {
Type string `json:"type"`
// Text is the content for "text" type blocks.
Text string `json:"text,omitempty"`
// Name is the tool name for "tool_use" type blocks.
Name string `json:"name,omitempty"`
// ID is the tool use identifier for "tool_use" type blocks.
ID string `json:"id,omitempty"`
// Input is the tool input for "tool_use" type blocks.
Input map[string]any `json:"input,omitempty"`
// ToolUseID is the tool use identifier for "tool_result" type blocks.
ToolUseID string `json:"tool_use_id,omitempty"`
// IsError is true when a tool_result block represents an error.
IsError bool `json:"is_error,omitempty"`
// Content is the text content for "tool_result" type blocks.
// Can be a string or an array of blocks — we only use the string form.
Content json.RawMessage `json:"content,omitempty"`
}

func (b *ContentBlock) ErrorContent() string

ErrorContent returns the text content of a tool_result error block. Handles both plain string content and array-of-blocks content.

ContentField handles the polymorphic content field — it can be either a plain string (user text prompts) or an array of ContentBlock objects (assistant responses, tool results).

type ContentField struct {
// Text is populated when content is a plain string.
Text string
// Blocks is populated when content is an array of content blocks.
Blocks []ContentBlock
}

func (cf *ContentField) UnmarshalJSON(data []byte) error

UnmarshalJSON handles the polymorphic content field in Claude’s JSONL. User prompts have content as a plain string, while assistant responses and tool results have content as an array of ContentBlock objects.

MessageBody holds the message payload for assistant and user entries.

type MessageBody struct {
Role string `json:"role"`
Model string `json:"model,omitempty"`
StopReason string `json:"stop_reason,omitempty"`
Usage *UsageInfo `json:"usage,omitempty"`
Content ContentField `json:"content"`
}

Parser implements agent.SessionParser for Claude Code session JSONL files. It is stateful — token counts accumulate across lines within a session. Create a new Parser for each session file.

type Parser struct {
// contains filtered or unexported fields
}

func NewParser() *Parser

NewParser creates a new Claude Code JSONL parser.

func (p *Parser) FindSessionFiles(homeDir string, project agent.ProjectInfo) []string

FindSessionFiles scans the per-project session directory and any worktree session directories for .jsonl files. Claude Code creates separate session directories for worktrees at paths like:

~/.claude/projects/-home-warden-myproject--claude-worktrees-branchname/

These are siblings of the project directory and share the same prefix.

func (p *Parser) ParseLine(line []byte) []agent.ParsedEvent

ParseLine parses a single JSONL line into zero or more ParsedEvents. Returns nil for entry types that don’t map to Warden events.

func (p *Parser) SessionDir(homeDir string, project agent.ProjectInfo) string

SessionDir returns the host-side directory containing Claude Code session JSONL files for a project. Claude encodes the container-side workspace path by replacing ”/” with ”-” to form the directory name.

Provider extracts status data from Claude Code’s .claude.json config file.

type Provider struct{}

func NewProvider() *Provider

NewProvider creates a new Claude Code status provider.

func (p *Provider) ConfigFilePath() string

ConfigFilePath returns the path to .claude.json inside the container.

func (p *Provider) ExtractStatus(configData []byte) map[string]*agent.Status

ExtractStatus parses .claude.json and returns status data keyed by the working directory path (which maps to our session worktree paths).

func (p *Provider) Name() string

Name returns the agent identifier.

func (p *Provider) NewSessionParser() agent.SessionParser

NewSessionParser creates a stateful JSONL parser for Claude Code sessions.

func (p *Provider) ProcessName() string

ProcessName returns the CLI binary name for pgrep detection.

SessionEntry is the top-level structure of every JSONL line. The Type field determines which other fields are populated.

type SessionEntry struct {
// Common fields present on all entry types.
Type string `json:"type"`
UUID string `json:"uuid"`
Timestamp string `json:"timestamp"`
SessionID string `json:"sessionId"`
CWD string `json:"cwd"`
GitBranch string `json:"gitBranch"`
// Message is populated for "assistant" and "user" type entries.
Message *MessageBody `json:"message,omitempty"`
// Subtype distinguishes system entry kinds (e.g. "turn_duration", "informational").
Subtype string `json:"subtype,omitempty"`
// DurationMs is the turn duration (system entries with subtype "turn_duration").
DurationMs int64 `json:"durationMs,omitempty"`
// Content is the text content for system entries.
Content string `json:"content,omitempty"`
// Level is the severity for system entries (e.g. "warning").
Level string `json:"level,omitempty"`
// TTFTMs is time to first token in ms (system/api_metrics).
TTFTMs float64 `json:"ttftMs,omitempty"`
// OutputTokensPerSec is output tokens per second (system/api_metrics).
OutputTokensPerSec float64 `json:"otps,omitempty"`
// Commands is a list of allowed commands (system/permission_retry).
Commands []string `json:"commands,omitempty"`
// CompactMetadata holds context compaction details (system/compact_boundary).
CompactMetadata *CompactMetadata `json:"compactMetadata,omitempty"`
// Operation distinguishes queue-operation entry kinds ("enqueue", "remove").
Operation string `json:"operation,omitempty"`
}

UsageInfo holds token consumption data from an assistant message.

type UsageInfo struct {
InputTokens int64 `json:"input_tokens"`
OutputTokens int64 `json:"output_tokens"`
CacheCreationInputTokens int64 `json:"cache_creation_input_tokens"`
CacheReadInputTokens int64 `json:"cache_read_input_tokens"`
}

Generated by gomarkdoc