cc-transcript 9.0.1__tar.gz → 10.0.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 (76) hide show
  1. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/Cargo.lock +130 -12
  2. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/PKG-INFO +14 -14
  3. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/README.md +13 -13
  4. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/__init__.py +2 -0
  5. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/_parser_rs.pyi +14 -0
  6. cc_transcript-10.0.0/cc_transcript/activity_probe.py +224 -0
  7. cc_transcript-10.0.0/cc_transcript/notifications.py +115 -0
  8. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/query.py +6 -0
  9. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/pyproject.toml +1 -1
  10. cc_transcript-10.0.0/rust/Cargo.toml +40 -0
  11. cc_transcript-10.0.0/rust/src/activity.rs +463 -0
  12. cc_transcript-10.0.0/rust/src/event.rs +288 -0
  13. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/rust/src/filter.rs +41 -44
  14. cc_transcript-10.0.0/rust/src/lib.rs +22 -0
  15. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/rust/src/mining.rs +132 -252
  16. cc_transcript-10.0.0/rust/src/parse.rs +628 -0
  17. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/rust/src/protocol.rs +9 -9
  18. cc_transcript-9.0.1/rust/src/lib.rs → cc_transcript-10.0.0/rust/src/python.rs +57 -45
  19. cc_transcript-10.0.0/rust/src/types.rs +331 -0
  20. cc_transcript-10.0.0/rust/src/value.rs +19 -0
  21. cc_transcript-9.0.1/rust/Cargo.toml +0 -29
  22. cc_transcript-9.0.1/rust/src/event.rs +0 -459
  23. cc_transcript-9.0.1/rust/src/value.rs +0 -44
  24. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/Cargo.toml +0 -0
  25. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/LICENSE +0 -0
  26. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/__main__.py +0 -0
  27. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/activity.py +0 -0
  28. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/backend.py +0 -0
  29. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/builders.py +0 -0
  30. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/cli.py +0 -0
  31. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/command.py +0 -0
  32. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/context.py +0 -0
  33. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/corrections.py +0 -0
  34. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/corrections_cli.py +0 -0
  35. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/cost.py +0 -0
  36. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/decisions.py +0 -0
  37. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/discovery.py +0 -0
  38. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/disktruth.py +0 -0
  39. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/evidence.py +0 -0
  40. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/extract/__init__.py +0 -0
  41. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/extract/correct.py +0 -0
  42. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/facts.py +0 -0
  43. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/filterspec.py +0 -0
  44. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/ids.py +0 -0
  45. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/judge/__init__.py +0 -0
  46. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/judge/llm.py +0 -0
  47. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/judge/similar.py +0 -0
  48. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/judge/verdicts.py +0 -0
  49. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/__init__.py +0 -0
  50. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/candidates.py +0 -0
  51. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/confidence.py +0 -0
  52. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/engine.py +0 -0
  53. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/filterspec.py +0 -0
  54. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/formats.py +0 -0
  55. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/signals.py +0 -0
  56. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/sourcekind.py +0 -0
  57. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/spec.py +0 -0
  58. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/mining/store.py +0 -0
  59. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/models.py +0 -0
  60. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/parser.py +0 -0
  61. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/py.typed +0 -0
  62. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/render.py +0 -0
  63. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/rust.py +0 -0
  64. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/sentiment/__init__.py +0 -0
  65. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/sentiment/buckets.py +0 -0
  66. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/sentiment/engine.py +0 -0
  67. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/sentiment/lexicon.py +0 -0
  68. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/sentiment/scorespec.py +0 -0
  69. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/store.py +0 -0
  70. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/cc_transcript/tools.py +0 -0
  71. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/rust/data/afinn-en-165.tsv +0 -0
  72. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/rust/data/domain_overrides.tsv +0 -0
  73. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/rust/src/command.rs +0 -0
  74. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/rust/src/lexicon.rs +0 -0
  75. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/rust/src/model.rs +0 -0
  76. {cc_transcript-9.0.1 → cc_transcript-10.0.0}/rust/src/score.rs +0 -0
@@ -42,6 +42,12 @@ version = "0.22.1"
42
42
  source = "registry+https://github.com/rust-lang/crates.io-index"
43
43
  checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
44
44
 
