Documentation
¶
Overview ¶
Package transcript — ExtractionState bridges parsed transcript entries into model.TranscriptData for statusline rendering.
Call ProcessEntry for each parsed Entry in order. Call ToTranscriptData to produce a snapshot suitable for passing to the render layer.
Package transcript handles incremental JSONL transcript reads for the statusline. state.go manages byte offset persistence between process invocations so each tick reads only the new bytes written since last time (O(delta) vs O(n)).
Package transcript parses JSONL transcript files produced by Claude Code. It provides entry-level parsing and content block extraction for use by higher-level extraction layers that populate model.TranscriptData.
Index ¶
- type ContentBlocks
- type Entry
- type ExtractionState
- func (es *ExtractionState) IncrementSpinnerFrame()
- func (es *ExtractionState) MarshalSnapshot() (json.RawMessage, error)
- func (es *ExtractionState) ProcessEntry(e Entry)
- func (es *ExtractionState) ToTranscriptData() *model.TranscriptData
- func (es *ExtractionState) UnmarshalSnapshot(data json.RawMessage) error
- type StateManager
- type ThinkingBlock
- type ToolResultBlock
- type ToolUseBlock
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ContentBlocks ¶
type ContentBlocks struct {
ToolUse []ToolUseBlock
ToolResult []ToolResultBlock
Thinking []ThinkingBlock
HasText bool // true when at least one "text" block is present
}
ContentBlocks holds the extracted content blocks from a single message. Blocks are classified during parsing; callers access only the types they need.
func ExtractContentBlocks ¶
func ExtractContentBlocks(e Entry) ContentBlocks
ExtractContentBlocks walks message.content and classifies each block by type. Unrecognised block types are silently ignored. Returns nil blocks (not an error) when content is absent or not a JSON array.
type Entry ¶
type Entry struct {
Type string `json:"type"`
UUID string `json:"uuid"`
Timestamp string `json:"timestamp"`
Slug string `json:"slug"`
// IsSidechain is true when this entry originates from an agent subprocess
// rather than the main conversation thread. Sidechain entries represent
// internal activity of sub-agents and must be filtered out before processing
// to avoid double-counting tool calls and agent launches.
IsSidechain bool `json:"isSidechain"`
// CustomTitle is populated when Type is "custom-title".
CustomTitle string `json:"customTitle"`
Message struct {
Role string `json:"role"`
Content json.RawMessage `json:"content"`
Model string `json:"model"`
StopReason *string `json:"stop_reason"`
Usage *struct {
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
} `json:"usage"`
} `json:"message"`
}
Entry represents a single JSONL line from a Claude Code session file. Fields map to the on-disk format at ~/.claude/projects/{project}/{session}.jsonl. Only the fields needed for statusline rendering are kept here — LeafUUID, Summary, and SourceToolUseID are omitted as they are not needed downstream.
func ParseEntry ¶
ParseEntry parses a single JSONL line into an Entry. Returns an error if the JSON is invalid. Entries without a UUID are accepted — some entry types (e.g. custom-title) may omit the UUID field legitimately.
func ParseTranscriptFile ¶
ParseTranscriptFile reads a JSONL transcript file and returns all successfully parsed entries. Lines that fail to parse are skipped. This is the intended top-level entry point for the --dump-current integration path in main.go.
func (Entry) ParsedTimestamp ¶
ParsedTimestamp returns the entry's Timestamp as a time.Time. Returns the zero value if the timestamp is missing or unparseable.
type ExtractionState ¶
type ExtractionState struct {
// contains filtered or unexported fields
}
ExtractionState accumulates tool, agent, todo, and thinking data across a sequence of parsed transcript entries. It is designed for incremental use: call ProcessEntry for each new line, then call ToTranscriptData for the latest snapshot.
The state is NOT safe for concurrent use. Callers must synchronise externally if ProcessEntry and ToTranscriptData are called from multiple goroutines.
func NewExtractionState ¶
func NewExtractionState() *ExtractionState
NewExtractionState returns an initialised, empty ExtractionState.
func (*ExtractionState) IncrementSpinnerFrame ¶
func (es *ExtractionState) IncrementSpinnerFrame()
IncrementSpinnerFrame advances the monotonic spinner counter by one. Call this once per statusline invocation, after restoring the snapshot and processing new transcript entries, so the frame always advances between renders.
func (*ExtractionState) MarshalSnapshot ¶
func (es *ExtractionState) MarshalSnapshot() (json.RawMessage, error)
MarshalSnapshot serializes the display-relevant state to JSON. It omits toolMap and agentMap because in-flight tool_use→tool_result correlations do not span invocations.
func (*ExtractionState) ProcessEntry ¶
func (es *ExtractionState) ProcessEntry(e Entry)
ProcessEntry classifies the content blocks in e and updates the extraction state accordingly. Unknown entry types and malformed blocks are silently ignored — the caller is responsible for feeding entries in order.
func (*ExtractionState) ToTranscriptData ¶
func (es *ExtractionState) ToTranscriptData() *model.TranscriptData
ToTranscriptData collapses the current extraction state into a model.TranscriptData snapshot for the render layer.
func (*ExtractionState) UnmarshalSnapshot ¶
func (es *ExtractionState) UnmarshalSnapshot(data json.RawMessage) error
UnmarshalSnapshot restores display state from a previously serialized snapshot. The toolMap and agentMap are not restored (in-flight correlations don't survive across invocations). Restored tools have no startTime, so duration won't be recomputed — DurationMs retains its final value from the snapshot.
type StateManager ¶
type StateManager struct {
// contains filtered or unexported fields
}
StateManager handles byte-offset tracking for incremental reads.
func NewStateManager ¶
func NewStateManager(stateDir string) *StateManager
NewStateManager creates a manager using the given directory for state files.
func (*StateManager) LoadSnapshot ¶
func (sm *StateManager) LoadSnapshot() json.RawMessage
LoadSnapshot returns the extraction snapshot that was loaded from disk during the most recent ReadIncremental call. Returns nil when no snapshot is available (e.g., first run, corrupt state, or path mismatch).
func (*StateManager) ReadIncremental ¶
func (sm *StateManager) ReadIncremental(transcriptPath string) ([]string, error)
ReadIncremental reads new lines from the transcript since the last read. It returns complete, valid-JSON lines only. A partial last line (mid-write) is discarded; the offset is not advanced past it so the next tick picks it up.
Reset conditions (start from byte 0):
- State file missing or corrupt
- Stored path differs (new session)
- Stored offset exceeds current file size (truncation)
func (*StateManager) SaveState ¶
func (sm *StateManager) SaveState(transcriptPath string) error
SaveState persists the current offset to disk atomically. Writes to a temp file then renames to prevent partial reads from concurrent processes.
func (*StateManager) SetSnapshot ¶
func (sm *StateManager) SetSnapshot(data json.RawMessage)
SetSnapshot stores data so it will be included in the next SaveState call.
type ThinkingBlock ¶
type ThinkingBlock struct{}
ThinkingBlock represents a thinking content block from an assistant message. The actual thinking text is intentionally omitted — only presence matters for the statusline.
type ToolResultBlock ¶
type ToolResultBlock struct {
ToolUseID string `json:"tool_use_id"`
Content json.RawMessage `json:"content"`
IsError bool `json:"is_error"`
}
ToolResultBlock represents a tool_result content block from a user message.
type ToolUseBlock ¶
type ToolUseBlock struct {
ID string `json:"id"`
Name string `json:"name"`
Input json.RawMessage `json:"input"`
}
ToolUseBlock represents a tool_use content block from an assistant message.