klaude-code 1.2.14__tar.gz → 1.2.15__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 (185) hide show
  1. {klaude_code-1.2.14 → klaude_code-1.2.15}/PKG-INFO +1 -1
  2. {klaude_code-1.2.14 → klaude_code-1.2.15}/pyproject.toml +1 -1
  3. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/thinking_cmd.py +1 -1
  4. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/input_common.py +1 -1
  5. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/session/templates/export_session.html +8 -12
  6. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/repl/event_handler.py +2 -1
  7. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/repl/renderer.py +1 -3
  8. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/metadata.py +49 -88
  9. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/thinking.py +2 -2
  10. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/tools.py +45 -1
  11. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/rich/markdown.py +27 -11
  12. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/rich/theme.py +12 -12
  13. {klaude_code-1.2.14 → klaude_code-1.2.15}/README.md +0 -0
  14. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/__init__.py +0 -0
  15. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/auth/__init__.py +0 -0
  16. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/auth/codex/__init__.py +0 -0
  17. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/auth/codex/exceptions.py +0 -0
  18. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
  19. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/auth/codex/oauth.py +0 -0
  20. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/auth/codex/token_manager.py +0 -0
  21. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/cli/__init__.py +0 -0
  22. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/cli/auth_cmd.py +0 -0
  23. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/cli/config_cmd.py +0 -0
  24. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/cli/debug.py +0 -0
  25. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/cli/main.py +0 -0
  26. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/cli/runtime.py +0 -0
  27. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/cli/session_cmd.py +0 -0
  28. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/__init__.py +0 -0
  29. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/clear_cmd.py +0 -0
  30. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/command_abc.py +0 -0
  31. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/diff_cmd.py +0 -0
  32. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/export_cmd.py +0 -0
  33. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/help_cmd.py +0 -0
  34. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/model_cmd.py +0 -0
  35. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/prompt-deslop.md +0 -0
  36. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/prompt-dev-docs-update.md +0 -0
  37. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/prompt-dev-docs.md +0 -0
  38. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/prompt-init.md +0 -0
  39. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/prompt_command.py +0 -0
  40. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/refresh_cmd.py +0 -0
  41. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/registry.py +0 -0
  42. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/release_notes_cmd.py +0 -0
  43. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/status_cmd.py +0 -0
  44. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/command/terminal_setup_cmd.py +0 -0
  45. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/config/__init__.py +0 -0
  46. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/config/config.py +0 -0
  47. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/config/list_model.py +0 -0
  48. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/config/select_model.py +0 -0
  49. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/const/__init__.py +0 -0
  50. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/__init__.py +0 -0
  51. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/agent.py +0 -0
  52. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/executor.py +0 -0
  53. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/manager/__init__.py +0 -0
  54. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/manager/agent_manager.py +0 -0
  55. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/manager/llm_clients.py +0 -0
  56. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/manager/llm_clients_builder.py +0 -0
  57. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/manager/sub_agent_manager.py +0 -0
  58. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompt.py +0 -0
  59. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
  60. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
  61. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1.md +0 -0
  62. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
  63. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
  64. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompts/prompt-subagent-explore.md +0 -0
  65. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompts/prompt-subagent-oracle.md +0 -0
  66. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompts/prompt-subagent-webfetch.md +0 -0
  67. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/prompts/prompt-subagent.md +0 -0
  68. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/reminders.py +0 -0
  69. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/task.py +0 -0
  70. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/__init__.py +0 -0
  71. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/__init__.py +0 -0
  72. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/_utils.py +0 -0
  73. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
  74. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
  75. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
  76. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
  77. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
  78. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/multi_edit_tool.md +0 -0
  79. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/multi_edit_tool.py +0 -0
  80. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/read_tool.md +0 -0
  81. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/read_tool.py +0 -0
  82. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/write_tool.md +0 -0
  83. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/file/write_tool.py +0 -0
  84. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/memory/__init__.py +0 -0
  85. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/memory/memory_tool.md +0 -0
  86. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/memory/memory_tool.py +0 -0
  87. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/memory/skill_loader.py +0 -0
  88. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/memory/skill_tool.md +0 -0
  89. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/memory/skill_tool.py +0 -0
  90. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/shell/__init__.py +0 -0
  91. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
  92. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/shell/bash_tool.py +0 -0
  93. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
  94. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/sub_agent_tool.py +0 -0
  95. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/todo/__init__.py +0 -0
  96. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
  97. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
  98. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
  99. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
  100. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
  101. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/tool_abc.py +0 -0
  102. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/tool_context.py +0 -0
  103. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/tool_registry.py +0 -0
  104. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/tool_runner.py +0 -0
  105. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/truncation.py +0 -0
  106. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/web/__init__.py +0 -0
  107. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
  108. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
  109. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
  110. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/tool/web/web_fetch_tool.py +0 -0
  111. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/core/turn.py +0 -0
  112. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/__init__.py +0 -0
  113. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/anthropic/__init__.py +0 -0
  114. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/anthropic/client.py +0 -0
  115. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/anthropic/input.py +0 -0
  116. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/client.py +0 -0
  117. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/codex/__init__.py +0 -0
  118. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/codex/client.py +0 -0
  119. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
  120. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/openai_compatible/client.py +0 -0
  121. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/openai_compatible/input.py +0 -0
  122. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/openai_compatible/stream_processor.py +0 -0
  123. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
  124. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/openrouter/__init__.py +0 -0
  125. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/openrouter/client.py +0 -0
  126. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/openrouter/input.py +0 -0
  127. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/openrouter/reasoning_handler.py +0 -0
  128. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/registry.py +0 -0
  129. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/responses/__init__.py +0 -0
  130. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/responses/client.py +0 -0
  131. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/responses/input.py +0 -0
  132. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/llm/usage.py +0 -0
  133. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/protocol/__init__.py +0 -0
  134. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/protocol/commands.py +0 -0
  135. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/protocol/events.py +0 -0
  136. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/protocol/llm_param.py +0 -0
  137. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/protocol/model.py +0 -0
  138. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/protocol/op.py +0 -0
  139. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/protocol/op_handler.py +0 -0
  140. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/protocol/sub_agent.py +0 -0
  141. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/protocol/tools.py +0 -0
  142. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/session/__init__.py +0 -0
  143. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/session/export.py +0 -0
  144. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/session/selector.py +0 -0
  145. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/session/session.py +0 -0
  146. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/trace/__init__.py +0 -0
  147. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/trace/log.py +0 -0
  148. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/__init__.py +0 -0
  149. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/core/__init__.py +0 -0
  150. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/core/display.py +0 -0
  151. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/core/input.py +0 -0
  152. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/core/stage_manager.py +0 -0
  153. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/__init__.py +0 -0
  154. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/debug/__init__.py +0 -0
  155. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/debug/display.py +0 -0
  156. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/exec/__init__.py +0 -0
  157. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/exec/display.py +0 -0
  158. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/repl/__init__.py +0 -0
  159. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/repl/clipboard.py +0 -0
  160. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/repl/completers.py +0 -0
  161. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/repl/display.py +0 -0
  162. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/repl/input_prompt_toolkit.py +0 -0
  163. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/modes/repl/key_bindings.py +0 -0
  164. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/__init__.py +0 -0
  165. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/assistant.py +0 -0
  166. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/common.py +0 -0
  167. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/developer.py +0 -0
  168. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/diffs.py +0 -0
  169. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/errors.py +0 -0
  170. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/sub_agent.py +0 -0
  171. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/renderers/user_input.py +0 -0
  172. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/rich/__init__.py +0 -0
  173. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/rich/live.py +0 -0
  174. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/rich/quote.py +0 -0
  175. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/rich/searchable_text.py +0 -0
  176. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/rich/status.py +0 -0
  177. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/terminal/__init__.py +0 -0
  178. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/terminal/color.py +0 -0
  179. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/terminal/control.py +0 -0
  180. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/terminal/notifier.py +0 -0
  181. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/terminal/progress_bar.py +0 -0
  182. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/utils/__init__.py +0 -0
  183. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/utils/common.py +0 -0
  184. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/ui/utils/debouncer.py +0 -0
  185. {klaude_code-1.2.14 → klaude_code-1.2.15}/src/klaude_code/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: klaude-code
