cc-transcript 12.1.0__tar.gz → 13.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 (91) hide show
  1. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/Cargo.lock +216 -2
  2. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/PKG-INFO +2 -2
  3. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/README.md +1 -1
  4. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/__init__.py +1 -2
  5. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/_parser_rs.pyi +12 -3
  6. cc_transcript-13.0.0/cc_transcript/activity_probe.py +98 -0
  7. cc_transcript-13.0.0/cc_transcript/backend.py +24 -0
  8. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/command.py +3 -17
  9. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/facts.py +1 -0
  10. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/filterspec.py +13 -38
  11. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/judge/similar.py +3 -1
  12. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/mining/__init__.py +9 -10
  13. cc_transcript-13.0.0/cc_transcript/mining/engine.py +78 -0
  14. cc_transcript-13.0.0/cc_transcript/mining/signals.py +65 -0
  15. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/mining/spec.py +30 -82
  16. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/mining/store.py +4 -2
  17. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/models.py +12 -7
  18. cc_transcript-13.0.0/cc_transcript/nlp.py +58 -0
  19. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/parser.py +33 -106
  20. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/query.py +5 -3
  21. cc_transcript-13.0.0/cc_transcript/sentiment/data/en-ewt.udpipe +0 -0
  22. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/sentiment/engine.py +10 -40
  23. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/sentiment/lexicon.py +18 -36
  24. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/sentiment/scorespec.py +2 -79
  25. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/tools.py +2 -2
  26. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/pyproject.toml +2 -2
  27. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/Cargo.toml +5 -0
  28. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/generated/mod.rs +0 -1
  29. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/lexicon.rs +36 -55
  30. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/lib.rs +2 -0
  31. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/mining.rs +317 -30
  32. cc_transcript-13.0.0/rust/src/nlp.rs +137 -0
  33. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/python.rs +27 -41
  34. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/score.rs +23 -22
  35. cc_transcript-12.1.0/cc_transcript/activity_probe.py +0 -225
  36. cc_transcript-12.1.0/cc_transcript/backend.py +0 -57
  37. cc_transcript-12.1.0/cc_transcript/mining/engine.py +0 -91
  38. cc_transcript-12.1.0/cc_transcript/mining/signals.py +0 -604
  39. cc_transcript-12.1.0/cc_transcript/rust.py +0 -51
  40. cc_transcript-12.1.0/rust/src/generated/unicode.rs +0 -665
  41. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/Cargo.toml +0 -0
  42. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/LICENSE +0 -0
  43. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/__main__.py +0 -0
  44. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/activity.py +0 -0
  45. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/builders.py +0 -0
  46. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/cli.py +0 -0
  47. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/context.py +0 -0
  48. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/corrections.py +0 -0
  49. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/corrections_cli.py +0 -0
  50. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/cost.py +0 -0
  51. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/decisions.py +0 -0
  52. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/discovery.py +0 -0
  53. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/disktruth.py +0 -0
  54. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/evidence.py +0 -0
  55. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/extract/__init__.py +0 -0
  56. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/extract/correct.py +0 -0
  57. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/ids.py +0 -0
  58. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/judge/__init__.py +0 -0
  59. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/judge/llm.py +0 -0
  60. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/judge/verdicts.py +0 -0
  61. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/ledger.py +0 -0
  62. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/mining/candidates.py +0 -0
  63. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/mining/confidence.py +0 -0
  64. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/mining/filterspec.py +0 -0
  65. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/mining/formats.py +0 -0
  66. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/mining/sampling.py +0 -0
  67. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/mining/sourcekind.py +0 -0
  68. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/notifications.py +0 -0
  69. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/py.typed +0 -0
  70. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/render.py +0 -0
  71. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/sentiment/__init__.py +0 -0
  72. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/sentiment/buckets.py +0 -0
  73. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/sentiment/data/afinn-en-165.tsv +0 -0
  74. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/sentiment/data/domain_overrides.tsv +0 -0
  75. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/store.py +0 -0
  76. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/cc_transcript/watch.py +0 -0
  77. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/build.rs +0 -0
  78. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/data/command_prefix_pins.tsv +0 -0
  79. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/rustfmt.toml +0 -0
  80. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/activity.rs +0 -0
  81. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/command.rs +0 -0
  82. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/event.rs +0 -0
  83. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/filter.rs +0 -0
  84. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/generated/command.rs +0 -0
  85. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/generated/mining.rs +0 -0
  86. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/generated/protocol.rs +0 -0
  87. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/model.rs +0 -0
  88. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/parse.rs +0 -0
  89. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/protocol.rs +0 -0
  90. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/types.rs +0 -0
  91. {cc_transcript-12.1.0 → cc_transcript-13.0.0}/rust/src/value.rs +0 -0
