cctx-cli 0.1.0__tar.gz

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.
Files changed (146) hide show
  1. cctx_cli-0.1.0/.github/workflows/ci.yml +38 -0
  2. cctx_cli-0.1.0/.github/workflows/publish.yml +48 -0
  3. cctx_cli-0.1.0/.gitignore +36 -0
  4. cctx_cli-0.1.0/CLAUDE.md +176 -0
  5. cctx_cli-0.1.0/DESIGN.md +54 -0
  6. cctx_cli-0.1.0/PKG-INFO +159 -0
  7. cctx_cli-0.1.0/PRODUCT.md +109 -0
  8. cctx_cli-0.1.0/README.md +139 -0
  9. cctx_cli-0.1.0/cctx/__init__.py +3 -0
  10. cctx_cli-0.1.0/cctx/cli.py +375 -0
  11. cctx_cli-0.1.0/cctx/diagnostician/__init__.py +81 -0
  12. cctx_cli-0.1.0/cctx/diagnostician/aggregate.py +40 -0
  13. cctx_cli-0.1.0/cctx/diagnostician/inflection.py +19 -0
  14. cctx_cli-0.1.0/cctx/diagnostician/patterns/__init__.py +1 -0
  15. cctx_cli-0.1.0/cctx/diagnostician/patterns/retry_loop.py +145 -0
  16. cctx_cli-0.1.0/cctx/diagnostician/patterns/scope_creep.py +87 -0
  17. cctx_cli-0.1.0/cctx/diagnostician/patterns/stale_context.py +147 -0
  18. cctx_cli-0.1.0/cctx/discovery.py +185 -0
  19. cctx_cli-0.1.0/cctx/exporters/__init__.py +0 -0
  20. cctx_cli-0.1.0/cctx/exporters/csv.py +64 -0
  21. cctx_cli-0.1.0/cctx/exporters/jsonl.py +64 -0
  22. cctx_cli-0.1.0/cctx/harvest.py +173 -0
  23. cctx_cli-0.1.0/cctx/models.py +269 -0
  24. cctx_cli-0.1.0/cctx/parsers/__init__.py +1 -0
  25. cctx_cli-0.1.0/cctx/parsers/claude_code.py +690 -0
  26. cctx_cli-0.1.0/cctx/pricing.py +18 -0
  27. cctx_cli-0.1.0/cctx/recommender/__init__.py +0 -0
  28. cctx_cli-0.1.0/cctx/recommender/claude_md.py +131 -0
  29. cctx_cli-0.1.0/cctx/recommender/evidence.py +46 -0
  30. cctx_cli-0.1.0/cctx/renderers/__init__.py +0 -0
  31. cctx_cli-0.1.0/cctx/renderers/report.py +58 -0
  32. cctx_cli-0.1.0/cctx/renderers/templates/autopsy.html.j2 +249 -0
  33. cctx_cli-0.1.0/cctx/renderers/terminal.py +251 -0
  34. cctx_cli-0.1.0/cctx/renderers/trace_tui.py +291 -0
  35. cctx_cli-0.1.0/cctx/tokenizer.py +77 -0
  36. cctx_cli-0.1.0/cctx-project-brief.md +372 -0
  37. cctx_cli-0.1.0/demo.gif +0 -0
  38. cctx_cli-0.1.0/demo.tape +14 -0
  39. cctx_cli-0.1.0/docs/health-reviews/2026-05-15-deep-review-summary.md +226 -0
  40. cctx_cli-0.1.0/docs/health-reviews/2026-05-15-health-review.md +149 -0
  41. cctx_cli-0.1.0/docs/product-reviews/2026-05-15-product-review.md +315 -0
  42. cctx_cli-0.1.0/docs/superpowers/plans/2026-05-12-claude-code-parser.md +3635 -0
  43. cctx_cli-0.1.0/docs/superpowers/plans/2026-05-14-autopsy-v0.md +2940 -0
  44. cctx_cli-0.1.0/docs/superpowers/plans/2026-05-16-readme-pypi-release.md +345 -0
  45. cctx_cli-0.1.0/docs/superpowers/specs/2026-05-12-claude-code-parser-design.md +433 -0
  46. cctx_cli-0.1.0/docs/superpowers/specs/2026-05-14-autopsy-design.md +618 -0
  47. cctx_cli-0.1.0/docs/superpowers/specs/2026-05-14-harvest-design.md +392 -0
  48. cctx_cli-0.1.0/docs/superpowers/specs/2026-05-14-trace-tui-design.md +733 -0
  49. cctx_cli-0.1.0/docs/superpowers/specs/2026-05-16-readme-pypi-release-design.md +178 -0
  50. cctx_cli-0.1.0/pyproject.toml +72 -0
  51. cctx_cli-0.1.0/tests/__init__.py +0 -0
  52. cctx_cli-0.1.0/tests/conftest.py +168 -0
  53. cctx_cli-0.1.0/tests/diagnostician/__init__.py +1 -0
  54. cctx_cli-0.1.0/tests/diagnostician/conftest.py +109 -0
  55. cctx_cli-0.1.0/tests/diagnostician/test_inflection.py +47 -0
  56. cctx_cli-0.1.0/tests/diagnostician/test_orchestrator.py +215 -0
  57. cctx_cli-0.1.0/tests/diagnostician/test_retry_loop.py +159 -0
  58. cctx_cli-0.1.0/tests/diagnostician/test_scope_creep.py +114 -0
  59. cctx_cli-0.1.0/tests/diagnostician/test_stale_context.py +165 -0
  60. cctx_cli-0.1.0/tests/exporters/__init__.py +0 -0
  61. cctx_cli-0.1.0/tests/exporters/test_csv.py +333 -0
  62. cctx_cli-0.1.0/tests/exporters/test_jsonl.py +251 -0
  63. cctx_cli-0.1.0/tests/fixtures/claude_code/README.md +28 -0
  64. cctx_cli-0.1.0/tests/fixtures/claude_code/short-clean/short-clean.jsonl +7 -0
  65. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a0b4c2cf1dde0ca56.meta.json +1 -0
  66. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a116ae34b1b09c332.meta.json +1 -0
  67. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a1c4c417b35658c9e.meta.json +1 -0
  68. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a1e41a901de38f1b5.meta.json +1 -0
  69. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a338f8d0c74612a24.meta.json +1 -0
  70. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a34f6f3c0e7094186.meta.json +1 -0
  71. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a5a5a0cff4d13308b.meta.json +1 -0
  72. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a6b0a3da6a0484db5.meta.json +1 -0
  73. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a7f73f1790b02cde5.meta.json +1 -0
  74. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a7f7c17c38a9d8788.meta.json +1 -0
  75. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a853259e2cd7bbe8a.meta.json +1 -0
  76. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-a8d9aedb0d0c6e12d.meta.json +1 -0
  77. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-aa778bc1d59e4a441.meta.json +1 -0
  78. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-aba869dedee4a12ba.meta.json +1 -0
  79. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-ada2746d9774b94db.meta.json +1 -0
  80. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-aea0132068c64d2dd.meta.json +1 -0
  81. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-aea215eff50874d5f.meta.json +1 -0
  82. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments/subagents/agent-afee21f2b3852a4a0.meta.json +1 -0
  83. cctx_cli-0.1.0/tests/fixtures/claude_code/with-attachments/with-attachments.jsonl +500 -0
  84. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a051d9c9a6b2f5cc3.jsonl +75 -0
  85. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a051d9c9a6b2f5cc3.meta.json +1 -0
  86. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a171f16f4e65cfe75.jsonl +41 -0
  87. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a171f16f4e65cfe75.meta.json +1 -0
  88. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a1b77fea2c0a2269b.jsonl +15 -0
  89. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a1b77fea2c0a2269b.meta.json +1 -0
  90. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a20da4c01a54acca8.jsonl +16 -0
  91. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a20da4c01a54acca8.meta.json +1 -0
  92. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a3c82739b1383fb14.jsonl +113 -0
  93. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a3c82739b1383fb14.meta.json +1 -0
  94. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a49e8539611c5fe12.jsonl +7 -0
  95. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a49e8539611c5fe12.meta.json +1 -0
  96. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a7bb58f3fff2b3e8d.jsonl +10 -0
  97. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a7bb58f3fff2b3e8d.meta.json +1 -0
  98. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a92b48c0331195aac.jsonl +92 -0
  99. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-a92b48c0331195aac.meta.json +1 -0
  100. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-ab96c4264099694a9.jsonl +8 -0
  101. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-ab96c4264099694a9.meta.json +1 -0
  102. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-acb2895c5e34ffec0.jsonl +41 -0
  103. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-acb2895c5e34ffec0.meta.json +1 -0
  104. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-adb2302769938fb3f.jsonl +62 -0
  105. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-adb2302769938fb3f.meta.json +1 -0
  106. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-ae585eca15cb93b9c.jsonl +35 -0
  107. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-ae585eca15cb93b9c.meta.json +1 -0
  108. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-aec9c917feb903d67.jsonl +77 -0
  109. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction/subagents/agent-aec9c917feb903d67.meta.json +1 -0
  110. cctx_cli-0.1.0/tests/fixtures/claude_code/with-compaction/with-compaction.jsonl +580 -0
  111. cctx_cli-0.1.0/tests/fixtures/claude_code/with-subagents/with-subagents/subagents/agent-a1a3a21aeb76bb0a9.jsonl +10 -0
  112. cctx_cli-0.1.0/tests/fixtures/claude_code/with-subagents/with-subagents/subagents/agent-a1a3a21aeb76bb0a9.meta.json +1 -0
  113. cctx_cli-0.1.0/tests/fixtures/claude_code/with-subagents/with-subagents/subagents/agent-aaa1d6ecc05a78442.jsonl +9 -0
  114. cctx_cli-0.1.0/tests/fixtures/claude_code/with-subagents/with-subagents/subagents/agent-aaa1d6ecc05a78442.meta.json +1 -0
  115. cctx_cli-0.1.0/tests/fixtures/claude_code/with-subagents/with-subagents/subagents/agent-af3c545ccd30036d2.jsonl +7 -0
  116. cctx_cli-0.1.0/tests/fixtures/claude_code/with-subagents/with-subagents/subagents/agent-af3c545ccd30036d2.meta.json +1 -0
  117. cctx_cli-0.1.0/tests/fixtures/claude_code/with-subagents/with-subagents/tool-results/btwp2bzro.txt +34 -0
  118. cctx_cli-0.1.0/tests/fixtures/claude_code/with-subagents/with-subagents/tool-results/byqjbgy4b.txt +17 -0
  119. cctx_cli-0.1.0/tests/fixtures/claude_code/with-subagents/with-subagents.jsonl +2218 -0
  120. cctx_cli-0.1.0/tests/fixtures/claude_code/with-tool-results/with-tool-results/tool-results/bosbkda0h.txt +13 -0
  121. cctx_cli-0.1.0/tests/fixtures/claude_code/with-tool-results/with-tool-results.jsonl +71 -0
  122. cctx_cli-0.1.0/tests/fixtures/scrub.py +167 -0
  123. cctx_cli-0.1.0/tests/fixtures/synthetic/bookkeeping_only.jsonl +3 -0
  124. cctx_cli-0.1.0/tests/fixtures/synthetic/malformed_middle.jsonl +3 -0
  125. cctx_cli-0.1.0/tests/fixtures/synthetic/truncated_final_line.jsonl +2 -0
  126. cctx_cli-0.1.0/tests/fixtures/synthetic/unknown_attachment_shape.jsonl +1 -0
  127. cctx_cli-0.1.0/tests/fixtures/synthetic/unknown_type.jsonl +2 -0
  128. cctx_cli-0.1.0/tests/parsers/__init__.py +0 -0
  129. cctx_cli-0.1.0/tests/parsers/test_claude_code.py +879 -0
  130. cctx_cli-0.1.0/tests/parsers/test_claude_code_integration.py +44 -0
  131. cctx_cli-0.1.0/tests/recommender/__init__.py +0 -0
  132. cctx_cli-0.1.0/tests/recommender/test_claude_md.py +353 -0
  133. cctx_cli-0.1.0/tests/recommender/test_evidence.py +139 -0
  134. cctx_cli-0.1.0/tests/renderers/__init__.py +0 -0
  135. cctx_cli-0.1.0/tests/renderers/test_report.py +283 -0
  136. cctx_cli-0.1.0/tests/renderers/test_terminal_renderer_full.py +310 -0
  137. cctx_cli-0.1.0/tests/test_aggregate.py +69 -0
  138. cctx_cli-0.1.0/tests/test_cli.py +102 -0
  139. cctx_cli-0.1.0/tests/test_cli_export.py +157 -0
  140. cctx_cli-0.1.0/tests/test_discovery.py +288 -0
  141. cctx_cli-0.1.0/tests/test_harvest.py +316 -0
  142. cctx_cli-0.1.0/tests/test_models.py +647 -0
  143. cctx_cli-0.1.0/tests/test_smoke.py +36 -0
  144. cctx_cli-0.1.0/tests/test_terminal_renderer.py +106 -0
  145. cctx_cli-0.1.0/tests/test_tokenizer.py +136 -0
  146. cctx_cli-0.1.0/tests/test_trace_tui.py +274 -0
