Documentation
¶
Overview ¶
Package cc reads Claude Code session transcripts (the JSONL files under ~/.claude/projects/<encoded-path>/<session-id>.jsonl) and turns them into compact, TOON-friendly digests. It is a Context Provider: a single 2-4 MB transcript costs ~hundreds of thousands of tokens to read raw, while a `sf cc show` digest is a few hundred — the per-session intent, tool histogram, real token usage, files touched, and token-heavy results.
Two views are exposed:
- `sf cc ls` — an index of sessions across all projects.
- `sf cc show` — a one-screen digest of a single session.
Unlike `sf history` (which reads sofia's *own* call log), cc reads the agent's transcripts, so the two are siblings: one measures the tools, the other measures the sessions that drove them.
quota.go implements `sf cc value --quota`: a "subscription quota stretcher" report. Unlike the rest of this file (which reads Claude Code session transcripts and converts to $), the quota report reads sf's OWN telemetry — calllog.Read(), the same calls.jsonl `sf history` reads — and asks a different question: on a Claude subscription plan there's no $ to save (it's a flat fee), the thing that actually runs out is the rolling 5-hour usage window, so what matters is how many output tokens sf handed back instead of the agent paying full price for a raw read/grep/diff.
Index ¶
- Constants
- func Categorize(cmd string) string
- func NewCommand() *cobra.Command
- func ProjectsDir(flagValue string) (string, error)
- func ResolveSelector(projectsDir, sel string) (string, error)
- func RunBash(w io.Writer, projectsDir, selector, category string, minCount, limit int, ...) error
- func RunCandidates(w io.Writer, projectsDir, selector, project, since string, minCount, limit int, ...) error
- func RunLs(w io.Writer, projectsDir, project, since string, limit int, format string) error
- func RunPrompts(w io.Writer, projectsDir, selector, format string) error
- func RunResume(w io.Writer, projectsDir, selector, format string) error
- func RunShow(w io.Writer, projectsDir, selector, format string) error
- type BashCmd
- type Brief
- type Candidates
- type CategoryCount
- type FatResult
- type FileTouch
- type HeavyTool
- type LsRow
- type ModelPrice
- type ModelUsage
- type PR
- type Period
- type Quota
- type RepeatedCmd
- type RepeatedRead
- type Session
- type SessionFile
- type TokenTypeCost
- type ToolCount
- type Value
Constants ¶
const ( CatSearch = "search" // grep/rg/find/fd — locating things CatRead = "read" // cat/head/tail/less — reading file content CatGit = "git" // version control CatTest = "test" // running test suites CatBuild = "build" // compile / install / bundle CatDB = "db" // database & migrations CatFS = "fs" // create/move/delete/inspect files CatOther = "other" )
Category labels for bash commands. They answer "what was the agent doing at the shell" — a classifier for commands instead of file paths.
const ProjectsDirKey = "CC_PROJECTS_DIR"
ProjectsDirKey is the env/.env key holding the Claude Code projects root.
const QuotaWindow = 5 * time.Hour
QuotaWindow is the busiest-window span the report scans for: 5 hours is the Claude subscription's own rolling quota window, so "which 5h span burned the most tokens sf just saved you" is the direct answer to "where did --quota actually stretch my usage."
Variables ¶
This section is empty.
Functions ¶
func Categorize ¶
Categorize classifies a single shell command. Compound commands (`cd x && grep ...`) are matched against the whole string, so the most specific rule still wins.
func NewCommand ¶
NewCommand returns the `cc` command group (ls, show), wired into the root command tree the same way every other tool group is in internal/cli.
func ProjectsDir ¶
ProjectsDir resolves the Claude Code projects root: flag, then $CC_PROJECTS_DIR (.env or process env), then ~/.claude/projects. The default is correct on virtually every install, so cc never prompts.
func ResolveSelector ¶
ResolveSelector maps a human selector to a single transcript path:
""/"last" → most recently modified session anywhere *.jsonl / path → that file directly <uuid-prefix> → newest session whose file name starts with the selector <project> → newest session whose project dir name contains the selector
Resolution mirrors how xref resolves constant names: try the precise interpretation first, fall back to the fuzzy one.
func RunBash ¶
func RunBash(w io.Writer, projectsDir, selector, category string, minCount, limit int, full bool, format string) error
RunBash is the `sf cc bash` entry point used by the MCP server.
func RunCandidates ¶
func RunCandidates(w io.Writer, projectsDir, selector, project, since string, minCount, limit int, format string) error
RunCandidates is the `sf cc candidates` entry point used by the MCP server. With a selector it scans one session; without, it scans a project/time window like the CLI does.
func RunPrompts ¶
RunPrompts is the `sf cc prompts` entry point used by the MCP server.
Types ¶
type BashCmd ¶
type BashCmd struct {
Count int `json:"count"`
Category string `json:"category"`
Command string `json:"command"`
}
BashCmd is one deduplicated command with its frequency and category.
type Brief ¶
type Brief struct {
Project string `json:"project"`
Branch string `json:"branch"`
Session string `json:"session"`
Age string `json:"age,omitempty"`
Messages int `json:"messages"`
Goal string `json:"goal,omitempty"`
Now string `json:"now,omitempty"`
Next string `json:"next,omitempty"`
Files []FileTouch `json:"files,omitempty"`
}
Brief is the compact resume payload — a handful of fields, each capped, so the whole thing is a few hundred tokens regardless of session size.
type Candidates ¶
type Candidates struct {
Scanned int `json:"scanned_sessions"`
HeavyTools []HeavyTool `json:"heavy_tools"`
RepeatedCommands []RepeatedCmd `json:"repeated_commands"`
RepeatedReads []RepeatedRead `json:"repeated_reads"`
}
Candidates is the full result of a scan.
type CategoryCount ¶
type CategoryCount struct {
Category string `json:"category"`
Calls int `json:"calls"`
Unique int `json:"unique,omitempty"`
}
CategoryCount is one row of the bash-category breakdown. Unique counts distinct commands in the category (set by `bash`; 0/omitted in `show`).
type FatResult ¶
type FatResult struct {
Tokens int64 `json:"tokens"`
Tool string `json:"tool"`
Brief string `json:"brief"`
}
FatResult is a single token-heavy tool result — a compaction candidate.
type FileTouch ¶
type FileTouch struct {
Path string `json:"path"`
Reads int `json:"reads"`
Edits int `json:"edits"`
Writes int `json:"writes"`
}
FileTouch counts how a path was accessed within a session.
type HeavyTool ¶
type HeavyTool struct {
Tool string `json:"tool"`
Calls int `json:"calls"`
ResultTokens int64 `json:"result_tokens"`
Suggestion string `json:"suggestion,omitempty"`
}
HeavyTool aggregates one tool's footprint across the scanned sessions.
type LsRow ¶
type LsRow struct {
ID string `json:"id"`
Project string `json:"project"`
Title string `json:"title"`
Updated time.Time `json:"updated"`
Messages int `json:"messages"`
Prompts int `json:"prompts"`
OutTokens int64 `json:"out_tokens"`
CacheRead int64 `json:"cache_read"`
Branch string `json:"branch"`
PRs int `json:"prs"`
SizeBytes int64 `json:"size_bytes"`
}
LsRow is one line of the session index.
type ModelPrice ¶
type ModelPrice struct {
Input float64 // $ / 1M base (uncached) input tokens
Output float64 // $ / 1M output tokens
CacheWrite float64 // $ / 1M cache-creation tokens (5-minute TTL)
CacheRead float64 // $ / 1M cache-read tokens
}
ModelPrice is USD price per 1,000,000 tokens, by token type, for one Claude model.
type ModelUsage ¶
type ModelUsage struct {
Model string `json:"model"`
Sessions int `json:"sessions"`
Tokens int64 `json:"tokens"`
CostUSD float64 `json:"cost_usd"`
Priced bool `json:"priced"`
}
ModelUsage aggregates one model's sessions/tokens/cost within the current window.
type Period ¶
type Period struct {
Since time.Time `json:"since"`
Until time.Time `json:"until"`
Sessions int `json:"sessions"`
CostUSD float64 `json:"cost_usd"`
ByType []TokenTypeCost `json:"by_type"`
UnpricedTokens int64 `json:"unpriced_tokens,omitempty"`
}
Period is one time window's aggregate: $ cost and a token-type breakdown. UnpricedTokens is the token volume from sessions whose model isn't in modelPrices — real usage, just not converted to $.
type Quota ¶ added in v0.3.0
type Quota struct {
Days int `json:"days"`
Since time.Time `json:"since"`
Until time.Time `json:"until"`
Calls int `json:"calls"`
WithBaseline int `json:"with_baseline"` // calls whose summary carries tok_raw or tok_rep
DedupStubs int `json:"dedup_stubs"`
EmittedTokens int64 `json:"emitted_tokens"` // Σ out_tokens across Calls
BaselineTokens int64 `json:"baseline_tokens"` // Σ tok_raw/tok_rep across WithBaseline
SavedTokens int64 `json:"saved_tokens"` // Σ max(baseline-emitted, 0)
SavedPct float64 `json:"saved_pct"` // SavedTokens / BaselineTokens * 100
BusiestStart time.Time `json:"busiest_start,omitempty"`
BusiestSaved int64 `json:"busiest_saved,omitempty"` // saved tokens inside that QuotaWindow
}
Quota is the aggregate `sf cc value --quota` renders. Pure data — built by buildQuota, independent of how it's read or rendered.
type RepeatedCmd ¶
type RepeatedCmd struct {
Count int `json:"count"`
Sessions int `json:"sessions"`
Category string `json:"category"`
Command string `json:"command"`
}
RepeatedCmd is an identical shell command seen more than once.
type RepeatedRead ¶
type RepeatedRead struct {
Reads int `json:"reads"`
Sessions int `json:"sessions"`
Path string `json:"path"`
}
RepeatedRead is a file read more than once.
type Session ¶
type Session struct {
Path string `json:"path"`
ID string `json:"id"` // short id (uuid prefix)
FullID string `json:"full_id"` // full session UUID
Project string `json:"project"` // basename of cwd
Cwd string `json:"cwd"`
Branch string `json:"branch"`
Model string `json:"model"`
Version string `json:"version"`
Title string `json:"title"`
Start time.Time `json:"-"` // surfaced as RFC3339 strings by the json renderer
End time.Time `json:"-"`
Messages int `json:"messages"`
SizeBytes int64 `json:"size_bytes"`
UserPrompts []string `json:"user_prompts"`
LastText string `json:"last_text,omitempty"` // last assistant narrative — the "next step"
ToolCalls map[string]int `json:"tool_calls"`
ToolResultTokens map[string]int64 `json:"tool_result_tokens"`
Bash []string `json:"-"`
Files []FileTouch `json:"files"`
FatResults []FatResult `json:"fat_results"`
OutputTokens int64 `json:"output_tokens"`
InputTokens int64 `json:"input_tokens"`
CacheReadTokens int64 `json:"cache_read_tokens"`
CacheCreateTokens int64 `json:"cache_create_tokens"`
DurationMs int64 `json:"duration_ms"`
PRs []PR `json:"prs"`
}
Session is the parsed digest of one transcript.
func Parse ¶
Parse reads a transcript and builds a Session. When collectDetail is false the heavy per-call slices (Bash, Files, FatResults) are skipped — `sf cc ls` only needs the aggregate counters and usage totals.
func (*Session) BashCategories ¶
func (s *Session) BashCategories() []CategoryCount
BashCategories returns counts of bash commands per category, desc.
func (*Session) SortedTools ¶
SortedTools returns the tool histogram ordered by call count desc.
type SessionFile ¶
type SessionFile struct {
Path string // absolute path to the .jsonl
Stem string // file name without .jsonl (the session UUID)
DirName string // encoded project dir name, e.g. -home-user-www-myapp
ModTime time.Time // file mtime — cheap recency signal
Size int64
}
SessionFile is a discovered transcript on disk, before parsing.
type TokenTypeCost ¶
type TokenTypeCost struct {
Type string `json:"type"`
Tokens int64 `json:"tokens"`
CostUSD float64 `json:"cost_usd"`
}
TokenTypeCost is one token type's aggregate volume and priced $ within a period.
type ToolCount ¶
type ToolCount struct {
Tool string `json:"tool"`
Calls int `json:"calls"`
ResultTokens int64 `json:"result_tokens"`
}
ToolCount is one row of the tool histogram, sorted for rendering.
type Value ¶
type Value struct {
Current Period `json:"current"`
Previous Period `json:"previous"`
DeltaUSD float64 `json:"delta_usd"`
DeltaPct float64 `json:"delta_pct,omitempty"`
ByModel []ModelUsage `json:"by_model"`
}
Value is the full result of `sf cc value`: the current window vs the preceding window of equal length, the $ delta between them, and a per-model breakdown of the current window.