1818 render_edit_tool ,
1919 render_bash_tool ,
2020 render_content_block ,
21+ strip_ansi ,
2122 analyze_conversation ,
2223 format_tool_stats ,
2324 is_tool_result_message ,
@@ -284,6 +285,21 @@ def test_tool_result_error(self, snapshot_html):
284285 result = render_content_block (block )
285286 assert result == snapshot_html
286287
288+ def test_tool_result_with_ansi_codes (self ):
289+ """Test that ANSI escape codes are stripped from tool results."""
290+ block = {
291+ "type" : "tool_result" ,
292+ "content" : "\x1b [38;2;166;172;186mTests passed:\x1b [0m \x1b [32m✓\x1b [0m All 5 tests passed\n \x1b [1;31mError:\x1b [0m None" ,
293+ "is_error" : False ,
294+ }
295+ result = render_content_block (block )
296+ assert "\x1b [" not in result
297+ assert "[38;2;" not in result
298+ assert "[32m" not in result
299+ assert "[0m" not in result
300+ assert "Tests passed:" in result
301+ assert "All 5 tests passed" in result
302+
287303 def test_tool_result_with_commit (self , snapshot_html ):
288304 """Test tool result with git commit output."""
289305 # Need to set the global _github_repo for commit link rendering
@@ -303,6 +319,21 @@ def test_tool_result_with_commit(self, snapshot_html):
303319 claude_code_transcripts ._github_repo = old_repo
304320
305321
322+ class TestStripAnsi :
323+ """Tests for ANSI escape stripping."""
324+
325+ def test_strips_csi_sequences (self ):
326+ text = "start\x1b [?25hend\x1b [2Jdone"
327+ assert strip_ansi (text ) == "startenddone"
328+
329+ def test_strips_osc_sequences (self ):
330+ text = "title\x1b ]0;My Title\x07 end"
331+ assert strip_ansi (text ) == "titleend"
332+
333+ def test_strips_osc_st_terminator (self ):
334+ text = "name\x1b ]0;Title\x1b \\ end"
335+ assert strip_ansi (text ) == "nameend"
336+
306337class TestAnalyzeConversation :
307338 """Tests for conversation analysis."""
308339
0 commit comments