klaude-code 1.2.25__tar.gz → 1.2.26__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 (199) hide show
  1. {klaude_code-1.2.25 → klaude_code-1.2.26}/PKG-INFO +1 -1
  2. {klaude_code-1.2.25 → klaude_code-1.2.26}/pyproject.toml +1 -1
  3. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/const.py +5 -1
  4. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/apply_patch_tool.py +26 -3
  5. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/model.py +24 -1
  6. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/repl/event_handler.py +22 -3
  7. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/repl/renderer.py +22 -17
  8. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/sub_agent.py +14 -12
  9. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/thinking.py +1 -1
  10. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/tools.py +26 -2
  11. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/rich/markdown.py +34 -14
  12. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/rich/theme.py +1 -4
  13. {klaude_code-1.2.25 → klaude_code-1.2.26}/README.md +0 -0
  14. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/__init__.py +0 -0
  15. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/auth/__init__.py +0 -0
  16. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/auth/codex/__init__.py +0 -0
  17. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/auth/codex/exceptions.py +0 -0
  18. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
  19. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/auth/codex/oauth.py +0 -0
  20. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/auth/codex/token_manager.py +0 -0
  21. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/cli/__init__.py +0 -0
  22. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/cli/auth_cmd.py +0 -0
  23. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/cli/config_cmd.py +0 -0
  24. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/cli/debug.py +0 -0
  25. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/cli/list_model.py +0 -0
  26. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/cli/main.py +0 -0
  27. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/cli/runtime.py +0 -0
  28. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/cli/self_update.py +0 -0
  29. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/cli/session_cmd.py +0 -0
  30. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/__init__.py +0 -0
  31. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/clear_cmd.py +0 -0
  32. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/command_abc.py +0 -0
  33. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/debug_cmd.py +0 -0
  34. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/export_cmd.py +0 -0
  35. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/export_online_cmd.py +0 -0
  36. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/help_cmd.py +0 -0
  37. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/model_cmd.py +0 -0
  38. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/prompt-init.md +0 -0
  39. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/prompt-jj-describe.md +0 -0
  40. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/prompt_command.py +0 -0
  41. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/refresh_cmd.py +0 -0
  42. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/registry.py +0 -0
  43. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/release_notes_cmd.py +0 -0
  44. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/status_cmd.py +0 -0
  45. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/terminal_setup_cmd.py +0 -0
  46. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/command/thinking_cmd.py +0 -0
  47. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/config/__init__.py +0 -0
  48. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/config/config.py +0 -0
  49. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/config/select_model.py +0 -0
  50. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/__init__.py +0 -0
  51. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/agent.py +0 -0
  52. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/executor.py +0 -0
  53. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/manager/__init__.py +0 -0
  54. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/manager/llm_clients.py +0 -0
  55. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/manager/llm_clients_builder.py +0 -0
  56. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/manager/sub_agent_manager.py +0 -0
  57. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompt.py +0 -0
  58. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
  59. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
  60. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md +0 -0
  61. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-codex.md +0 -0
  62. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
  63. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
  64. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -0
  65. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-sub-agent-oracle.md +0 -0
  66. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-sub-agent-web.md +0 -0
  67. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
  68. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/reminders.py +0 -0
  69. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/task.py +0 -0
  70. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/__init__.py +0 -0
  71. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/__init__.py +0 -0
  72. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/_utils.py +0 -0
  73. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
  74. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
  75. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/diff_builder.py +0 -0
  76. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
  77. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
  78. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/read_tool.md +0 -0
  79. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/read_tool.py +0 -0
  80. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/write_tool.md +0 -0
  81. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/file/write_tool.py +0 -0
  82. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/report_back_tool.py +0 -0
  83. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/shell/__init__.py +0 -0
  84. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
  85. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/shell/bash_tool.py +0 -0
  86. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
  87. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/skill/__init__.py +0 -0
  88. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/skill/skill_tool.md +0 -0
  89. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/skill/skill_tool.py +0 -0
  90. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/sub_agent_tool.py +0 -0
  91. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/todo/__init__.py +0 -0
  92. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
  93. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
  94. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
  95. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
  96. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
  97. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/tool_abc.py +0 -0
  98. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/tool_context.py +0 -0
  99. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/tool_registry.py +0 -0
  100. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/tool_runner.py +0 -0
  101. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/truncation.py +0 -0
  102. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/web/__init__.py +0 -0
  103. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
  104. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
  105. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
  106. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/web/web_fetch_tool.py +0 -0
  107. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
  108. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/tool/web/web_search_tool.py +0 -0
  109. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/core/turn.py +0 -0
  110. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/__init__.py +0 -0
  111. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/anthropic/__init__.py +0 -0
  112. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/anthropic/client.py +0 -0
  113. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/anthropic/input.py +0 -0
  114. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/client.py +0 -0
  115. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/codex/__init__.py +0 -0
  116. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/codex/client.py +0 -0
  117. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/input_common.py +0 -0
  118. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
  119. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/openai_compatible/client.py +0 -0
  120. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/openai_compatible/input.py +0 -0
  121. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/openai_compatible/stream.py +0 -0
  122. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
  123. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/openrouter/__init__.py +0 -0
  124. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/openrouter/client.py +0 -0
  125. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/openrouter/input.py +0 -0
  126. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/openrouter/reasoning.py +0 -0
  127. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/registry.py +0 -0
  128. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/responses/__init__.py +0 -0
  129. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/responses/client.py +0 -0
  130. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/responses/input.py +0 -0
  131. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/llm/usage.py +0 -0
  132. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/__init__.py +0 -0
  133. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/commands.py +0 -0
  134. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/events.py +0 -0
  135. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/llm_param.py +0 -0
  136. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/op.py +0 -0
  137. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/op_handler.py +0 -0
  138. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
  139. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/sub_agent/explore.py +0 -0
  140. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/sub_agent/oracle.py +0 -0
  141. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/sub_agent/task.py +0 -0
  142. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/sub_agent/web.py +0 -0
  143. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/protocol/tools.py +0 -0
  144. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/session/__init__.py +0 -0
  145. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/session/codec.py +0 -0
  146. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/session/export.py +0 -0
  147. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/session/selector.py +0 -0
  148. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/session/session.py +0 -0
  149. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/session/store.py +0 -0
  150. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/session/templates/export_session.html +0 -0
  151. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/skill/__init__.py +0 -0
  152. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/skill/assets/deslop/SKILL.md +0 -0
  153. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/skill/assets/dev-docs/SKILL.md +0 -0
  154. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/skill/assets/handoff/SKILL.md +0 -0
  155. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/skill/assets/jj-workspace/SKILL.md +0 -0
  156. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/skill/assets/skill-creator/SKILL.md +0 -0
  157. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/skill/loader.py +0 -0
  158. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/skill/manager.py +0 -0
  159. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/skill/system_skills.py +0 -0
  160. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/trace/__init__.py +0 -0
  161. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/trace/log.py +0 -0
  162. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/__init__.py +0 -0
  163. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/core/__init__.py +0 -0
  164. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/core/display.py +0 -0
  165. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/core/input.py +0 -0
  166. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/core/stage_manager.py +0 -0
  167. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/__init__.py +0 -0
  168. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/debug/__init__.py +0 -0
  169. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/debug/display.py +0 -0
  170. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/exec/__init__.py +0 -0
  171. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/exec/display.py +0 -0
  172. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/repl/__init__.py +0 -0
  173. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/repl/clipboard.py +0 -0
  174. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/repl/completers.py +0 -0
  175. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/repl/display.py +0 -0
  176. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/repl/input_prompt_toolkit.py +0 -0
  177. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/modes/repl/key_bindings.py +0 -0
  178. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/__init__.py +0 -0
  179. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/assistant.py +0 -0
  180. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/common.py +0 -0
  181. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/developer.py +0 -0
  182. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/diffs.py +0 -0
  183. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/errors.py +0 -0
  184. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/metadata.py +0 -0
  185. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/renderers/user_input.py +0 -0
  186. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/rich/__init__.py +0 -0
  187. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/rich/cjk_wrap.py +0 -0
  188. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/rich/code_panel.py +0 -0
  189. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/rich/live.py +0 -0
  190. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/rich/quote.py +0 -0
  191. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/rich/searchable_text.py +0 -0
  192. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/rich/status.py +0 -0
  193. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/terminal/__init__.py +0 -0
  194. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/terminal/color.py +0 -0
  195. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/terminal/control.py +0 -0
  196. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/terminal/notifier.py +0 -0
  197. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/terminal/progress_bar.py +0 -0
  198. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/utils/__init__.py +0 -0
  199. {klaude_code-1.2.25 → klaude_code-1.2.26}/src/klaude_code/ui/utils/common.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: klaude-code
