cctx-cli 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cctx/__init__.py +3 -0
- cctx/cli.py +375 -0
- cctx/diagnostician/__init__.py +81 -0
- cctx/diagnostician/aggregate.py +40 -0
- cctx/diagnostician/inflection.py +19 -0
- cctx/diagnostician/patterns/__init__.py +1 -0
- cctx/diagnostician/patterns/retry_loop.py +145 -0
- cctx/diagnostician/patterns/scope_creep.py +87 -0
- cctx/diagnostician/patterns/stale_context.py +147 -0
- cctx/discovery.py +185 -0
- cctx/exporters/__init__.py +0 -0
- cctx/exporters/csv.py +64 -0
- cctx/exporters/jsonl.py +64 -0
- cctx/harvest.py +173 -0
- cctx/models.py +269 -0
- cctx/parsers/__init__.py +1 -0
- cctx/parsers/claude_code.py +690 -0
- cctx/pricing.py +18 -0
- cctx/recommender/__init__.py +0 -0
- cctx/recommender/claude_md.py +131 -0
- cctx/recommender/evidence.py +46 -0
- cctx/renderers/__init__.py +0 -0
- cctx/renderers/report.py +58 -0
- cctx/renderers/templates/autopsy.html.j2 +249 -0
- cctx/renderers/terminal.py +251 -0
- cctx/renderers/trace_tui.py +291 -0
- cctx/tokenizer.py +77 -0
- cctx_cli-0.1.0.dist-info/METADATA +159 -0
- cctx_cli-0.1.0.dist-info/RECORD +31 -0
- cctx_cli-0.1.0.dist-info/WHEEL +4 -0
- cctx_cli-0.1.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cctx-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Diagnose Claude Code sessions — find what went wrong, what it cost, and what to add to CLAUDE.md
|
|
5
|
+
Author: Jacquard Labs
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: anthropic>=0.25
|
|
9
|
+
Requires-Dist: click>=8.0
|
|
10
|
+
Requires-Dist: jinja2>=3.0
|
|
11
|
+
Requires-Dist: rich-click>=1.8
|
|
12
|
+
Requires-Dist: rich>=13.0
|
|
13
|
+
Requires-Dist: textual>=0.59
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: anyio[trio]; extra == 'dev'
|
|
16
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
17
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# cctx
|
|
22
|
+
|
|
23
|
+
Diagnose your Claude Code sessions — find out when they went wrong, why they cost what they did, and what to add to your `CLAUDE.md` so it doesn't happen again.
|
|
24
|
+
|
|
25
|
+
[](https://github.com/jacquardlabs/cctx/actions/workflows/ci.yml)
|
|
26
|
+
[](https://pypi.org/project/cctx-cli/)
|
|
27
|
+
[](https://pypi.org/project/cctx-cli/)
|
|
28
|
+
[](LICENSE)
|
|
29
|
+
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pipx install cctx-cli
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or with pip:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install cctx-cli
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`pipx` is recommended — it installs cctx in an isolated environment so its dependencies don't conflict with your projects.
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cctx ls # find your sessions
|
|
50
|
+
cctx autopsy --latest # diagnose the most recent one
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
cctx is a forensic tool. You reach for it after a session — when something felt off, when the cost was higher than expected, or on a weekly review pass. It reads the JSONL logs Claude Code writes to `~/.claude/projects/` and produces findings with attributed cost and copy-pasteable `CLAUDE.md` patches.
|
|
54
|
+
|
|
55
|
+
## Commands
|
|
56
|
+
|
|
57
|
+
### `cctx ls` — list projects and sessions
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
cctx ls # list all Claude Code projects
|
|
61
|
+
cctx ls ~/Projects/myapp # list sessions for a specific project
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `cctx autopsy` — diagnose a session
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Most recent session in the current directory
|
|
68
|
+
cctx autopsy --latest
|
|
69
|
+
|
|
70
|
+
# Specific session file
|
|
71
|
+
cctx autopsy ~/.claude/projects/-Users-you-Projects-myapp/abc123.jsonl
|
|
72
|
+
|
|
73
|
+
# All sessions from the last 7 days
|
|
74
|
+
cctx autopsy ~/Projects/myapp --since 7
|
|
75
|
+
|
|
76
|
+
# Write a self-contained HTML report
|
|
77
|
+
cctx autopsy ~/.claude/projects/-Users-you-Projects-myapp/abc123.jsonl --html report.html
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Runs three pattern classifiers (retry loop, scope creep, stale context) and prints findings with attributed cost. Use `--since N` to aggregate patterns across multiple sessions in a project.
|
|
81
|
+
|
|
82
|
+
### `cctx harvest` — apply patches to CLAUDE.md
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Interactive: preview then confirm
|
|
86
|
+
cctx harvest ~/.claude/projects/-Users-you-Projects-myapp/abc123.jsonl
|
|
87
|
+
|
|
88
|
+
# Preview only — don't write anything
|
|
89
|
+
cctx harvest ~/.claude/projects/-Users-you-Projects-myapp/abc123.jsonl --dry-run
|
|
90
|
+
|
|
91
|
+
# Apply without confirmation
|
|
92
|
+
cctx harvest ~/.claude/projects/-Users-you-Projects-myapp/abc123.jsonl --apply
|
|
93
|
+
|
|
94
|
+
# Cross-session: patches from the last 7 days of sessions
|
|
95
|
+
cctx harvest ~/Projects/myapp --since 7
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Turns autopsy findings into copy-pasteable `CLAUDE.md` additions. Patches are idempotent — running harvest twice on the same session won't duplicate entries. Use `--target-dir DIR` to specify which directory's `CLAUDE.md` to patch (default: current working directory).
|
|
99
|
+
|
|
100
|
+
### `cctx export` — export session data
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# CSV to file
|
|
104
|
+
cctx export ~/.claude/projects/-Users-you-Projects-myapp/abc123.jsonl --format csv --out session.csv
|
|
105
|
+
|
|
106
|
+
# JSONL to stdout
|
|
107
|
+
cctx export ~/.claude/projects/-Users-you-Projects-myapp/abc123.jsonl --format jsonl
|
|
108
|
+
|
|
109
|
+
# Omit patch text and finding summaries (smaller output for scripted use)
|
|
110
|
+
cctx export ~/.claude/projects/-Users-you-Projects-myapp/abc123.jsonl --format jsonl --no-content
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Dumps session analysis as JSONL (one object per session) or CSV (one row per turn) for use in external tools.
|
|
114
|
+
|
|
115
|
+
### `cctx trace` — interactive TUI
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cctx trace ~/.claude/projects/-Users-you-Projects-myapp/abc123.jsonl
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Steps through a session turn by turn in a terminal UI with autopsy findings overlaid. Press `q` to quit.
|
|
122
|
+
|
|
123
|
+
## What cctx detects
|
|
124
|
+
|
|
125
|
+
| Pattern | What it means | How it wastes money |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| **Retry loop** | The same tool call failing 2+ times with no successful fix | Repeated identical API calls burn input tokens |
|
|
128
|
+
| **Scope creep** | Assistant expanding scope mid-task without being asked | Unnecessary extra turns and tool calls |
|
|
129
|
+
| **Stale context** | Large tool results sitting in context long after their last reference | `content_tokens × billed_turns_stale` — a 22K grep result still present 14 turns later costs ~308K token-turns |
|
|
130
|
+
|
|
131
|
+
## Cost attribution
|
|
132
|
+
|
|
133
|
+
cctx estimates session cost using Anthropic's published billing rates:
|
|
134
|
+
|
|
135
|
+
- Input tokens: standard rate
|
|
136
|
+
- Cache reads: 10% of the input rate
|
|
137
|
+
- Cache writes: 125% of the input rate
|
|
138
|
+
|
|
139
|
+
Stale-context waste is attributed turn by turn: every turn a large result stays in context after its last reference counts against waste.
|
|
140
|
+
|
|
141
|
+
These are **approximations** (~85–95% of actual API billing). The gap is internal prompt framing that isn't observable in the JSONL logs. cctx shows estimated costs, not billing-exact figures.
|
|
142
|
+
|
|
143
|
+
## Requirements
|
|
144
|
+
|
|
145
|
+
- Python 3.10+
|
|
146
|
+
- Claude Code session logs at `~/.claude/projects/` (written automatically by Claude Code)
|
|
147
|
+
- No API key required for analysis
|
|
148
|
+
|
|
149
|
+
An `ANTHROPIC_API_KEY` is optional. When set, cctx can call the Anthropic API for exact token counts. Without it, cctx uses the token counts already recorded in the JSONL logs (the default and recommended mode for most users).
|
|
150
|
+
|
|
151
|
+
## Session log location
|
|
152
|
+
|
|
153
|
+
Claude Code writes logs to `~/.claude/projects/<encoded-path>/<session-id>.jsonl`. The project path is URL-encoded with `-` replacing `/`, so `/Users/you/Projects/myapp` becomes `-Users-you-Projects-myapp`.
|
|
154
|
+
|
|
155
|
+
`cctx ls` handles discovery automatically — you don't need to navigate the encoded directory structure by hand.
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
MIT
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
cctx/__init__.py,sha256=fgiHMk_CoF0UCot_yu-1KsIyOVOtpvGGBeZ0LkXKi94,100
|
|
2
|
+
cctx/cli.py,sha256=2EOWnN3RFzZCEmcjF3snX3-fOtpPsOUEw8hrXnqvTTg,12315
|
|
3
|
+
cctx/discovery.py,sha256=0Kytb1i9QssHejDWWQ6oTG_FJSqbxrvCdPFbLJsp1r8,5990
|
|
4
|
+
cctx/harvest.py,sha256=_eayKTYJ2F0ke1d35Y-KZ0JWRQOBdyB49EGn3lapGp0,5451
|
|
5
|
+
cctx/models.py,sha256=HZQfkANT1n4F6V8BoG4MbX8MwAnUAoQnXicWT3SiQhM,8207
|
|
6
|
+
cctx/pricing.py,sha256=bL_ExFf6sEZKIpqCvggBix3NbP9iMm4sWbFd-yjEH7E,616
|
|
7
|
+
cctx/tokenizer.py,sha256=OZweLUzPiKdyEQkmQEzQT_K4rQ_CDcnRtCQlcQS09Ww,2313
|
|
8
|
+
cctx/diagnostician/__init__.py,sha256=2oRnaphdsfEiEAj2qxAcWzmzU_vMoHMIOiBwufFVoSM,2808
|
|
9
|
+
cctx/diagnostician/aggregate.py,sha256=AlDzBvMV0EnWF-SSFw3A0VjGA0rrOYkXDuocHLsENxU,1264
|
|
10
|
+
cctx/diagnostician/inflection.py,sha256=662llgSnXj4d8I7t7LZC8Lv6yvp2NYtWNQtZPicr-b8,606
|
|
11
|
+
cctx/diagnostician/patterns/__init__.py,sha256=33Ps2ct4yXXpx-hHg03zGug4DmkgzOlmxoAXmP-GuIk,27
|
|
12
|
+
cctx/diagnostician/patterns/retry_loop.py,sha256=5tNUSD02pms5GSdgzSAX9mF2jNM1iaBiXxSXVrI-yvk,4555
|
|
13
|
+
cctx/diagnostician/patterns/scope_creep.py,sha256=bTNI5nUoRiUZjg5NI5bKslqkH_9vBvP15sJWzTos6as,2500
|
|
14
|
+
cctx/diagnostician/patterns/stale_context.py,sha256=Gq0fxVEmfV9it30IVNYebd9cn1ILIiOOVJ7SCl0goz0,4987
|
|
15
|
+
cctx/exporters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
cctx/exporters/csv.py,sha256=0Zhv0z8l7elEf0jdLR_vgT4dT5TG6hJqMj63P-IJLWA,2005
|
|
17
|
+
cctx/exporters/jsonl.py,sha256=6BYdME4-8lVri1CCZy4ravybcghCjACqpxGlZVM1uz8,1841
|
|
18
|
+
cctx/parsers/__init__.py,sha256=i_Y3dbwhGddRB66GTvy29rMmrFcfMktFophCRHplXZM,39
|
|
19
|
+
cctx/parsers/claude_code.py,sha256=13ltJ6mVR1vgjkw02EKEPq51W5Mxu-7GbBkyCKu81H8,23869
|
|
20
|
+
cctx/recommender/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
cctx/recommender/claude_md.py,sha256=jUNlPAg6kDGb_MDpHxCZ0prGkmFdeM2U0iO_VwSjtr0,4981
|
|
22
|
+
cctx/recommender/evidence.py,sha256=ND33Z4Z_udqiMMCaPBbyIjAyWBlIQHFJtoUBMD_fRZE,1720
|
|
23
|
+
cctx/renderers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
+
cctx/renderers/report.py,sha256=D9bEnnlxrXWrzn5qcy_oE_seUqxd-Q5O36m3pp9cHAk,1963
|
|
25
|
+
cctx/renderers/terminal.py,sha256=fC0TWv4asOYYey8TvJCNdIZcabMMGEQINEqNvv6AO0w,8055
|
|
26
|
+
cctx/renderers/trace_tui.py,sha256=FmtVT3o4hvB3T9NYyafOb4cw6spv6ts8bPBtVBDBs9c,10636
|
|
27
|
+
cctx/renderers/templates/autopsy.html.j2,sha256=P0ggSvpB7-ykJp6rQGF_MXKJh85iCTY3glI7JSeDBY4,8213
|
|
28
|
+
cctx_cli-0.1.0.dist-info/METADATA,sha256=k4JYA4wsKTTdfoobwg25g69P3Agtag9MNoJ6U_1ZVeU,6117
|
|
29
|
+
cctx_cli-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
30
|
+
cctx_cli-0.1.0.dist-info/entry_points.txt,sha256=Jdaxy27-9Top4lGdKW8Oaj_ETIS7sfEc-lw9R4Z_HkM,38
|
|
31
|
+
cctx_cli-0.1.0.dist-info/RECORD,,
|