45
+ [[package]]
46
+ name = "bitflags"
47
+ version = "2.13.0"
48
+ source = "registry+https://github.com/rust-lang/crates.io-index"
49
+ checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
50
+
45
51
  [[package]]
46
52
  name = "bumpalo"
47
53
  version = "3.20.3"
@@ -77,13 +83,21 @@ dependencies = [
77
83
  "pyo3",
78
84
  "rayon",
79
85
  "regex",
80
- "serde",
81
86
  "sonic-rs",
82
87
  "tree-sitter",
83
88
  "tree-sitter-bash",
84
89
  "udpipe-rs",
85
90
  ]
86
91
 
92
+ [[package]]
93
+ name = "cc_transcript_swift"
94
+ version = "0.8.0"
95
+ dependencies = [
96
+ "cc_transcript_parser",
97
+ "swift-bridge",
98
+ "swift-bridge-build",
99
+ ]
100
+
87
101
  [[package]]
88
102
  name = "cfg-if"
89
103
  version = "1.0.4"
@@ -175,6 +189,22 @@ version = "1.0.2"
175
189
  source = "registry+https://github.com/rust-lang/crates.io-index"
176
190
  checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
177
191
 
192
+ [[package]]
193
+ name = "errno"
194
+ version = "0.3.14"
195
+ source = "registry+https://github.com/rust-lang/crates.io-index"
196
+ checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
197
+ dependencies = [
198
+ "libc",
199
+ "windows-sys 0.52.0",
200
+ ]
201
+
202
+ [[package]]
203
+ name = "fastrand"
204
+ version = "2.4.1"
205
+ source = "registry+https://github.com/rust-lang/crates.io-index"
206
+ checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
207
+
178
208
  [[package]]
179
209
  name = "faststr"
180
210
  version = "0.2.34"
@@ -327,6 +357,12 @@ dependencies = [
327
357
  "libc",
328
358
  ]
329
359
 
360
+ [[package]]
361
+ name = "linux-raw-sys"
362
+ version = "0.12.1"
363
+ source = "registry+https://github.com/rust-lang/crates.io-index"
364
+ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
365
+
330
366
  [[package]]
331
367
  name = "log"
332
368
  version = "0.4.32"
@@ -366,7 +402,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931"
366
402
  dependencies = [
367
403
  "proc-macro2",
368
404
  "quote",
369
- "syn",
405
+ "syn 2.0.117",
370
406
  ]
371
407
 
372
408
  [[package]]
@@ -444,7 +480,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1"
444
480
  dependencies = [
445
481
  "proc-macro2",
446
482
  "quote",
447
- "syn",
483
+ "syn 2.0.117",
448
484
  ]
449
485
 
450
486
  [[package]]
@@ -490,7 +526,7 @@ dependencies = [
490
526
  "proc-macro2",
491
527
  "pyo3-macros-backend",
492
528
  "quote",
493
- "syn",
529
+ "syn 2.0.117",
494
530
  ]
495
531
 
496
532
  [[package]]
@@ -503,7 +539,7 @@ dependencies = [
503
539
  "proc-macro2",
504
540
  "pyo3-build-config",
505
541
  "quote",
506
- "syn",
542
+ "syn 2.0.117",
507
543
  ]
508
544
 
509
545
  [[package]]
@@ -578,7 +614,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
578
614
  dependencies = [
579
615
  "proc-macro2",
580
616
  "quote",
581
- "syn",
617
+ "syn 2.0.117",
582
618
  ]
583
619
 
584
620
  [[package]]
@@ -656,7 +692,20 @@ checksum = "5d2ed0b54125315fb36bd021e82d314d1c126548f871634b483f46b31d13cac6"
656
692
  dependencies = [
657
693
  "proc-macro2",
658
694
  "quote",
659
- "syn",
695
+ "syn 2.0.117",
696
+ ]
697
+
698
+ [[package]]
699
+ name = "rustix"
700
+ version = "1.1.4"
701
+ source = "registry+https://github.com/rust-lang/crates.io-index"
702
+ checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
703
+ dependencies = [
704
+ "bitflags",
705
+ "errno",
706
+ "libc",
707
+ "linux-raw-sys",
708
+ "windows-sys 0.52.0",
660
709
  ]
661
710
 