@@ -0,0 +1,38 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ concurrency:
9
+ group: ${{ github.workflow }}-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ jobs:
13
+ test:
14
+ name: test (py${{ matrix.python-version }})
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - uses: actions/setup-python@v5
24
+ with:
25
+ python-version: ${{ matrix.python-version }}
26
+ cache: pip
27
+ cache-dependency-path: pyproject.toml
28
+
29
+ - name: Install
30
+ run: pip install -e ".[dev]"
31
+
32
+ - name: Ruff check
33
+ run: ruff check cctx tests
34
+
35
+ - name: Pytest
36
+ env:
37
+ CCTX_OFFLINE: "1"
38
+ run: pytest -v
@@ -0,0 +1,48 @@
1
+ name: publish
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ test:
9
+ name: Test before publish
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - uses: actions/setup-python@v5
15
+ with:
16
+ python-version: "3.12"
17
+
18
+ - name: Install
19
+ run: pip install -e ".[dev]"
20
+
21
+ - name: Pytest
22
+ env:
23
+ CCTX_OFFLINE: "1"
24
+ run: pytest -v
25
+
26
+ publish:
27
+ name: Publish to PyPI
28
+ needs: [test]
29
+ runs-on: ubuntu-latest
30
+ environment: pypi
31
+ permissions:
32
+ id-token: write
33
+ contents: read
34
+
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+
38
+ - uses: actions/setup-python@v5
39
+ with:
40
+ python-version: "3.12"
41
+
42
+ - name: Build
43
+ run: |
44
+ pip install build
45
+ python -m build
46
+
47
+ - name: Publish
48
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,36 @@
1
+ # macOS
2
+ .DS_Store
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+ *.egg-info/
9
+ build/
10
+ dist/
11
+ .eggs/
12
+ pip-log.txt
13
+
14
+ # Virtual environments
15
+ .venv/
16
+ venv/
17
+ env/
18
+
19
+ # Test / coverage / type-check caches
20
+ .pytest_cache/
21
+ .ruff_cache/
22
+ .mypy_cache/
23
+ .tox/
24
+ .coverage
25
+ .coverage.*
26
+ htmlcov/
27
+ coverage.xml
28
+
29
+ # IDE
30
+ .idea/
31
+ .vscode/
32
+ *.swp
33
+ *.swo
34
+
35
+ # Local Claude Code settings (machine-specific permissions)
36
+ .claude/settings.local.json
@@ -0,0 +1,176 @@
1
+ # cctx
2
+
3
+ Open-source Python CLI that diagnoses individual Claude Code sessions: when they went wrong, why they went wrong, what they cost, and what to add to your `CLAUDE.md` so it doesn't happen again. Reads the JSONL session logs Claude Code writes to `~/.claude/projects/` and produces actionable autopsy reports.
4
+
5
+ The complete product pitch, example outputs, growth staircase, and positioning vs. adjacent tools are in [`cctx-project-brief.md`](cctx-project-brief.md). Read it once.
6
+
7
+ ## Tech stack
8
+
9
+ - **Python 3.10+**
10
+ - **click** — CLI argument parsing and subcommand routing
11
+ - **rich-click** — re-skins click's `--help` through rich (drop-in: `import rich_click as click`). Pure shininess win on the `--help` surface, no behavioral cost
12
+ - **rich** — terminal output: tables, banners, severity badges, diff blocks
13
+ - **textual** — the TUI for `cctx trace`
14
+ - **anthropic** — token counting only, via `anthropic.messages.count_tokens` in the tokenizer module. **Not imported anywhere else.**
15
+ - **pandas** — optional, only inside the cross-session aggregator if/when row-level work justifies it. Stdlib-first.
16
+ - **Jinja2** — HTML report templates for `cctx autopsy --html`
17
+
18
+ Explicitly not used: web frameworks, databases, ORMs, async runtimes, cloud SDKs. cctx is a local CLI.
19
+
20
+ ## Architecture
21
+
22
+ ```
23
+ Session log (Claude Code JSONL on disk)
24
+
25
+ Parser ← dependency-free; takes a path, returns SessionTrace
26
+
27
+ Tokenizer ← only place that imports anthropic; offline-mode safe for CI
28
+
29
+ Diagnostician ← per-turn investigation: inflection detection + pattern
30
+ classifiers (retry loop, scope creep, stale context).
31
+ Produces a Diagnosis.
32
+
33
+ Recommender ← turns Findings into Patches: copy-pasteable CLAUDE.md /
34
+ rule / skill diffs, evidence-backed when cross-session.
35
+
36
+ Renderers ← rich (terminal), Jinja2 (HTML report), textual (trace
37
+ TUI overlay).
38
+
39
+ Exporters ← jsonl, csv.
40
+ ```
41
+
42
+ ## Project layout
43
+
44
+ ```
45
+ cctx/
46
+ ├── cli.py # click + rich-click; routes to autopsy / trace / export
47
+ ├── parsers/
48
+ │ └── claude_code.py # SHIPPED. Parse ~/.claude JSONL logs.
49
+ │ # Spec: docs/superpowers/specs/2026-05-12-claude-code-parser-design.md
50
+ ├── tokenizer.py # SHIPPED. anthropic.count_tokens wrapper; CCTX_OFFLINE heuristic.
51
+ ├── models.py # SHIPPED. Turn, ToolUse, ToolResult, Usage, Attachment,
52
+ │ # RawToolResultFile, SessionTrace + group_into_exchanges().
53
+ │ # M2 extends with Finding, Patch, Diagnosis.
54
+ ├── diagnostician/
55
+ │ ├── __init__.py # public: run(trace) -> Diagnosis
56
+ │ ├── inflection.py # detect the turn where the session diverged
57
+ │ ├── patterns/
58
+ │ │ ├── retry_loop.py
59
+ │ │ ├── scope_creep.py
60
+ │ │ └── stale_context.py
61
+ │ └── aggregate.py # cross-session pattern aggregator (--since mode)
62
+ ├── recommender/
63
+ │ ├── claude_md.py # Finding -> Patch (CLAUDE.md diff proposals)
64
+ │ └── evidence.py # session-count + dollar evidence accumulation
65
+ ├── harvest.py # SHIPPED. apply_patch, preview_patches, apply_patches —
66
+ │ # append-only, idempotent CLAUDE.md patching with
67
+ │ # fingerprint-based deduplication.
68
+ ├── renderers/
69
+ │ ├── terminal.py # rich rendering of a Diagnosis
70
+ │ ├── report.py # Jinja2 HTML report (cctx autopsy --html)
71
+ │ └── trace_tui.py # textual TUI with autopsy findings overlaid
72
+ └── exporters/
73
+ ├── jsonl.py
74
+ └── csv.py
75
+ ```
76
+
77
+ ## Layering rules (enforced by convention)
78
+
79
+ These keep the dependency graph clean so modules stay independently testable and refactorable:
80
+
81
+ - **Parsers never import the tokenizer, the anthropic SDK, or any analyzer.** A parser takes a path and returns a `SessionTrace` with `token_count: int = 0` placeholders.
82
+ - **Tokenizer is the only module that imports `anthropic`.** Everyone else gets token counts pre-populated on the dataclasses.
83
+ - **Analyzers (diagnostician, recommender, aggregate) never import each other across boundary lines.** Inside the diagnostician package, helpers can compose freely. The recommender takes a Diagnosis and emits Patches without reaching back into the diagnostician's internals.
84
+ - **Renderers never compute analysis.** They take an analyzer's output and render it. Swapping `terminal.py` for `report.py` should not change a single number or finding.
85
+ - **Only `cli.py` imports `click` and `rich_click`.** Everything else uses plain `rich.Console` if it needs to output. Analyzers and parsers return data; the CLI decides how to display it.
86
+
87
+ ## Core design decisions
88
+
89
+ These came out of the brief, the parser brainstorming session, and the autopsy pivot. They apply across the entire codebase:
90
+
91
+ - **Diagnose the specific session, not the aggregate.** cctx is forensic. CodeBurn covers daily cost tracking; cctx is "what went sideways here, and what do I add to CLAUDE.md so it doesn't happen again."
92
+ - **Token-turns is a useful metric for stale-content attribution.** `tokens × turns_present`, compaction-aware. A 22K grep result sitting in context for 14 turns after its last reference costs ~310K token-turns of waste. This is how stale-context findings attribute their dollar cost.
93
+ - **Approximate decomposition is fine.** Reconstructing the API request from the JSONL gets you ~85–95% of the actual `input_tokens`. The remainder is internal framing you can't observe. The system internals slice is honest; don't pretend to be exact.
94
+ - **Binary waste detection only in v1.** "Loaded but never called" is high-confidence. "Partially used" is fragile. Ship the binary version.
95
+ - **Patches must be copy-pasteable.** Every Patch carries a unified diff against a target file (CLAUDE.md, rules, skill, ADR). Lower the barrier to action to zero.
96
+ - **Single-session AND cross-session, same diagnostician.** `cctx autopsy <session>` and `cctx autopsy <project> --since <window>` go through the same per-session pipeline; the aggregator runs after.
97
+ - **Group up, never down.** Parse at the finest granularity the source provides (per JSONL line). Aggregate in the view layer. (Originated in the parser design — applies everywhere.)
98
+ - **Empirical evidence collapses speculative complexity.** Before designing for a hypothetical case, scan real data. The parser spec's tool-result handling was simplified by 80% after one 30-line empirical scan.
99
+ - **Deterministic over LLM-assisted in v0.** Pattern classifiers use heuristics, not LLM calls. (Future v1+ harvest may invoke an LLM for summarization, opt-in with API key.) The deterministic core has predictable cost and is testable on fixtures.
100
+
101
+ ## Build order (post-pivot)
102
+
103
+ 1. **M0 — Project setup.** SHIPPED. (#1)
104
+ 2. **M1 — Foundation.** SHIPPED — parser, tokenizer, models, fixtures, CI. (#2–#6, plus PR #38)
105
+ 3. **M2 — Autopsy v0.** SHIPPED — single-session diagnosis + cross-session pattern detection. The wedge product. (#9, #10, #40–#49)
106
+ 4. **M3 — Trace TUI** with autopsy overlay. SHIPPED. (PR #57)
107
+ 5. **M4 — Export.** SHIPPED — jsonl + csv exporters (html moved to autopsy --html; json deferred). (PR #54)
108
+ 6. **M5 — Harvest v1.** SHIPPED — CLAUDE.md target only in v0; promote autopsy findings to durable CLAUDE.md diffs. (PR #56)
109
+ 7. **M6 — Release v0.1.0.** Release prep underway — README, PRODUCT.md, DESIGN.md, version bump, PyPI publish. (#31, #32)
110
+
111
+ Future, not yet milestoned:
112
+ - **Memory hygiene** (`cctx harvest --check`) — audit existing CLAUDE.md and memory files for staleness / contradictions / dead skills.
113
+ - **Live mode** (`cctx watch`) — filesystem watcher on `~/.claude/projects` to surface waste signals during a session.
114
+ - **Cross-agent layer** — emit the same captured knowledge as `.cursorrules`, `AGENTS.md`, `.windsurfrules`, GitHub Copilot instructions.
115
+
116
+ ## Design docs
117
+
118
+ Feature designs live in `docs/superpowers/specs/`, dated and committed before implementation begins. Each implementation plan in `docs/superpowers/plans/` references its spec. Don't start a feature without one.
119
+
120
+ Current specs landed on main:
121
+ - `docs/superpowers/specs/2026-05-12-claude-code-parser-design.md` — the Claude Code JSONL parser.
122
+
123
+ In progress / pending:
124
+ - `docs/superpowers/specs/<date>-autopsy-design.md` — autopsy v0 design (#40). The next spec to be brainstormed.
125
+
126
+ ## GitHub issue structure
127
+
128
+ The post-pivot board is anchored to autopsy. New work should follow the same conventions so the board stays coherent.
129
+
130
+ **Granularity.** One issue = one PR. If a ticket can't reasonably land in a single PR, split it. Cross-cutting infrastructure gets its own ticket rather than being buried inside the first consumer. Test fixtures that block a feature get their own ticket. High-polish or novel surfaces (e.g. the TUI) split into spec + implementation.
131
+
132
+ **Milestones.** Phases get milestones (`M0 — Project setup` through `M6 — Release v0.1.0`). Every issue belongs to exactly one milestone. Add a new milestone if a phase is genuinely new; don't reuse an existing milestone for unrelated work.
133
+
134
+ **Labels.** Use `area:*` labels only (parser, analyzer, cli, renderer, exporter, tokenizer, tui, models, infra, docs). An issue can have multiple `area:` labels if it touches multiple layers. Don't invent new label taxonomies (priority, type, status) — milestones + the issue board cover that.
135
+
136
+ **Body template.** Every issue has these sections, in this order:
137
+
138
+ ```markdown
139
+ **Phase:** Mn — <phase name>
140
+ **Module:** `path/to/file.py` (or files plural)
141
+
142
+ ## Goal
143
+ One paragraph: what this delivers and why.
144
+
145
+ ## Acceptance criteria
146
+ - [ ] Spec at `docs/superpowers/specs/<date>-<slug>.md` reviewed first (if a spec is warranted — see below)
147
+ - [ ] Concrete, testable items
148
+ - [ ] Tests that prove the behavior
149
+ - [ ] Layering invariants honored (e.g. "no imports from `anthropic`")
150
+
151
+ ## Files
152
+ - Exact paths the PR touches
153
+
154
+ ## References
155
+ - Brief sections, prior spec sections, CLAUDE.md sections
156
+
157
+ ## Blocked by
158
+ - (Posted as a comment with `#N` references after all related issues are filed — GitHub auto-links and surfaces the dependency graph.)
159
+ ```
160
+
161
+ **Spec gate inside the ticket.** CLAUDE.md requires specs before implementation. The default is **the spec is the first acceptance-criteria checkbox in the implementation ticket**, not a separate ticket. Exceptions: surfaces big enough that the spec is itself a meaningful deliverable (the autopsy v0 design is #40 — separate from the implementation tickets that consume it).
162
+
163
+ **Dependencies.** After filing a batch of issues, post a comment on each blocked ticket: `Blocked by #N, #M`. GitHub auto-links and shows the parent/child relationship in the timeline. Don't try to encode the dep graph in the issue body — it goes stale and is painful to maintain.
164
+
165
+ **Granularity smell tests** (use these when proposing a new ticket):
166
+ - *Too thick* — needs two specs, two reviewers, or PRs in two different areas (`area:parser` + `area:cli`). Split along the layering boundary.
167
+ - *Too thin* — the entire ticket fits in a 5-line PR with no tests. Combine with its sibling.
168
+ - *Hidden dependency* — the work assumes something exists that isn't filed yet. File that first or note it as blocked-by.
169
+
170
+ ## Working in this repo
171
+
172
+ - The brief is authoritative for product scope. Don't rewrite it during implementation; if scope needs to change, amend the brief deliberately.
173
+ - Specs are authoritative for module design. Don't deviate during implementation without updating the spec.
174
+ - When implementing a feature: write the spec, get it reviewed, then write the plan (via the superpowers `writing-plans` skill), then implement.
175
+ - The parser is dependency-free by design. If you find yourself adding `import anthropic` or `import click` inside `parsers/`, stop — that work belongs in `tokenizer.py` or `cli.py`.
176
+ - The tokenizer's offline mode (`CCTX_OFFLINE=1`) is the default for CI and tests. Live tokenization happens only when the CLI explicitly opts in and `ANTHROPIC_API_KEY` is set.
@@ -0,0 +1,54 @@
1
+ # cctx Design System
2
+
3
+ Reference for the three output surfaces: Rich terminal, Textual TUI, Jinja2 HTML report.
4
+
5
+ ## Color palette (terminal/TUI)
6
+
7
+ | State | Rich style |
8
+ |---|---|
9
+ | HIGH severity | `bold red` |
10
+ | MEDIUM severity | `bold yellow` |
11
+ | LOW severity | `bold green` |
12
+ | Applied/success | `green` |
13
+ | Error/failure | `red` |
14
+ | Skipped/neutral | `dim` |
15
+
16
+ ## Cost formatting
17
+
18
+ | Context | Format | Example |
19
+ |---|---|---|
20
+ | User-facing summary (verdict, totals) | `:.2f` | `$1.42` |
21
+ | Per-finding detail | `:.4f` | `$0.0082` |
22
+
23
+ ## Finding kind labels
24
+
25
+ Canonical display form is space-separated uppercase. Never use the raw enum value in user-facing output.
26
+
27
+ | Enum value | Display label |
28
+ |---|---|
29
+ | `retry_loop` | `RETRY LOOP` |
30
+ | `scope_creep` | `SCOPE CREEP` |
31
+ | `stale_context` | `STALE CONTEXT` |
32
+
33
+ Use `_KIND_LABEL` dict in `renderers/terminal.py` as the source of truth. The HTML template currently uses `.replace("_", " ").upper()` inline — this is equivalent for the three current kinds but will diverge if a new kind uses a non-underscore separator.
34
+
35
+ ## Verdict string
36
+
37
+ Format across all surfaces: `"Clean session"` (no findings) or `"{n} finding(s) · ${waste:.2f} waste"` (with findings).
38
+
39
+ The brief examples use `"⚠ retry loop + scope creep"` (kind-based) — that is a future format, not yet implemented.
40
+
41
+ ## Evidence rendering
42
+
43
+ | Surface | Rendering |
44
+ |---|---|
45
+ | Terminal | `finding.summary` inline text |
46
+ | HTML report | Per-finding `<details>` with evidence as formatted JSON (TODO: structured per-kind in v0.2) |
47
+ | TUI FindingModal | Summary + raw evidence (TODO: structured per-kind in v0.2) |
48
+
49
+ ## Anti-patterns
50
+
51
+ - **Never** use `red` style for success states (APPLIED patch = success = green)
52
+ - **Never** render evidence dicts as raw `json.dumps` in the primary user-facing path (HTML verdict area is OK for v0; structured per-kind in v0.2)
53
+ - **Never** define CSS syntax-highlighting classes without corresponding template markup to apply them
54
+ - **Never** import `click` or `rich_click` outside `cli.py`
@@ -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
+ [![CI](https://github.com/jacquardlabs/cctx/actions/workflows/ci.yml/badge.svg)](https://github.com/jacquardlabs/cctx/actions/workflows/ci.yml)
26
+ [![PyPI](https://img.shields.io/pypi/v/cctx-cli)](https://pypi.org/project/cctx-cli/)
27
+ [![Python](https://img.shields.io/badge/python-3.10_%7C_3.11_%7C_3.12_%7C_3.13-blue)](https://pypi.org/project/cctx-cli/)
28
+ [![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
29
+
30
+ ![demo](demo.gif)
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,109 @@
1
+ # PRODUCT.md — cctx
2
+
3
+ ## What is this
4
+
5
+ cctx is a local Python CLI that reads Claude Code session logs and tells you what went wrong, why it cost what it did, and what to add to your CLAUDE.md so it doesn't happen again.
6
+
7
+ It is a forensic tool, not a monitoring tool. You reach for it after a session — when something felt off, when the bill was higher than expected, or on a weekly review pass.
8
+
9
+ ## Primary persona
10
+
11
+ **The regular Claude Code user** who:
12
+ - Runs multiple Claude Code sessions per day across one or more projects
13
+ - Maintains a CLAUDE.md and wants it to get smarter over time
14
+ - Is willing to read a terminal report and act on its suggestions
15
+ - Cares about cost and session quality but does not need a dashboard
16
+ - Is comfortable with the command line and with `~/.claude/projects/` on disk
17
+
18
+ This persona is already the target; everything shipped to date serves them directly.
19
+
20
+ ## What cctx is NOT for
21
+
22
+ - Teams or organizations (no shared reports, no access control, no multi-user state)
23
+ - Real-time monitoring (completed sessions only in v0 and v1)
24
+ - General cost dashboards (CodeBurn covers that; cctx is forensic)
25
+ - Multi-provider support (Claude Code only in v0/v1)
26
+ - Users who do not read session transcripts or maintain CLAUDE.md
27
+
28
+ ## Product principles
29
+
30
+ **1. Forensic, not ambient.**
31
+ cctx is used after something goes wrong, not as background infrastructure. Every feature should be justified by this use case: "I just ran a session, something went sideways, I want to know what."
32
+
33
+ **2. Output must be actionable.**
34
+ Every report should produce at least one thing the user can do immediately. Findings without patches are incomplete. Patches must be copy-pasteable or auto-applicable.
35
+
36
+ **3. Honest about uncertainty.**
37
+ Costs are approximated (85–95% of actual). Pattern classifiers fire only on high-confidence signals. Low-confidence signals are shown with explicit confidence labels. "System internals" token budget is never hidden or misattributed.
38
+
39
+ **4. Local and stateless.**
40
+ No network calls in the core analysis path (tokenizer may call the API for token counting; that is opt-in). No persistent database. No telemetry. No account. Users own their data.
41
+
42
+ **5. Deterministic.**
43
+ Pattern classifiers are heuristics, not LLM calls. The same session file produces the same output every time. Testable on fixtures. Predictable cost to run.
44
+
45
+ **6. Small surface, deep on each command.**
46
+ Four commands. No command is shallow. Users should be able to learn the product in an afternoon and trust what it tells them.
47
+
48
+ ## Feature map (v0.1.0)
49
+
50
+ ### Shipped
51
+
52
+ | Feature | Command | Status |
53
+ |---|---|---|
54
+ | Single-session diagnosis | `cctx autopsy <session>` | Shipped (M2) |
55
+ | Cross-session pattern detection | `cctx autopsy <project> --since N` | Shipped (M2) |
56
+ | HTML report | `cctx autopsy <session> --html FILE` | Shipped (M2/PR#59) |
57
+ | Session trace TUI | `cctx trace <session>` | Shipped (M3) |
58
+ | JSONL export | `cctx export <session> --format jsonl` | Shipped (M4) |
59
+ | CSV export | `cctx export <session> --format csv` | Shipped (M4) |
60
+ | Harvest (CLAUDE.md patcher) | `cctx harvest <session>` | Shipped (M5) |
61
+ | Cross-session harvest | `cctx harvest <project> --since N` | Shipped (M5) |
62
+
63
+ ### Pattern classifiers (v0.1.0)
64
+
65
+ | Pattern | Status |
66
+ |---|---|
67
+ | Retry loop | Shipped |
68
+ | Scope creep | Shipped |
69
+ | Stale context | Shipped |
70
+ | Dead-end exploration | Not shipped in v0 |
71
+ | Tool thrashing | Not shipped in v0 |
72
+
73
+ ### NOT in v0.1.0
74
+
75
+ - `--format json` and `--format html` on `export` (html moved to `autopsy --html`; json not scheduled)
76
+ - `--since` string formats (`7d`, `2w`, date ranges, `--until`, `--top N`) — accepts integer days only
77
+ - Patch targets other than `CLAUDE.md` (rules, skills, ADR — v1+)
78
+ - Interactive aggregate drill-down ("press N to inspect pattern") — read-only in v0
79
+ - `cctx ls` / session discovery helper
80
+ - Dead-end and tool-thrash classifiers
81
+
82
+ ## What we are NOT building
83
+
84
+ - A SaaS or cloud product
85
+ - An agent (cctx reads logs; it does not call the Anthropic API except optionally for token counting)
86
+ - A real-time watcher (v2+ roadmap item)
87
+ - Multi-provider support (v3+ roadmap item)
88
+ - A fork-and-replay debugger
89
+ - A general eval or testing framework
90
+
91
+ ## Known problems (as of 2026-05-15)
92
+
93
+ **Release blockers for v0.1.0 (M6):**
94
+
95
+ 1. **No README.md.** `pyproject.toml` uses `cctx-project-brief.md` as the readme. The brief contains architecture diagrams and an internal "First session prompt" that should not be on PyPI. A user-facing README.md is required before publish.
96
+
97
+ 2. **`pyproject.toml` description is inaccurate.** Current: "Profile, debug, and optimize Claude Code and Agent SDK sessions." Accurate: "Diagnose Claude Code sessions — find what went wrong, what it cost, and what to add to CLAUDE.md."
98
+
99
+ 3. **Version is `0.0.1`.** M6 requires bumping to `0.1.0`.
100
+
101
+ 4. **Brief example outputs show unshipped features.** The `cctx-project-brief.md` (which currently IS the readme) shows 5 pattern classifiers, 4 export formats, string `--since` arguments, a `Verdict` headline, and interactive aggregate output. None of these are accurate for the shipped CLI. Before PyPI publish, either ship them or update the brief.
102
+
103
+ **Active gaps (non-blocking for v0.1.0 but worth tracking):**
104
+
105
+ 5. **Cost approximation honesty not surfaced in output.** The terminal renderer shows `$X.XX` total cost with no confidence annotation. The brief says "The system internals slice is honest; don't pretend to be exact" — this is a principle not yet expressed to users in output.
106
+
107
+ 6. **No session discovery helper.** Users must manually navigate URL-encoded project directories in `~/.claude/projects/` to find session files. First-run friction.
108
+
109
+ 7. **Aggregate output is read-only.** The brief's example shows an interactive aggregate view. Shipped aggregate is a static table. The interactive drill-down is a meaningful UX gap that the brief implicitly promises.