klaude-code 1.2.17__tar.gz → 1.2.18__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.17 → klaude_code-1.2.18}/PKG-INFO +16 -6
  2. {klaude_code-1.2.17 → klaude_code-1.2.18}/README.md +15 -5
  3. {klaude_code-1.2.17 → klaude_code-1.2.18}/pyproject.toml +5 -1
  4. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/cli/config_cmd.py +1 -1
  5. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/cli/debug.py +1 -1
  6. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/cli/main.py +3 -9
  7. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/cli/runtime.py +10 -13
  8. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/__init__.py +4 -1
  9. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/clear_cmd.py +2 -7
  10. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/command_abc.py +33 -5
  11. klaude_code-1.2.18/src/klaude_code/command/debug_cmd.py +79 -0
  12. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/diff_cmd.py +2 -6
  13. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/export_cmd.py +7 -7
  14. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/export_online_cmd.py +1 -5
  15. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/help_cmd.py +4 -9
  16. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/model_cmd.py +10 -6
  17. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/prompt_command.py +2 -6
  18. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/refresh_cmd.py +2 -7
  19. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/registry.py +2 -4
  20. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/release_notes_cmd.py +2 -6
  21. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/status_cmd.py +2 -7
  22. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/terminal_setup_cmd.py +2 -6
  23. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/thinking_cmd.py +13 -8
  24. klaude_code-1.2.18/src/klaude_code/config/select_model.py +133 -0
  25. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/const/__init__.py +1 -1
  26. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/executor.py +236 -109
  27. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/manager/__init__.py +2 -4
  28. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompts/prompt-claude-code.md +1 -1
  29. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompts/prompt-sub-agent-web.md +8 -5
  30. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/reminders.py +9 -35
  31. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/read_tool.py +38 -10
  32. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/shell/bash_tool.py +22 -2
  33. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/tool_runner.py +26 -23
  34. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/truncation.py +23 -9
  35. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/web/web_fetch_tool.md +1 -1
  36. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/web/web_fetch_tool.py +36 -1
  37. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/turn.py +28 -0
  38. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/commands.py +1 -0
  39. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/sub_agent/web.py +3 -2
  40. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/session/session.py +2 -2
  41. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/session/templates/export_session.html +24 -13
  42. klaude_code-1.2.18/src/klaude_code/trace/__init__.py +21 -0
  43. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/repl/completers.py +19 -2
  44. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/repl/event_handler.py +8 -6
  45. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/metadata.py +2 -4
  46. klaude_code-1.2.18/src/klaude_code/ui/renderers/thinking.py +55 -0
  47. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/tools.py +79 -10
  48. klaude_code-1.2.18/src/klaude_code/ui/rich/code_panel.py +112 -0
  49. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/rich/markdown.py +3 -4
  50. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/rich/status.py +0 -2
  51. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/rich/theme.py +10 -1
  52. klaude_code-1.2.17/src/klaude_code/config/select_model.py +0 -57
  53. klaude_code-1.2.17/src/klaude_code/core/manager/agent_manager.py +0 -132
  54. klaude_code-1.2.17/src/klaude_code/trace/__init__.py +0 -3
  55. klaude_code-1.2.17/src/klaude_code/ui/renderers/thinking.py +0 -39
  56. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/__init__.py +0 -0
  57. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/auth/__init__.py +0 -0
  58. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/auth/codex/__init__.py +0 -0
  59. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/auth/codex/exceptions.py +0 -0
  60. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
  61. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/auth/codex/oauth.py +0 -0
  62. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/auth/codex/token_manager.py +0 -0
  63. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/cli/__init__.py +0 -0
  64. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/cli/auth_cmd.py +0 -0
  65. {klaude_code-1.2.17/src/klaude_code/config → klaude_code-1.2.18/src/klaude_code/cli}/list_model.py +0 -0
  66. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/cli/session_cmd.py +0 -0
  67. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/prompt-deslop.md +0 -0
  68. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/prompt-dev-docs-update.md +0 -0
  69. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/prompt-dev-docs.md +0 -0
  70. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/prompt-handoff.md +0 -0
  71. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/command/prompt-init.md +0 -0
  72. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/config/__init__.py +0 -0
  73. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/config/config.py +0 -0
  74. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/__init__.py +0 -0
  75. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/agent.py +0 -0
  76. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/manager/llm_clients.py +0 -0
  77. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/manager/llm_clients_builder.py +0 -0
  78. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/manager/sub_agent_manager.py +0 -0
  79. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompt.py +0 -0
  80. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
  81. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1.md +0 -0
  82. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
  83. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
  84. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -0
  85. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompts/prompt-sub-agent-oracle.md +0 -0
  86. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
  87. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/task.py +0 -0
  88. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/__init__.py +0 -0
  89. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/__init__.py +0 -0
  90. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/_utils.py +0 -0
  91. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
  92. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
  93. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
  94. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
  95. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
  96. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/multi_edit_tool.md +0 -0
  97. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/multi_edit_tool.py +0 -0
  98. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/read_tool.md +0 -0
  99. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/write_tool.md +0 -0
  100. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/file/write_tool.py +0 -0
  101. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/memory/__init__.py +0 -0
  102. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/memory/memory_tool.md +0 -0
  103. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/memory/memory_tool.py +0 -0
  104. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/memory/skill_loader.py +0 -0
  105. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/memory/skill_tool.md +0 -0
  106. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/memory/skill_tool.py +0 -0
  107. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/report_back_tool.py +0 -0
  108. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/shell/__init__.py +0 -0
  109. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
  110. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
  111. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/sub_agent_tool.py +0 -0
  112. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/todo/__init__.py +0 -0
  113. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
  114. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
  115. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
  116. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
  117. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
  118. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/tool_abc.py +0 -0
  119. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/tool_context.py +0 -0
  120. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/tool_registry.py +0 -0
  121. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/web/__init__.py +0 -0
  122. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
  123. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
  124. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
  125. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/core/tool/web/web_search_tool.py +0 -0
  126. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/__init__.py +0 -0
  127. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/anthropic/__init__.py +0 -0
  128. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/anthropic/client.py +0 -0
  129. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/anthropic/input.py +0 -0
  130. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/client.py +0 -0
  131. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/codex/__init__.py +0 -0
  132. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/codex/client.py +0 -0
  133. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/input_common.py +0 -0
  134. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
  135. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/openai_compatible/client.py +0 -0
  136. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/openai_compatible/input.py +0 -0
  137. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/openai_compatible/stream_processor.py +0 -0
  138. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
  139. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/openrouter/__init__.py +0 -0
  140. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/openrouter/client.py +0 -0
  141. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/openrouter/input.py +0 -0
  142. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/openrouter/reasoning_handler.py +0 -0
  143. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/registry.py +0 -0
  144. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/responses/__init__.py +0 -0
  145. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/responses/client.py +0 -0
  146. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/responses/input.py +0 -0
  147. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/llm/usage.py +0 -0
  148. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/__init__.py +0 -0
  149. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/events.py +0 -0
  150. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/llm_param.py +0 -0
  151. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/model.py +0 -0
  152. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/op.py +0 -0
  153. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/op_handler.py +0 -0
  154. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
  155. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/sub_agent/explore.py +0 -0
  156. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/sub_agent/oracle.py +0 -0
  157. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/sub_agent/task.py +0 -0
  158. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/protocol/tools.py +0 -0
  159. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/session/__init__.py +0 -0
  160. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/session/export.py +0 -0
  161. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/session/selector.py +0 -0
  162. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/trace/log.py +0 -0
  163. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/__init__.py +0 -0
  164. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/core/__init__.py +0 -0
  165. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/core/display.py +0 -0
  166. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/core/input.py +0 -0
  167. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/core/stage_manager.py +0 -0
  168. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/__init__.py +0 -0
  169. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/debug/__init__.py +0 -0
  170. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/debug/display.py +0 -0
  171. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/exec/__init__.py +0 -0
  172. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/exec/display.py +0 -0
  173. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/repl/__init__.py +0 -0
  174. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/repl/clipboard.py +0 -0
  175. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/repl/display.py +0 -0
  176. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/repl/input_prompt_toolkit.py +0 -0
  177. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/repl/key_bindings.py +0 -0
  178. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/modes/repl/renderer.py +0 -0
  179. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/__init__.py +0 -0
  180. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/assistant.py +0 -0
  181. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/common.py +0 -0
  182. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/developer.py +0 -0
  183. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/diffs.py +0 -0
  184. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/errors.py +0 -0
  185. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/sub_agent.py +0 -0
  186. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/renderers/user_input.py +0 -0
  187. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/rich/__init__.py +0 -0
  188. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/rich/live.py +0 -0
  189. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/rich/quote.py +0 -0
  190. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/rich/searchable_text.py +0 -0
  191. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/terminal/__init__.py +0 -0
  192. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/terminal/color.py +0 -0
  193. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/terminal/control.py +0 -0
  194. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/terminal/notifier.py +0 -0
  195. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/terminal/progress_bar.py +0 -0
  196. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/utils/__init__.py +0 -0
  197. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/utils/common.py +0 -0
  198. {klaude_code-1.2.17 → klaude_code-1.2.18}/src/klaude_code/ui/utils/debouncer.py +0 -0
  199. {klaude_code-1.2.17 → klaude_code-1.2.18}/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.17