662
711
  [[package]]
@@ -727,7 +776,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
727
776
  dependencies = [
728
777
  "proc-macro2",
729
778
  "quote",
730
- "syn",
779
+ "syn 2.0.117",
731
780
  ]
732
781
 
733
782
  [[package]]
@@ -819,6 +868,62 @@ version = "2.6.1"
819
868
  source = "registry+https://github.com/rust-lang/crates.io-index"
820
869
  checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
821
870
 
871
+ [[package]]
872
+ name = "swift-bridge"
873
+ version = "0.1.59"
874
+ source = "registry+https://github.com/rust-lang/crates.io-index"
875
+ checksum = "384ed39ea10f1cefabb197b7d8e67f0034b15a94ccbb1038b8e020da59bfb0be"
876
+ dependencies = [
877
+ "swift-bridge-build",
878
+ "swift-bridge-macro",
879
+ ]
880
+
881
+ [[package]]
882
+ name = "swift-bridge-build"
883
+ version = "0.1.59"
884
+ source = "registry+https://github.com/rust-lang/crates.io-index"
885
+ checksum = "71b36df21e7f8a8b5eeb718d2e71f9cfc308477bfb705981cca705de9767dcb7"
886
+ dependencies = [
887
+ "proc-macro2",
888
+ "swift-bridge-ir",
889
+ "syn 1.0.109",
890
+ "tempfile",
891
+ ]
892
+
893
+ [[package]]
894
+ name = "swift-bridge-ir"
895
+ version = "0.1.59"
896
+ source = "registry+https://github.com/rust-lang/crates.io-index"
897
+ checksum = "c73bd16155df50708b92306945656e57d62d321290a7db490f299f709fb31c83"
898
+ dependencies = [
899
+ "proc-macro2",
900
+ "quote",
901
+ "syn 1.0.109",
902
+ ]
903
+
904
+ [[package]]
905
+ name = "swift-bridge-macro"
906
+ version = "0.1.59"
907
+ source = "registry+https://github.com/rust-lang/crates.io-index"
908
+ checksum = "a1a13dc0dc875d85341dec5b5344a7d713f20eb5650b71086b27d09a6ece272f"
909
+ dependencies = [
910
+ "proc-macro2",
911
+ "quote",
912
+ "swift-bridge-ir",
913
+ "syn 1.0.109",
914
+ ]
915
+
916
+ [[package]]
917
+ name = "syn"
918
+ version = "1.0.109"
919
+ source = "registry+https://github.com/rust-lang/crates.io-index"
920
+ checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
921
+ dependencies = [
922
+ "proc-macro2",
923
+ "quote",
924
+ "unicode-ident",
925
+ ]
926
+
822
927
  [[package]]
823
928
  name = "syn"
824
929
  version = "2.0.117"
@@ -836,6 +941,19 @@ version = "0.13.5"
836
941
  source = "registry+https://github.com/rust-lang/crates.io-index"
837
942
  checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
838
943
 
944
+ [[package]]
945
+ name = "tempfile"
946
+ version = "3.27.0"
947
+ source = "registry+https://github.com/rust-lang/crates.io-index"
948
+ checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
949
+ dependencies = [
950
+ "fastrand",
951
+ "getrandom 0.3.4",
952
+ "once_cell",
953
+ "rustix",
954
+ "windows-sys 0.52.0",
955
+ ]
956
+
839
957
  [[package]]
840
958
  name = "thiserror"
841
959
  version = "1.0.69"
@@ -862,7 +980,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
862
980
  dependencies = [
863
981
  "proc-macro2",
864
982
  "quote",
865
- "syn",
983
+ "syn 2.0.117",
866
984
  ]
867
985
 
868
986
  [[package]]
@@ -873,7 +991,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
873
991
  dependencies = [
874
992
  "proc-macro2",
875
993
  "quote",
876
- "syn",
994
+ "syn 2.0.117",
877
995
  ]
878
996
 
879
997
  [[package]]
@@ -1041,7 +1159,7 @@ dependencies = [
1041
1159
  "bumpalo",
1042
1160
  "proc-macro2",
1043
1161
  "quote",
1044
- "syn",
1162
+ "syn 2.0.117",
1045
1163
  "wasm-bindgen-shared",
1046
1164
  ]
1047
1165
 
@@ -1225,7 +1343,7 @@ checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639"
1225
1343
  dependencies = [
1226
1344
  "proc-macro2",
1227
1345
  "quote",
1228
- "syn",
1346
+ "syn 2.0.117",
1229
1347
  ]
1230
1348
 
1231
1349
  [[package]]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cc-transcript
3
- Version: 9.0.1
3
+ Version: 10.0.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -47,7 +47,7 @@ Project-URL: Repository, https://github.com/yasyf/cc-transcript
47
47
 
48
48
  [![CI](https://github.com/yasyf/cc-transcript/actions/workflows/ci.yml/badge.svg)](https://github.com/yasyf/cc-transcript/actions/workflows/ci.yml)
49
49
  [![PyPI](https://img.shields.io/pypi/v/cc-transcript.svg)](https://pypi.org/project/cc-transcript/)
50
- [![License: PolyForm Noncommercial](https://img.shields.io/badge/license-PolyForm--Noncommercial--1.0.0-blue)](https://github.com/yasyf/cc-transcript/blob/main/LICENSE)
50
+ [![License PolyForm Noncommercial](https://img.shields.io/badge/license-PolyForm--Noncommercial--1.0.0-blue)](https://github.com/yasyf/cc-transcript/blob/main/LICENSE)
51
51
 
52
52
  ## Get started
53
53
 
@@ -55,9 +55,9 @@ Project-URL: Repository, https://github.com/yasyf/cc-transcript
55
55
  uvx cc-transcript list
56
56
  ```
57
57
 
58
- Every session is already on disk under `~/.claude/projects` `list` finds them newest first, and `stats` collapses one into a screenful:
58
+ Every session is already on disk under `~/.claude/projects`. `list` finds them newest first, and `stats` collapses one into a screenful:
59
59
 
60
- <img src="https://github.com/yasyf/cc-transcript/raw/main/docs/assets/demo.png" alt="Terminal running 'uvx cc-transcript stats' — a 1,023-event session summarized as counts, kinds, models, and tool names" width="700">
60
+ <img src="https://github.com/yasyf/cc-transcript/raw/main/docs/assets/demo.png" alt="Terminal running 'uvx cc-transcript stats' — one session summarized as counts, kinds, models, and tool names" width="700">
61
61
 
62
62
  Driving with an agent? Paste this:
63
63
 
@@ -66,7 +66,7 @@ Driving with an agent? Paste this:
66
66
  /plugin install cc-transcript@cc-transcript
67
67
  ```
68
68
 
69
- The plugin's skill teaches Claude to answer "what did I ask you yesterday?" from its own history, funneling through the CLI instead of reading raw JSONL.
69
+ The plugin's skill teaches Claude to answer "what did I ask you yesterday" from its own history, funneling through the CLI instead of reading raw JSONL.
70
70
 
71
71
  <details>
72
72
  <summary>No Claude Code? Point any agent at the CLI</summary>
@@ -92,7 +92,7 @@ Yesterday's session is a megabyte of JSONL, and pasting it into a chat blows the
92
92
  uvx cc-transcript show --signal --tail 20 ~/.claude/projects/<project>/<session>.jsonl
93
93
  ```
94
94
 
95
- `--signal` keeps only the substantive user and assistant turns one line per event, a few hundred tokens for the whole exchange. With the plugin installed, skip the command: ask Claude directly and its skill runs this funnel for you.
95
+ `--signal` keeps only the substantive user and assistant turns. One line per event, a few hundred tokens for the whole exchange. With the plugin installed, skip the command and ask Claude directly; its skill runs this funnel for you.
96
96
 
97
97
  ### Find the session where you fixed that bug
98
98
 
@@ -102,7 +102,7 @@ The fix happened weeks ago, in one of a few hundred transcripts. Search them all
102
102
  uvx cc-transcript grep "TranscriptExpiredError" --project cc-transcript
103
103
  ```
104
104
 
105
- Hits print under their transcript's path, each line carrying its raw event index feed an index back into `show --range` to re-read the conversation around the fix. `grep` searches your newest 50 transcripts by default; `--all` takes it to every session on disk, and a no-match run exits 1 so it scripts cleanly.
105
+ Hits print under their transcript's path, each line carrying its raw event index; feed an index back into `show --range` to re-read the conversation around the fix. `grep` searches your newest 50 transcripts by default; `--all` takes it to every session on disk, and a no-match run exits 1 so it scripts cleanly.
106
106
 
107
107
  ### Debug a token blowup from transcript evidence
108
108
 
@@ -112,16 +112,16 @@ A session burned through the context window and you want the culprit, not a gues
112
112
  uvx cc-transcript stats --per-file --project myapp
113
113
  ```
114
114
 
115
- Each block reports text, thinking, and tool-io bytes plus per-tool call counts the blowup stands out as an outsized `tool io` line. Then `grep --tool <name> --with-result` pins it to the exact calls.
115
+ Each block reports text, thinking, and tool-io bytes plus per-tool call counts; the blowup stands out as an outsized `tool io` line. Then `grep --tool <name> --with-result` pins it to the exact calls.
116
116
 
117
117
  ## More in the docs
118
118
 
119
- - **The Python library** raw JSONL bytes to typed events, a composed filter, and a score in a dozen lines — [getting started](https://yasyf.github.io/cc-transcript/docs/getting-started/index.html)
120
- - **Filtering events** — composable clauses, specs, and the ready-made `NOISE_SPEC` — [builder catalog](https://yasyf.github.io/cc-transcript/docs/guide/filtering-events.html)
121
- - **Sentiment scoring** — bucket conversations and score them around any inference engine — [score specs](https://yasyf.github.io/cc-transcript/docs/guide/scoring-sentiment.html)
122
- - **Feedback mining** detectors, confidence calibration, and LLM verdict passes over your corpus — [mine your sessions](https://yasyf.github.io/cc-transcript/docs/guide/mining-feedback.html)
123
- - **Two backends, one protocol** a Rust fast path and a Python reference, parity-asserted against each other — [how parity works](https://yasyf.github.io/cc-transcript/docs/guide/backends-and-parity.html)
124
- - **API reference** the complete typed surface, from `TranscriptEvent` to `SessionActivity` — [reference](https://yasyf.github.io/cc-transcript/reference/index.html)
119
+ - [The Python library](https://yasyf.github.io/cc-transcript/docs/getting-started/index.html) turns raw JSONL bytes into typed events, a composed filter, and a score in a dozen lines.
120
+ - [Filtering events](https://yasyf.github.io/cc-transcript/docs/guide/filtering-events.html) covers composable clauses, specs, and the ready-made `NOISE_SPEC`.
121
+ - [Sentiment scoring](https://yasyf.github.io/cc-transcript/docs/guide/scoring-sentiment.html) buckets conversations and scores them around any inference engine.
122
+ - [Feedback mining](https://yasyf.github.io/cc-transcript/docs/guide/mining-feedback.html) runs detectors, confidence calibration, and LLM verdict passes over your corpus.
123
+ - [Two backends, one protocol](https://yasyf.github.io/cc-transcript/docs/guide/backends-and-parity.html) pairs a Rust fast path with a Python reference, parity-asserted against each other.
124
+ - [API reference](https://yasyf.github.io/cc-transcript/reference/index.html) documents the complete typed surface, from `TranscriptEvent` to `SessionActivity`.
125
125
 
126
126
  Read the [docs](https://yasyf.github.io/cc-transcript/) for the full guide. Licensed under [PolyForm Noncommercial 1.0.0](https://github.com/yasyf/cc-transcript/blob/main/LICENSE).
127
127
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![CI](https://github.com/yasyf/cc-transcript/actions/workflows/ci.yml/badge.svg)](https://github.com/yasyf/cc-transcript/actions/workflows/ci.yml)
6
6
  [![PyPI](https://img.shields.io/pypi/v/cc-transcript.svg)](https://pypi.org/project/cc-transcript/)
7
- [![License: PolyForm Noncommercial](https://img.shields.io/badge/license-PolyForm--Noncommercial--1.0.0-blue)](https://github.com/yasyf/cc-transcript/blob/main/LICENSE)
7
+ [![License PolyForm Noncommercial](https://img.shields.io/badge/license-PolyForm--Noncommercial--1.0.0-blue)](https://github.com/yasyf/cc-transcript/blob/main/LICENSE)
8
8
 
9
9
  ## Get started
10
10
 
@@ -12,9 +12,9 @@
12
12
  uvx cc-transcript list
13
13
  ```
14
14
 
15
- Every session is already on disk under `~/.claude/projects` `list` finds them newest first, and `stats` collapses one into a screenful:
15
+ Every session is already on disk under `~/.claude/projects`. `list` finds them newest first, and `stats` collapses one into a screenful:
16
16
 
17
- <img src="https://github.com/yasyf/cc-transcript/raw/main/docs/assets/demo.png" alt="Terminal running 'uvx cc-transcript stats' — a 1,023-event session summarized as counts, kinds, models, and tool names" width="700">
17
+ <img src="https://github.com/yasyf/cc-transcript/raw/main/docs/assets/demo.png" alt="Terminal running 'uvx cc-transcript stats' — one session summarized as counts, kinds, models, and tool names" width="700">
18
18
 
19
19
  Driving with an agent? Paste this:
20
20
 
@@ -23,7 +23,7 @@ Driving with an agent? Paste this:
23
23
  /plugin install cc-transcript@cc-transcript
24
24
  ```
25
25
 
26
- The plugin's skill teaches Claude to answer "what did I ask you yesterday?" from its own history, funneling through the CLI instead of reading raw JSONL.
26
+ The plugin's skill teaches Claude to answer "what did I ask you yesterday" from its own history, funneling through the CLI instead of reading raw JSONL.
27
27
 
28
28
  <details>
29
29
  <summary>No Claude Code? Point any agent at the CLI</summary>
@@ -49,7 +49,7 @@ Yesterday's session is a megabyte of JSONL, and pasting it into a chat blows the
49
49
  uvx cc-transcript show --signal --tail 20 ~/.claude/projects/<project>/<session>.jsonl
50
50
  ```
51
51
 
52
- `--signal` keeps only the substantive user and assistant turns one line per event, a few hundred tokens for the whole exchange. With the plugin installed, skip the command: ask Claude directly and its skill runs this funnel for you.
52
+ `--signal` keeps only the substantive user and assistant turns. One line per event, a few hundred tokens for the whole exchange. With the plugin installed, skip the command and ask Claude directly; its skill runs this funnel for you.
53
53
 
54
54
  ### Find the session where you fixed that bug
55
55
 
@@ -59,7 +59,7 @@ The fix happened weeks ago, in one of a few hundred transcripts. Search them all
59
59
  uvx cc-transcript grep "TranscriptExpiredError" --project cc-transcript
60
60
  ```
61
61
 
62
- Hits print under their transcript's path, each line carrying its raw event index feed an index back into `show --range` to re-read the conversation around the fix. `grep` searches your newest 50 transcripts by default; `--all` takes it to every session on disk, and a no-match run exits 1 so it scripts cleanly.
62
+ Hits print under their transcript's path, each line carrying its raw event index; feed an index back into `show --range` to re-read the conversation around the fix. `grep` searches your newest 50 transcripts by default; `--all` takes it to every session on disk, and a no-match run exits 1 so it scripts cleanly.
63
63
 
64
64
  ### Debug a token blowup from transcript evidence
65
65
 
@@ -69,15 +69,15 @@ A session burned through the context window and you want the culprit, not a gues
69
69
  uvx cc-transcript stats --per-file --project myapp
70
70
  ```
71
71
 
72
- Each block reports text, thinking, and tool-io bytes plus per-tool call counts the blowup stands out as an outsized `tool io` line. Then `grep --tool <name> --with-result` pins it to the exact calls.
72
+ Each block reports text, thinking, and tool-io bytes plus per-tool call counts; the blowup stands out as an outsized `tool io` line. Then `grep --tool <name> --with-result` pins it to the exact calls.
73
73
 
74
74
  ## More in the docs
75
75
 
76
- - **The Python library** raw JSONL bytes to typed events, a composed filter, and a score in a dozen lines — [getting started](https://yasyf.github.io/cc-transcript/docs/getting-started/index.html)
77
- - **Filtering events** — composable clauses, specs, and the ready-made `NOISE_SPEC` — [builder catalog](https://yasyf.github.io/cc-transcript/docs/guide/filtering-events.html)
78
- - **Sentiment scoring** — bucket conversations and score them around any inference engine — [score specs](https://yasyf.github.io/cc-transcript/docs/guide/scoring-sentiment.html)
79
- - **Feedback mining** detectors, confidence calibration, and LLM verdict passes over your corpus — [mine your sessions](https://yasyf.github.io/cc-transcript/docs/guide/mining-feedback.html)
80
- - **Two backends, one protocol** a Rust fast path and a Python reference, parity-asserted against each other — [how parity works](https://yasyf.github.io/cc-transcript/docs/guide/backends-and-parity.html)
81
- - **API reference** the complete typed surface, from `TranscriptEvent` to `SessionActivity` — [reference](https://yasyf.github.io/cc-transcript/reference/index.html)
76
+ - [The Python library](https://yasyf.github.io/cc-transcript/docs/getting-started/index.html) turns raw JSONL bytes into typed events, a composed filter, and a score in a dozen lines.
77
+ - [Filtering events](https://yasyf.github.io/cc-transcript/docs/guide/filtering-events.html) covers composable clauses, specs, and the ready-made `NOISE_SPEC`.
78
+ - [Sentiment scoring](https://yasyf.github.io/cc-transcript/docs/guide/scoring-sentiment.html) buckets conversations and scores them around any inference engine.
79
+ - [Feedback mining](https://yasyf.github.io/cc-transcript/docs/guide/mining-feedback.html) runs detectors, confidence calibration, and LLM verdict passes over your corpus.
80
+ - [Two backends, one protocol](https://yasyf.github.io/cc-transcript/docs/guide/backends-and-parity.html) pairs a Rust fast path with a Python reference, parity-asserted against each other.
81
+ - [API reference](https://yasyf.github.io/cc-transcript/reference/index.html) documents the complete typed surface, from `TranscriptEvent` to `SessionActivity`.
82
82
 
83
83
  Read the [docs](https://yasyf.github.io/cc-transcript/) for the full guide. Licensed under [PolyForm Noncommercial 1.0.0](https://github.com/yasyf/cc-transcript/blob/main/LICENSE).
@@ -158,6 +158,7 @@ EXPORTS: dict[str, str] = {
158
158
  "capture_window",
159
159
  ),
160
160
  "cc_transcript.render": ("Budget", "render_session", "render_tool_call", "render_turn"),
161
+ "cc_transcript.notifications": ("Notifications",),
161
162
  "cc_transcript.query": ("FileRef", "Session", "SubagentIndex", "SubagentSession", "ToolCallQuery"),
162
163
  "cc_transcript.decisions": ("DECISIONS_DDL", "Action", "Decision", "DecisionLog"),
163
164
  "cc_transcript.disktruth": (
@@ -554,6 +555,7 @@ if TYPE_CHECKING:
554
555
  from cc_transcript.models import (
555
556
  tool_uses as tool_uses,
556
557
  )
558
+ from cc_transcript.notifications import Notifications as Notifications
557
559
  from cc_transcript.parser import (
558
560
  TranscriptParser as TranscriptParser,
559
561
  )
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing import Any
4
+
3
5
  from cc_transcript.models import PrintResult, TranscriptEvent
4
6
 
5
7
  class ParseStream:
@@ -41,3 +43,15 @@ def score_post_process(spec_json: str, buckets: list[list[str]], raw: list[int],
41
43
 
42
44
  def command_prefixes(commands: list[str], /) -> list[list[str]]:
43
45
  """Permission-style prefixes per command line, parsed in parallel off the GIL."""
46
+
47
+ def mine_signals(raw: bytes, spec_json: str, /) -> list[dict[str, Any]]:
48
+ """Parses raw transcript bytes and mines signal dicts per the portable mining spec."""
49
+
50
+ def session_activity_probe(
51
+ path: str, waiting_tools: list[str] | None = ..., human_facing_tools: list[str] | None = ..., /
52
+ ) -> dict[str, Any]:
53
+ """Parses the transcript at ``path`` and returns the session-activity verdict dict.
54
+
55
+ The dict carries ``is_waiting: bool``, ``mid_tool: bool``, ``last_event_epoch: int | None``,
56
+ and ``pending: list[dict]`` with ``tool_use_id``/``name``/``kind`` per contributing call.
57
+ """