3
- Version: 1.2.14
3
+ Version: 1.2.15
4
4
  Summary: Add your description here
5
5
  Requires-Dist: anthropic>=0.66.0
6
6
  Requires-Dist: openai>=1.102.0
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "klaude-code"
7
- version = "1.2.14"
7
+ version = "1.2.15"
8
8
  description = "Add your description here"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -142,7 +142,7 @@ def _select_anthropic_thinking_sync() -> llm_param.Thinking | None:
142
142
  use_jk_keys=False,
143
143
  style=SELECT_STYLE,
144
144
  ).ask()
145
- if result is None:
145
+ if not result:
146
146
  return llm_param.Thinking(type="disabled", budget_tokens=0)
147
147
  return llm_param.Thinking(type="enabled", budget_tokens=result or 0)
148
148
  except KeyboardInterrupt:
@@ -149,7 +149,7 @@ def parse_message_groups(history: list[model.ConversationItem]) -> list[MessageG
149
149
  for item in items:
150
150
  if isinstance(item, (model.UserMessageItem, model.DeveloperMessageItem)):
151
151
  if item.content:
152
- group.text_parts.append(item.content)
152
+ group.text_parts.append(item.content + "\n")
153
153
  if item.images:
154
154
  group.images.extend(item.images)
155
155
  groups.append(group)
@@ -9,19 +9,15 @@
9
9
  href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%230851b2%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22><polyline points=%2216 18 22 12 16 6%22></polyline><polyline points=%228 6 2 12 8 18%22></polyline></svg>"
10
10
  />
11
11
  <link
12
- href="https://cdn.jsdelivr.net/npm/@fontsource/iosevka/400.css"
12
+ href="https://cdn.jsdelivr.net/npm/@fontsource/geist-sans/latin-400.css"
13
13
  rel="stylesheet"
14
14
  />
15
15
  <link
16
- href="https://cdn.jsdelivr.net/npm/@fontsource/iosevka/500.css"
16
+ href="https://cdn.jsdelivr.net/npm/@fontsource/geist-sans/latin-500.css"
17
17
  rel="stylesheet"
18
18
  />
19
19
  <link
20
- href="https://cdn.jsdelivr.net/npm/@fontsource/iosevka/800.css"
21
- rel="stylesheet"
22
- />
23
- <link
24
- href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&display=swap"
20
+ href="https://cdn.jsdelivr.net/npm/@fontsource/geist-sans/latin-700.css"
25
21
  rel="stylesheet"
26
22
  />
27
23
  <style>
@@ -39,9 +35,9 @@
39
35
  --bg-error: #ffebee;
40
36
  --bg-code: #f3f3f3;
41
37
  --fg-inline-code: #4f4fc7;
42
- --font-mono: "Iosevka", "SF Mono", Menlo, monospace;
43
- --font-markdown-mono: "IBM Plex Mono", Menlo, monospace;
44
- --font-markdown: "IBM Plex Sans", system-ui, sans-serif;
38
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
39
+ --font-markdown-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
40
+ --font-markdown: "Geist Sans", system-ui, sans-serif;
45
41
  --font-weight-bold: 800;
46
42
  --font-size-xs: 13px;
47
43
  --font-size-sm: 14px;
@@ -114,7 +110,7 @@
114
110
 
115
111
  .meta-value {
116
112
  font-family: var(--font-mono);
117
- font-size: var(--font-size-base);
113
+ font-size: var(--font-size-xs);
118
114
  color: var(--text);
119
115
  overflow: hidden;
120
116
  text-overflow: ellipsis;
@@ -1199,7 +1195,7 @@
1199
1195
  mermaid.initialize({
1200
1196
  startOnLoad: true,
1201
1197
  theme: "neutral",
1202
- fontFamily: '"Iosevka", "SF Mono", Menlo, monospace',
1198
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace',
1203
1199
  });
1204
1200
  </script>
1205
1201
  <script>
@@ -9,7 +9,7 @@ from klaude_code import const
9
9
  from klaude_code.protocol import events
10
10
  from klaude_code.ui.core.stage_manager import Stage, StageManager
11
11
  from klaude_code.ui.modes.repl.renderer import REPLRenderer
12
- from klaude_code.ui.rich.markdown import MarkdownStream
12
+ from klaude_code.ui.rich.markdown import MarkdownStream, ThinkingMarkdown
13
13
  from klaude_code.ui.rich.theme import ThemeKey
14
14
  from klaude_code.ui.terminal.notifier import Notification, NotificationType, TerminalNotifier
15
15
  from klaude_code.ui.terminal.progress_bar import OSC94States, emit_osc94
@@ -318,6 +318,7 @@ class DisplayEventHandler:
318
318
  console=self.renderer.console,
319
319
  spinner=self.renderer.spinner_renderable(),
320
320
  indent=2,
321
+ markdown_class=ThinkingMarkdown,
321
322
  )
322
323
  self.thinking_stream.start(mdstream)
323
324
  self.renderer.spinner_stop()
@@ -145,9 +145,7 @@ class REPLRenderer:
145
145
  case events.AssistantMessageEvent() as e:
146
146
  if is_sub_agent:
147
147
  continue
148
- renderable = r_assistant.render_assistant_message(
149
- e.content, code_theme=self.themes.code_theme
150
- )
148
+ renderable = r_assistant.render_assistant_message(e.content, code_theme=self.themes.code_theme)
151
149
  if renderable is not None:
152
150
  self.print(renderable)
153
151
  self.print()
@@ -9,6 +9,7 @@ from rich.text import Text
9
9
 
10
10
  from klaude_code.protocol import events, model
11
11
  from klaude_code.trace import is_debug_enabled
12
+ from klaude_code.ui.renderers.common import create_grid
12
13
  from klaude_code.ui.rich.theme import ThemeKey
13
14
  from klaude_code.ui.utils.common import format_number
14
15
 
@@ -24,163 +25,123 @@ def _get_version() -> str:
24
25
  def _render_task_metadata_block(
25
26
  metadata: model.TaskMetadata,
26
27
  *,
27
- indent: int = 0,
28
+ is_sub_agent: bool = False,
28
29
  show_context_and_time: bool = True,
29
- ) -> list[RenderableType]:
30
+ ) -> RenderableType:
30
31
  """Render a single TaskMetadata block.
31
32
 
32
33
  Args:
33
34
  metadata: The TaskMetadata to render.
34
- indent: Number of spaces to indent (0 for main, 2 for sub-agents).
35
+ is_sub_agent: Whether this is a sub-agent block.
35
36
  show_context_and_time: Whether to show context usage percent and time.
36
37
 
37
38
  Returns:
38
- List of renderables for this metadata block.
39
+ A renderable for this metadata block.
39
40
  """
41
+ grid = create_grid()
42
+
40
43
  # Get currency symbol
41
44
  currency = metadata.usage.currency if metadata.usage else "USD"
42
45
  currency_symbol = "¥" if currency == "CNY" else "$"
43
46
 
44
- # Line 1: Model and Provider
45
- prefix = (
46
- Text(" " * indent + "• ", style=ThemeKey.METADATA_BOLD)
47
- if indent == 0
48
- else Text(" " * indent + "└ ", style=ThemeKey.METADATA_DIM)
49
- )
50
- model_text = Text()
51
- model_text.append_text(prefix).append_text(Text(metadata.model_name, style=ThemeKey.METADATA_BOLD))
47
+ # First column: mark only
48
+ mark = Text("└", style=ThemeKey.METADATA_DIM) if is_sub_agent else Text("•", style=ThemeKey.METADATA_BOLD)
49
+
50
+ # Second column: model@provider / tokens / cost / ...
51
+ content = Text()
52
+ content.append_text(Text(metadata.model_name, style=ThemeKey.METADATA_BOLD))
52
53
  if metadata.provider is not None:
53
- model_text.append_text(Text("@", style=ThemeKey.METADATA)).append_text(
54
+ content.append_text(Text("@", style=ThemeKey.METADATA)).append_text(
54
55
  Text(metadata.provider.lower().replace(" ", "-"), style=ThemeKey.METADATA)
55
56
  )
56
57
 
57
- renderables: list[RenderableType] = [model_text]
58
-
59
- # Line 2: Token consumption, Context, TPS, Cost
60
- parts2: list[Text] = []
58
+ # All info parts (tokens, cost, context, etc.)
59
+ parts: list[Text] = []
61
60
 
62
61
  if metadata.usage is not None:
63
- # Input
64
- input_parts: list[tuple[str, str]] = [
65
- ("input:", ThemeKey.METADATA_DIM),
66
- (format_number(metadata.usage.input_tokens), ThemeKey.METADATA_DIM),
62
+ # Tokens: ↑37k c5k ↓907 r45k
63
+ token_parts: list[tuple[str, str]] = [
64
+ ("", ThemeKey.METADATA_DIM),
65
+ (format_number(metadata.usage.input_tokens), ThemeKey.METADATA),
67
66
  ]
68
- if metadata.usage.input_cost is not None:
69
- input_parts.append((f"({currency_symbol}{metadata.usage.input_cost:.4f})", ThemeKey.METADATA_DIM))
70
- parts2.append(Text.assemble(*input_parts))
71
-
72
- # Cached
73
67
  if metadata.usage.cached_tokens > 0:
74
- cached_parts: list[tuple[str, str]] = [
75
- ("cached:", ThemeKey.METADATA_DIM),
76
- (format_number(metadata.usage.cached_tokens), ThemeKey.METADATA_DIM),
77
- ]
78
- if metadata.usage.cache_read_cost is not None:
79
- cached_parts.append((f"({currency_symbol}{metadata.usage.cache_read_cost:.4f})", ThemeKey.METADATA_DIM))
80
- parts2.append(Text.assemble(*cached_parts))
81
-
82
- # Output
83
- output_parts: list[tuple[str, str]] = [
84
- ("output:", ThemeKey.METADATA_DIM),
85
- (format_number(metadata.usage.output_tokens), ThemeKey.METADATA_DIM),
86
- ]
87
- if metadata.usage.output_cost is not None:
88
- output_parts.append((f"({currency_symbol}{metadata.usage.output_cost:.4f})", ThemeKey.METADATA_DIM))
89
- parts2.append(Text.assemble(*output_parts))
90
-
91
- # Reasoning
68
+ token_parts.append((" c", ThemeKey.METADATA_DIM))
69
+ token_parts.append((format_number(metadata.usage.cached_tokens), ThemeKey.METADATA))
70
+ token_parts.append((" ↓", ThemeKey.METADATA_DIM))
71
+ token_parts.append((format_number(metadata.usage.output_tokens), ThemeKey.METADATA))
92
72
  if metadata.usage.reasoning_tokens > 0:
93
- parts2.append(
94
- Text.assemble(
95
- ("thinking", ThemeKey.METADATA_DIM),
96
- (":", ThemeKey.METADATA_DIM),
97
- (
98
- format_number(metadata.usage.reasoning_tokens),
99
- ThemeKey.METADATA_DIM,
100
- ),
101
- )
102
- )
73
+ token_parts.append((" r", ThemeKey.METADATA_DIM))
74
+ token_parts.append((format_number(metadata.usage.reasoning_tokens), ThemeKey.METADATA))
75
+ parts.append(Text.assemble(*token_parts))
103
76
 
104
77
  # Cost
105
78
  if metadata.usage is not None and metadata.usage.total_cost is not None:
106
- parts2.append(
79
+ parts.append(
107
80
  Text.assemble(
108
- ("cost", ThemeKey.METADATA_DIM),
109
- (":", ThemeKey.METADATA_DIM),
110
- (f"{currency_symbol}{metadata.usage.total_cost:.4f}", ThemeKey.METADATA_DIM),
81
+ (currency_symbol, ThemeKey.METADATA_DIM),
82
+ (f"{metadata.usage.total_cost:.4f}", ThemeKey.METADATA),
111
83
  )
112
84
  )
113
- if parts2:
114
- line2 = Text(" / ", style=ThemeKey.METADATA_DIM).join(parts2)
115
- renderables.append(Padding(line2, (0, 0, 0, indent + 2)))
116
-
117
- parts3: list[Text] = []
118
85
  if metadata.usage is not None:
119
86
  # Context (only for main agent)
120
87
  if show_context_and_time and metadata.usage.context_usage_percent is not None:
121
88
  context_size = format_number(metadata.usage.context_size or 0)
122
- parts3.append(
89
+ parts.append(
123
90
  Text.assemble(
124
- ("context", ThemeKey.METADATA_DIM),
125
- (":", ThemeKey.METADATA_DIM),
126
- (
127
- f"{context_size}({metadata.usage.context_usage_percent:.1f}%)",
128
- ThemeKey.METADATA_DIM,
129
- ),
91
+ (context_size, ThemeKey.METADATA),
92
+ (f" ({metadata.usage.context_usage_percent:.1f}%)", ThemeKey.METADATA_DIM),
130
93
  )
131
94
  )
132
95
 
133
96
  # TPS
134
97
  if metadata.usage.throughput_tps is not None:
135
- parts3.append(
98
+ parts.append(
136
99
  Text.assemble(
100
+ (f"{metadata.usage.throughput_tps:.1f} ", ThemeKey.METADATA),
137
101
  ("tps", ThemeKey.METADATA_DIM),
138
- (":", ThemeKey.METADATA_DIM),
139
- (f"{metadata.usage.throughput_tps:.1f}", ThemeKey.METADATA_DIM),
140
102
  )
141
103
  )
142
104
 
143
105
  # Duration
144
106
  if show_context_and_time and metadata.task_duration_s is not None:
145
- parts3.append(
107
+ parts.append(
146
108
  Text.assemble(
147
- ("time", ThemeKey.METADATA_DIM),
148
- (":", ThemeKey.METADATA_DIM),
149
- (f"{metadata.task_duration_s:.1f}s", ThemeKey.METADATA_DIM),
109
+ (f"{metadata.task_duration_s:.1f}", ThemeKey.METADATA),
110
+ ("s", ThemeKey.METADATA_DIM),
150
111
  )
151
112
  )
152
113
 
153
114
  # Turn count
154
115
  if show_context_and_time and metadata.turn_count > 0:
155
- parts3.append(
116
+ parts.append(
156
117
  Text.assemble(
157
- ("turns", ThemeKey.METADATA_DIM),
158
- (":", ThemeKey.METADATA_DIM),
159
- (str(metadata.turn_count), ThemeKey.METADATA_DIM),
118
+ (str(metadata.turn_count), ThemeKey.METADATA),
119
+ (" turns", ThemeKey.METADATA_DIM),
160
120
  )
161
121
  )
162
122
 
163
- if parts3:
164
- line2 = Text(" / ", style=ThemeKey.METADATA_DIM).join(parts3)
165
- renderables.append(Padding(line2, (0, 0, 0, indent + 2)))
123
+ if parts:
124
+ content.append_text(Text(" · ", style=ThemeKey.METADATA_DIM))
125
+ content.append_text(Text(" · ", style=ThemeKey.METADATA_DIM).join(parts))
166
126
 
167
- return renderables
127
+ grid.add_row(mark, content)
128
+ return grid if not is_sub_agent else Padding(grid, (0, 0, 0, 2))
168
129
 
169
130
 
170
131
  def render_task_metadata(e: events.TaskMetadataEvent) -> RenderableType:
171
132
  """Render task metadata including main agent and sub-agents, aggregated by model+provider."""
172
133
  renderables: list[RenderableType] = []
173
134
 
174
- renderables.extend(_render_task_metadata_block(e.metadata.main, indent=0, show_context_and_time=True))
135
+ renderables.append(_render_task_metadata_block(e.metadata.main, is_sub_agent=False, show_context_and_time=True))
175
136
 
176
137
  # Aggregate by (model_name, provider), sorted by total_cost descending
177
138
  sorted_items = model.TaskMetadata.aggregate_by_model(e.metadata.sub_agent_task_metadata)
178
139
 
179
140
  # Render each aggregated model block
180
141
  for meta in sorted_items:
181
- renderables.extend(_render_task_metadata_block(meta, indent=2, show_context_and_time=False))
142
+ renderables.append(_render_task_metadata_block(meta, is_sub_agent=True, show_context_and_time=False))
182
143
 
183
- return Group(*renderables)
144
+ return Padding(Group(*renderables), (0, 0, 0, 1))
184
145
 
185
146
 
186
147
  def render_welcome(e: events.WelcomeEvent, *, box_style: Box | None = None) -> RenderableType:
@@ -2,7 +2,7 @@ from rich.console import RenderableType
2
2
  from rich.padding import Padding
3
3
  from rich.text import Text
4
4
 
5
- from klaude_code.ui.rich.markdown import NoInsetMarkdown
5
+ from klaude_code.ui.rich.markdown import ThinkingMarkdown
6
6
  from klaude_code.ui.rich.theme import ThemeKey
7
7
 
8
8
 
@@ -30,7 +30,7 @@ def render_thinking(content: str, *, code_theme: str, style: str) -> RenderableT
30
30
  return None
31
31
 
32
32
  return Padding.indent(
33
- NoInsetMarkdown(
33
+ ThinkingMarkdown(
34
34
  _normalize_thinking_content(content),
35
35
  code_theme=code_theme,
36
36
  style=style,
@@ -1,5 +1,6 @@
1
1
  import json
2
2
  from pathlib import Path
3
+ from typing import Any, cast
3
4
 
4
5
  from rich.console import RenderableType
5
6
  from rich.padding import Padding
@@ -58,6 +59,49 @@ def render_generic_tool_call(tool_name: str, arguments: str, markup: str = "•"
58
59
  return grid
59
60
 
60
61
 
62
+ def render_bash_tool_call(arguments: str) -> RenderableType:
63
+ grid = create_grid()
64
+ tool_name_column = Text.assemble((">", ThemeKey.TOOL_MARK), " ", ("Bash", ThemeKey.TOOL_NAME))
65
+
66
+ try:
67
+ payload_raw: Any = json.loads(arguments) if arguments else {}
68
+ except json.JSONDecodeError:
69
+ summary = Text(
70
+ arguments.strip()[: const.INVALID_TOOL_CALL_MAX_LENGTH],
71
+ style=ThemeKey.INVALID_TOOL_CALL_ARGS,
72
+ )
73
+ grid.add_row(tool_name_column, summary)
74
+ return grid
75
+
76
+ if not isinstance(payload_raw, dict):
77
+ summary = Text(
78
+ str(payload_raw)[: const.INVALID_TOOL_CALL_MAX_LENGTH],
79
+ style=ThemeKey.INVALID_TOOL_CALL_ARGS,
80
+ )
81
+ grid.add_row(tool_name_column, summary)
82
+ return grid
83
+
84
+ payload: dict[str, object] = cast(dict[str, object], payload_raw)
85
+
86
+ summary = Text("", ThemeKey.TOOL_PARAM)
87
+ command = payload.get("command")
88
+ timeout_ms = payload.get("timeout_ms")
89
+
90
+ if isinstance(command, str) and command.strip():
91
+ summary.append(command.strip(), style=ThemeKey.TOOL_PARAM)
92
+
93
+ if isinstance(timeout_ms, int):
94
+ if summary:
95
+ summary.append(" ")
96
+ if timeout_ms >= 1000 and timeout_ms % 1000 == 0:
97
+ summary.append(f"{timeout_ms // 1000}s", style=ThemeKey.TOOL_TIMEOUT)
98
+ else:
99
+ summary.append(f"{timeout_ms}ms", style=ThemeKey.TOOL_TIMEOUT)
100
+
101
+ grid.add_row(tool_name_column, summary)
102
+ return grid
103
+
104
+
61
105
  def render_update_plan_tool_call(arguments: str) -> RenderableType:
62
106
  grid = create_grid()
63
107
  tool_name_column = Text.assemble(("◎", ThemeKey.TOOL_MARK), " ", ("Update Plan", ThemeKey.TOOL_NAME))
@@ -461,7 +505,7 @@ def render_tool_call(e: events.ToolCallEvent) -> RenderableType | None:
461
505
  case tools.MULTI_EDIT:
462
506
  return render_multi_edit_tool_call(e.arguments)
463
507
  case tools.BASH:
464
- return render_generic_tool_call(e.tool_name, e.arguments, ">")
508
+ return render_bash_tool_call(e.arguments)
465
509
  case tools.APPLY_PATCH:
466
510
  return render_apply_patch_tool_call(e.arguments)
467
511
  case tools.TODO_WRITE:
@@ -4,8 +4,10 @@ from __future__ import annotations
4
4
  import contextlib
5
5
  import io
6
6
  import time
7
+ from collections.abc import Callable
7
8
  from typing import Any, ClassVar
8
9
 
10
+ from rich import box
9
11
  from rich.console import Console, ConsoleOptions, Group, RenderableType, RenderResult
10
12
  from rich.live import Live
11
13
  from rich.markdown import CodeBlock, Heading, Markdown
@@ -32,7 +34,16 @@ class NoInsetCodeBlock(CodeBlock):
32
34
  word_wrap=True,
33
35
  padding=(0, 1),
34
36
  )
35
- yield Panel.fit(syntax, padding=0, border_style="markdown.code.panel")
37
+ yield Panel.fit(syntax, padding=(0, 0), style="markdown.code.block", box=box.SIMPLE)
38
+
39
+
40
+ class ThinkingCodeBlock(CodeBlock):
41
+ """A code block for thinking content that uses grey styling instead of syntax highlighting."""
42
+
43
+ def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult:
44
+ code = str(self.text).rstrip()
45
+ text = Text("```\n" + code + "\n```")
46
+ yield text
36
47
 
37
48
 
38
49
  class LeftHeading(Heading):
@@ -41,15 +52,6 @@ class LeftHeading(Heading):
41
52
  def __rich_console__(self, console: Console, options: ConsoleOptions) -> RenderResult:
42
53
  text = self.text
43
54
  text.justify = "left" # Override justification
44
- # if self.tag == "h1":
45
- # from rich.panel import Panel
46
- # from rich import box
47
- # # Draw a border around h1s, but keep text left-aligned
48
- # yield Panel(
49
- # text,
50
- # box=box.SQUARE,
51
- # style="markdown.h1.border",
52
- # )
53
55
  if self.tag == "h2":
54
56
  text.stylize(Style(bold=True, underline=False))
55
57
  yield Rule(title=text, characters="-", style="markdown.h2.border", align="left")
@@ -68,6 +70,17 @@ class NoInsetMarkdown(Markdown):
68
70
  }
69
71
 
70
72
 
73
+ class ThinkingMarkdown(Markdown):
74
+ """Markdown for thinking content with grey-styled code blocks and left-justified headings."""
75
+
76
+ elements: ClassVar[dict[str, type[Any]]] = {
77
+ **Markdown.elements,
78
+ "fence": ThinkingCodeBlock,
79
+ "code_block": ThinkingCodeBlock,
80
+ "heading_open": LeftHeading,
81
+ }
82
+
83
+
71
84
  class MarkdownStream:
72
85
  """Streaming markdown renderer that progressively displays content with a live updating window.
73
86
 
@@ -84,6 +97,7 @@ class MarkdownStream:
84
97
  spinner: Spinner | None = None,
85
98
  mark: str | None = None,
86
99
  indent: int = 0,
100
+ markdown_class: Callable[..., Markdown] | None = None,
87
101
  ) -> None:
88
102
  """Initialize the markdown stream.
89
103
 
@@ -93,6 +107,7 @@ class MarkdownStream:
93
107
  console (Console, optional): External console to use for rendering
94
108
  mark (str | None, optional): Marker shown before the first non-empty line when indent >= 2
95
109
  indent (int, optional): Number of spaces to indent all rendered lines on the left
110
+ markdown_class: Markdown class to use for rendering (defaults to NoInsetMarkdown)
96
111
  """
97
112
  self.printed: list[str] = [] # Stores lines that have already been printed
98
113
 
@@ -118,6 +133,7 @@ class MarkdownStream:
118
133
  self.spinner: Spinner | None = spinner
119
134
  self.mark: str | None = mark
120
135
  self.indent: int = max(indent, 0)
136
+ self.markdown_class: Callable[..., Markdown] = markdown_class or NoInsetMarkdown
121
137
 
122
138
  @property
123
139
  def _live_started(self) -> bool:
@@ -154,7 +170,7 @@ class MarkdownStream:
154
170
  width=effective_width,
155
171
  )
156
172
 
157
- markdown = NoInsetMarkdown(text, **self.mdargs)
173
+ markdown = self.markdown_class(text, **self.mdargs)
158
174
  temp_console.print(markdown)
159
175
  output = string_io.getvalue()
160
176
 
@@ -14,12 +14,12 @@ class Palette:
14
14
  blue: str
15
15
  orange: str
16
16
  magenta: str
17
- grey_blue: str
18
17
  grey1: str
19
18
  grey2: str
20
19
  grey3: str
21
20
  grey_green: str
22
21
  purple: str
22
+ lavender: str
23
23
  diff_add: str
24
24
  diff_remove: str
25
25
  code_theme: str
@@ -31,15 +31,15 @@ LIGHT_PALETTE = Palette(
31
31
  yellow="yellow",
32
32
  green="spring_green4",
33
33
  cyan="cyan",
34
- blue="#3678b7",
34
+ blue="#3078C5",
35
35
  orange="#d77757",
36
36
  magenta="magenta",
37
- grey_blue="steel_blue",
38
37
  grey1="#667e90",
39
38
  grey2="#93a4b1",
40
39
  grey3="#c4ced4",
41
- grey_green="#96a696",
40
+ grey_green="#96a096",
42
41
  purple="slate_blue3",
42
+ lavender="steel_blue",
43
43
  diff_add="#2e5a32 on #e8f5e9",
44
44
  diff_remove="#5a2e32 on #ffebee",
45
45
  code_theme="ansi_light",
@@ -54,12 +54,12 @@ DARK_PALETTE = Palette(
54
54
  blue="deep_sky_blue1",
55
55
  orange="#e6704e",
56
56
  magenta="magenta",
57
- grey_blue="steel_blue",
58
57
  grey1="#99aabb",
59
58
  grey2="#778899",
60
59
  grey3="#646464",
61
60
  grey_green="#6d8672",
62
61
  purple="#afbafe",
62
+ lavender="#9898b8",
63
63
  diff_add="#c8e6c9 on #2e4a32",
64
64
  diff_remove="#ffcdd2 on #4a2e32",
65
65
  code_theme="ansi_dark",
@@ -107,6 +107,7 @@ class ThemeKey(str, Enum):
107
107
  TOOL_MARK = "tool.mark"
108
108
  TOOL_APPROVED = "tool.approved"
109
109
  TOOL_REJECTED = "tool.rejected"
110
+ TOOL_TIMEOUT = "tool.timeout"
110
111
  # THINKING
111
112
  THINKING = "thinking"
112
113
  THINKING_BOLD = "thinking.bold"
@@ -174,9 +175,9 @@ def get_theme(theme: str | None = None) -> Themes:
174
175
  ThemeKey.USER_INPUT_AT_PATTERN.value: palette.purple,
175
176
  ThemeKey.USER_INPUT_SLASH_COMMAND.value: "bold reverse " + palette.blue,
176
177
  # METADATA
177
- ThemeKey.METADATA.value: palette.grey_blue,
178
- ThemeKey.METADATA_DIM.value: "dim " + palette.grey_blue,
179
- ThemeKey.METADATA_BOLD.value: "bold " + palette.grey_blue,
178
+ ThemeKey.METADATA.value: palette.lavender,
179
+ ThemeKey.METADATA_DIM.value: "dim " + palette.lavender,
180
+ ThemeKey.METADATA_BOLD.value: "bold " + palette.lavender,
180
181
  # SPINNER_STATUS
181
182
  ThemeKey.SPINNER_STATUS.value: palette.blue,
182
183
  ThemeKey.SPINNER_STATUS_TEXT.value: palette.blue,
@@ -196,6 +197,7 @@ def get_theme(theme: str | None = None) -> Themes:
196
197
  ThemeKey.TOOL_MARK.value: "bold",
197
198
  ThemeKey.TOOL_APPROVED.value: palette.green + " bold reverse",
198
199
  ThemeKey.TOOL_REJECTED.value: palette.red + " bold reverse",
200
+ ThemeKey.TOOL_TIMEOUT.value: palette.yellow,
199
201
  # THINKING
200
202
  ThemeKey.THINKING.value: "italic " + palette.grey2,
201
203
  ThemeKey.THINKING_BOLD.value: "bold italic " + palette.grey1,
@@ -232,7 +234,7 @@ def get_theme(theme: str | None = None) -> Themes:
232
234
  markdown_theme=Theme(
233
235
  styles={
234
236
  "markdown.code": palette.purple,
235
- "markdown.code.panel": palette.grey3,
237
+ "markdown.code.block": "on " + palette.text_background,
236
238
  "markdown.h1": "bold reverse",
237
239
  "markdown.h1.border": palette.grey3,
238
240
  "markdown.h2.border": palette.grey3,
@@ -245,8 +247,7 @@ def get_theme(theme: str | None = None) -> Themes:
245
247
  ),
246
248
  thinking_markdown_theme=Theme(
247
249
  styles={
248
- "markdown.code": palette.grey1 + " on " + palette.text_background,
249
- "markdown.code.panel": palette.grey3,
250
+ "markdown.code": palette.grey1 + " italic on " + palette.text_background,
250
251
  "markdown.h1": "bold reverse",
251
252
  "markdown.h1.border": palette.grey3,
252
253
  "markdown.h2.border": palette.grey3,
@@ -265,7 +266,6 @@ def get_theme(theme: str | None = None) -> Themes:
265
266
  Style(color=palette.blue),
266
267
  Style(color=palette.purple),
267
268
  Style(color=palette.orange),
268
- Style(color=palette.grey_blue),
269
269
  Style(color=palette.red),
270
270
  Style(color=palette.grey1),
271
271
  Style(color=palette.yellow),
File without changes