Documentation
¶
Overview ¶
Package parser extracts billable events from Claude Code session JSONL logs.
Claude Code writes one JSON object per line to files under $HOME/.claude/projects/<project>/*.jsonl (and subagents/ subdirs). Every line has a "type" field. Only lines with type:"assistant" carry token usage; the rest (progress, user, system, file-history-snapshot, queue-operation, pr-link, last-prompt) are skipped silently.
Schema observations from real data (2026-04-09, n=38,911 assistant events across 727 files in 3 projects):
- Every assistant line has "cwd", "gitBranch", "uuid", "sessionId", "timestamp", and "message.model". We trust these and fail loudly if any are missing.
- Claude Code writes gitBranch directly — we do NOT walk .git/HEAD. Detached HEAD shows up literally as "HEAD".
- Models seen: claude-opus-4-6, claude-sonnet-4-6, claude-sonnet-4-5-20250929, claude-haiku-4-5-20251001, <synthetic>.
- The "<synthetic>" model with null service_tier represents Claude Code framework internals that Anthropic does not bill. We skip them.
- cache_creation_input_tokens is the total; the breakdown into ephemeral_5m_input_tokens and ephemeral_1h_input_tokens lives in the nested "cache_creation" object. These have different prices (1.25× vs 2× input rate) so we split them here.
This package is deliberately pure: it takes bytes, returns events or errors. File tailing, deduplication, and attribution belong to other packages.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrMalformed = errors.New("malformed JSONL line")
ErrMalformed wraps errors for invalid JSONL lines or assistant lines missing required fields. Use errors.Is to check.
Functions ¶
This section is empty.
Types ¶
type Event ¶
type Event struct {
// Identity
UUID string // message uuid, unique per event (dedupe key)
SessionID string // Claude Code session uuid
Timestamp time.Time // message timestamp in UTC
// Attribution
CWD string // working directory from the JSONL line
Project string // basename of CWD
GitBranch string // provided verbatim by Claude Code
// Cost inputs
Model string // e.g. "claude-opus-4-6"
ServiceTier string // "standard", "batch", "priority"; defaults to standard
InputTokens int
OutputTokens int
CacheReadTokens int
CacheCreation5mTokens int // ephemeral 5-minute cache write
CacheCreation1hTokens int // ephemeral 1-hour cache write
}
Event is one billable assistant message, flattened for downstream consumers (rollups, budget evaluator, enforcer).
func Parse ¶
Parse decodes a single JSONL line. It returns:
(event, nil) for a billable assistant message (nil, nil) for any non-billable or empty line (caller should skip) (nil, err) for malformed JSON or an assistant line missing required fields
Callers iterating a file line-by-line should treat (nil, nil) as "keep going" and log-and-continue on errors.