3
+ Version: 1.2.18
4
4
  Summary: Add your description here
5
5
  Requires-Dist: anthropic>=0.66.0
6
6
  Requires-Dist: ddgs>=9.9.3
@@ -51,12 +51,17 @@ klaude [--model <name>] [--select-model]
51
51
 
52
52
  **Options:**
53
53
  - `--version`/`-V`: Show version and exit.
54
- - `--model`/`-m`: Select a model by logical name from config.
55
- - `--select-model`/`-s`: Interactively choose a model at startup.
54
+ - `--model`/`-m`: Preferred model name (exact match picks immediately; otherwise opens the interactive selector filtered by this value).
55
+ - `--select-model`/`-s`: Open the interactive model selector at startup (shows all models unless `--model` is also provided).
56
56
  - `--continue`/`-c`: Resume the most recent session.
57
57
  - `--resume`/`-r`: Select a session to resume for this project.
58
58
  - `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit) and no system prompts.
59
59
 
60
+ **Model selection behavior:**
61
+ - Default: uses `main_model` from config.
62
+ - `--select-model`: always prompts you to pick.
63
+ - `--model <value>`: tries to resolve `<value>` to a single model; if it can't, it prompts with a filtered list (and falls back to showing all models if there are no matches).
64
+
60
65
  **Debug Options:**
61
66
  - `--debug`/`-d`: Enable debug mode with verbose logging and LLM trace.
62
67
  - `--debug-filter`: Filter debug output by type (comma-separated).
@@ -64,7 +69,7 @@ klaude [--model <name>] [--select-model]
64
69
 
65
70
  ### Configuration
66
71
 
67
- An example config will be created in `~/.klaude/config.yaml` when first run.
72
+ An example config will be created in `~/.klaude/klaude-config.yaml` when first run.
68
73
 
69
74
  Open the configuration file in editor:
70
75
 
@@ -201,7 +206,7 @@ sub_agent_models:
201
206
  oracle: gpt-5.1
202
207
  explore: haiku
203
208
  task: opus
204
- webfetchagent: haiku
209
+ webagent: haiku
205
210
 
206
211
  ```
207
212
 
@@ -263,5 +268,10 @@ klaude exec "what is 2+2?"
263
268
  echo "hello world" | klaude exec
264
269
 
265
270
  # With model selection
271
+
272
+ # Exact model name (non-interactive)
266
273
  echo "generate quicksort in python" | klaude exec --model gpt-5.1
267
- ```
274
+
275
+ # Partial/ambiguous name opens the interactive selector (filtered)
276
+ echo "generate quicksort in python" | klaude exec --model gpt
277
+ ```
@@ -33,12 +33,17 @@ klaude [--model <name>] [--select-model]
33
33
 
34
34
  **Options:**
35
35
  - `--version`/`-V`: Show version and exit.
36
- - `--model`/`-m`: Select a model by logical name from config.
37
- - `--select-model`/`-s`: Interactively choose a model at startup.
36
+ - `--model`/`-m`: Preferred model name (exact match picks immediately; otherwise opens the interactive selector filtered by this value).
37
+ - `--select-model`/`-s`: Open the interactive model selector at startup (shows all models unless `--model` is also provided).
38
38
  - `--continue`/`-c`: Resume the most recent session.
39
39
  - `--resume`/`-r`: Select a session to resume for this project.
40
40
  - `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit) and no system prompts.
41
41
 
42
+ **Model selection behavior:**
43
+ - Default: uses `main_model` from config.
44
+ - `--select-model`: always prompts you to pick.
45
+ - `--model <value>`: tries to resolve `<value>` to a single model; if it can't, it prompts with a filtered list (and falls back to showing all models if there are no matches).
46
+
42
47
  **Debug Options:**
43
48
  - `--debug`/`-d`: Enable debug mode with verbose logging and LLM trace.
44
49
  - `--debug-filter`: Filter debug output by type (comma-separated).
@@ -46,7 +51,7 @@ klaude [--model <name>] [--select-model]
46
51
 
47
52
  ### Configuration
48
53
 
49
- An example config will be created in `~/.klaude/config.yaml` when first run.
54
+ An example config will be created in `~/.klaude/klaude-config.yaml` when first run.
50
55
 
51
56
  Open the configuration file in editor:
52
57
 
@@ -183,7 +188,7 @@ sub_agent_models:
183
188
  oracle: gpt-5.1
184
189
  explore: haiku
185
190
  task: opus
186
- webfetchagent: haiku
191
+ webagent: haiku
187
192
 
188
193
  ```
189
194
 
@@ -245,5 +250,10 @@ klaude exec "what is 2+2?"
245
250
  echo "hello world" | klaude exec
246
251
 
247
252
  # With model selection
253
+
254
+ # Exact model name (non-interactive)
248
255
  echo "generate quicksort in python" | klaude exec --model gpt-5.1
249
- ```
256
+
257
+ # Partial/ambiguous name opens the interactive selector (filtered)
258
+ echo "generate quicksort in python" | klaude exec --model gpt
259
+ ```
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "klaude-code"
7
- version = "1.2.17"
7
+ version = "1.2.18"
8
8
  description = "Add your description here"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -77,10 +77,14 @@ name = "Layered architecture"
77
77
  type = "layers"
78
78
  layers = [
79
79
  "klaude_code.cli",
80
+ "klaude_code.ui",
80
81
  "klaude_code.core",
82
+ "klaude_code.command",
81
83
  "klaude_code.session",
82
84
  "klaude_code.config",
83
85
  "klaude_code.llm",
84
86
  "klaude_code.protocol",
87
+ "klaude_code.trace",
88
+ "klaude_code.auth",
85
89
  "klaude_code.const",
86
90
  ]
@@ -12,7 +12,7 @@ from klaude_code.trace import log
12
12
 
13
13
  def list_models() -> None:
14
14
  """List all models and providers configuration"""
15
- from klaude_code.config.list_model import display_models_and_providers
15
+ from klaude_code.cli.list_model import display_models_and_providers
16
16
  from klaude_code.ui.terminal.color import is_light_terminal_background
17
17
 
18
18
  config = load_config()
@@ -48,7 +48,7 @@ def open_log_file_in_editor(path: Path) -> None:
48
48
  editor = os.environ.get("EDITOR")
49
49
 
50
50
  if not editor:
51
- for cmd in ["open", "xdg-open", "code", "nvim", "vim", "nano"]:
51
+ for cmd in ["open", "xdg-open", "code", "TextEdit", "notepad"]:
52
52
  try:
53
53
  subprocess.run(["which", cmd], check=True, capture_output=True)
54
54
  editor = cmd
@@ -11,7 +11,6 @@ from klaude_code.cli.auth_cmd import register_auth_commands
11
11
  from klaude_code.cli.config_cmd import register_config_commands
12
12
  from klaude_code.cli.debug import DEBUG_FILTER_HELP, open_log_file_in_editor, resolve_debug_settings
13
13
  from klaude_code.cli.session_cmd import register_session_commands
14
- from klaude_code.config import load_config
15
14
  from klaude_code.session import Session, resume_select_session
16
15
  from klaude_code.trace import DebugType, prepare_debug_log_file
17
16
 
@@ -157,13 +156,8 @@ def exec_command(
157
156
  from klaude_code.config.select_model import select_model_from_config
158
157
 
159
158
  chosen_model = model
160
- if select_model:
161
- # Prefer the explicitly provided model as default; otherwise main model
162
- config = load_config()
163
- if config is None:
164
- raise typer.Exit(1)
165
- default_name = model or config.main_model
166
- chosen_model = select_model_from_config(preferred=default_name)
159
+ if model or select_model:
160
+ chosen_model = select_model_from_config(preferred=model)
167
161
  if chosen_model is None:
168
162
  return
169
163
 
@@ -243,7 +237,7 @@ def main_callback(
243
237
  setup_terminal_title()
244
238
 
245
239
  chosen_model = model
246
- if select_model:
240
+ if model or select_model:
247
241
  chosen_model = select_model_from_config(preferred=model)
248
242
  if chosen_model is None:
249
243
  return
@@ -10,7 +10,7 @@ from rich.text import Text
10
10
  from klaude_code import ui
11
11
  from klaude_code.command import has_interactive_command
12
12
  from klaude_code.config import Config, load_config
13
- from klaude_code.core.agent import Agent, DefaultModelProfileProvider, VanillaModelProfileProvider
13
+ from klaude_code.core.agent import DefaultModelProfileProvider, VanillaModelProfileProvider
14
14
  from klaude_code.core.executor import Executor
15
15
  from klaude_code.core.manager import build_llm_clients
16
16
  from klaude_code.protocol import events, op
@@ -98,8 +98,10 @@ async def initialize_app_components(init_config: AppInitConfig) -> AppComponents
98
98
  executor_task = asyncio.create_task(executor.start())
99
99
 
100
100
  theme: str | None = config.theme
101
- if theme is None:
101
+ if theme is None and not init_config.is_exec_mode:
102
102
  # Auto-detect theme from terminal background when config does not specify a theme.
103
+ # Skip detection in exec mode to avoid TTY race conditions with parent process's
104
+ # ESC monitor when running as a subprocess.
103
105
  detected = is_light_terminal_background()
104
106
  if detected is True:
105
107
  theme = "light"
@@ -145,8 +147,8 @@ async def initialize_session(
145
147
  await executor.submit_and_wait(op.InitAgentOperation(session_id=session_id))
146
148
  await event_queue.join()
147
149
 
148
- active_session_ids = executor.context.agent_manager.active_session_ids()
149
- return active_session_ids[0] if active_session_ids else session_id
150
+ active_session_id = executor.context.current_session_id()
151
+ return active_session_id or session_id
150
152
 
151
153
 
152
154
  async def cleanup_app_components(components: AppComponents) -> None:
@@ -214,16 +216,12 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
214
216
 
215
217
  # Create status provider for bottom toolbar
216
218
  def _status_provider() -> REPLStatusSnapshot:
217
- agent: Agent | None = None
218
- # Get the first active agent (there should only be one in interactive mode)
219
- active_agents = components.executor.context.active_agents
220
- if active_agents:
221
- agent = next(iter(active_agents.values()), None)
222
-
223
219
  # Check for updates (returns None if uv not available)
224
220
  update_message = get_update_message()
225
221
 
226
- return build_repl_status_snapshot(agent=agent, update_message=update_message)
222
+ return build_repl_status_snapshot(
223
+ agent=components.executor.context.current_agent, update_message=update_message
224
+ )
227
225
 
228
226
  # Set up input provider for interactive mode
229
227
  input_provider: ui.InputProviderABC = ui.PromptToolkitInput(status_provider=_status_provider)
@@ -268,8 +266,7 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
268
266
 
269
267
  This is necessary because /clear command creates a new session with a different ID.
270
268
  """
271
- active_ids = components.executor.context.agent_manager.active_session_ids()
272
- return active_ids[0] if active_ids else None
269
+ return components.executor.context.current_session_id()
273
270
 
274
271
  # Input
275
272
  await input_provider.start()
@@ -28,6 +28,7 @@ def ensure_commands_loaded() -> None:
28
28
 
29
29
  # Import and register commands in display order
30
30
  from .clear_cmd import ClearCommand
31
+ from .debug_cmd import DebugCommand
31
32
  from .diff_cmd import DiffCommand
32
33
  from .export_cmd import ExportCommand
33
34
  from .export_online_cmd import ExportOnlineCommand
@@ -46,12 +47,13 @@ def ensure_commands_loaded() -> None:
46
47
  register(ThinkingCommand())
47
48
  register(ModelCommand())
48
49
  load_prompt_commands()
49
- register(ClearCommand())
50
50
  register(StatusCommand())
51
51
  register(DiffCommand())
52
52
  register(HelpCommand())
53
53
  register(ReleaseNotesCommand())
54
54
  register(TerminalSetupCommand())
55
+ register(DebugCommand())
56
+ register(ClearCommand())
55
57
 
56
58
  # Load prompt-based commands (appended after built-in commands)
57
59
 
@@ -60,6 +62,7 @@ def ensure_commands_loaded() -> None:
60
62
  def __getattr__(name: str) -> object:
61
63
  _commands_map = {
62
64
  "ClearCommand": "clear_cmd",
65
+ "DebugCommand": "debug_cmd",
63
66
  "DiffCommand": "diff_cmd",
64
67
  "ExportCommand": "export_cmd",
65
68
  "ExportOnlineCommand": "export_online_cmd",
@@ -1,11 +1,6 @@
1
- from typing import TYPE_CHECKING
2
-
3
- from klaude_code.command.command_abc import CommandABC, CommandResult, InputAction
1
+ from klaude_code.command.command_abc import Agent, CommandABC, CommandResult, InputAction
4
2
  from klaude_code.protocol import commands
5
3
 
6
- if TYPE_CHECKING:
7
- from klaude_code.core.agent import Agent
8
-
9
4
 
10
5
  class ClearCommand(CommandABC):
11
6
  """Clear current session and start a new conversation"""
@@ -18,5 +13,5 @@ class ClearCommand(CommandABC):
18
13
  def summary(self) -> str:
19
14
  return "Clear conversation history and free up context"
20
15
 
21
- async def run(self, raw: str, agent: "Agent") -> CommandResult:
16
+ async def run(self, raw: str, agent: Agent) -> CommandResult:
22
17
  return CommandResult(actions=[InputAction.clear()])
@@ -1,14 +1,37 @@
1
1
  from abc import ABC, abstractmethod
2
2
  from enum import Enum
3
- from typing import TYPE_CHECKING
3
+ from typing import Protocol
4
4
 
5
5
  from pydantic import BaseModel
6
6
 
7
- from klaude_code.protocol import commands
7
+ from klaude_code.llm import LLMClientABC
8
+ from klaude_code.protocol import commands, llm_param
8
9
  from klaude_code.protocol import events as protocol_events
10
+ from klaude_code.session.session import Session
9
11
 
10
- if TYPE_CHECKING:
11
- from klaude_code.core.agent import Agent
12
+
13
+ class AgentProfile(Protocol):
14
+ """Protocol for the agent's active model profile."""
15
+
16
+ @property
17
+ def llm_client(self) -> LLMClientABC: ...
18
+
19
+ @property
20
+ def system_prompt(self) -> str | None: ...
21
+
22
+ @property
23
+ def tools(self) -> list[llm_param.ToolSchema]: ...
24
+
25
+
26
+ class Agent(Protocol):
27
+ """Protocol for Agent objects passed to commands."""
28
+
29
+ session: Session
30
+
31
+ @property
32
+ def profile(self) -> AgentProfile | None: ...
33
+
34
+ def get_llm_client(self) -> LLMClientABC: ...
12
35
 
13
36
 
14
37
  class InputActionType(str, Enum):
@@ -80,8 +103,13 @@ class CommandABC(ABC):
80
103
  """Whether this command support additional parameters."""
81
104
  return False
82
105
 
106
+ @property
107
+ def placeholder(self) -> str:
108
+ """Placeholder text for additional parameters in help display."""
109
+ return "additional instructions"
110
+
83
111
  @abstractmethod
84
- async def run(self, raw: str, agent: "Agent") -> CommandResult:
112
+ async def run(self, raw: str, agent: Agent) -> CommandResult:
85
113
  """
86
114
  Execute the command.
87
115
 
@@ -0,0 +1,79 @@
1
+ from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
2
+ from klaude_code.protocol import commands, events, model
3
+ from klaude_code.trace import DebugType, get_current_log_file, is_debug_enabled, set_debug_logging
4
+
5
+
6
+ def _format_status() -> str:
7
+ """Format the current debug status for display."""
8
+ if not is_debug_enabled():
9
+ return "Debug: OFF"
10
+
11
+ log_file = get_current_log_file()
12
+ log_path_str = str(log_file) if log_file else "(console)"
13
+ return f"Debug: ON\nLog file: {log_path_str}"
14
+
15
+
16
+ def _parse_debug_filters(raw: str) -> set[DebugType] | None:
17
+ filters: set[DebugType] = set()
18
+ for chunk in raw.split(","):
19
+ normalized = chunk.strip().lower().replace("-", "_")
20
+ if not normalized:
21
+ continue
22
+ try:
23
+ filters.add(DebugType(normalized))
24
+ except ValueError as exc:
25
+ raise ValueError(normalized) from exc
26
+ return filters or None
27
+
28
+
29
+ class DebugCommand(CommandABC):
30
+ """Toggle debug mode and configure debug filters."""
31
+
32
+ @property
33
+ def name(self) -> commands.CommandName:
34
+ return commands.CommandName.DEBUG
35
+
36
+ @property
37
+ def summary(self) -> str:
38
+ return "Toggle debug mode (optional: filter types)"
39
+
40
+ @property
41
+ def support_addition_params(self) -> bool:
42
+ return True
43
+
44
+ @property
45
+ def placeholder(self) -> str:
46
+ return "filter types"
47
+
48
+ async def run(self, raw: str, agent: Agent) -> CommandResult:
49
+ raw = raw.strip()
50
+
51
+ # /debug (no args) - enable debug
52
+ if not raw:
53
+ set_debug_logging(True, write_to_file=True)
54
+ return self._message_result(agent, _format_status())
55
+
56
+ # /debug <filters> - enable with filters
57
+ try:
58
+ filters = _parse_debug_filters(raw)
59
+ if filters:
60
+ set_debug_logging(True, write_to_file=True, filters=filters)
61
+ filter_names = ", ".join(sorted(dt.value for dt in filters))
62
+ return self._message_result(agent, f"Filters: {filter_names}\n{_format_status()}")
63
+ except ValueError:
64
+ pass
65
+
66
+ return self._message_result(agent, f"Invalid filter: {raw}\nValid: {', '.join(dt.value for dt in DebugType)}")
67
+
68
+ def _message_result(self, agent: "Agent", content: str) -> CommandResult:
69
+ return CommandResult(
70
+ events=[
71
+ events.DeveloperMessageEvent(
72
+ session_id=agent.session.id,
73
+ item=model.DeveloperMessageItem(
74
+ content=content,
75
+ command_output=model.CommandOutput(command_name=self.name),
76
+ ),
77
+ )
78
+ ]
79
+ )
@@ -1,13 +1,9 @@
1
1
  import subprocess
2
2
  from pathlib import Path
3
- from typing import TYPE_CHECKING
4
3
 
5
- from klaude_code.command.command_abc import CommandABC, CommandResult
4
+ from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
6
5
  from klaude_code.protocol import commands, events, model
7
6
 
8
- if TYPE_CHECKING:
9
- from klaude_code.core.agent import Agent
10
-
11
7
 
12
8
  class DiffCommand(CommandABC):
13
9
  """Show git diff for the current repository."""
@@ -20,7 +16,7 @@ class DiffCommand(CommandABC):
20
16
  def summary(self) -> str:
21
17
  return "Show git diff"
22
18
 
23
- async def run(self, raw: str, agent: "Agent") -> CommandResult:
19
+ async def run(self, raw: str, agent: Agent) -> CommandResult:
24
20
  try:
25
21
  # Check if current directory is in a git repository
26
22
  git_check = subprocess.run(
@@ -2,15 +2,11 @@ from __future__ import annotations
2
2
 
3
3
  import subprocess
4
4
  from pathlib import Path
5
- from typing import TYPE_CHECKING
6
5
 
7
- from klaude_code.command.command_abc import CommandABC, CommandResult
6
+ from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
8
7
  from klaude_code.protocol import commands, events, model
9
8
  from klaude_code.session.export import build_export_html, get_default_export_path
10
9
 
11
- if TYPE_CHECKING:
12
- from klaude_code.core.agent import Agent
13
-
14
10
 
15
11
  class ExportCommand(CommandABC):
16
12
  """Export the current session into a standalone HTML transcript."""
@@ -25,7 +21,11 @@ class ExportCommand(CommandABC):
25
21
 
26
22
  @property
27
23
  def support_addition_params(self) -> bool:
28
- return False
24
+ return True
25
+
26
+ @property
27
+ def placeholder(self) -> str:
28
+ return "output path"
29
29
 
30
30
  @property
31
31
  def is_interactive(self) -> bool:
@@ -33,7 +33,7 @@ class ExportCommand(CommandABC):
33
33
 
34
34
  async def run(self, raw: str, agent: Agent) -> CommandResult:
35
35
  try:
36
- output_path = self._resolve_output_path("", agent)
36
+ output_path = self._resolve_output_path(raw, agent)
37
37
  html_doc = self._build_html(agent)
38
38
  output_path.parent.mkdir(parents=True, exist_ok=True)
39
39
  output_path.write_text(html_doc, encoding="utf-8")
@@ -5,15 +5,11 @@ import shutil
5
5
  import subprocess
6
6
  import tempfile
7
7
  from pathlib import Path
8
- from typing import TYPE_CHECKING
9
8
 
10
- from klaude_code.command.command_abc import CommandABC, CommandResult
9
+ from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
11
10
  from klaude_code.protocol import commands, events, model
12
11
  from klaude_code.session.export import build_export_html
13
12
 
14
- if TYPE_CHECKING:
15
- from klaude_code.core.agent import Agent
16
-
17
13
 
18
14
  class ExportOnlineCommand(CommandABC):
19
15
  """Export and deploy the current session to surge.sh as a static webpage."""
@@ -1,11 +1,6 @@
1
- from typing import TYPE_CHECKING
2
-
3
- from klaude_code.command.command_abc import CommandABC, CommandResult
1
+ from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
4
2
  from klaude_code.protocol import commands, events, model
5
3
 
6
- if TYPE_CHECKING:
7
- from klaude_code.core.agent import Agent
8
-
9
4
 
10
5
  class HelpCommand(CommandABC):
11
6
  """Display help information for all available slash commands."""
@@ -18,7 +13,7 @@ class HelpCommand(CommandABC):
18
13
  def summary(self) -> str:
19
14
  return "Show help and available commands"
20
15
 
21
- async def run(self, raw: str, agent: "Agent") -> CommandResult:
16
+ async def run(self, raw: str, agent: Agent) -> CommandResult:
22
17
  lines: list[str] = [
23
18
  """
24
19
  Usage:
@@ -39,8 +34,8 @@ Available slash commands:"""
39
34
 
40
35
  if commands:
41
36
  for cmd_name, cmd_obj in sorted(commands.items()):
42
- additional_instructions = " \\[additional instructions]" if cmd_obj.support_addition_params else ""
43
- lines.append(f" [b]/{cmd_name}[/b]{additional_instructions} — {cmd_obj.summary}")
37
+ placeholder = f" \\[{cmd_obj.placeholder}]" if cmd_obj.support_addition_params else ""
38
+ lines.append(f" [b]/{cmd_name}[/b]{placeholder} — {cmd_obj.summary}")
44
39
 
45
40
  event = events.DeveloperMessageEvent(
46
41
  session_id=agent.session.id,
@@ -1,13 +1,9 @@
1
1
  import asyncio
2
- from typing import TYPE_CHECKING
3
2
 
4
- from klaude_code.command.command_abc import CommandABC, CommandResult, InputAction
3
+ from klaude_code.command.command_abc import Agent, CommandABC, CommandResult, InputAction
5
4
  from klaude_code.config.select_model import select_model_from_config
6
5
  from klaude_code.protocol import commands, events, model
7
6
 
8
- if TYPE_CHECKING:
9
- from klaude_code.core.agent import Agent
10
-
11
7
 
12
8
  class ModelCommand(CommandABC):
13
9
  """Display or change the model configuration."""
@@ -24,7 +20,15 @@ class ModelCommand(CommandABC):
24
20
  def is_interactive(self) -> bool:
25
21
  return True
26
22
 
27
- async def run(self, raw: str, agent: "Agent") -> CommandResult:
23
+ @property
24
+ def support_addition_params(self) -> bool:
25
+ return True
26
+
27
+ @property
28
+ def placeholder(self) -> str:
29
+ return "model name"
30
+
31
+ async def run(self, raw: str, agent: Agent) -> CommandResult:
28
32
  selected_model = await asyncio.to_thread(select_model_from_config, preferred=raw)
29
33
 
30
34
  current_model = agent.profile.llm_client.model_name if agent.profile else None
@@ -1,15 +1,11 @@
1
1
  from importlib.resources import files
2
- from typing import TYPE_CHECKING
3
2
 
4
3
  import yaml
5
4
 
6
- from klaude_code.command.command_abc import CommandABC, CommandResult, InputAction
5
+ from klaude_code.command.command_abc import Agent, CommandABC, CommandResult, InputAction
7
6
  from klaude_code.protocol import commands
8
7
  from klaude_code.trace import log_debug
9
8
 
10
- if TYPE_CHECKING:
11
- from klaude_code.core.agent import Agent
12
-
13
9
 
14
10
  class PromptCommand(CommandABC):
15
11
  """Command that loads a prompt from a markdown file."""
@@ -59,7 +55,7 @@ class PromptCommand(CommandABC):
59
55
  def support_addition_params(self) -> bool:
60
56
  return True
61
57
 
62
- async def run(self, raw: str, agent: "Agent") -> CommandResult:
58
+ async def run(self, raw: str, agent: Agent) -> CommandResult:
63
59
  self._ensure_loaded()
64
60
  template_content = self._content or ""
65
61
  user_input = raw.strip() or "<none>"
@@ -1,11 +1,6 @@
1
- from typing import TYPE_CHECKING
2
-
3
- from klaude_code.command.command_abc import CommandABC, CommandResult
1
+ from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
4
2
  from klaude_code.protocol import commands, events
5
3
 
6
- if TYPE_CHECKING:
7
- from klaude_code.core.agent import Agent
8
-
9
4
 
10
5
  class RefreshTerminalCommand(CommandABC):
11
6
  """Refresh terminal display"""
@@ -22,7 +17,7 @@ class RefreshTerminalCommand(CommandABC):
22
17
  def is_interactive(self) -> bool:
23
18
  return True
24
19
 
25
- async def run(self, raw: str, agent: "Agent") -> CommandResult:
20
+ async def run(self, raw: str, agent: Agent) -> CommandResult:
26
21
  import os
27
22
 
28
23
  os.system("cls" if os.name == "nt" else "clear")
@@ -1,14 +1,12 @@
1
1
  from importlib.resources import files
2
2
  from typing import TYPE_CHECKING
3
3
 
4
- from klaude_code.command.command_abc import CommandResult, InputAction
4
+ from klaude_code.command.command_abc import Agent, CommandResult, InputAction
5
5
  from klaude_code.command.prompt_command import PromptCommand
6
6
  from klaude_code.protocol import commands, events, model
7
7
  from klaude_code.trace import log_debug
8
8
 
9
9
  if TYPE_CHECKING:
10
- from klaude_code.core.agent import Agent
11
-
12
10
  from .command_abc import CommandABC
13
11
 
14
12
  _COMMANDS: dict[commands.CommandName | str, "CommandABC"] = {}
@@ -50,7 +48,7 @@ def is_slash_command_name(name: str) -> bool:
50
48
  return name in _COMMANDS
51
49
 
52
50
 
53
- async def dispatch_command(raw: str, agent: "Agent") -> CommandResult:
51
+ async def dispatch_command(raw: str, agent: Agent) -> CommandResult:
54
52
  _ensure_commands_loaded()
55
53
  # Detect command name
56
54
  if not raw.startswith("/"):