3
- Version: 1.2.25
3
+ Version: 1.2.26
4
4
  Summary: Add your description here
5
5
  Requires-Dist: anthropic>=0.66.0
6
6
  Requires-Dist: chardet>=5.2.0
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "klaude-code"
7
- version = "1.2.25"
7
+ version = "1.2.26"
8
8
  description = "Add your description here"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -97,7 +97,11 @@ SUB_AGENT_RESULT_MAX_LINES = 50
97
97
 
98
98
 
99
99
  # UI refresh rate (frames per second) for debounced content streaming
100
- UI_REFRESH_RATE_FPS = 20
100
+ UI_REFRESH_RATE_FPS = 10
101
+
102
+ # Enable live area for streaming markdown (shows incomplete blocks being typed)
103
+ # When False, only completed markdown blocks are displayed (more stable, less flicker)
104
+ MARKDOWN_STREAM_LIVE_REPAINT_ENABLED = False
101
105
 
102
106
  # Number of lines to keep visible at bottom of markdown streaming window
103
107
  MARKDOWN_STREAM_LIVE_WINDOW = 6
@@ -20,7 +20,7 @@ class ApplyPatchHandler:
20
20
  @classmethod
21
21
  async def handle_apply_patch(cls, patch_text: str) -> model.ToolResultItem:
22
22
  try:
23
- output, diff_ui = await asyncio.to_thread(cls._apply_patch_in_thread, patch_text)
23
+ output, ui_extra = await asyncio.to_thread(cls._apply_patch_in_thread, patch_text)
24
24
  except apply_patch_module.DiffError as error:
25
25
  return model.ToolResultItem(status="error", output=str(error))
26
26
  except Exception as error: # pragma: no cover # unexpected errors bubbled to tool result
@@ -28,11 +28,11 @@ class ApplyPatchHandler:
28
28
  return model.ToolResultItem(
29
29
  status="success",
30
30
  output=output,
31
- ui_extra=diff_ui,
31
+ ui_extra=ui_extra,
32
32
  )
33
33
 
34
34
  @staticmethod
35
- def _apply_patch_in_thread(patch_text: str) -> tuple[str, model.DiffUIExtra]:
35
+ def _apply_patch_in_thread(patch_text: str) -> tuple[str, model.ToolResultUIExtra]:
36
36
  ap = apply_patch_module
37
37
  normalized_start = patch_text.lstrip()
38
38
  if not normalized_start.startswith("*** Begin Patch"):
@@ -69,6 +69,16 @@ class ApplyPatchHandler:
69
69
  commit = ap.patch_to_commit(patch, orig)
70
70
  diff_ui = ApplyPatchHandler._commit_to_structured_diff(commit)
71
71
 
72
+ md_items: list[model.MarkdownDocUIExtra] = []
73
+ for change_path, change in commit.changes.items():
74
+ if change.type == apply_patch_module.ActionType.ADD and change_path.endswith(".md"):
75
+ md_items.append(
76
+ model.MarkdownDocUIExtra(
77
+ file_path=resolve_path(change_path),
78
+ content=change.new_content or "",
79
+ )
80
+ )
81
+
72
82
  def write_fn(path: str, content: str) -> None:
73
83
  resolved = resolve_path(path)
74
84
  if os.path.isdir(resolved):
@@ -102,6 +112,16 @@ class ApplyPatchHandler:
102
112
  file_tracker.pop(resolved, None)
103
113
 
104
114
  ap.apply_commit(commit, write_fn, remove_fn)
115
+
116
+ # apply_patch can include multiple operations. If we added markdown files,
117
+ # return a MultiUIExtra so UI can render markdown previews (without showing a diff for those markdown adds).
118
+ if md_items:
119
+ items: list[model.MultiUIExtraItem] = []
120
+ items.extend(md_items)
121
+ if diff_ui.files:
122
+ items.append(diff_ui)
123
+ return "Done!", model.MultiUIExtra(items=items)
124
+
105
125
  return "Done!", diff_ui
