Skip to main content

cc-session-core

PyPI Python versions CI codecov Dependabot License: MIT

Typed, lossless parser for both Claude Code transcripts (~/.claude/projects/**/*.jsonl) and Codex rollout transcripts ($CODEX_HOME/sessions/**/*.jsonl, normally ~/.codex/sessions), plus a provider-neutral session-analysis layer (timeline, tool-call pairing, usage/cost) and a context-map tool built on it.

TRANSCRIPT_RECORD_ADAPTER is a shared Pydantic discriminated union. Its callable discriminator routes Claude record types (assistant, user, system, …) and Codex rollout types (session_meta, turn_context, response_item, event_msg, …) without a format flag. Each provider then has nested discriminated unions for its own content: Claude message blocks/attachments, and Codex response items/events. Provider-specific adapters remain available when a caller deliberately wants one format only.

Parsing is lossless: models keep unknown fields (extra="allow"), and an unmodeled record/block/attachment/event/response-item type lands in an Unknown* carrier that still holds its payload—nothing is silently dropped. This matters especially for Codex because its hook documentation explicitly says the transcript format is not a stable interface. The typed Codex model tracks the current open-source RolloutItem and ResponseItem definitions while retaining forward-compatible fallbacks.

Install

pip install -e .          # or: uv pip install -e .

Library

Parse either provider through one shared boundary:

from pathlib import Path
from cc_session_core import (
    ParseFailure,
    iter_transcript_records,
    parse_transcript_line,
)

rec = parse_transcript_line(line)  # -> Claude Record | CodexRecord | unknown fallback

for rec in iter_transcript_records(Path("session.jsonl")):
    if isinstance(rec, ParseFailure):
        ...  # file, line_number, error, raw
    else:
        print(rec.type)

The backward-compatible Claude-only parse_line() / iter_records() API and the explicit Codex-only parse_codex_line() / iter_codex_records() API are also available.

Per-tool input/result resolution:

from cc_session_core import parse_tool_input, parse_tool_result, tool_name_index, result_tool_name

typed_input = parse_tool_input(block.name, block.input)  # model, or raw value
index = tool_name_index(records)  # tool_use_id -> tool name
typed_result = parse_tool_result(result_tool_name(rec, index), rec.tool_use_result)

Analyze a whole session. Session.load() auto-detects the provider and returns the same normalized timeline/tool/cost views:

from cc_session_core import Session

s = Session.load("session.jsonl")
s.timeline()  # ordered, decomposed events (text / thinking / tool_use / tool_result / ...)
s.tool_calls()  # every tool_use paired with its tool_result, plus the assistant's "why"
s.cost_summary()  # token + cost rollup per model (one API request counted once)
s.label()
s.info()  # human title + one-line summary

For Codex, response messages, reasoning, tool calls, tool outputs, compaction, and usage events are normalized into the canonical view. The original typed rollout remains available as s.codex_records when isinstance(s, CodexSession). Codex input_tokens includes cached input, so normalization subtracts cached_input_tokens before filling the canonical uncached-input field; totals therefore do not double-count cache reads.

Cost uses cc_session_core.cost.pricing (published list rates in EXAMPLE_PRICING); pass your own PriceTable for a different valuation. Rates are a usage valuation, not a billed amount.

CLI

cc-session PATH [--tools] [--queries] [--audit] [--list] [--json] [--strict]
cc-session PATH --export <text|markdown|json|jsonl> [--select k=v ...] [-o OUT]

PATH is a Claude or Codex .jsonl file, or a directory (directories load recursively). --tools lists paired tool calls; --queries prints the full why/queried/returned timeline; --list indexes sessions in a directory; --audit reports Claude schema coverage over the target (field names + value-types only, safe to share).

--export writes a filtered slice of the session; --select narrows it (space-separated key=comma,values): parts= (text,thinking,tool_use,tool_result,image,other), tools=, types=, uuids=, main_only=true. -o writes to a file instead of stdout.

cc-session-map [TRANSCRIPTS_DIR] [-o OUT_DIR]   # default: ~/.claude/projects, .

Aggregates per transcript and overall: turns (main vs sidechain), tool usage, token usage by kind, server web tools, and cost; writes map.json and map.csv into OUT_DIR.

MCP server

cc-session-mcp (stdio) exposes list_sessions, session_summary, tool_calls, export_session, and audit. Session listing and lookup search both default Claude and Codex roots. It needs the mcp extra (pip install "cc-session-core[mcp]"). Register in a Claude Code .mcp.json:

{
  "mcpServers": {
    "cc-session": { "command": "cc-session-mcp" }
  }
}

Tests

uv sync --all-groups                                    # pytest, ruff, pyright, mcp
uv run pytest                                           # fast unit tests on frozen, scrubbed fixtures
CC_SESSION_CORPUS=~/.claude/projects uv run pytest -m corpus   # opt-in: asserts zero Unknown*/extra/parse-failures on real data

The corpus test is the lossless coverage gate: it fails if any real line lands in an Unknown* fallback, leaves a field in model_extra, or a modeled built-in tool result falls back to raw. Fixtures are regenerated with python tests/_extract_fixtures.py (CC_SESSION_CORPUS set); free-text, paths, and base64 are scrubbed.

Metadata

Release files for cc-session-core 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cc-session-core 0.2.0
File Size Uploaded Provenance Actions
cc_session_core-0.2.0.tar.gz 80.2 kB With provenance Details for cc_session_core-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cc-session-core 0.2.0
File Interpreter ABI Platform Actions
cc_session_core-0.2.0-py3-none-any.whl Python 3 none any Details for cc_session_core-0.2.0-py3-none-any.whl

Total release size: 146.6 kB

Release files / cc_session_core-0.2.0.tar.gz

Download URL cc_session_core-0.2.0.tar.gz
Size 80.2 kB
Tags Source
SHA-256 checksum
How to use checksums
82453571c349703207004a2cf0d4834c4b025101b0df004aa1253e65b5974964
BLAKE2b-256 checksum
How to use checksums
0cce0fc200df2ee4e2007229171c45bc7493b12b3537f7632636e6ce005ea13c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

Release files / cc_session_core-0.2.0-py3-none-any.whl

Download URL cc_session_core-0.2.0-py3-none-any.whl
Size 66.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
163085c5f869f151386f90479acbadf1d9a533ce537003eb94b53830868d05fc
BLAKE2b-256 checksum
How to use checksums
72bbc83f1a90815579659b7be56b999b3288895ebb5003c71aad583afe14f0ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

Security for cc-session-core 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cc_session_core-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page