Skip to main content

cctrail

version py versions downloads license donate

cctrail reads local Claude Code and Codex history and reports token usage, estimated cost, and project statistics. It can also be used as a Python library for working with parsed sessions, messages, tool calls, and agents.

$ uvx cctrail groups today
Group     Projects Sessions Tokens Last active   Cost   Time
exp              2        2 32.36M 2026-08-09  $24.00 1h 15m
wrk              1        1 24.93M 2026-08-09  $19.45 0h 49m
ungrouped        2        4 20.56M 2026-08-09  $17.31 1h 26m
oss              1        1 10.35M 2026-08-09   $7.90 0h 31m
comms            1        1  71.1K 2026-08-09   $0.10 0h 06m
total            7        9 88.27M 2026-08-09  $68.74 4h 08m
$ uvx cctrail projects today
Project             Sessions Total tokens Last active   Cost   Time
~/Code/vibe/cctrail        1       32.04M 2026-08-09  $23.43 1h 10m
atlas                      1       24.93M 2026-08-09  $19.45 0h 49m
starship                   2       17.87M 2026-08-09  $14.37 1h 02m
~/Code/pub/macmon          1       10.35M 2026-08-09   $7.90 0h 31m
~/Code/sideproj            2        2.68M 2026-08-09   $2.93 0h 24m
~/Code/labs                1       322.1K 2026-08-09   $0.57 0h 05m
~/Code/client-app          1        71.1K 2026-08-09   $0.10 0h 06m
total                      9       88.27M 2026-08-09  $68.74 4h 08m
$ uvx cctrail usage this-month
Date        Input Output   Total     Cost    Time
2026-08-01  5.75M  1.30M 281.22M  $174.00 12h 45m
2026-08-02  6.93M 780.8K 204.76M  $276.40 10h 24m
2026-08-03  4.88M 338.4K 138.49M  $193.10  6h 02m
2026-08-04  4.55M 693.6K 244.77M   $92.25  6h 39m
2026-08-05  4.43M 444.6K 166.19M  $102.47  6h 06m
2026-08-06  4.52M 226.4K  93.27M   $83.17  6h 22m
2026-08-07  6.15M 631.3K 232.52M  $153.22  9h 14m
2026-08-08  24.5K   4.0K  123.3K    $0.31  0h 07m
2026-08-09  3.06M 196.9K  92.68M   $72.05  4h 14m
total      40.30M  4.61M   1.45B $1146.97 61h 56m

Why cctrail?

Before coding agents, I tracked time with a VS Code extension. That worked while most of the job happened inside the editor. In the new agentic coding era, much of my work happens in terminal sessions instead: I start an agent, review its results, send another prompt, and move between several projects. The editor no longer sees enough of that activity to answer a simple question: where did my time go?

I tried several ways to recover that information, and local agent history turned out to be the most useful source. cctrail turns it into reports that help explore how agent-assisted work is distributed over time, projects, and configurable groups. Its purpose is broader than any single report: to make the work recorded by coding agents visible and understandable from different perspectives.

ccusage is an excellent alternative for ready-made token and cost reports across many coding agents. cctrail grew from a different question: not only how many tokens were used, but what I worked on and how my time was divided.

CLI

Show token usage by day:

uvx cctrail usage

Use named calendar periods and group longer reports by week or month:

uvx cctrail usage today
uvx cctrail usage last-week
uvx cctrail usage this-month --by week
uvx cctrail usage all --by month

Available periods are today, yesterday, this-week, last-week, this-month, last-month, and all. Weeks follow the first weekday of the system locale.

Show a per-model breakdown or the detailed reasoning and cache token columns:

uvx cctrail usage this-month --models
uvx cctrail usage this-month --models --full

For an arbitrary date range, use --since and --until:

uvx cctrail usage --since 2026-07-01 --until 2026-07-31

Show usage grouped by project directory:

uvx cctrail projects this-month

Projects accept the same named periods and arbitrary date ranges as usage reports. Paths inside your home directory are shortened to ~/…; pass --full to show absolute paths.

Show usage aggregated across configured project groups:

uvx cctrail groups this-month
uvx cctrail groups --provider codex
uvx cctrail groups --json

Groups accept the same periods, date ranges, and provider filter as project reports. Projects that do not match a configured group are included under ungrouped.

Configuration

Project aliases can combine a project's main checkout and worktrees into a single project in the report. This is optional: without an alias, cctrail reports each path separately.

[aliases]
cctrail = ["~/Code/vibe/cctrail", "~/.worktrees/cctrail--*"]

[groups]
personal = ["cctrail", "~/Code/dotfiles"]
opensource = ["~/Code/pub/**"]

Alias paths support ~ and glob patterns. * matches within one path segment, while ** can match across directories. A trailing /** includes both the named directory and everything below it. For example, ~/.worktrees/cctrail--* matches sibling worktrees and ~/Code/**/cctrail/** matches the project at any depth below ~/Code together with all of its checkouts.

Groups are resolved after aliases, so a group can contain an alias such as cctrail, an exact project path, or a glob pattern. A project can match only one group.

Use --config to select a file for one command, or --no-config to ignore every TOML configuration:

uvx cctrail --config ~/configs/work.toml projects
uvx cctrail --no-config projects

Configuration is selected in this order:

  1. --no-config disables configuration
  2. --config PATH selects a specific file
  3. ./cctrail.toml
  4. ~/.config/cctrail.toml

An explicitly selected file must exist. The automatic locations are optional.

You can also configure every Claude Code and Codex history directory instead of setting CLAUDE_CONFIG_DIR or CODEX_HOME for each command:

[sources]
claude = ["~/.claude", "~/.claude-work"]
codex = ["~/.codex", "~/.codex-work"]

When a provider is present in [sources], its list replaces the default directories. Environment variables still take precedence when set.

Claude data is read from ~/.config/claude and ~/.claude, while Codex data is read from ~/.codex. Set CLAUDE_CONFIG_DIR or CODEX_HOME to replace these defaults. Both variables accept comma-separated directories:

CLAUDE_CONFIG_DIR="$HOME/.claude,$HOME/.claude-qh" uvx cctrail usage
CODEX_HOME="$HOME/.codex,$HOME/.codex-work" uvx cctrail usage

Claude Code deletes session files older than 30 days at startup by default. Because cctrail reads those local transcripts, deleted sessions also disappear from its reports. To preserve a long-term history, increase cleanupPeriodDays in ~/.claude/settings.json before the default cleanup removes it:

{
  "cleanupPeriodDays": 9999
}

Usage reports count each provider message once, while parsed sessions retain their original message and sub-agent structure. Costs are estimates based on the pricing catalog embedded in the installed cctrail version.

Active time is estimated by treating every activity event as a five-minute window. Sessions without token usage in the selected period are ignored. Overlapping sessions within a project are merged; when several projects are active at once, that time is divided evenly between them. This keeps the project and group totals equal to the overall active time.

Python library

Add cctrail to a project:

uv add cctrail

Iterate over parsed sessions:

from cctrail import iter_sessions, tool_call_counts

for session in iter_sessions():
    print(session.provider, session.cwd, session.title, session.usage.total)

    for call in session.iter_tool_calls():
        print(call.name, call.input, call.duration)

    for agent in session.iter_agents():
        print(agent.agent_type, agent.usage.total)

    print(tool_call_counts(session))

Provider-specific iterators are available as iter_claude_sessions() and iter_codex_sessions(). Sub-agent transcripts are attached to the tool call that launched them.

The main data types are Session, Message, ToolCall, and Usage. Every model supports .as_dict() and .as_json().

from cctrail import Usage, by_project, calculate_cost, get_pricing, iter_sessions, usage_by_period

sessions = list(iter_sessions())
weekly = usage_by_period(sessions, granularity="week")
projects = by_project(sessions)

pricing = get_pricing("claude-sonnet-5")
cost = calculate_cost("claude-sonnet-5", Usage(input=1_000, output=100))

Usage is grouped in the system timezone by default. usage_by_period() accepts day, week, and month granularities, while usage_by_day() remains the daily shortcut. Pass a datetime.tzinfo as the timezone argument to use another timezone. UsageSummary values expose .cost, .active_time, and per-model .models; ProjectSummary values expose .cost and .active_time.

Development

The project requires Python 3.11 or newer and uses uv.

uv sync
make check
make test

License

Distributed under the MIT License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cctrail-0.1.1.tar.gz (75.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cctrail-0.1.1-py3-none-any.whl (34.3 kB view details)

Uploaded Python 3

File details

Details for the file cctrail-0.1.1.tar.gz.

File metadata

  • Download URL: cctrail-0.1.1.tar.gz
  • Upload date:
  • Size: 75.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cctrail-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2caa97b234f258b377c4dcbb0abdbd2cb292f02a03e07d580a288977aafc4631
MD5 90e64d101cdf2ae4f95bdf4ff122eab0
BLAKE2b-256 c88fd490460c76c7b35c377b084350121020e5557212da412639c096266228dc

See more details on using hashes here.

Provenance

The following attestation bundles were made for cctrail-0.1.1.tar.gz:

Publisher: main.yml on vladkens/cctrail

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cctrail-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: cctrail-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 34.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cctrail-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ac83aa85788afa107f425ee49dc4470d9a6d77540e65b873e9ac68ef4f940640
MD5 b045fef95d263fa291850deaf498dee3
BLAKE2b-256 8da7826ca5dccf161881ea5fe09e70c6e42eff9190452341a8971194ffca07b8

See more details on using hashes here.

Provenance

The following attestation bundles were made for cctrail-0.1.1-py3-none-any.whl:

Publisher: main.yml on vladkens/cctrail

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page