106
126
 
107
127
  @staticmethod
@@ -110,6 +130,9 @@ class ApplyPatchHandler:
110
130
  for path in sorted(commit.changes):
111
131
  change = commit.changes[path]
112
132
  if change.type == apply_patch_module.ActionType.ADD:
133
+ # For markdown files created via Add File, we render content via MarkdownDocUIExtra instead of a diff.
134
+ if path.endswith(".md"):
135
+ continue
113
136
  files.append(build_structured_file_diff("", change.new_content or "", file_path=path))
114
137
  elif change.type == apply_patch_module.ActionType.DELETE:
115
138
  files.append(build_structured_file_diff(change.old_content or "", "", file_path=path))
@@ -151,6 +151,28 @@ class SessionStatusUIExtra(BaseModel):
151
151
  by_model: list["TaskMetadata"] = []
152
152
 
153
153
 
154
+ MultiUIExtraItem = (
155
+ DiffUIExtra
156
+ | TodoListUIExtra
157
+ | SessionIdUIExtra
158
+ | MermaidLinkUIExtra
159
+ | TruncationUIExtra
160
+ | MarkdownDocUIExtra
161
+ | SessionStatusUIExtra
162
+ )
163
+
164
+
165
+ class MultiUIExtra(BaseModel):
166
+ """A container UIExtra that can render multiple UI blocks for a single tool result.
167
+
168
+ This is primarily used by tools like apply_patch which can perform multiple
169
+ operations in one invocation.
170
+ """
171
+
172
+ type: Literal["multi"] = "multi"
173
+ items: list[MultiUIExtraItem]
174
+
175
+
154
176
  ToolResultUIExtra = Annotated[
155
177
  DiffUIExtra
156
178
  | TodoListUIExtra
@@ -158,7 +180,8 @@ ToolResultUIExtra = Annotated[
158
180
  | MermaidLinkUIExtra
159
181
  | TruncationUIExtra
160
182
  | MarkdownDocUIExtra
161
- | SessionStatusUIExtra,
183
+ | SessionStatusUIExtra
184
+ | MultiUIExtra,
162
185
  Field(discriminator="type"),
163
186
  ]
164
187
 
@@ -122,6 +122,7 @@ class ActivityState:
122
122
 
123
123
  def __init__(self) -> None:
124
124
  self._composing: bool = False
125
+ self._buffer_length: int = 0
125
126
  self._tool_calls: dict[str, int] = {}
126
127
 
127
128
  @property
@@ -134,6 +135,11 @@ class ActivityState:
134
135
 
135
136
  def set_composing(self, composing: bool) -> None:
136
137
  self._composing = composing
138
+ if not composing:
139
+ self._buffer_length = 0
140
+
141
+ def set_buffer_length(self, length: int) -> None:
142
+ self._buffer_length = length
137
143
 
138
144
  def add_tool_call(self, tool_name: str) -> None:
139
145
  self._tool_calls[tool_name] = self._tool_calls.get(tool_name, 0) + 1
@@ -143,6 +149,7 @@ class ActivityState:
143
149
 
144
150
  def reset(self) -> None:
145
151
  self._composing = False
152
+ self._buffer_length = 0
146
153
  self._tool_calls = {}
147
154
 
148
155
  def get_activity_text(self) -> Text | None:
@@ -159,7 +166,12 @@ class ActivityState:
159
166
  first = False
160
167
  return activity_text
161
168
  if self._composing:
162
- return Text("Composing")
169
+ # Main status text with creative verb
170
+ text = Text.assemble(
171
+ ("Composing ", ThemeKey.STATUS_TEXT_BOLD),
172
+ (f"({self._buffer_length:,})", ThemeKey.STATUS_TEXT),
173
+ )
174
+ return text
163
175
  return None
164
176
 
165
177
 
@@ -206,6 +218,10 @@ class SpinnerStatusState:
206
218
  self._reasoning_status = None
207
219
  self._activity.set_composing(composing)
208
220
 
221
+ def set_buffer_length(self, length: int) -> None:
222
+ """Set buffer length for composing state display."""
223
+ self._activity.set_buffer_length(length)
224
+
209
225
  def add_tool_call(self, tool_name: str) -> None:
210
226
  """Add a tool call to the accumulator."""
211
227
  self._activity.add_tool_call(tool_name)
@@ -375,7 +391,7 @@ class DisplayEventHandler:
375
391
  },
376
392
  theme=self.renderer.themes.thinking_markdown_theme,
377
393
  console=self.renderer.console,
378
- live_sink=self.renderer.set_stream_renderable,
394
+ live_sink=self.renderer.set_stream_renderable if const.MARKDOWN_STREAM_LIVE_REPAINT_ENABLED else None,
379
395
  mark=THINKING_MESSAGE_MARK,
380
396
  mark_style=ThemeKey.THINKING,
381
397
  left_margin=const.MARKDOWN_LEFT_MARGIN,
@@ -412,12 +428,15 @@ class DisplayEventHandler:
412
428
  mdargs={"code_theme": self.renderer.themes.code_theme},
413
429
  theme=self.renderer.themes.markdown_theme,
414
430
  console=self.renderer.console,
415
- live_sink=self.renderer.set_stream_renderable,
431
+ live_sink=self.renderer.set_stream_renderable if const.MARKDOWN_STREAM_LIVE_REPAINT_ENABLED else None,
416
432
  mark=ASSISTANT_MESSAGE_MARK,
417
433
  left_margin=const.MARKDOWN_LEFT_MARGIN,
418
434
  )
419
435
  self.assistant_stream.start(mdstream)
420
436
  self.assistant_stream.append(event.content)
437
+ self.spinner_status.set_buffer_length(len(self.assistant_stream.buffer))
438
+ if not first_delta:
439
+ self._update_spinner()
421
440
  if first_delta and self.assistant_stream.mdstream is not None:
422
441
  self.assistant_stream.mdstream.update(self.assistant_stream.buffer)
423
442
  await self.stage_manager.transition_to(Stage.ASSISTANT)
@@ -332,23 +332,28 @@ class REPLRenderer:
332
332
  self._bottom_live.start()
333
333
 
334
334
  def _bottom_renderable(self) -> RenderableType:
335
- stream = self._stream_renderable
336
- if stream is not None:
337
- current_width = self.console.size.width
338
- if self._stream_last_width != current_width:
339
- height = len(self.console.render_lines(stream, self.console.options, pad=False))
340
- self._stream_last_height = height
341
- self._stream_last_width = current_width
342
- self._stream_max_height = max(self._stream_max_height, height)
343
- else:
344
- height = self._stream_last_height
345
-
346
- pad_lines = max(self._stream_max_height - height, 0)
347
- if pad_lines:
348
- stream = Padding(stream, (0, 0, pad_lines, 0))
349
-
350
- stream_part: RenderableType = stream if stream is not None else Group()
351
- gap_part: RenderableType = Text("") if self._spinner_visible else Group()
335
+ stream_part: RenderableType = Group()
336
+ gap_part: RenderableType = Group()
337
+
338
+ if const.MARKDOWN_STREAM_LIVE_REPAINT_ENABLED:
339
+ stream = self._stream_renderable
340
+ if stream is not None:
341
+ current_width = self.console.size.width
342
+ if self._stream_last_width != current_width:
343
+ height = len(self.console.render_lines(stream, self.console.options, pad=False))
344
+ self._stream_last_height = height
345
+ self._stream_last_width = current_width
346
+ self._stream_max_height = max(self._stream_max_height, height)
347
+ else:
348
+ height = self._stream_last_height
349
+
350
+ pad_lines = max(self._stream_max_height - height, 0)
351
+ if pad_lines:
352
+ stream = Padding(stream, (0, 0, pad_lines, 0))
353
+ stream_part = stream
354
+
355
+ gap_part = Text("") if self._spinner_visible else Group()
356
+
352
357
  status_part: RenderableType = SingleLine(self._status_spinner) if self._spinner_visible else Group()
353
358
  return Group(stream_part, gap_part, status_part)
354
359
 
@@ -68,24 +68,22 @@ def render_sub_agent_result(
68
68
  panel_style: Style | None = None,
69
69
  ) -> RenderableType:
70
70
  stripped_result = result.strip()
71
-
72
- # Add markdown heading if description is provided
73
- if description:
74
- stripped_result = f"# {description}\n\n{stripped_result}"
75
-
76
71
  result_panel_style = panel_style or ThemeKey.SUB_AGENT_RESULT_PANEL
77
72
 
78
73
  # Use rich JSON for structured output
79
74
  if has_structured_output:
80
75
  try:
81
- return Panel.fit(
82
- Group(
83
- Text(
84
- "use /export to view full output",
85
- style=ThemeKey.TOOL_RESULT,
86
- ),
87
- JSON(stripped_result),
76
+ group_elements: list[RenderableType] = [
77
+ Text(
78
+ "use /export to view full output",
79
+ style=ThemeKey.TOOL_RESULT,
88
80
  ),
81
+ JSON(stripped_result),
82
+ ]
83
+ if description:
84
+ group_elements.insert(0, NoInsetMarkdown(f"# {description}", code_theme=code_theme, style=style or ""))
85
+ return Panel.fit(
86
+ Group(*group_elements),
89
87
  box=box.SIMPLE,
90
88
  border_style=ThemeKey.LINES,
91
89
  style=result_panel_style,
@@ -94,6 +92,10 @@ def render_sub_agent_result(
94
92
  # Fall back to markdown if not valid JSON
95
93
  pass
96
94
 
95
+ # Add markdown heading if description is provided for non-structured output
96
+ if description:
97
+ stripped_result = f"# {description}\n\n{stripped_result}"
98
+
97
99
  lines = stripped_result.splitlines()
98
100
  if len(lines) > const.SUB_AGENT_RESULT_MAX_LINES:
99
101
  hidden_count = len(lines) - const.SUB_AGENT_RESULT_MAX_LINES
@@ -10,7 +10,7 @@ from klaude_code.ui.rich.markdown import ThinkingMarkdown
10
10
  from klaude_code.ui.rich.theme import ThemeKey
11
11
 
12
12
  # UI markers
13
- THINKING_MESSAGE_MARK = ""
13
+ THINKING_MESSAGE_MARK = ""
14
14
 
15
15
 
16
16
  def normalize_thinking_content(content: str) -> str:
@@ -19,7 +19,7 @@ from klaude_code.ui.rich.theme import ThemeKey
19
19
  # Tool markers (Unicode symbols for UI display)
20
20
  MARK_GENERIC = "⚒"
21
21
  MARK_BASH = "→"
22
- MARK_PLAN = ""
22
+ MARK_PLAN = "Ξ"
23
23
  MARK_READ = "←"
24
24
  MARK_EDIT = "±"
25
25
  MARK_WRITE = "+"
@@ -528,19 +528,28 @@ def render_tool_call(e: events.ToolCallEvent) -> RenderableType | None:
528
528
  def _extract_diff(ui_extra: model.ToolResultUIExtra | None) -> model.DiffUIExtra | None:
529
529
  if isinstance(ui_extra, model.DiffUIExtra):
530
530
  return ui_extra
531
+ if isinstance(ui_extra, model.MultiUIExtra):
532
+ for item in ui_extra.items:
533
+ if isinstance(item, model.DiffUIExtra):
534
+ return item
531
535
  return None
532
536
 
533
537
 
534
538
  def _extract_markdown_doc(ui_extra: model.ToolResultUIExtra | None) -> model.MarkdownDocUIExtra | None:
535
539
  if isinstance(ui_extra, model.MarkdownDocUIExtra):
536
540
  return ui_extra
541
+ if isinstance(ui_extra, model.MultiUIExtra):
542
+ for item in ui_extra.items:
543
+ if isinstance(item, model.MarkdownDocUIExtra):
544
+ return item
537
545
  return None
538
546
 
539
547
 
540
548
  def render_markdown_doc(md_ui: model.MarkdownDocUIExtra, *, code_theme: str) -> RenderableType:
541
549
  """Render markdown document content in a panel."""
550
+ header = render_path(md_ui.file_path, ThemeKey.TOOL_PARAM_FILE_PATH)
542
551
  return Panel.fit(
543
- NoInsetMarkdown(md_ui.content, code_theme=code_theme),
552
+ Group(header, Text(""), NoInsetMarkdown(md_ui.content, code_theme=code_theme)),
544
553
  box=box.SIMPLE,
545
554
  border_style=ThemeKey.LINES,
546
555
  style=ThemeKey.WRITE_MARKDOWN_PANEL,
@@ -562,6 +571,19 @@ def render_tool_result(e: events.ToolResultEvent, *, code_theme: str = "monokai"
562
571
  error_msg = truncate_display(e.result)
563
572
  return r_errors.render_error(error_msg)
564
573
 
574
+ # Render multiple ui blocks if present
575
+ if isinstance(e.ui_extra, model.MultiUIExtra) and e.ui_extra.items:
576
+ rendered: list[RenderableType] = []
577
+ for item in e.ui_extra.items:
578
+ if isinstance(item, model.MarkdownDocUIExtra):
579
+ rendered.append(Padding.indent(render_markdown_doc(item, code_theme=code_theme), level=2))
580
+ elif isinstance(item, model.DiffUIExtra):
581
+ show_file_name = e.tool_name == tools.APPLY_PATCH
582
+ rendered.append(
583
+ Padding.indent(r_diffs.render_structured_diff(item, show_file_name=show_file_name), level=2)
584
+ )
585
+ return Group(*rendered) if rendered else None
586
+
565
587
  # Show truncation info if output was truncated and saved to file
566
588
  truncation_info = get_truncation_info(e)
567
589
  if truncation_info:
@@ -580,6 +602,8 @@ def render_tool_result(e: events.ToolResultEvent, *, code_theme: str = "monokai"
580
602
  return Padding.indent(render_markdown_doc(md_ui, code_theme=code_theme), level=2)
581
603
  return Padding.indent(r_diffs.render_structured_diff(diff_ui) if diff_ui else Text(""), level=2)
582
604
  case tools.APPLY_PATCH:
605
+ if md_ui:
606
+ return Padding.indent(render_markdown_doc(md_ui, code_theme=code_theme), level=2)
583
607
  if diff_ui:
584
608
  return Padding.indent(r_diffs.render_structured_diff(diff_ui, show_file_name=True), level=2)
585
609
  if len(e.result.strip()) == 0:
@@ -1,4 +1,3 @@
1
- # copy from https://github.com/Aider-AI/aider/blob/main/aider/mdstream.py
2
1
  from __future__ import annotations
3
2
 
4
3
  import contextlib
@@ -9,11 +8,13 @@ from typing import Any, ClassVar
9
8
 
10
9
  from markdown_it import MarkdownIt
11
10
  from markdown_it.token import Token
11
+ from rich import box
12
12
  from rich.console import Console, ConsoleOptions, RenderableType, RenderResult
13
- from rich.markdown import CodeBlock, Heading, Markdown, MarkdownElement
13
+ from rich.markdown import CodeBlock, Heading, Markdown, MarkdownElement, TableElement
14
14
  from rich.rule import Rule
15
15
  from rich.style import Style, StyleType
16
16
  from rich.syntax import Syntax
17
+ from rich.table import Table
17
18
  from rich.text import Text
18
19
  from rich.theme import Theme
19
20
 
@@ -53,6 +54,24 @@ class Divider(MarkdownElement):
53
54
  yield Rule(style=style, characters="-")
54
55
 
55
56
 
57
+ class MinimalHeavyHeadTable(TableElement):
58
+ """A table element with MINIMAL_HEAVY_HEAD box style."""
59
+
60
+ def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult:
61
+ table = Table(box=box.MARKDOWN)
62
+
63
+ if self.header is not None and self.header.row is not None:
64
+ for column in self.header.row.cells:
65
+ table.add_column(column.content)
66
+
67
+ if self.body is not None:
68
+ for row in self.body.rows:
69
+ row_content = [element.content for element in row.cells]
70
+ table.add_row(*row_content)
71
+
72
+ yield table
73
+
74
+
56
75
  class LeftHeading(Heading):
57
76
  """A heading class that renders left-justified."""
58
77
 
@@ -64,7 +83,7 @@ class LeftHeading(Heading):
64
83
  yield h1_text
65
84
  elif self.tag == "h2":
66
85
  text.stylize(Style(bold=True, underline=False))
67
- yield Rule(title=text, characters="·", style="markdown.h2.border", align="left")
86
+ yield text
68
87
  else:
69
88
  yield text
70
89
 
@@ -78,6 +97,7 @@ class NoInsetMarkdown(Markdown):
78
97
  "code_block": NoInsetCodeBlock,
79
98
  "heading_open": LeftHeading,
80
99
  "hr": Divider,
100
+ "table_open": MinimalHeavyHeadTable,
81
101
  }
82
102
 
83
103
 
@@ -90,6 +110,7 @@ class ThinkingMarkdown(Markdown):
90
110
  "code_block": ThinkingCodeBlock,
91
111
  "heading_open": LeftHeading,
92
112
  "hr": Divider,
113
+ "table_open": MinimalHeavyHeadTable,
93
114
  }
94
115
 
95
116
 
@@ -341,9 +362,6 @@ class MarkdownStream:
341
362
  def update(self, text: str, final: bool = False) -> None:
342
363
  """Update the display with the latest full markdown buffer."""
343
364
 
344
- if self._live_sink is None:
345
- return
346
-
347
365
  now = time.time()
348
366
  if not final and now - self.when < self.min_delay:
349
367
  return
@@ -374,18 +392,20 @@ class MarkdownStream:
374
392
  self._stable_source_line_count = stable_line
375
393
 
376
394
  if final:
377
- self._live_sink(None)
395
+ if self._live_sink is not None:
396
+ self._live_sink(None)
378
397
  return
379
398
 
380
- apply_mark_live = self._stable_source_line_count == 0
381
- live_lines = self._render_markdown_to_lines(live_source, apply_mark=apply_mark_live)
399
+ if const.MARKDOWN_STREAM_LIVE_REPAINT_ENABLED and self._live_sink is not None:
400
+ apply_mark_live = self._stable_source_line_count == 0
401
+ live_lines = self._render_markdown_to_lines(live_source, apply_mark=apply_mark_live)
382
402
 
383
- if self._stable_rendered_lines and not self._stable_rendered_lines[-1].strip():
384
- while live_lines and not live_lines[0].strip():
385
- live_lines.pop(0)
403
+ if self._stable_rendered_lines and not self._stable_rendered_lines[-1].strip():
404
+ while live_lines and not live_lines[0].strip():
405
+ live_lines.pop(0)
386
406
 
387
- live_text = Text.from_ansi("".join(live_lines))
388
- self._live_sink(live_text)
407
+ live_text = Text.from_ansi("".join(live_lines))
408
+ self._live_sink(live_text)
389
409
 
390
410
  elapsed = time.time() - start
391
411
  self.min_delay = min(max(elapsed * 6, 1.0 / 30), 0.5)
@@ -291,7 +291,7 @@ def get_theme(theme: str | None = None) -> Themes:
291
291
  "markdown.code.border": palette.grey3,
292
292
  "markdown.h1": "bold reverse",
293
293
  "markdown.h1.border": palette.grey3,
294
- "markdown.h2.border": palette.grey3,
294
+ "markdown.h2": "bold underline",
295
295
  "markdown.h3": "bold " + palette.grey1,
296
296
  "markdown.h4": "bold " + palette.grey2,
297
297
  "markdown.hr": palette.grey3,
@@ -311,7 +311,6 @@ def get_theme(theme: str | None = None) -> Themes:
311
311
  "markdown.code.border": palette.grey3,
312
312
  "markdown.h1": "bold reverse",
313
313
  "markdown.h1.border": palette.grey3,
314
- "markdown.h2.border": palette.grey3,
315
314
  "markdown.h3": "bold " + palette.grey1,
316
315
  "markdown.h4": "bold " + palette.grey2,
317
316
  "markdown.hr": palette.grey3,
@@ -329,7 +328,6 @@ def get_theme(theme: str | None = None) -> Themes:
329
328
  Style(color=palette.blue),
330
329
  Style(color=palette.purple),
331
330
  Style(color=palette.orange),
332
- Style(color=palette.red),
333
331
  Style(color=palette.grey1),
334
332
  Style(color=palette.yellow),
335
333
  ],
@@ -339,7 +337,6 @@ def get_theme(theme: str | None = None) -> Themes:
339
337
  Style(bgcolor=palette.blue_sub_background),
340
338
  Style(bgcolor=palette.purple_background),
341
339
  Style(bgcolor=palette.orange_background),
342
- Style(bgcolor=palette.red_background),
343
340
  Style(bgcolor=palette.grey_background),
344
341
  Style(bgcolor=palette.yellow_background),
345
342
  ],
File without changes