Skip to content
refoPublic

About

Per-project token, cost, and time analysis of Claude Code session logs

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

40 Commits

Folders and files

Repository files navigation

ccspan

Per-project token, cost, and time analysis of Claude Code session logs. Zero dependencies — reads ~/.claude/projects in place.

Install

npx ccspan             # run without installing
npm install -g ccspan  # or install globally

Requires Node.js ≥ 18.

Interactive mode (default on a terminal)

On a real terminal, ccspan launches a full-screen interactive app:

ccspan                 # project list → Enter opens its timeline tree
ccspan <project-name>  # jump straight into a project's timeline

It's a unified app: a project list, then a collapsible timeline tree per project. Keys:

Key Action
↑/↓ or j/k Move
Enter / → / Space Open project · expand agent
← / h Collapse · go back
Esc Back to the project list
q / Ctrl-C Quit

Sub-agent trees start collapsed (▸); expand the ones you care about (▾). When the output is piped, or you pass --json or --plain, you get the text report instead — so ccspan <project> --plain --timeline | less and ccspan --json still work for scripting.

Text usage

# Picker — show all projects, newest first
ccspan --plain [--all]

# Single project — tokens, cost, duration, per-day table
ccspan <project-name> --plain

# With flags
ccspan <project-name> --plain --sessions   # add top sessions table
ccspan <project-name> --plain --timeline   # add prompt-cascade timeline
ccspan <project-name> --json               # machine-readable JSON

# Date filters
ccspan <project-name> --from 2026-06-01 --to 2026-06-30

# Skip cost lookup (faster; no CodeBurn required)
ccspan --no-cost
ccspan <project-name> --no-cost

# Tune idle gap (default 300s)
ccspan <project-name> --idle 120

Flags:

Flag Description
--from YYYY-MM-DD Only include sessions on or after this UTC date
--to YYYY-MM-DD Only include sessions on or before this UTC date
--idle <sec> Gap threshold between active/idle (default: 300)
--sessions Show top sessions by cost and compute time
--timeline Show per-day prompt-cascade timeline
--all Show all projects in picker (default: top 20)
--json Emit JSON instead of formatted output
--plain Force the text report instead of the interactive TUI
--no-cost Skip CodeBurn cost lookup
-v, --version Print version

Example Output

Picker (ccspan --no-cost)

  CLAUDE CODE SESSIONS  ·  18 projects  ·  tokens+duration from logs, cost from CodeBurn

  #   project                       last active   sess   cost       active
  1   ccspan                        2026-06-26     1        n/a       50m
  2   Medgneering.AgenticPlatform   2026-06-26    24        n/a     7h15m
  3   spine                         2026-06-26    52        n/a    11h35m
  4   Medgneering.Portal            2026-06-26     1        n/a       30m
  5   coolify                       2026-06-25     6        n/a     8h01m
  6   dayofai                       2026-06-25     3        n/a     2h40m
  ...

  18 total. Run `ccspan <name>` to analyze a project.

Single project (ccspan ccspan --no-cost)

  ccspan  ·  /Users/username/Developer/refo/tmp/ccspan
  1 sessions  ·  cost: CodeBurn (LiteLLM pricing)

  TOKENS
    input          31.4k
    output         116.9k
    cache-create   187.3k
    cache-read     8.98M
    ─────────────────────
    total          9.32M

  COST
    n/a (codeburn unavailable — run: npm i -g codeburn)

  DURATION
    wall       2h35m    calendar span across sessions
    active     50m      at-keyboard time (gaps within idle)
    compute    12m      measured engine time
    idle       1h44m    waiting / away

  PER DAY
    date         input    output   cache-cr   cache-rd      cost   compute
    2026-06-26    31.4k   116.9k    187.3k      8.98M       n/a     12m

  tip: --timeline for the per-day agent cascade · --sessions for top sessions

(Token totals are de-duplicated by (message.id, requestId), the same way ccusage counts, so replayed usage from resumed sessions is not double-counted.)

Timeline (ccspan ccspan --no-cost --timeline)

The timeline is a prompt cascade: each ▸ row is a user prompt (slash commands shown as /cmd), and the sub-agents it spawned are drawn as a tree beneath it. Sub-agents that spawn their own sub-agents are nested recursively (read from each agent's transcript under <session>/subagents/), so a deep flow like /integrate shows its full tree. Each agent is labeled with the Agent tool's description; duration and tokens align in a right-hand gutter so you can scan a column. Session markers (/clear, caveats) collapse to one dim line.

  AgenticPlatform — TIMELINE

  2026-06-23                                             16h28m   537.7M tok
    · 3 session markers (/clear, <local-command-ca…, …)
  ▸ Base directory for this skill: ~/Developer…          16h30m    45.8k tok
      Bash ×11
    ├─ general-purpose      Integrate plan gw             2h03m   177.1k tok
    │  ├─ maestro:developer  GW Wave 1: seam + host…         9m    69.9k tok
    │  ├─ maestro:developer  GW Wave 2: errors, auth…       35m   201.4k tok
    │  ├─ maestro:reviewer   Review GW sprint diff           5m   114.0k tok
    │  └─ maestro:security   Security scan GW sprint         4m    66.4k tok
    └─ general-purpose      Integrate plan platform       3h09m   162.2k tok

The --json output carries the same tree under each timeline group's agents[], nested recursively, with both description and promptHead per agent.

How it works

Tokens are summed from every model call in ~/.claude/projects/ — including sub-agent transcripts (<session>/subagents/), so token totals account for work done inside sub-agents, not just the main thread. Duplicate usage records (replayed when a session is resumed) are de-duplicated by (message.id, requestId), the same way ccusage counts.

Duration is read from the main-thread events only (sub-agents run concurrently, so counting their wall time would double-count). Three metrics:

  • wall — total elapsed calendar time across all events (includes idle gaps)
  • active — time within the configured idle threshold (default 5 min); approximates at-keyboard time
  • compute — sum of turn_duration measurements from Claude Code's engine; the most precise measure of actual LLM compute

There is intentionally no $/hr metric: wall time is a poor proxy for productivity, and mixing compute time with total cost would produce misleading numbers.

Cost requires CodeBurn (npm i -g codeburn). When unavailable, tokens and duration are still shown. Set --no-cost or CCSPAN_NO_COST=1 to skip the cost lookup entirely.

Project matching — the project argument is a case-insensitive substring match on your project paths. If multiple paths match, ccspan lists them and asks you to be more specific.

Privacy

All data stays local. ccspan reads ~/.claude/projects/*.jsonl in place and never writes, copies, or transmits anything.

About

Per-project token, cost, and time analysis of Claude Code session logs

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages