cc-transcript 14.16.0__tar.gz → 14.16.1__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 (162) hide show
  1. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/PKG-INFO +1 -1
  2. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/query.py +56 -22
  3. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/pyproject.toml +1 -1
  4. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/Cargo.lock +0 -0
  5. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/Cargo.toml +0 -0
  6. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/LICENSE +0 -0
  7. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/README.md +0 -0
  8. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/__init__.py +0 -0
  9. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/__init__.pyi +0 -0
  10. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/_native.pyi +0 -0
  11. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/activity.py +0 -0
  12. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/activity_probe.py +0 -0
  13. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/builders.py +0 -0
  14. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/codex.py +0 -0
  15. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/command.py +0 -0
  16. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/context.py +0 -0
  17. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/corrections.py +0 -0
  18. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/cost.py +0 -0
  19. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/decision_store.py +0 -0
  20. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/decisions.py +0 -0
  21. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/discovery.py +0 -0
  22. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/disktruth.py +0 -0
  23. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/evidence.py +0 -0
  24. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/extract/__init__.py +0 -0
  25. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/extract/correct.py +0 -0
  26. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/facts.py +0 -0
  27. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/filterspec.py +0 -0
  28. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/heartbeats.py +0 -0
  29. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/ids.py +0 -0
  30. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/judge/__init__.py +0 -0
  31. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/judge/llm.py +0 -0
  32. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/judge/similar.py +0 -0
  33. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/judge/verdicts.py +0 -0
  34. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/ledger.py +0 -0
  35. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/literals.py +0 -0
  36. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/__init__.py +0 -0
  37. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/candidates.py +0 -0
  38. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/confidence.py +0 -0
  39. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/engine.py +0 -0
  40. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/formats.py +0 -0
  41. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/sampling.py +0 -0
  42. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/signals.py +0 -0
  43. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/sourcekind.py +0 -0
  44. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/spec.py +0 -0
  45. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/mining/store.py +0 -0
  46. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/models.py +0 -0
  47. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/nlp.py +0 -0
  48. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/notifications.py +0 -0
  49. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/parser.py +0 -0
  50. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/py.typed +0 -0
  51. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/render.py +0 -0
  52. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/sentiment/__init__.py +0 -0
  53. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/sentiment/buckets.py +0 -0
  54. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/sentiment/data/afinn-en-165.tsv +0 -0
  55. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/sentiment/data/domain_overrides.tsv +0 -0
  56. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/sentiment/data/en-ewt.udpipe +0 -0
  57. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/sentiment/engine.py +0 -0
  58. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/sentiment/lexicon.py +0 -0
  59. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/sentiment/scorespec.py +0 -0
  60. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/synthetic.py +0 -0
  61. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/tools.py +0 -0
  62. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/cc_transcript/watch.py +0 -0
  63. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/Cargo.toml +0 -0
  64. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/blame.rs +0 -0
  65. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/corrections.rs +0 -0
  66. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/digest.rs +0 -0
  67. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/facts.rs +0 -0
  68. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/grep.rs +0 -0
  69. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/list.rs +0 -0
  70. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/mod.rs +0 -0
  71. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/scratchpad.rs +0 -0
  72. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/show.rs +0 -0
  73. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/slice.rs +0 -0
  74. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/stats.rs +0 -0
  75. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/commands/watch.rs +0 -0
  76. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/lib.rs +0 -0
  77. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/main.rs +0 -0
  78. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/output.rs +0 -0
  79. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/target.rs +0 -0
  80. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/cli/src/timearg.rs +0 -0
  81. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/Cargo.toml +0 -0
  82. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/benches/parse.rs +0 -0
  83. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/benches/render.rs +0 -0
  84. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/benches/toolcall.rs +0 -0
  85. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/activity.rs +0 -0
  86. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/actor.rs +0 -0
  87. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/blame.rs +0 -0
  88. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/buckets.rs +0 -0
  89. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/codex/discovery.rs +0 -0
  90. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/codex/lower.rs +0 -0
  91. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/codex/mod.rs +0 -0
  92. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/codex/parse.rs +0 -0
  93. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/codex/probe.rs +0 -0
  94. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/codex/protocol.rs +0 -0
  95. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/codex/types.rs +0 -0
  96. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/command.rs +0 -0
  97. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/context.rs +0 -0
  98. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/corrections.rs +0 -0
  99. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/cost.rs +0 -0
  100. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/discovery.rs +0 -0
  101. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/facts.rs +0 -0
  102. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/feedback.rs +0 -0
  103. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/filter.rs +0 -0
  104. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/gateway.rs +0 -0
  105. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/ids.rs +0 -0
  106. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/judge.rs +0 -0
  107. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/lib.rs +0 -0
  108. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/literals/command.rs +0 -0
  109. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/literals/corrections.rs +0 -0
  110. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/literals/feedback.rs +0 -0
  111. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/literals/mining.rs +0 -0
  112. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/literals/mod.rs +0 -0
  113. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/literals/protocol.rs +0 -0
  114. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/notifications.rs +0 -0
  115. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/parse.rs +0 -0
  116. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/protocol.rs +0 -0
  117. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/pystr.rs +0 -0
  118. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/query.rs +0 -0
  119. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/render.rs +0 -0
  120. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/rng.rs +0 -0
  121. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/schema.rs +0 -0
  122. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/sqlite.rs +0 -0
  123. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/toolcall.rs +0 -0
  124. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/types.rs +0 -0
  125. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/value.rs +0 -0
  126. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/core/src/watch.rs +0 -0
  127. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/Cargo.toml +0 -0
  128. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/build.rs +0 -0
  129. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/data/command_prefix_pins.tsv +0 -0
  130. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/actor_bridge.rs +0 -0
  131. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/bin/stub_gen.rs +0 -0
  132. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/codex.rs +0 -0
  133. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/command.rs +0 -0
  134. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/context.rs +0 -0
  135. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/corrections.rs +0 -0
  136. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/discovery.rs +0 -0
  137. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/feedback.rs +0 -0
  138. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/judge.rs +0 -0
  139. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/lexicon.rs +0 -0
  140. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/lib.rs +0 -0
  141. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/mining.rs +0 -0
  142. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/nlp.rs +0 -0
  143. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/python.rs +0 -0
  144. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/render.rs +0 -0
  145. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/score.rs +0 -0
  146. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/sqlite.rs +0 -0
  147. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/toolcall.rs +0 -0
  148. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/attachment.rs +0 -0
  149. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/blocks.rs +0 -0
  150. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/command.rs +0 -0
  151. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/convert.rs +0 -0
  152. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/dunder.rs +0 -0
  153. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/events.rs +0 -0
  154. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/meta.rs +0 -0
  155. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/mod.rs +0 -0
  156. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/print.rs +0 -0
  157. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/store.rs +0 -0
  158. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/system.rs +0 -0
  159. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/toolcall.rs +0 -0
  160. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/toolresult.rs +0 -0
  161. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/views/transcript.rs +0 -0
  162. {cc_transcript-14.16.0 → cc_transcript-14.16.1}/rust/crates/py/src/watch.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cc-transcript
3
- Version: 14.16.0
3
+ Version: 14.16.1
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -12,8 +12,9 @@ from __future__ import annotations
12
12
 
13
13
  import re
14
14
  import threading
15
+ from collections import OrderedDict
15
16
  from collections.abc import Mapping
16
- from dataclasses import dataclass
17
+ from dataclasses import dataclass, field
17
18
  from fnmatch import fnmatch
18
19
  from functools import cached_property
19
20
  from pathlib import PurePath
@@ -47,29 +48,62 @@ if TYPE_CHECKING:
47
48
  from cc_transcript.models import TranscriptEvent
48
49
 
49
50
 
50
- DEEP_LIFT_BUDGET = 64 * 1024 * 1024
51
+ DEEP_LIFT_BUDGET = 1024 * 1024 * 1024
51
52
 
52
- DEEP_LIFTS: dict[LiftKey, tuple[LiftStamp, DeepSession]] = {}
53
- """Lifted sidechain transcripts, keyed by tree position and stamped with the file's ``(size, mtime_ns)``.
53
+ type LiftStamp = tuple[int, int, int]
54
+ type LiftKey = tuple[Path, int, ToolUseId | None]
54
55
 
55
- :meth:`Session.walk` re-reads every node of a tree in the same order, so evicting the
56
- least-recently-used entry thrashes on any tree larger than the cache — each walk drops
57
- exactly what the next one asks for first. Admission stops at :data:`DEEP_LIFT_BUDGET`
58
- source bytes instead: what is held stays held, and a tree that outgrows the budget
59
- reparses only its tail. A sidechain that grew replaces its own entry, budget or not.
60
- """
61
56
 
62
- DEEP_LIFT_GUARD = threading.Lock()
57
+ @dataclass(slots=True)
58
+ class LiftCache:
59
+ held: OrderedDict[LiftKey, tuple[LiftStamp, DeepSession]] = field(default_factory=OrderedDict)
60
+ size: int = 0
61
+ guard: threading.Lock = field(default_factory=threading.Lock)
62
+
63
+ def get(self, key: LiftKey, stamp: LiftStamp) -> DeepSession | None:
64
+ with self.guard:
65
+ match self.held.get(key):
66
+ case None:
67
+ return None
68
+ case (held_stamp, deep) if held_stamp == stamp:
69
+ self.held.move_to_end(key)
70
+ return deep
71
+ case _:
72
+ self.drop(key)
73
+ return None
74
+
75
+ def put(self, key: LiftKey, stamp: LiftStamp, deep: DeepSession) -> DeepSession:
76
+ with self.guard:
77
+ self.drop(key)
78
+ self.held[key] = (stamp, deep)
79
+ self.size += stamp[0]
80
+ while self.size > DEEP_LIFT_BUDGET:
81
+ self.drop(next(iter(self.held)))
82
+ return deep
83
+
84
+ def drop(self, key: LiftKey) -> None:
85
+ if (held := self.held.pop(key, None)) is not None:
86
+ self.size -= held[0][0]
87
+
88
+ def clear(self) -> None:
89
+ with self.guard:
90
+ self.held.clear()
91
+ self.size = 0
92
+
93
+ def __len__(self) -> int:
94
+ return len(self.held)
63
95
 
64
- type LiftStamp = tuple[int, int]
65
- type LiftKey = tuple[Path, int, ToolUseId | None]
66
96
 
97
+ DEEP_LIFTS = LiftCache()
98
+ """Lifted sidechain transcripts, keyed by tree position and stamped with the file's ``(size, mtime_ns, inode)``.
67
99
 
68
- def hold_lift(key: LiftKey, stamp: LiftStamp, deep: DeepSession) -> DeepSession:
69
- with DEEP_LIFT_GUARD:
70
- if key in DEEP_LIFTS or sum(size for (size, _), _ in DEEP_LIFTS.values()) < DEEP_LIFT_BUDGET:
71
- DEEP_LIFTS[key] = (stamp, deep)
72
- return deep
100
+ A least-recently-used hold bounded at :data:`DEEP_LIFT_BUDGET` source bytes. One resident
101
+ process serves many lead sessions, so the tree walked most recently stays held while an
102
+ idle lead's sidechains age out; a changed stamp drops the stale lift and releases its
103
+ bytes. A lifted session costs about 2.3 times its source bytes in resident memory, so the
104
+ default holds roughly 2.3 GiB. A single tree larger than the budget reparses the part that
105
+ no longer fits on every walk.
106
+ """
73
107
 
74
108
 
75
109
  def is_failure(use: ToolUse) -> bool:
@@ -719,11 +753,11 @@ def load_deep_session(path: Path, depth: int, spawned_by: ToolUseId | None) -> D
719
753
  stat = path.stat()
720
754
  except OSError:
721
755
  return None
722
- stamp = (stat.st_size, stat.st_mtime_ns)
756
+ stamp = (stat.st_size, stat.st_mtime_ns, stat.st_ino)
723
757
  key = (path, depth, spawned_by)
724
- if (held := DEEP_LIFTS.get(key)) is not None and held[0] == stamp:
725
- return held[1]
758
+ if (held := DEEP_LIFTS.get(key, stamp)) is not None:
759
+ return held
726
760
  try:
727
- return hold_lift(key, stamp, lift_deep_session(path, depth, spawned_by))
761
+ return DEEP_LIFTS.put(key, stamp, lift_deep_session(path, depth, spawned_by))
728
762
  except OSError:
729
763
  return None
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cc-transcript"
3
- version = "14.16.0" # informational — releases stamp the version from the git tag
3
+ version = "14.16.1" # informational — releases stamp the version from the git tag
4
4
  description = "Grep every Claude Code session you've ever run."
5
5
  readme = "README.md"
6
6
  license = "PolyForm-Noncommercial-1.0.0"
File without changes