cc-transcript 14.21.0__tar.gz → 14.23.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.

Potentially problematic release.


This version of cc-transcript might be problematic. Click here for more details.

Files changed (162) hide show
  1. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/PKG-INFO +1 -1
  2. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/_native.pyi +1 -1
  3. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/render.py +29 -11
  4. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/pyproject.toml +1 -1
  5. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/context.rs +1 -1
  6. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/render.rs +66 -22
  7. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/render.rs +2 -0
  8. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/Cargo.lock +0 -0
  9. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/Cargo.toml +0 -0
  10. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/LICENSE +0 -0
  11. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/README.md +0 -0
  12. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/__init__.py +0 -0
  13. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/__init__.pyi +0 -0
  14. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/activity.py +0 -0
  15. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/activity_probe.py +0 -0
  16. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/builders.py +0 -0
  17. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/codex.py +0 -0
  18. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/command.py +0 -0
  19. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/context.py +0 -0
  20. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/corrections.py +0 -0
  21. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/cost.py +0 -0
  22. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/decision_store.py +0 -0
  23. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/decisions.py +0 -0
  24. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/discovery.py +0 -0
  25. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/disktruth.py +0 -0
  26. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/evidence.py +0 -0
  27. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/extract/__init__.py +0 -0
  28. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/extract/correct.py +0 -0
  29. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/facts.py +0 -0
  30. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/filterspec.py +0 -0
  31. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/heartbeats.py +0 -0
  32. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/ids.py +0 -0
  33. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/judge/__init__.py +0 -0
  34. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/judge/llm.py +0 -0
  35. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/judge/similar.py +0 -0
  36. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/judge/verdicts.py +0 -0
  37. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/ledger.py +0 -0
  38. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/literals.py +0 -0
  39. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/__init__.py +0 -0
  40. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/candidates.py +0 -0
  41. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/confidence.py +0 -0
  42. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/engine.py +0 -0
  43. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/formats.py +0 -0
  44. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/sampling.py +0 -0
  45. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/signals.py +0 -0
  46. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/sourcekind.py +0 -0
  47. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/spec.py +0 -0
  48. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/mining/store.py +0 -0
  49. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/models.py +0 -0
  50. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/nlp.py +0 -0
  51. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/notifications.py +0 -0
  52. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/parser.py +0 -0
  53. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/py.typed +0 -0
  54. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/query.py +0 -0
  55. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/__init__.py +0 -0
  56. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/buckets.py +0 -0
  57. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/data/afinn-en-165.tsv +0 -0
  58. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/data/domain_overrides.tsv +0 -0
  59. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/data/en-ewt.udpipe +0 -0
  60. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/engine.py +0 -0
  61. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/lexicon.py +0 -0
  62. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/scorespec.py +0 -0
  63. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/synthetic.py +0 -0
  64. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/tools.py +0 -0
  65. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/cc_transcript/watch.py +0 -0
  66. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/Cargo.toml +0 -0
  67. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/blame.rs +0 -0
  68. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/corrections.rs +0 -0
  69. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/digest.rs +0 -0
  70. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/facts.rs +0 -0
  71. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/grep.rs +0 -0
  72. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/list.rs +0 -0
  73. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/mod.rs +0 -0
  74. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/scratchpad.rs +0 -0
  75. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/show.rs +0 -0
  76. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/slice.rs +0 -0
  77. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/stats.rs +0 -0
  78. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/watch.rs +0 -0
  79. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/lib.rs +0 -0
  80. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/main.rs +0 -0
  81. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/output.rs +0 -0
  82. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/target.rs +0 -0
  83. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/cli/src/timearg.rs +0 -0
  84. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/Cargo.toml +0 -0
  85. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/benches/parse.rs +0 -0
  86. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/benches/render.rs +0 -0
  87. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/benches/toolcall.rs +0 -0
  88. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/activity.rs +0 -0
  89. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/actor.rs +0 -0
  90. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/blame.rs +0 -0
  91. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/buckets.rs +0 -0
  92. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/discovery.rs +0 -0
  93. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/lower.rs +0 -0
  94. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/mod.rs +0 -0
  95. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/parse.rs +0 -0
  96. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/probe.rs +0 -0
  97. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/protocol.rs +0 -0
  98. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/types.rs +0 -0
  99. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/command.rs +0 -0
  100. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/corrections.rs +0 -0
  101. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/cost.rs +0 -0
  102. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/discovery.rs +0 -0
  103. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/facts.rs +0 -0
  104. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/feedback.rs +0 -0
  105. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/filter.rs +0 -0
  106. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/gateway.rs +0 -0
  107. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/ids.rs +0 -0
  108. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/judge.rs +0 -0
  109. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/lib.rs +0 -0
  110. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/command.rs +0 -0
  111. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/corrections.rs +0 -0
  112. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/feedback.rs +0 -0
  113. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/mining.rs +0 -0
  114. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/mod.rs +0 -0
  115. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/protocol.rs +0 -0
  116. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/notifications.rs +0 -0
  117. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/parse.rs +0 -0
  118. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/protocol.rs +0 -0
  119. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/pystr.rs +0 -0
  120. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/query.rs +0 -0
  121. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/rng.rs +0 -0
  122. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/schema.rs +0 -0
  123. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/sqlite.rs +0 -0
  124. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/toolcall.rs +0 -0
  125. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/types.rs +0 -0
  126. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/value.rs +0 -0
  127. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/core/src/watch.rs +0 -0
  128. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/Cargo.toml +0 -0
  129. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/build.rs +0 -0
  130. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/data/command_prefix_pins.tsv +0 -0
  131. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/actor_bridge.rs +0 -0
  132. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/bin/stub_gen.rs +0 -0
  133. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/codex.rs +0 -0
  134. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/command.rs +0 -0
  135. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/context.rs +0 -0
  136. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/corrections.rs +0 -0
  137. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/discovery.rs +0 -0
  138. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/feedback.rs +0 -0
  139. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/judge.rs +0 -0
  140. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/lexicon.rs +0 -0
  141. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/lib.rs +0 -0
  142. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/mining.rs +0 -0
  143. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/nlp.rs +0 -0
  144. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/python.rs +0 -0
  145. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/score.rs +0 -0
  146. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/sqlite.rs +0 -0
  147. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/toolcall.rs +0 -0
  148. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/attachment.rs +0 -0
  149. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/blocks.rs +0 -0
  150. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/command.rs +0 -0
  151. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/convert.rs +0 -0
  152. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/dunder.rs +0 -0
  153. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/events.rs +0 -0
  154. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/meta.rs +0 -0
  155. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/mod.rs +0 -0
  156. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/print.rs +0 -0
  157. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/store.rs +0 -0
  158. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/system.rs +0 -0
  159. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/toolcall.rs +0 -0
  160. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/toolresult.rs +0 -0
  161. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/transcript.rs +0 -0
  162. {cc_transcript-14.21.0 → cc_transcript-14.23.0}/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.21.0
3
+ Version: 14.23.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -2500,7 +2500,7 @@ def render_tool_call(name: builtins.str, input_json: builtins.str, turn_chars: b
2500
2500
 
2501
2501
  def render_tool_call_view(call: tools.ToolCall, turn_chars: builtins.int, tool_chars: builtins.int) -> builtins.str: ...
2502
2502
 
2503
- def render_turn_from_events(prompt: builtins.str, events: list[models.TranscriptEvent], turn_chars: builtins.int, tool_chars: builtins.int) -> builtins.str: ...
2503
+ def render_turn_from_events(prompt: builtins.str, events: list[models.TranscriptEvent], turn_chars: builtins.int, tool_chars: builtins.int, tool_results: builtins.bool) -> builtins.str: ...
2504
2504
 
2505
2505
  def score_post_process(spec_json: builtins.str, buckets: typing.Sequence[typing.Sequence[builtins.str]], raw: typing.Sequence[builtins.int]) -> builtins.list[builtins.int]: ...
2506
2506
 
@@ -61,23 +61,41 @@ def prefixed(prefix: str, text: str) -> tuple[str, ...]:
61
61
  return tuple(f"{prefix}{line}" for line in text.splitlines()) or (prefix.rstrip(),)
62
62
 
63
63
 
64
- def render_turn(turn: Turn, *, budget: Budget) -> str:
65
- """Render one turn: the prompt, the user's mid-turn messages, assistant prose, and every tool call with its result, in order.
66
-
67
- Prose chunks and tool results clip to ``budget.turn_chars``; each tool call
68
- renders via :func:`render_tool_call` under ``budget.tool_chars``. A result
69
- renders as ``result:``, or ``failed:`` when the call errored; an
70
- AskUserQuestion answer renders as ``user answered:`` with the chosen option's
71
- description, the selected preview and any notes.
64
+ def render_turn(turn: Turn, *, budget: Budget, tool_results: bool = False) -> str:
65
+ """Render one turn: the prompt, the user's mid-turn messages, assistant prose, and every tool call, in order.
66
+
67
+ Prose chunks clip to ``budget.turn_chars``; each tool call renders via
68
+ :func:`render_tool_call` under ``budget.tool_chars``. An AskUserQuestion answer
69
+ renders as ``user answered:`` with the chosen option's description, the
70
+ selected preview and any notes.
71
+
72
+ Args:
73
+ turn: The turn to render.
74
+ budget: Character budgets for prose and tool calls.
75
+ tool_results: Render each other tool result after its call: a ``result:``
76
+ head, or ``failed:`` when the call errored, naming the tool, then the
77
+ content clipped to ``budget.turn_chars`` on ``> `` lines. Calls batched in
78
+ one message and their results carry a ``call i/n``/``result i/n`` ordinal.
72
79
  """
73
80
  return _native.render_turn_from_events(
74
81
  turn.prompt,
75
82
  list(turn.events),
76
83
  budget.turn_chars,
77
84
  budget.tool_chars,
85
+ tool_results,
78
86
  )
79
87
 
80
88
 
81
- def render_session(activity: SessionActivity, *, budget: Budget) -> str:
82
- """Render every turn of a session under ``budget``, separated by blank lines."""
83
- return "\n\n".join(rendered for turn in activity.turns if (rendered := render_turn(turn, budget=budget)))
89
+ def render_session(activity: SessionActivity, *, budget: Budget, tool_results: bool = False) -> str:
90
+ """Render every turn of a session under ``budget``, separated by blank lines.
91
+
92
+ Args:
93
+ activity: The session to render.
94
+ budget: Character budgets for prose and tool calls.
95
+ tool_results: Render each tool result after its call; see :func:`render_turn`.
96
+ """
97
+ return "\n\n".join(
98
+ rendered
99
+ for turn in activity.turns
100
+ if (rendered := render_turn(turn, budget=budget, tool_results=tool_results))
101
+ )
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cc-transcript"
3
- version = "14.21.0" # informational — releases stamp the version from the git tag
3
+ version = "14.23.0" # 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"
@@ -514,7 +514,7 @@ fn turn_ref(turn: &Turn, budget: &Budget) -> TurnRef {
514
514
  tool_use_id: None,
515
515
  })
516
516
  .collect(),
517
- preview: render_turn(turn, budget),
517
+ preview: render_turn(turn, budget, false),
518
518
  tool_digests: turn_tool_uses(turn)
519
519
  .map(|tu| tool_digest(&tu.name, &tu.input).expect("tool input digests"))
520
520
  .collect(),
@@ -437,29 +437,45 @@ pub fn render_tool_call(call: &ToolCall, budget: &Budget) -> String {
437
437
  }
438
438
 
439
439
  /// Render one turn — the prompt, the user's mid-turn messages, assistant prose,
440
- /// every tool call with its result, and the user's AskUserQuestion answers, in order
441
- /// (render.py render_turn). Prose and tool results clip to `budget.turn_chars`; each
442
- /// tool call and answer preview renders under `budget.tool_chars`.
443
- pub fn render_turn(turn: &Turn, budget: &Budget) -> String {
440
+ /// every tool call, and the user's AskUserQuestion answers, in order (render.py
441
+ /// render_turn). With `tool_results`, each other result follows its call as a
442
+ /// `result:`/`failed:` head naming the call, its content on `> ` lines, and a
443
+ /// `call i/n`/`result i/n` ordinal on calls batched in one message.
444
+ pub fn render_turn(turn: &Turn, budget: &Budget, tool_results: bool) -> String {
444
445
  let mut parts: Vec<String> = Vec::new();
445
446
  if !turn.prompt.is_empty() {
446
447
  parts.push(format!("user: {}", clip(&turn.prompt, budget.turn_chars)));
447
448
  }
448
- let mut calls: HashMap<&str, &str> = HashMap::new();
449
+ let mut calls: HashMap<&str, CallLabel<'_>> = HashMap::new();
449
450
  for &event in &turn.events {
450
451
  match event {
451
452
  Entry::Assistant(assistant) => {
453
+ let batch = assistant
454
+ .blocks
455
+ .iter()
456
+ .filter(|block| matches!(block, ContentBlock::ToolUse(_)))
457
+ .count();
458
+ let mut ordinal = 0;
452
459
  for block in &assistant.blocks {
453
460
  match block {
454
461
  ContentBlock::Text(text) if !pystr::strip(text).is_empty() => {
455
462
  parts.push(format!("assistant: {}", clip(text, budget.turn_chars)));
456
463
  }
457
464
  ContentBlock::ToolUse(tool_use) => {
458
- calls.insert(&tool_use.id, &tool_use.name);
459
- parts.push(render_tool_call(
465
+ ordinal += 1;
466
+ let label = CallLabel {
467
+ name: &tool_use.name,
468
+ ordinal: (tool_results && batch > 1).then_some((ordinal, batch)),
469
+ };
470
+ let rendered = render_tool_call(
460
471
  &parse_tool_call(&tool_use.name, &tool_use.input),
461
472
  budget,
462
- ));
473
+ );
474
+ parts.push(match label.ordinal {
475
+ Some((i, n)) => format!("call {i}/{n}: {rendered}"),
476
+ None => rendered,
477
+ });
478
+ calls.insert(&tool_use.id, label);
463
479
  }
464
480
  _ => {}
465
481
  }
@@ -468,8 +484,8 @@ pub fn render_turn(turn: &Turn, budget: &Budget) -> String {
468
484
  Entry::User(user) => {
469
485
  for block in user.blocks() {
470
486
  if let ContentBlock::ToolResult(result) = block {
471
- if let Some(name) = calls.get(result.tool_use_id.as_str()) {
472
- parts.extend(result_lines(name, result, budget));
487
+ if let Some(label) = calls.get(result.tool_use_id.as_str()) {
488
+ parts.extend(result_lines(label, result, budget, tool_results));
473
489
  }
474
490
  }
475
491
  }
@@ -485,29 +501,57 @@ pub fn render_turn(turn: &Turn, budget: &Budget) -> String {
485
501
  parts.join("\n")
486
502
  }
487
503
 
488
- fn result_lines(name: &str, result: &ToolResultBlock, budget: &Budget) -> Vec<String> {
504
+ struct CallLabel<'a> {
505
+ name: &'a str,
506
+ ordinal: Option<(usize, usize)>,
507
+ }
508
+
509
+ impl CallLabel<'_> {
510
+ fn head(&self, verdict: &str) -> String {
511
+ match self.ordinal {
512
+ Some((i, n)) => format!("{verdict} {i}/{n}: {}", self.name),
513
+ None => format!("{verdict}: {}", self.name),
514
+ }
515
+ }
516
+ }
517
+
518
+ fn result_lines(
519
+ label: &CallLabel<'_>,
520
+ result: &ToolResultBlock,
521
+ budget: &Budget,
522
+ tool_results: bool,
523
+ ) -> Vec<String> {
489
524
  if result.is_error {
490
- return vec![format!(
491
- "failed: {}",
492
- clip(&result.content, budget.turn_chars)
493
- )];
525
+ if !tool_results {
526
+ return Vec::new();
527
+ }
528
+ return quoted_result(label.head("failed"), &result.content, budget);
494
529
  }
495
- if name == ASK_USER_QUESTION {
530
+ if label.name == ASK_USER_QUESTION {
496
531
  if let Some(ToolResult::AskUserQuestion(answer)) = result
497
532
  .tool_use_result
498
533
  .as_ref()
499
- .map(|payload| parse_tool_result(name, payload))
534
+ .map(|payload| parse_tool_result(label.name, payload))
500
535
  {
501
536
  return answer_lines(&answer, budget);
502
537
  }
538
+ return vec![format!(
539
+ "user answered: {}",
540
+ clip(&result.content, budget.tool_chars)
541
+ )];
503
542
  }
504
- if pystr::strip(&result.content).is_empty() {
543
+ if !tool_results {
505
544
  return Vec::new();
506
545
  }
507
- vec![format!(
508
- "result: {}",
509
- clip(&result.content, budget.turn_chars)
510
- )]
546
+ quoted_result(label.head("result"), &result.content, budget)
547
+ }
548
+
549
+ fn quoted_result(head: String, content: &str, budget: &Budget) -> Vec<String> {
550
+ let mut lines = vec![head];
551
+ if !pystr::strip(content).is_empty() {
552
+ lines.extend(prefixed("> ", &clip(content, budget.turn_chars)));
553
+ }
554
+ lines
511
555
  }
512
556
 
513
557
  fn answer_lines(answer: &AskUserQuestionResult, budget: &Budget) -> Vec<String> {
@@ -72,6 +72,7 @@ pub(crate) fn render_turn_from_events(
72
72
  events: Vec<Bound<'_, PyAny>>,
73
73
  turn_chars: usize,
74
74
  tool_chars: usize,
75
+ tool_results: bool,
75
76
  ) -> PyResult<String> {
76
77
  let entries = events
77
78
  .iter()
@@ -91,6 +92,7 @@ pub(crate) fn render_turn_from_events(
91
92
  turn_chars,
92
93
  tool_chars,
93
94
  },
95
+ tool_results,
94
96
  ))
95
97
  }
96
98
 
File without changes