@@ -2,6 +2,12 @@
2
2
  # It is not intended for manual editing.
3
3
  version = 4
4
4
 
5
+ [[package]]
6
+ name = "adler2"
7
+ version = "2.0.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
10
+
5
11
  [[package]]
6
12
  name = "ahash"
7
13
  version = "0.8.12"
@@ -9,7 +15,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
9
15
  checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
10
16
  dependencies = [
11
17
  "cfg-if",
12
- "getrandom",
18
+ "getrandom 0.3.4",
13
19
  "once_cell",
14
20
  "version_check",
15
21
  "zerocopy",
@@ -30,6 +36,12 @@ version = "1.5.1"
30
36
  source = "registry+https://github.com/rust-lang/crates.io-index"
31
37
  checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
32
38
 
39
+ [[package]]
40
+ name = "base64"
41
+ version = "0.22.1"
42
+ source = "registry+https://github.com/rust-lang/crates.io-index"
43
+ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
44
+
33
45
  [[package]]
34
46
  name = "bitflags"
35
47
  version = "2.13.0"
@@ -74,6 +86,7 @@ dependencies = [
74
86
  "sonic-rs",
75
87
  "tree-sitter",
76
88
  "tree-sitter-bash",
89
+ "udpipe-rs",
77
90
  ]
78
91
 
79
92
  [[package]]
@@ -100,6 +113,15 @@ dependencies = [
100
113
  "num-traits",
101
114
  ]
102
115
 
116
+ [[package]]
117
+ name = "crc32fast"
118
+ version = "1.5.0"
119
+ source = "registry+https://github.com/rust-lang/crates.io-index"
120
+ checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
121
+ dependencies = [
122
+ "cfg-if",
123
+ ]
124
+
103
125
  [[package]]
104
126
  name = "crossbeam-channel"
105
127
  version = "0.5.15"
@@ -180,6 +202,16 @@ version = "0.1.9"
180
202
  source = "registry+https://github.com/rust-lang/crates.io-index"
181
203
  checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
182
204
 
205
+ [[package]]
206
+ name = "flate2"
207
+ version = "1.1.9"
208
+ source = "registry+https://github.com/rust-lang/crates.io-index"
209
+ checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
210
+ dependencies = [
211
+ "crc32fast",
212
+ "miniz_oxide",
213
+ ]
214
+
183
215
  [[package]]
184
216
  name = "futures-core"
185
217
  version = "0.3.32"
@@ -204,6 +236,17 @@ dependencies = [
204
236
  "slab",
205
237
  ]
206
238
 
239
+ [[package]]
240
+ name = "getrandom"
241
+ version = "0.2.17"
242
+ source = "registry+https://github.com/rust-lang/crates.io-index"
243
+ checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
244
+ dependencies = [
245
+ "cfg-if",
246
+ "libc",
247
+ "wasi",
248
+ ]
249
+
207
250
  [[package]]
208
251
  name = "getrandom"
209
252
  version = "0.3.4"
@@ -234,6 +277,22 @@ version = "0.5.2"
234
277
  source = "registry+https://github.com/rust-lang/crates.io-index"
235
278
  checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
236
279
 
280
+ [[package]]
281
+ name = "http"
282
+ version = "1.4.2"
283
+ source = "registry+https://github.com/rust-lang/crates.io-index"
284
+ checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
285
+ dependencies = [
286
+ "bytes",
287
+ "itoa",
288
+ ]
289
+
290
+ [[package]]
291
+ name = "httparse"
292
+ version = "1.10.1"
293
+ source = "registry+https://github.com/rust-lang/crates.io-index"
294
+ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
295
+
237
296
  [[package]]
238
297
  name = "indexmap"
239
298
  version = "2.14.0"
@@ -274,12 +333,28 @@ version = "0.12.1"
274
333
  source = "registry+https://github.com/rust-lang/crates.io-index"
275
334
  checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
276
335
 
336
+ [[package]]
337
+ name = "log"
338
+ version = "0.4.33"
339
+ source = "registry+https://github.com/rust-lang/crates.io-index"
340
+ checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
341
+
277
342
  [[package]]
278
343
  name = "memchr"
279
344
  version = "2.8.1"
280
345
  source = "registry+https://github.com/rust-lang/crates.io-index"
281
346
  checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
282
347
 
348
+ [[package]]
349
+ name = "miniz_oxide"
350
+ version = "0.8.9"
351
+ source = "registry+https://github.com/rust-lang/crates.io-index"
352
+ checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
353
+ dependencies = [
354
+ "adler2",
355
+ "simd-adler32",
356
+ ]
357
+
283
358
  [[package]]
284
359
  name = "munge"
285
360
  version = "0.4.7"
@@ -325,6 +400,12 @@ version = "1.21.4"
325
400
  source = "registry+https://github.com/rust-lang/crates.io-index"
326
401
  checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
327
402
 
403
+ [[package]]
404
+ name = "percent-encoding"
405
+ version = "2.3.2"
406
+ source = "registry+https://github.com/rust-lang/crates.io-index"
407
+ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
408
+
328
409
  [[package]]
329
410
  name = "pin-project-lite"
330
411
  version = "0.2.17"
@@ -524,6 +605,20 @@ version = "0.5.3"
524
605
  source = "registry+https://github.com/rust-lang/crates.io-index"
525
606
  checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6"
526
607
 
608
+ [[package]]
609
+ name = "ring"
610
+ version = "0.17.14"
611
+ source = "registry+https://github.com/rust-lang/crates.io-index"
612
+ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
613
+ dependencies = [
614
+ "cc",
615
+ "cfg-if",
616
+ "getrandom 0.2.17",
617
+ "libc",
618
+ "untrusted",
619
+ "windows-sys",
620
+ ]
621
+
527
622
  [[package]]
528
623
  name = "rkyv"
529
624
  version = "0.8.16"
@@ -566,6 +661,41 @@ dependencies = [
566
661
  "windows-sys",
567
662
  ]
568
663
 
664
+ [[package]]
665
+ name = "rustls"
666
+ version = "0.23.41"
667
+ source = "registry+https://github.com/rust-lang/crates.io-index"
668
+ checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f"
669
+ dependencies = [
670
+ "log",
671
+ "once_cell",
672
+ "ring",
673
+ "rustls-pki-types",
674
+ "rustls-webpki",
675
+ "subtle",
676
+ "zeroize",
677
+ ]
678
+
679
+ [[package]]
680
+ name = "rustls-pki-types"
681
+ version = "1.15.0"
682
+ source = "registry+https://github.com/rust-lang/crates.io-index"
683
+ checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046"
684
+ dependencies = [
685
+ "zeroize",
686
+ ]
687
+
688
+ [[package]]
689
+ name = "rustls-webpki"
690
+ version = "0.103.13"
691
+ source = "registry+https://github.com/rust-lang/crates.io-index"
692
+ checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
693
+ dependencies = [
694
+ "ring",
695
+ "rustls-pki-types",
696
+ "untrusted",
697
+ ]
698
+
569
699
  [[package]]
570
700
  name = "rustversion"
571
701
  version = "1.0.22"
@@ -622,6 +752,12 @@ version = "2.0.1"
622
752
  source = "registry+https://github.com/rust-lang/crates.io-index"
623
753
  checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
624
754
 
755
+ [[package]]
756
+ name = "simd-adler32"
757
+ version = "0.3.9"
758
+ source = "registry+https://github.com/rust-lang/crates.io-index"
759
+ checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
760
+
625
761
  [[package]]
626
762
  name = "simdutf8"
627
763
  version = "0.1.5"
@@ -679,6 +815,12 @@ version = "0.1.9"
679
815
  source = "registry+https://github.com/rust-lang/crates.io-index"
680
816
  checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
681
817
 
818
+ [[package]]
819
+ name = "subtle"
820
+ version = "2.6.1"
821
+ source = "registry+https://github.com/rust-lang/crates.io-index"
822
+ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
823
+
682
824
  [[package]]
683
825
  name = "swift-bridge"
684
826
  version = "0.1.59"
@@ -759,7 +901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
759
901
  checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
760
902
  dependencies = [
761
903
  "fastrand",
762
- "getrandom",
904
+ "getrandom 0.3.4",
763
905
  "once_cell",
764
906
  "rustix",
765
907
  "windows-sys",
@@ -830,12 +972,63 @@ version = "0.1.7"
830
972
  source = "registry+https://github.com/rust-lang/crates.io-index"
831
973
  checksum = "009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782"
832
974
 
975
+ [[package]]
976
+ name = "udpipe-rs"
977
+ version = "0.2.0"
978
+ source = "registry+https://github.com/rust-lang/crates.io-index"
979
+ checksum = "9a8f34a036b145a2d253613c2742c836f79c9d5f9c2220f03931762224d23452"
980
+ dependencies = [
981
+ "cc",
982
+ "ureq",
983
+ ]
984
+
833
985
  [[package]]
834
986
  name = "unicode-ident"
835
987
  version = "1.0.24"
836
988
  source = "registry+https://github.com/rust-lang/crates.io-index"
837
989
  checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
838
990
 
991
+ [[package]]
992
+ name = "untrusted"
993
+ version = "0.9.0"
994
+ source = "registry+https://github.com/rust-lang/crates.io-index"
995
+ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
996
+
997
+ [[package]]
998
+ name = "ureq"
999
+ version = "3.3.0"
1000
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1001
+ checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0"
1002
+ dependencies = [
1003
+ "base64",
1004
+ "flate2",
1005
+ "log",
1006
+ "percent-encoding",
1007
+ "rustls",
1008
+ "rustls-pki-types",
1009
+ "ureq-proto",
1010
+ "utf8-zero",
1011
+ "webpki-roots",
1012
+ ]
1013
+
1014
+ [[package]]
1015
+ name = "ureq-proto"
1016
+ version = "0.6.0"
1017
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1018
+ checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c"
1019
+ dependencies = [
1020
+ "base64",
1021
+ "http",
1022
+ "httparse",
1023
+ "log",
1024
+ ]
1025
+
1026
+ [[package]]
1027
+ name = "utf8-zero"
1028
+ version = "0.8.1"
1029
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1030
+ checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e"
1031
+
839
1032
  [[package]]
840
1033
  name = "uuid"
841
1034
  version = "1.23.2"
@@ -852,6 +1045,12 @@ version = "0.9.5"
852
1045
  source = "registry+https://github.com/rust-lang/crates.io-index"
853
1046
  checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
854
1047
 
1048
+ [[package]]
1049
+ name = "wasi"
1050
+ version = "0.11.1+wasi-snapshot-preview1"
1051
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1052
+ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
1053
+
855
1054
  [[package]]
856
1055
  name = "wasip2"
857
1056
  version = "1.0.3+wasi-0.2.9"
@@ -906,6 +1105,15 @@ dependencies = [
906
1105
  "unicode-ident",
907
1106
  ]
908
1107
 
1108
+ [[package]]
1109
+ name = "webpki-roots"
1110
+ version = "1.0.8"
1111
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1112
+ checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf"
1113
+ dependencies = [
1114
+ "rustls-pki-types",
1115
+ ]
1116
+
909
1117
  [[package]]
910
1118
  name = "windows-sys"
911
1119
  version = "0.52.0"
@@ -1005,6 +1213,12 @@ dependencies = [
1005
1213
  "syn 2.0.117",
1006
1214
  ]
1007
1215
 
1216
+ [[package]]
1217
+ name = "zeroize"
1218
+ version = "1.9.0"
1219
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1220
+ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
1221
+
1008
1222
  [[package]]
1009
1223
  name = "zmij"
1010
1224
  version = "1.0.21"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cc-transcript
3
- Version: 12.1.0
3
+ Version: 13.0.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -117,7 +117,7 @@ Each block reports text, thinking, and tool-io bytes plus per-tool call counts;
117
117
  - [Filtering events](https://yasyf.github.io/cc-transcript/docs/guide/filtering-events.html) covers composable clauses, specs, and the ready-made `NOISE_SPEC`.
118
118
  - [Sentiment scoring](https://yasyf.github.io/cc-transcript/docs/guide/scoring-sentiment.html) buckets conversations and scores them around any inference engine.
119
119
  - [Feedback mining](https://yasyf.github.io/cc-transcript/docs/guide/mining-feedback.html) runs detectors, confidence calibration, and LLM verdict passes over your corpus.
120
- - [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.
120
+ - [The Rust engine](https://yasyf.github.io/cc-transcript/docs/guide/rust-engine.html) executes parsing, filtering, scoring, and mining, its correctness pinned by generated literals and golden fixtures.
121
121
  - [API reference](https://yasyf.github.io/cc-transcript/reference/index.html) documents the complete typed surface, from `TranscriptEvent` to `SessionActivity`.
122
122
 
123
123
  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).
@@ -77,7 +77,7 @@ Each block reports text, thinking, and tool-io bytes plus per-tool call counts;
77
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
78
  - [Sentiment scoring](https://yasyf.github.io/cc-transcript/docs/guide/scoring-sentiment.html) buckets conversations and scores them around any inference engine.
79
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.
80
+ - [The Rust engine](https://yasyf.github.io/cc-transcript/docs/guide/rust-engine.html) executes parsing, filtering, scoring, and mining, its correctness pinned by generated literals and golden fixtures.
81
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).
@@ -147,7 +147,7 @@ EXPORTS: dict[str, str] = {
147
147
  "cost_of_assistant",
148
148
  "resolve_pricing",
149
149
  ),
150
- "cc_transcript.backend": ("Backend", "ParsedTranscript"),
150
+ "cc_transcript.backend": ("ParsedTranscript",),
151
151
  "cc_transcript.discovery": (
152
152
  "CLAUDE_PROJECTS_DIR",
153
153
  "TranscriptDiscovery",
@@ -275,7 +275,6 @@ if TYPE_CHECKING:
275
275
  from cc_transcript.activity import (
276
276
  result_index as result_index,
277
277
  )
278
- from cc_transcript.backend import Backend as Backend
279
278
  from cc_transcript.backend import ParsedTranscript as ParsedTranscript
280
279
  from cc_transcript.builders import (
281
280
  NOISE_SPEC as NOISE_SPEC,
@@ -30,11 +30,18 @@ def lexicon_polarity(token: str, /) -> int:
30
30
  """Polarity of a single token surface: domain override, else AFINN floored at MIN_MAGNITUDE."""
31
31
 
32
32
  def lexicon_has_hit(text: str, want_negative: bool, /) -> bool:
33
- """Whether any token surface's polarity crosses the fixed ±3 floor (the negative side when ``want_negative``)."""
33
+ """Whether any content token's effective (negation-flipped) polarity crosses the fixed ±3 floor."""
34
34
 
35
35
  def lexicon_overrides() -> list[tuple[str, int]]:
36
36
  """The embedded domain-override entries (for the single-source drift guard)."""
37
37
 
38
+ def nlp_analyze(text: str, /) -> list[tuple[str, str, str, str, int, int, int, bool]]:
39
+ """Analyze ``text`` with the embedded UDPipe model.
40
+
41
+ Per token: ``(form, lower, lemma, upos, char_start, char_end, polarity, negated)``,
42
+ where offsets are codepoint indices and polarity is the surface-keyed lexicon score.
43
+ """
44
+
38
45
  def embedded_literals() -> dict[str, str | float | list[str]]:
39
46
  """The generated protocol, mining, and command literals keyed ``module.NAME`` (for the single-source drift guard)."""
40
47
 
@@ -47,8 +54,10 @@ def score_post_process(spec_json: str, buckets: list[list[str]], raw: list[int],
47
54
  def command_prefixes(commands: list[str], /) -> list[list[str]]:
48
55
  """Permission-style prefixes per command line, parsed in parallel off the GIL."""
49
56
 
50
- def mine_signals(raw: bytes, spec_json: str, /) -> list[dict[str, Any]]:
51
- """Parses raw transcript bytes and mines signal dicts per the portable mining spec."""
57
+ def mine_events(
58
+ events: list[TranscriptEvent], spec_json: str, callable_formats: list[tuple[str, Any, Any]], /
59
+ ) -> list[dict[str, Any]]:
60
+ """Mines signal dicts from parsed transcript events per the portable mining spec."""
52
61
 
53
62
  def session_activity_probe(
54
63
  path: str, waiting_tools: list[str] | None = ..., human_facing_tools: list[str] | None = ..., /
@@ -0,0 +1,98 @@
1
+ """Session-activity probe — captain-hook's ``is_waiting`` oracle over one transcript.
2
+
3
+ :func:`session_activity_probe` is the public entry: it hands a ``.jsonl`` transcript to the
4
+ Rust extension, which reads and parses the file and runs the oracle in one pass, returning a
5
+ :class:`SessionActivityProbe`. The verdict spans undelivered task notifications (the
6
+ :class:`~cc_transcript.notifications.Notifications` queue replay), ephemeral waits (waiting
7
+ tools, backgrounded Agent/Task/Bash, subagentless Agent/Task) over the current turn, and
8
+ pending async launches (async Agent/Task, live Workflow) session-wide — a launch counts as
9
+ completed only once its notification was delivered or drained, never when merely enqueued —
10
+ and flags unanswered non-human-facing tool calls in the current turn as mid-tool.
11
+ Compact-summary user lines do not open turns, matching captain-hook, which consumes this
12
+ probe since the 10.2.0 shared-classifier fix.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from dataclasses import dataclass
18
+ from typing import TYPE_CHECKING, Literal
19
+
20
+ from cc_transcript.tools import expand_tool_names
21
+
22
+ if TYPE_CHECKING:
23
+ from pathlib import Path
24
+
25
+ DEFAULT_WAITING_TOOLS = frozenset({"Monitor", "ScheduleWakeup", "SendMessage", "TeamCreate"})
26
+ DEFAULT_HUMAN_FACING_TOOLS = expand_tool_names("AskUserQuestion|ExitPlanMode")
27
+
28
+ PendingKind = Literal[
29
+ "waiting_tool",
30
+ "background",
31
+ "subagentless_task",
32
+ "pending_async_task",
33
+ "pending_async_workflow",
34
+ "mid_tool",
35
+ ]
36
+ """How a tool call contributes to the session-activity verdict."""
37
+
38
+
39
+ @dataclass(frozen=True, slots=True)
40
+ class PendingItem:
41
+ """One tool call contributing to the session-activity verdict.
42
+
43
+ Attributes:
44
+ tool_use_id: The contributing call's tool-use id.
45
+ name: The tool's name exactly as invoked.
46
+ kind: How the call contributes to the verdict.
47
+ """
48
+
49
+ tool_use_id: str | None
50
+ name: str
51
+ kind: PendingKind
52
+
53
+
54
+ @dataclass(frozen=True, slots=True)
55
+ class SessionActivityProbe:
56
+ """The session-activity verdict over one transcript.
57
+
58
+ Attributes:
59
+ is_waiting: Whether the session waits on ephemeral or pending async work.
60
+ mid_tool: Whether the current turn has an unanswered non-human-facing call.
61
+ pending: The contributing calls, in document order, deduped by tool-use id.
62
+ last_event_epoch: The latest envelope timestamp as epoch seconds, or None.
63
+ """
64
+
65
+ is_waiting: bool
66
+ mid_tool: bool
67
+ pending: tuple[PendingItem, ...]
68
+ last_event_epoch: int | None
69
+
70
+
71
+ def session_activity_probe(
72
+ path: Path,
73
+ *,
74
+ waiting_tools: frozenset[str] = DEFAULT_WAITING_TOOLS,
75
+ human_facing_tools: frozenset[str] = DEFAULT_HUMAN_FACING_TOOLS,
76
+ ) -> SessionActivityProbe:
77
+ """Probes the transcript at ``path`` for session activity.
78
+
79
+ The Rust extension reads and parses the file and runs the oracle in one pass,
80
+ returning the session-activity verdict.
81
+
82
+ Args:
83
+ path: The ``.jsonl`` transcript to probe.
84
+ waiting_tools: Tool names whose calls in the current turn mark the session waiting.
85
+ human_facing_tools: Tool names whose unanswered calls are the user's move, never mid-tool.
86
+
87
+ Returns:
88
+ The session-activity verdict.
89
+ """
90
+ from cc_transcript import _parser_rs
91
+
92
+ payload = _parser_rs.session_activity_probe(str(path), sorted(waiting_tools), sorted(human_facing_tools))
93
+ return SessionActivityProbe(
94
+ is_waiting=payload["is_waiting"],
95
+ mid_tool=payload["mid_tool"],
96
+ pending=tuple(PendingItem(**item) for item in payload["pending"]),
97
+ last_event_epoch=payload["last_event_epoch"],
98
+ )
@@ -0,0 +1,24 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from pathlib import Path
8
+
9
+ from cc_transcript.models import TranscriptEvent
10
+
11
+
12
+ @dataclass(frozen=True, slots=True)
13
+ class ParsedTranscript:
14
+ """The parsed events of a single transcript file.
15
+
16
+ Attributes:
17
+ path: The transcript's path on disk.
18
+ mtime: The transcript's modification time when parsed.
19
+ events: The parsed events, in file order.
20
+ """
21
+
22
+ path: Path
23
+ mtime: float
24
+ events: tuple[TranscriptEvent, ...]
@@ -495,22 +495,8 @@ def command_prefixes(command: str) -> tuple[str, ...]:
495
495
  return parse_command_line(command).prefixes
496
496
 
497
497
 
498
- def load_rust_prefixes() -> Callable[[list[str]], list[list[str]]] | None:
499
- # Stale-extension guard (mirrors parser.load_rust_backend): the compiled
500
- # extension may be absent or predate the command_prefixes symbol.
501
- try:
502
- from cc_transcript import _parser_rs
503
- except ImportError:
504
- return None
505
- return _parser_rs.command_prefixes if hasattr(_parser_rs, "command_prefixes") else None
506
-
507
-
508
498
  def bulk_command_prefixes(commands: Sequence[str]) -> list[tuple[str, ...]]:
509
- """``command_prefixes`` over many commands at once, on the Rust fast path when available.
499
+ """``command_prefixes`` over many commands at once, on the Rust fast path."""
500
+ from cc_transcript import _parser_rs
510
501
 
511
- Falls back to the Python parser when the compiled extension is missing or
512
- predates the ``command_prefixes`` symbol.
513
- """
514
- if rust := load_rust_prefixes():
515
- return [tuple(prefixes) for prefixes in rust(list(commands))]
516
- return [command_prefixes(command) for command in commands]
502
+ return [tuple(prefixes) for prefixes in _parser_rs.command_prefixes(list(commands))]
@@ -95,6 +95,7 @@ def fact_of(use: ToolUse, session_id: SessionId, path: Path, prefixes: tuple[str
95
95
  call = use.call
96
96
  server, tool, access = mcp_split(call.name)
97
97
  denied, user_said = denial_fields(use.result)
98
+ assert use.ref.tool_use_id is not None, "ToolUse refs always carry the tool-use id"
98
99
  return ToolFact(
99
100
  ts=use.ts,
100
101
  session_id=session_id,
@@ -1,9 +1,12 @@
1
- """Declarative, both-backend filtering of a transcript event stream.
1
+ """Declarative filtering of a transcript event stream.
2
2
 
3
3
  A :class:`FilterSpec` is an ordered list of :class:`Clause` rules — *filters as
4
- data*. The same spec is interpreted by the Python interpreter here and, when
5
- :func:`is_portable` holds, serialized via :func:`spec_to_json` and executed by
6
- the Rust backend, which drops events before ever materializing a Python object.
4
+ data*. Parse-time filtering runs in Rust: :func:`spec_to_json` serializes the spec to
5
+ the JSON contract the Rust backend executes, dropping events during parsing before
6
+ they ever materialize (pass a spec to
7
+ :meth:`~cc_transcript.TranscriptParser.stream_transcripts`). Already-materialized
8
+ events — a list the caller already holds — are filtered with :func:`apply_spec` or
9
+ :func:`keep`.
7
10
 
8
11
  Consumers compose specs from the builders in :mod:`cc_transcript.builders` over
9
12
  named building blocks: the junk regex is split into categories
@@ -168,20 +171,6 @@ HEDGE_GROUPS: tuple[tuple[str, str], ...] = (
168
171
  ("hedged", r"\b(?:maybe|perhaps|possibly|might|not sure|i think|i guess|if you (?:want|prefer)|up to you)\b"),
169
172
  )
170
173
 
171
- PORTABLE_GROUP_NAMES: frozenset[str] = frozenset(
172
- name
173
- for name, _ in (
174
- *STRUCTURAL_NOISE_GROUPS,
175
- *INTERRUPT_MARKER_GROUPS,
176
- *STOP_HOOK_GROUPS,
177
- *CONTINUATION_GROUPS,
178
- *COMMAND_ECHO_GROUPS,
179
- *FRUSTRATION_GROUPS,
180
- *MILD_IMPATIENCE_GROUPS,
181
- *HEDGE_GROUPS,
182
- )
183
- )
184
-
185
174
  RESUME_PHRASE_SET: frozenset[str] = frozenset(
186
175
  {
187
176
  "continue",
@@ -491,7 +480,11 @@ def clause_matches(clause: Clause, event: TranscriptEvent, kind: EventKind) -> b
491
480
 
492
481
 
493
482
  def keep(event: TranscriptEvent, spec: FilterSpec) -> bool:
494
- """Returns whether ``event`` survives every ``DROP`` clause of ``spec``."""
483
+ """Returns whether ``event`` survives every ``DROP`` clause of ``spec``.
484
+
485
+ Filters an already-materialized :class:`~cc_transcript.models.TranscriptEvent`;
486
+ parse-time filtering runs in Rust before materialization via :func:`spec_to_json`.
487
+ """
495
488
  kind = event_kind(event)
496
489
  return not any(clause.action is Action.DROP and clause_matches(clause, event, kind) for clause in spec.clauses)
497
490
 
@@ -509,7 +502,7 @@ def labels_for(event: TranscriptEvent, spec: FilterSpec) -> tuple[str, ...]:
509
502
 
510
503
 
511
504
  def apply_spec(events: Iterable[TranscriptEvent], spec: FilterSpec) -> Iterator[TranscriptEvent]:
512
- """Yields the events that survive every ``DROP`` clause of ``spec``."""
505
+ """Yields the already-materialized events that survive every ``DROP`` clause of ``spec``."""
513
506
  return (event for event in events if keep(event, spec))
514
507
 
515
508
 
@@ -520,24 +513,6 @@ def annotate_spec(
520
513
  return ((event, labels_for(event, spec)) for event in events if keep(event, spec))
521
514
 
522
515
 
523
- def is_portable(spec: FilterSpec) -> bool:
524
- """Returns whether every clause is executable by the Rust interpreter.
525
-
526
- A spec is portable when each :class:`TextMatchesAny` uses only group names
527
- proven to match identically under the Rust ``regex`` crate; non-portable
528
- specs fall back to the Python interpreter.
529
- """
530
- return all(clause_portable(clause) for clause in spec.clauses)
531
-
532
-
533
- def clause_portable(clause: Clause) -> bool:
534
- match clause.predicate:
535
- case TextMatchesAny(groups=groups):
536
- return all(name in PORTABLE_GROUP_NAMES for name, _ in groups)
537
- case _:
538
- return True
539
-
540
-
541
516
  def spec_to_json(spec: FilterSpec) -> str:
542
517
  """Serializes ``spec`` to the JSON contract consumed by the Rust backend."""
543
518
  return orjson.dumps({"clauses": [clause_to_dict(clause) for clause in spec.clauses]}).decode()