jsonl

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package jsonl implements ports.SessionSource by reading Claude Code JSONL session files from ~/.claude/projects/<encoded-cwd>/.

Directory layout

~/.claude/projects/
  -Users-alice-work-clyde/   ← encodeProjectPath("/Users/alice/work/clyde")
    <uuid>.jsonl              ← one file per session

JSONL format

Each line is a JSON object representing one event. All events share a common envelope (uuid, type, timestamp, sessionId, parentUuid). Per-type variable fields are captured in json.RawMessage so the domain stays free of JSON types.

Design notes

  • bufio.Scanner buffer is raised to 4MB (from the default 64KB) because assistant events with extended thinking blocks can exceed 64KB on a single JSONL line.
  • Unknown event types are returned as event.OpaquePayload{Raw: rawLine} with the ENTIRE line preserved (not just the payload sub-object). This keeps the door open for future panels to decode it without a domain change.
  • Malformed lines (invalid JSON) return a wrapped error naming file + line number. Skipping vs. failing is a policy choice; we fail to avoid silently returning incomplete data. Document callers that want skip behavior.
  • Sessions() uses file mtime for LastActivity (cheap: one stat per file). Reading every JSONL to find the last timestamp is O(events) vs O(sessions); mtime is close enough for session ordering and is consistent with the append-only semantics of the JSONL files.
  • Missing or empty project directory → empty slice, no error (not every project has had a Claude Code session).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ShapeMisses

type ShapeMisses struct {
	// User is the number of user-message decodes that returned an error.
	User int64
	// Assistant is the number of assistant-message Usage decodes that errored.
	Assistant int64
	// Content is the number of assistant-message Content decodes that errored.
	Content int64
}

ShapeMisses is a snapshot of decode-failure counters. Returned by Source.ShapeMisses(). Counters are process-global (decode is a free function so the fuzz harness can call it without a Source).

type Source

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

Source implements ports.SessionSource by reading Claude Code JSONL files. The zero value is not ready to use — construct with NewSource.

func NewProductionSource

func NewProductionSource() (*Source, error)

NewProductionSource returns a Source wired to the real Claude Code project directory. Returns an error if the user's home directory cannot be determined.

func NewSource

func NewSource(baseDir string) *Source

NewSource returns a Source that resolves session files under baseDir. In production pass filepath.Join(homeDir, ".claude", "projects"). Tests pass a temporary directory with the same structure.

func (*Source) AllProjectSessions

func (s *Source) AllProjectSessions(_ context.Context, maxResults int) ([]ports.GlobalSessionRef, error)

AllProjectSessions returns refs to all sessions across every project directory under s.baseDir, ordered by LastActivity descending (most recently active first).

It walks every subdirectory of baseDir, lists *.jsonl files in each, and records their mtime as LastActivity. At most maxResults refs are returned; pass maxResults=0 for no cap.

Missing or unreadable directories degrade gracefully: errors on individual project dirs are skipped so a single corrupt project does not break the whole aggregation.

func (*Source) Events

func (s *Source) Events(_ context.Context, id session.ID) ([]event.Event, error)

Events returns all events for the given session in strictly ascending chronological order (file order, which matches Claude Code's append semantics).

Returns an error if the JSONL file does not exist or contains a malformed line. The error message includes the file path and 1-based line number to aid debugging.

Cache: results are memoised per session keyed on (mtime, size). When the TUI ticks every second on the Σ aggregate tab, only the session(s) that just received an append re-decode; idle sessions return the cached slice in microseconds. The cached slice is shared by reference — callers MUST NOT mutate it (livesession's pipeline only reads).

func (*Source) Name

func (s *Source) Name() string

Name returns the LLM source identifier. Satisfies ports.LLMSource.

func (*Source) PlanLimits

func (s *Source) PlanLimits(_ context.Context) *ports.PlanLimits

PlanLimits returns nil — Claude Code does not expose plan limits in JSONL files. The 5h/7d rolling windows are enforced server-side; clyde displays countdown timers but cannot determine the exact token cap from local data. Satisfies ports.LLMSource.

func (*Source) Sessions

func (s *Source) Sessions(_ context.Context, projectCWD string) ([]session.Summary, error)

Sessions returns all sessions for the given project working directory, ordered by LastActivity descending (most recently active first).

LastActivity is derived from the file mtime — this is cheap (one stat per file) and consistent with the append-only nature of the JSONL files.

Empty or missing directory → empty slice, no error.

func (*Source) ShapeMisses

func (s *Source) ShapeMisses() ShapeMisses

ShapeMisses returns the current snapshot of decode-failure counters. Safe to call concurrently with decode-driven traffic.

func (*Source) SubagentEvents

func (s *Source) SubagentEvents(_ context.Context, projectCWD, parentSessionID, agentID string) ([]event.Event, error)

SubagentEvents returns all events from a subagent's JSONL file in file order. Returns an error if the file does not exist or contains a malformed line.

func (*Source) Subagents

func (s *Source) Subagents(_ context.Context, projectCWD, parentSessionID string) ([]ports.SubagentInfo, error)

Subagents returns all subagent infos for a given parent session. Reads from <baseDir>/<encoded-cwd>/<sessionID>/subagents/agent-*.jsonl. Returns an empty slice (no error) when the subagents directory is absent.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL