Skip to main content

Typed, non-lossy events for Claude Code transcripts: a superset JSONL parser (Rust fast path, Python reference), sentiment and feedback-mining domains, and a transcript-investigation CLI.

Project description

cc-transcript

cc-transcript banner

PyPI Python Docs License: PolyForm Noncommercial

cc-transcript parses Claude Code's on-disk JSONL transcripts into a typed superset event model — every entry type preserved, nothing dropped — so you build on one faithful representation and apply your own semantic filtering on top.

The one property that makes it worth using: the parser is non-lossy. It never silently discards sidechains, synthetic turns, tool results, or unrecognized entry types; filtering is opt-in and lives in your code, not buried in the parser. It ships as a Python library, a uvx-runnable CLI, and a Claude Code plugin.

Install

uv add cc-transcript        # or: pip install cc-transcript
uvx cc-transcript --help    # CLI, no install needed

Quickstart

Discover the transcripts on disk, parse one, and look at the events:

import anyio

from cc_transcript import AssistantEvent, TranscriptDiscovery, UserEvent, parse_events_from_bytes

path = anyio.run(TranscriptDiscovery.find_transcripts)[0]
events = parse_events_from_bytes(path.read_bytes())

for event in events:
    match event:
        case UserEvent(text=text):
            print("user:", text[:80])
        case AssistantEvent(model=model, text=text):
            print(f"assistant ({model}):", text[:80])

Compose a filter from small builders and apply it. The builders return clauses, build_spec assembles them into a spec, and apply_spec yields the survivors:

from cc_transcript import apply_spec, build_spec, keep_only, drop_junk, drop_short

spec = build_spec(keep_only("user", "assistant"), drop_junk("structural"), drop_short(2))
clean = list(apply_spec(events, spec))

NOISE_SPEC is a ready-made spec for the universal structural noise (system reminders, local-command output, skill banners). For flag-style filtering, FilterConfig is also available — every rule is off by default, so a bare FilterConfig() passes everything through.

The CLI

Four commands — list, show, grep, stats — and every one runs as uvx cc-transcript ..., no install step. list finds transcripts, newest first:

$ uvx cc-transcript list --limit 3
2026-06-11 19:27    1.0MB ~/.claude/projects/-Users-yasyf-Code-captain-hook/d2ca206a-2561-4c2c-9a4c-3ecaac9f8443/subagents/agent-a804d9aea43a110b5.jsonl
2026-06-11 19:27   70.6KB ~/.claude/projects/-Users-yasyf-Code-cc-transcript/4c77d556-8694-4613-8f50-253d905da68e/subagents/agent-affd5dbe069a3660d.jsonl
2026-06-11 19:27  740.8KB ~/.claude/projects/-Users-yasyf-Code-cc-transcript/4c77d556-8694-4613-8f50-253d905da68e.jsonl
3 of 6608 transcripts under ~/.claude/projects

stats summarizes a session before you read any of it:

$ uvx cc-transcript stats ~/.claude/projects/-Users-yasyf-Code-cc-transcript/4c77d556-8694-4613-8f50-253d905da68e.jsonl
files        1
events       181
kinds        other 68 · assistant 53 · user 33 · mode 22 · system 5
models       claude-fable-5 53
tools        TaskCreate 10 · Agent 5 · Read 5 · TaskUpdate 5 · Bash 2 · ToolSearch 2 · AskUserQuestion 1 · ExitPlanMode 1
text         14.8KB
thinking     8.7KB
tool io      89.0KB
sessions     1
span         2026-06-12 01:07:55 → 2026-06-12 02:28:03
interrupts   0
tool errors  0
sidechain    0

show renders one compact line per event; --signal keeps the conversational spine, and the index column is the event's position in the raw file:

$ uvx cc-transcript show ~/.claude/projects/-Users-yasyf-Code-cc-transcript/4c77d556-8694-4613-8f50-253d905da68e.jsonl --signal --tail 4
  189 asst  02:30:49 [claude-fable-5] Bash(rg -A3 'name = "great-docs"' /Users/yasyf/Code/cc-transcript/uv.lock | head -6; echo ---; rg -n "cl…)
  194 asst  02:31:31 [claude-fable-5] "`cli:` support confirmed in the pinned great-docs. Checking the exact config shape before writing:"
  195 asst  02:31:31 [claude-fable-5] TaskUpdate(8)
  196 asst  02:31:32 [claude-fable-5] Bash(sed -n '40,60p;1750,1790p' /Users/yasyf/.cache/uv/git-v0/checkouts/a9f52a54772f9b4e/d318527/great_d…)

grep searches event content; hit indexes feed straight back into show --range:

$ uvx cc-transcript grep -i "filterspec" --kind user --max-matches 3 ~/.claude/projects/-Users-yasyf-Code-cc-transcript/4c77d556-8694-4613-8f50-253d905da68e.jsonl
== ~/.claude/projects/-Users-yasyf-Code-cc-transcript/4c77d556-8694-4613-8f50-253d905da68e.jsonl
   16 user  01:12:00 <-Agent (10161ch) ## Findings Report: cc-transcript Repository Based on a thorough exploration of `/Users/yasyf/Code/…
   29 user  01:16:29 <-? (1378ch) /Users/yasyf/Code/cc-transcript/cc_transcript/: total 8648 drwxr-xr-x@ 19 yasyf staff 608 Jun 11 17…
   69 user  01:36:17 <-Read (4247ch) 1 """Composable builder fragments for :class:`~cc_transcript.FilterSpec`. 2 3 Each fragment returns…
1 files, 3 matches

The output is compact by design — one line per event, hard truncation — so an agent triages a session in a few hundred tokens instead of paging through megabytes of JSONL.

Claude Code plugin

Install the bundled plugin from inside Claude Code:

/plugin marketplace add yasyf/cc-transcript
/plugin install cc-transcript@cc-transcript

The plugin's skill teaches Claude to answer questions about its own history — "what did I ask yesterday", "find the session where we fixed the parser" — by funneling through the CLI's list, stats, grep, and show commands instead of reading raw JSONL.

What problems does this solve?

  • One faithful parse. Anything reading Claude Code transcripts re-implements the same JSONL quirks (str-or-list content, tool results nested two ways, envelope-less mode markers). This is that parser, written once and typed strictly.
  • Non-lossy by design. The event model is a superset: sidechains, <synthetic> turns, thinking blocks, and unrecognized entry types all survive parsing. You decide what to drop, via composable filter specs (build_spec) or FilterConfig.
  • Incremental ingestion. FileStateStore tracks per-file mtimes in SQLite (WAL, safe across concurrent tasks) so re-runs only reparse changed files, and you compose your own writes in the same transaction.
  • Two engines, one contract. A single Backend protocol with two implementations: RustBackend (PyO3 + rayon) is the default fast path, and PythonBackend is the readable reference — parity-asserted against each other. Filter specs are portable, so a spec built in Python runs Rust-side without giving up the fast path.
  • Analysis domains. domains.sentiment scores conversational sentiment per time-bucketed conversation window; domains.mining mines transcripts for user feedback — detectors, confidence calibration, candidate filtering, and verdicts.
  • Transcript investigation for agents. The CLI answers "what happened in that session" in a few hundred tokens, which is what makes the Claude Code plugin viable.

Docs

Each section of the docs site is a focused guide:

License

PolyForm Noncommercial 1.0.0.

Project details


Download files

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

Source Distribution

cc_transcript-0.9.0.tar.gz (93.2 kB view details)

Uploaded Source

Built Distributions

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

cc_transcript-0.9.0-cp313-abi3-manylinux_2_28_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.13+manylinux: glibc 2.28+ x86-64

cc_transcript-0.9.0-cp313-abi3-manylinux_2_28_aarch64.whl (2.3 MB view details)

Uploaded CPython 3.13+manylinux: glibc 2.28+ ARM64

cc_transcript-0.9.0-cp313-abi3-macosx_11_0_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.13+macOS 11.0+ x86-64

cc_transcript-0.9.0-cp313-abi3-macosx_11_0_arm64.whl (2.1 MB view details)

Uploaded CPython 3.13+macOS 11.0+ ARM64

File details

Details for the file cc_transcript-0.9.0.tar.gz.

File metadata

  • Download URL: cc_transcript-0.9.0.tar.gz
  • Upload date:
  • Size: 93.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cc_transcript-0.9.0.tar.gz
Algorithm Hash digest
SHA256 e6f61ce7094e619a952a79e7c0779712fb45465c1f84a66d687834206cd288bb
MD5 27dd9aafab64b224b311d7e9355102da
BLAKE2b-256 192f444a781b5f27d23e449a82417cb352bcd3984d9a6ad5747871a5963a7dd1

See more details on using hashes here.

Provenance

The following attestation bundles were made for cc_transcript-0.9.0.tar.gz:

Publisher: release-pypi.yml on yasyf/cc-transcript

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

File details

Details for the file cc_transcript-0.9.0-cp313-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cc_transcript-0.9.0-cp313-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 17dd91bd99048b1f9ef3d7a2482c8d828d6c38bdf4621ce261c9a0179595f404
MD5 ab32b649a380382fcb87bfe365092771
BLAKE2b-256 15f02942879304bcf04d2fae1c2b10565a88270f33b1daa5abd07548ae0071f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for cc_transcript-0.9.0-cp313-abi3-manylinux_2_28_x86_64.whl:

Publisher: release-pypi.yml on yasyf/cc-transcript

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

File details

Details for the file cc_transcript-0.9.0-cp313-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for cc_transcript-0.9.0-cp313-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8ed52c69a65578c2d7ceae1509de8104f330012fc5b2b1eefae673c60b496850
MD5 c0034257cc4693fc5ec62ba11d027b44
BLAKE2b-256 c908d9b25ff10f88f48e8f4f3b07f101831ee3121624351a3ea96cb2b64f4b4c

See more details on using hashes here.

Provenance

The following attestation bundles were made for cc_transcript-0.9.0-cp313-abi3-manylinux_2_28_aarch64.whl:

Publisher: release-pypi.yml on yasyf/cc-transcript

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

File details

Details for the file cc_transcript-0.9.0-cp313-abi3-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for cc_transcript-0.9.0-cp313-abi3-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 6f9b2f26257edde83638d71f979f52fbe8db8bfa13ec5f0c20027b29121625a0
MD5 a84f79ed38a4996bd4918921bc8c3021
BLAKE2b-256 9b5d4d30f0db8a1b88eeb596f6768d693480f9e57ff04cba80c3cb4b0fbc64af

See more details on using hashes here.

Provenance

The following attestation bundles were made for cc_transcript-0.9.0-cp313-abi3-macosx_11_0_x86_64.whl:

Publisher: release-pypi.yml on yasyf/cc-transcript

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

File details

Details for the file cc_transcript-0.9.0-cp313-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for cc_transcript-0.9.0-cp313-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c0cec1171a42f72bf2d1604a2685a8d5e999f96dedc856e08a81d5eeb20f4a70
MD5 5ef182484176467b140d565deb464638
BLAKE2b-256 a966812d73223b23839f2f098c50814e47954961891084caed93884424fbe583

See more details on using hashes here.

Provenance

The following attestation bundles were made for cc_transcript-0.9.0-cp313-abi3-macosx_11_0_arm64.whl:

Publisher: release-pypi.yml on yasyf/cc-transcript

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