klaude-code 2.1.1__tar.gz → 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. {klaude_code-2.1.1 → klaude_code-2.2.0}/PKG-INFO +16 -81
  2. {klaude_code-2.1.1 → klaude_code-2.2.0}/README.md +15 -80
  3. {klaude_code-2.1.1 → klaude_code-2.2.0}/pyproject.toml +1 -1
  4. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/app/__init__.py +1 -2
  5. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/app/runtime.py +26 -41
  6. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/cli/main.py +19 -152
  7. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/config/assets/builtin_config.yaml +13 -0
  8. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/const.py +1 -1
  9. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/agent_profile.py +28 -0
  10. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/manager/llm_clients_builder.py +1 -1
  11. klaude_code-2.2.0/src/klaude_code/core/prompts/prompt-nano-banana.md +1 -0
  12. klaude_code-2.2.0/src/klaude_code/core/tool/shell/command_safety.py +175 -0
  13. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/turn.py +1 -1
  14. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/anthropic/client.py +1 -1
  15. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/google/client.py +1 -1
  16. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/openai_compatible/stream.py +1 -1
  17. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/responses/client.py +1 -1
  18. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/message.py +2 -2
  19. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/clear_cmd.py +1 -1
  20. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/command_abc.py +1 -2
  21. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/copy_cmd.py +1 -2
  22. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/fork_session_cmd.py +4 -4
  23. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/refresh_cmd.py +1 -2
  24. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/resume_cmd.py +3 -4
  25. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/status_cmd.py +1 -1
  26. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/developer.py +11 -11
  27. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/metadata.py +1 -1
  28. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/rich/theme.py +2 -2
  29. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/user_input.py +9 -21
  30. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/runner.py +2 -2
  31. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/terminal/selector.py +3 -15
  32. klaude_code-2.2.0/src/klaude_code/ui/__init__.py +18 -0
  33. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/ui/common.py +3 -2
  34. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/ui/core/display.py +2 -2
  35. klaude_code-2.1.1/src/klaude_code/core/tool/shell/command_safety.py +0 -360
  36. klaude_code-2.1.1/src/klaude_code/tui/command/prompt-commit.md +0 -82
  37. klaude_code-2.1.1/src/klaude_code/ui/__init__.py +0 -42
  38. klaude_code-2.1.1/src/klaude_code/ui/exec_mode.py +0 -60
  39. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/__init__.py +0 -0
  40. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/__init__.py +0 -0
  41. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/base.py +0 -0
  42. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/claude/__init__.py +0 -0
  43. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/claude/exceptions.py +0 -0
  44. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/claude/oauth.py +0 -0
  45. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/claude/token_manager.py +0 -0
  46. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/codex/__init__.py +0 -0
  47. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/codex/exceptions.py +0 -0
  48. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
  49. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/codex/oauth.py +0 -0
  50. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/auth/codex/token_manager.py +0 -0
  51. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/cli/__init__.py +0 -0
  52. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/cli/auth_cmd.py +0 -0
  53. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/cli/config_cmd.py +0 -0
  54. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/cli/cost_cmd.py +0 -0
  55. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/cli/debug.py +0 -0
  56. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/cli/list_model.py +0 -0
  57. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/cli/self_update.py +0 -0
  58. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/cli/session_cmd.py +0 -0
  59. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/config/__init__.py +0 -0
  60. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/config/assets/__init__.py +0 -0
  61. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/config/builtin_config.py +0 -0
  62. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/config/config.py +0 -0
  63. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/config/select_model.py +0 -0
  64. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/config/thinking.py +0 -0
  65. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/__init__.py +0 -0
  66. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/agent.py +0 -0
  67. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/executor.py +0 -0
  68. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/manager/__init__.py +0 -0
  69. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/manager/llm_clients.py +0 -0
  70. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/manager/sub_agent_manager.py +0 -0
  71. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
  72. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
  73. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md +0 -0
  74. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-codex.md +0 -0
  75. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
  76. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
  77. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -0
  78. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-sub-agent-image-gen.md +0 -0
  79. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-sub-agent-web.md +0 -0
  80. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
  81. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/reminders.py +0 -0
  82. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/task.py +0 -0
  83. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/__init__.py +0 -0
  84. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/context.py +0 -0
  85. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/__init__.py +0 -0
  86. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/_utils.py +0 -0
  87. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
  88. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
  89. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
  90. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/diff_builder.py +0 -0
  91. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
  92. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
  93. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/read_tool.md +0 -0
  94. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/read_tool.py +0 -0
  95. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/write_tool.md +0 -0
  96. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/file/write_tool.py +0 -0
  97. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/report_back_tool.py +0 -0
  98. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/shell/__init__.py +0 -0
  99. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
  100. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/shell/bash_tool.py +0 -0
  101. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/sub_agent_tool.py +0 -0
  102. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/todo/__init__.py +0 -0
  103. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
  104. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
  105. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
  106. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
  107. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
  108. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/tool_abc.py +0 -0
  109. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/tool_registry.py +0 -0
  110. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/tool_runner.py +0 -0
  111. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/truncation.py +0 -0
  112. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/web/__init__.py +0 -0
  113. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
  114. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
  115. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
  116. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/web/web_fetch_tool.py +0 -0
  117. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
  118. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/core/tool/web/web_search_tool.py +0 -0
  119. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/__init__.py +0 -0
  120. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/anthropic/__init__.py +0 -0
  121. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/anthropic/input.py +0 -0
  122. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/bedrock/__init__.py +0 -0
  123. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/bedrock/client.py +0 -0
  124. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/claude/__init__.py +0 -0
  125. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/claude/client.py +0 -0
  126. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/client.py +0 -0
  127. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/codex/__init__.py +0 -0
  128. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/codex/client.py +0 -0
  129. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/google/__init__.py +0 -0
  130. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/google/input.py +0 -0
  131. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/image.py +0 -0
  132. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/input_common.py +0 -0
  133. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
  134. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/openai_compatible/client.py +0 -0
  135. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/openai_compatible/input.py +0 -0
  136. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
  137. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/openrouter/__init__.py +0 -0
  138. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/openrouter/client.py +0 -0
  139. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/openrouter/input.py +0 -0
  140. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/openrouter/reasoning.py +0 -0
  141. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/registry.py +0 -0
  142. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/responses/__init__.py +0 -0
  143. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/responses/input.py +0 -0
  144. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/llm/usage.py +0 -0
  145. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/log.py +0 -0
  146. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/__init__.py +0 -0
  147. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/commands.py +0 -0
  148. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/events/__init__.py +0 -0
  149. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/events/base.py +0 -0
  150. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/events/chat.py +0 -0
  151. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/events/lifecycle.py +0 -0
  152. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/events/metadata.py +0 -0
  153. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/events/streaming.py +0 -0
  154. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/events/system.py +0 -0
  155. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/events/tools.py +0 -0
  156. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/llm_param.py +0 -0
  157. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/model.py +0 -0
  158. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/op.py +0 -0
  159. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/op_handler.py +0 -0
  160. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
  161. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/sub_agent/explore.py +0 -0
  162. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/sub_agent/image_gen.py +0 -0
  163. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/sub_agent/task.py +0 -0
  164. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/sub_agent/web.py +0 -0
  165. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/protocol/tools.py +0 -0
  166. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/session/__init__.py +0 -0
  167. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/session/codec.py +0 -0
  168. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/session/export.py +0 -0
  169. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/session/selector.py +0 -0
  170. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/session/session.py +0 -0
  171. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/session/store.py +0 -0
  172. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/session/templates/export_session.html +0 -0
  173. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/session/templates/mermaid_viewer.html +0 -0
  174. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/skill/__init__.py +0 -0
  175. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/skill/assets/create-plan/SKILL.md +0 -0
  176. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/skill/assets/deslop/SKILL.md +0 -0
  177. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/skill/assets/handoff/SKILL.md +0 -0
  178. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/skill/assets/jj-workspace/SKILL.md +0 -0
  179. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/skill/assets/skill-creator/SKILL.md +0 -0
  180. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/skill/loader.py +0 -0
  181. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/skill/manager.py +0 -0
  182. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/skill/system_skills.py +0 -0
  183. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/__init__.py +0 -0
  184. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/__init__.py +4 -4
  185. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/debug_cmd.py +0 -0
  186. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/export_cmd.py +0 -0
  187. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/export_online_cmd.py +0 -0
  188. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/help_cmd.py +0 -0
  189. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/model_cmd.py +0 -0
  190. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/model_select.py +0 -0
  191. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/prompt-init.md +0 -0
  192. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/prompt_command.py +0 -0
  193. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/registry.py +0 -0
  194. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/release_notes_cmd.py +0 -0
  195. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/terminal_setup_cmd.py +0 -0
  196. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/command/thinking_cmd.py +0 -0
  197. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/commands.py +0 -0
  198. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/__init__.py +0 -0
  199. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/assistant.py +0 -0
  200. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/bash_syntax.py +0 -0
  201. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/common.py +0 -0
  202. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/diffs.py +0 -0
  203. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/errors.py +0 -0
  204. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/mermaid_viewer.py +0 -0
  205. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/rich/__init__.py +0 -0
  206. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/rich/cjk_wrap.py +0 -0
  207. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/rich/code_panel.py +0 -0
  208. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/rich/live.py +0 -0
  209. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/rich/markdown.py +0 -0
  210. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/rich/quote.py +0 -0
  211. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/rich/searchable_text.py +0 -0
  212. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/rich/status.py +0 -0
  213. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/sub_agent.py +0 -0
  214. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/thinking.py +0 -0
  215. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/components/tools.py +0 -0
  216. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/display.py +0 -0
  217. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/input/__init__.py +0 -0
  218. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/input/clipboard.py +0 -0
  219. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/input/completers.py +0 -0
  220. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/input/key_bindings.py +0 -0
  221. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/input/prompt_toolkit.py +0 -0
  222. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/machine.py +0 -0
  223. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/renderer.py +0 -0
  224. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/terminal/__init__.py +0 -0
  225. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/terminal/color.py +0 -0
  226. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/terminal/control.py +0 -0
  227. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/terminal/image.py +0 -0
  228. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/terminal/notifier.py +0 -0
  229. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/tui/terminal/progress_bar.py +0 -0
  230. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/ui/core/__init__.py +0 -0
  231. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/ui/core/input.py +0 -0
  232. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/ui/debug_mode.py +0 -0
  233. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/ui/terminal/__init__.py +0 -0
  234. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/ui/terminal/title.py +0 -0
  235. {klaude_code-2.1.1 → klaude_code-2.2.0}/src/klaude_code/update.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: klaude-code
3
- Version: 2.1.1
3
+ Version: 2.2.0
4
4
  Summary: Minimal code agent CLI
5
5
  Requires-Dist: anthropic>=0.66.0
6
6
  Requires-Dist: chardet>=5.2.0
@@ -25,21 +25,19 @@ Description-Content-Type: text/markdown
25
25
  Minimal code agent CLI.
26
26
 
27
27
  ## Features
28
- - **Multi-provider**: Anthropic, OpenAI Responses API, OpenRouter
28
+ - **Multi-provider**: Anthropic Message API, OpenAI Responses API, OpenRouter, Claude Max OAuth and ChatGPT Codex OAuth etc.
29
29
  - **Keep reasoning item in context**: Interleaved thinking support
30
- - **Model-aware tools**: Claude Code tools for Sonnet, `apply_patch` for GPT-5/Codex
31
- - **Structured sub-agent output**: Define JSON schema, get schema-compliant responses via constrained decoding
30
+ - **Model-aware tools**: Claude Code tool set for Opus, `apply_patch` for GPT-5/Codex
31
+ - **Reminders**: Cooldown-based todo tracking, instruction reinforcement and external file change reminder
32
+ - **Sub-agents**: Task, Explore, Web, ImageGen
33
+ - **Structured sub-agent output**: Main agent defines JSON schema and get schema-compliant responses via constrained decoding
32
34
  - **Recursive `@file` mentions**: Circular dependency protection, relative path resolution
33
- - **Reminders**: Cooldown-based todo tracking and instruction reinforcement
34
35
  - **External file sync**: Monitoring for external edits (linter, manual)
35
36
  - **Interrupt handling**: Ctrl+C preserves partial responses and synthesizes tool cancellation results
36
37
  - **Output truncation**: Large outputs saved to file system with snapshot links
37
- - **Skills**: Built-in + user + project Agent Skills (with implicit invocation by Skill tool or explicit invocation by typing `$`)
38
+ - **Agent Skills**: Built-in + user + project Agent Skills (with implicit invocation by Skill tool or explicit invocation by typing `$`)
38
39
  - **Sessions**: Resumable with `--continue`
39
- - **Cost tracking**: Automatic API cost calculation and display (USD/CNY)
40
- - **Version update check**: Background PyPI version check with upgrade prompts
41
- - **Terminal title**: Shows current directory and model name
42
- - **Mermaid diagrams**: Interactive local HTML viewer with zoom, pan, and SVG export
40
+ - **Mermaid diagrams**: Terminal image preview and Interactive local HTML viewer with zoom, pan, and SVG export
43
41
  - **Extras**: Slash commands, sub-agents, image paste, terminal notifications, auto-theming
44
42
 
45
43
  ## Installation
@@ -59,32 +57,23 @@ Or use the built-in alias command:
59
57
  ```bash
60
58
  klaude update
61
59
  klaude upgrade
62
- ```
63
-
64
- To show version:
65
-
66
- ```bash
67
60
  klaude --version
68
- klaude -v
69
- klaude version
61
+
70
62
  ```
71
63
 
72
64
  ## Usage
73
65
 
74
- ### Interactive Mode
75
-
76
66
  ```bash
77
67
  klaude [--model <name>] [--select-model]
78
68
  ```
79
69
 
80
70
  **Options:**
81
- - `--version`/`-V`/`-v`: Show version and exit.
82
71
  - `--model`/`-m`: Preferred model name (exact match picks immediately; otherwise opens the interactive selector filtered by this value).
83
72
  - `--select-model`/`-s`: Open the interactive model selector at startup (shows all models unless `--model` is also provided).
84
73
  - `--continue`/`-c`: Resume the most recent session.
85
74
  - `--resume`/`-r`: Select a session to resume for this project.
86
75
  - `--resume-by-id <id>`: Resume a session by its ID directly.
87
- - `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit) and no system prompts.
76
+ - `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit, Write) and no system prompts.
88
77
 
89
78
  **Model selection behavior:**
90
79
  - Default: uses `main_model` from config.
@@ -255,48 +244,16 @@ provider_list:
255
244
  context_limit: 128000
256
245
  ```
257
246
 
258
- ##### Full Example
259
-
260
- ```yaml
261
- # User configuration - merged with built-in config
262
- main_model: opus
263
-
264
- sub_agent_models:
265
- explore: sonnet
266
- task: opus
267
- webagent: sonnet
268
-
269
- provider_list:
270
- # Add models to built-in openrouter
271
- - provider_name: openrouter
272
- model_list:
273
- - model_name: qwen-coder
274
- model_params:
275
- model: qwen/qwen-2.5-coder-32b-instruct
276
- context_limit: 131072
277
-
278
- # Add a completely new provider
279
- - provider_name: local-ollama
280
- protocol: openai
281
- base_url: http://localhost:11434/v1
282
- api_key: ollama
283
- model_list:
284
- - model_name: local-llama
285
- model_params:
286
- model: llama3.2
287
- context_limit: 8192
288
- ```
289
-
290
247
  ##### Supported Protocols
291
248
 
292
- - `anthropic` - Anthropic Claude API
249
+ - `anthropic` - Anthropic Messages API
293
250
  - `claude_oauth` - Claude OAuth (for Claude Pro/Max subscribers)
294
- - `openai` - OpenAI-compatible API
251
+ - `openai` - OpenAI Chat Completion API
295
252
  - `responses` - OpenAI Responses API (for o-series, GPT-5, Codex)
296
- - `openrouter` - OpenRouter API
297
- - `google` - Google Gemini API
298
- - `bedrock` - AWS Bedrock (uses AWS credentials instead of api_key)
299
253
  - `codex_oauth` - OpenAI Codex CLI (OAuth-based, for ChatGPT Pro subscribers)
254
+ - `openrouter` - OpenRouter API (handling `reasoning_details` for interleaved thinking)
255
+ - `google` - Google Gemini API
256
+ - `bedrock` - AWS Bedrock for Claude(uses AWS credentials instead of api_key)
300
257
 
301
258
  List configured providers and models:
302
259
 
@@ -338,6 +295,7 @@ Inside the interactive session (`klaude`), use these commands to streamline your
338
295
  - `/model` - Switch the active LLM during the session.
339
296
  - `/thinking` - Configure model thinking/reasoning level.
340
297
  - `/clear` - Clear the current conversation context.
298
+ - `/copy` - Copy last assistant message.
341
299
  - `/status` - Show session usage statistics (cost, tokens, model breakdown).
342
300
  - `/resume` - Select and resume a previous session.
343
301
  - `/fork-session` - Fork current session to a new session ID (supports interactive fork point selection).
@@ -364,29 +322,6 @@ Inside the interactive session (`klaude`), use these commands to streamline your
364
322
  | `Backspace` | Delete character or selected text |
365
323
  | `c` (with selection) | Copy selected text to clipboard |
366
324
 
367
- ### Non-Interactive Headless Mode (exec)
368
-
369
- Execute a single command without starting the interactive REPL:
370
-
371
- ```bash
372
- # Direct input
373
- klaude exec "what is 2+2?"
374
-
375
- # Pipe input
376
- echo "hello world" | klaude exec
377
-
378
- # With model selection
379
-
380
- # Exact model name (non-interactive)
381
- echo "generate quicksort in python" | klaude exec --model gpt-5.1
382
-
383
- # Partial/ambiguous name opens the interactive selector (filtered)
384
- echo "generate quicksort in python" | klaude exec --model gpt
385
-
386
- # Stream all events as JSON lines (for programmatic processing)
387
- klaude exec "what is 2+2?" --stream-json
388
- ```
389
-
390
325
  ### Sub-Agents
391
326
 
392
327
  The main agent can spawn specialized sub-agents for specific tasks:
@@ -3,21 +3,19 @@
3
3
  Minimal code agent CLI.
4
4
 
5
5
  ## Features
6
- - **Multi-provider**: Anthropic, OpenAI Responses API, OpenRouter
6
+ - **Multi-provider**: Anthropic Message API, OpenAI Responses API, OpenRouter, Claude Max OAuth and ChatGPT Codex OAuth etc.
7
7
  - **Keep reasoning item in context**: Interleaved thinking support
8
- - **Model-aware tools**: Claude Code tools for Sonnet, `apply_patch` for GPT-5/Codex
9
- - **Structured sub-agent output**: Define JSON schema, get schema-compliant responses via constrained decoding
8
+ - **Model-aware tools**: Claude Code tool set for Opus, `apply_patch` for GPT-5/Codex
9
+ - **Reminders**: Cooldown-based todo tracking, instruction reinforcement and external file change reminder
10
+ - **Sub-agents**: Task, Explore, Web, ImageGen
11
+ - **Structured sub-agent output**: Main agent defines JSON schema and get schema-compliant responses via constrained decoding
10
12
  - **Recursive `@file` mentions**: Circular dependency protection, relative path resolution
11
- - **Reminders**: Cooldown-based todo tracking and instruction reinforcement
12
13
  - **External file sync**: Monitoring for external edits (linter, manual)
13
14
  - **Interrupt handling**: Ctrl+C preserves partial responses and synthesizes tool cancellation results
14
15
  - **Output truncation**: Large outputs saved to file system with snapshot links
15
- - **Skills**: Built-in + user + project Agent Skills (with implicit invocation by Skill tool or explicit invocation by typing `$`)
16
+ - **Agent Skills**: Built-in + user + project Agent Skills (with implicit invocation by Skill tool or explicit invocation by typing `$`)
16
17
  - **Sessions**: Resumable with `--continue`
17
- - **Cost tracking**: Automatic API cost calculation and display (USD/CNY)
18
- - **Version update check**: Background PyPI version check with upgrade prompts
19
- - **Terminal title**: Shows current directory and model name
20
- - **Mermaid diagrams**: Interactive local HTML viewer with zoom, pan, and SVG export
18
+ - **Mermaid diagrams**: Terminal image preview and Interactive local HTML viewer with zoom, pan, and SVG export
21
19
  - **Extras**: Slash commands, sub-agents, image paste, terminal notifications, auto-theming
22
20
 
23
21
  ## Installation
@@ -37,32 +35,23 @@ Or use the built-in alias command:
37
35
  ```bash
38
36
  klaude update
39
37
  klaude upgrade
40
- ```
41
-
42
- To show version:
43
-
44
- ```bash
45
38
  klaude --version
46
- klaude -v
47
- klaude version
39
+
48
40
  ```
49
41
 
50
42
  ## Usage
51
43
 
52
- ### Interactive Mode
53
-
54
44
  ```bash
55
45
  klaude [--model <name>] [--select-model]
56
46
  ```
57
47
 
58
48
  **Options:**
59
- - `--version`/`-V`/`-v`: Show version and exit.
60
49
  - `--model`/`-m`: Preferred model name (exact match picks immediately; otherwise opens the interactive selector filtered by this value).
61
50
  - `--select-model`/`-s`: Open the interactive model selector at startup (shows all models unless `--model` is also provided).
62
51
  - `--continue`/`-c`: Resume the most recent session.
63
52
  - `--resume`/`-r`: Select a session to resume for this project.
64
53
  - `--resume-by-id <id>`: Resume a session by its ID directly.
65
- - `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit) and no system prompts.
54
+ - `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit, Write) and no system prompts.
66
55
 
67
56
  **Model selection behavior:**
68
57
  - Default: uses `main_model` from config.
@@ -233,48 +222,16 @@ provider_list:
233
222
  context_limit: 128000
234
223
  ```
235
224
 
236
- ##### Full Example
237
-
238
- ```yaml
239
- # User configuration - merged with built-in config
240
- main_model: opus
241
-
242
- sub_agent_models:
243
- explore: sonnet
244
- task: opus
245
- webagent: sonnet
246
-
247
- provider_list:
248
- # Add models to built-in openrouter
249
- - provider_name: openrouter
250
- model_list:
251
- - model_name: qwen-coder
252
- model_params:
253
- model: qwen/qwen-2.5-coder-32b-instruct
254
- context_limit: 131072
255
-
256
- # Add a completely new provider
257
- - provider_name: local-ollama
258
- protocol: openai
259
- base_url: http://localhost:11434/v1
260
- api_key: ollama
261
- model_list:
262
- - model_name: local-llama
263
- model_params:
264
- model: llama3.2
265
- context_limit: 8192
266
- ```
267
-
268
225
  ##### Supported Protocols
269
226
 
270
- - `anthropic` - Anthropic Claude API
227
+ - `anthropic` - Anthropic Messages API
271
228
  - `claude_oauth` - Claude OAuth (for Claude Pro/Max subscribers)
272
- - `openai` - OpenAI-compatible API
229
+ - `openai` - OpenAI Chat Completion API
273
230
  - `responses` - OpenAI Responses API (for o-series, GPT-5, Codex)
274
- - `openrouter` - OpenRouter API
275
- - `google` - Google Gemini API
276
- - `bedrock` - AWS Bedrock (uses AWS credentials instead of api_key)
277
231
  - `codex_oauth` - OpenAI Codex CLI (OAuth-based, for ChatGPT Pro subscribers)
232
+ - `openrouter` - OpenRouter API (handling `reasoning_details` for interleaved thinking)
233
+ - `google` - Google Gemini API
234
+ - `bedrock` - AWS Bedrock for Claude(uses AWS credentials instead of api_key)
278
235
 
279
236
  List configured providers and models:
280
237
 
@@ -316,6 +273,7 @@ Inside the interactive session (`klaude`), use these commands to streamline your
316
273
  - `/model` - Switch the active LLM during the session.
317
274
  - `/thinking` - Configure model thinking/reasoning level.
318
275
  - `/clear` - Clear the current conversation context.
276
+ - `/copy` - Copy last assistant message.
319
277
  - `/status` - Show session usage statistics (cost, tokens, model breakdown).
320
278
  - `/resume` - Select and resume a previous session.
321
279
  - `/fork-session` - Fork current session to a new session ID (supports interactive fork point selection).
@@ -342,29 +300,6 @@ Inside the interactive session (`klaude`), use these commands to streamline your
342
300
  | `Backspace` | Delete character or selected text |
343
301
  | `c` (with selection) | Copy selected text to clipboard |
344
302
 
345
- ### Non-Interactive Headless Mode (exec)
346
-
347
- Execute a single command without starting the interactive REPL:
348
-
349
- ```bash
350
- # Direct input
351
- klaude exec "what is 2+2?"
352
-
353
- # Pipe input
354
- echo "hello world" | klaude exec
355
-
356
- # With model selection
357
-
358
- # Exact model name (non-interactive)
359
- echo "generate quicksort in python" | klaude exec --model gpt-5.1
360
-
361
- # Partial/ambiguous name opens the interactive selector (filtered)
362
- echo "generate quicksort in python" | klaude exec --model gpt
363
-
364
- # Stream all events as JSON lines (for programmatic processing)
365
- klaude exec "what is 2+2?" --stream-json
366
- ```
367
-
368
303
  ### Sub-Agents
369
304
 
370
305
  The main agent can spawn specialized sub-agents for specific tasks:
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "klaude-code"
7
- version = "2.1.1"
7
+ version = "2.2.0"
8
8
  description = "Minimal code agent CLI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -4,9 +4,8 @@ This package coordinates core execution (Executor) with frontend displays.
4
4
  Terminal-specific rendering and input handling live in `klaude_code.tui`.
5
5
  """
6
6
 
7
- from .runtime import AppInitConfig, run_exec
7
+ from .runtime import AppInitConfig
8
8
 
9
9
  __all__ = [
10
10
  "AppInitConfig",
11
- "run_exec",
12
11
  ]
@@ -9,12 +9,15 @@ import typer
9
9
  from klaude_code import ui
10
10
  from klaude_code.config import Config, load_config
11
11
  from klaude_code.core.agent import Agent
12
- from klaude_code.core.agent_profile import DefaultModelProfileProvider, VanillaModelProfileProvider
12
+ from klaude_code.core.agent_profile import (
13
+ DefaultModelProfileProvider,
14
+ NanoBananaModelProfileProvider,
15
+ VanillaModelProfileProvider,
16
+ )
13
17
  from klaude_code.core.executor import Executor
14
18
  from klaude_code.core.manager import build_llm_clients
15
19
  from klaude_code.log import DebugType, log, set_debug_logging
16
20
  from klaude_code.protocol import events, op
17
- from klaude_code.protocol.message import UserInputPayload
18
21
  from klaude_code.session.session import Session, close_default_store
19
22
 
20
23
 
@@ -25,8 +28,8 @@ class AppInitConfig:
25
28
  model: str | None
26
29
  debug: bool
27
30
  vanilla: bool
31
+ banana: bool
28
32
  debug_filters: set[DebugType] | None = None
29
- stream_json: bool = False
30
33
 
31
34
 
32
35
  @dataclass
@@ -52,6 +55,20 @@ async def initialize_app_components(
52
55
 
53
56
  config = load_config()
54
57
 
58
+ if init_config.banana:
59
+ # Banana mode is strict: it requires the built-in Nano Banana image model to be available.
60
+ required_model = "nano-banana-pro@or"
61
+ available = {m.model_name for m in config.iter_model_entries(only_available=True)}
62
+ if required_model not in available:
63
+ log(
64
+ (
65
+ f"Error: --banana requires model '{required_model}', but it is not available in the current environment",
66
+ "red",
67
+ )
68
+ )
69
+ log(("Hint: set OPENROUTER_API_KEY (Nano Banana Pro is configured via OpenRouter by default)", "yellow"))
70
+ raise typer.Exit(2)
71
+
55
72
  try:
56
73
  llm_clients = build_llm_clients(
57
74
  config,
@@ -70,7 +87,12 @@ async def initialize_app_components(
70
87
  log((f"Error: failed to load the default model configuration: {exc}", "red"))
71
88
  raise typer.Exit(2) from None
72
89
 
73
- model_profile_provider = VanillaModelProfileProvider() if init_config.vanilla else DefaultModelProfileProvider()
90
+ if init_config.banana:
91
+ model_profile_provider = NanoBananaModelProfileProvider()
92
+ elif init_config.vanilla:
93
+ model_profile_provider = VanillaModelProfileProvider()
94
+ else:
95
+ model_profile_provider = DefaultModelProfileProvider()
74
96
 
75
97
  event_queue: asyncio.Queue[events.Event] = asyncio.Queue()
76
98
 
@@ -176,40 +198,3 @@ async def handle_keyboard_interrupt(executor: Executor) -> None:
176
198
  log(("Resume with:", "dim"), (f"klaude --resume-by-id {session_id}", "green"))
177
199
  with contextlib.suppress(Exception):
178
200
  await executor.submit(op.InterruptOperation(target_session_id=None))
179
-
180
-
181
- async def run_exec(init_config: AppInitConfig, input_content: str) -> None:
182
- """Run a single task non-interactively (exec mode)."""
183
- from klaude_code.ui.terminal.title import update_terminal_title
184
-
185
- display = ui.create_exec_display(debug=init_config.debug, stream_json=init_config.stream_json)
186
- components = await initialize_app_components(
187
- init_config=init_config,
188
- display=display,
189
- on_model_change=update_terminal_title,
190
- )
191
-
192
- try:
193
- session_id = await initialize_session(components.executor, components.event_queue)
194
- backfill_session_model_config(
195
- components.executor.context.current_agent,
196
- init_config.model,
197
- components.config.main_model,
198
- is_new_session=True,
199
- )
200
-
201
- if session_id is None:
202
- raise RuntimeError("No active session")
203
-
204
- op_id = await components.executor.submit(
205
- op.RunAgentOperation(
206
- session_id=session_id,
207
- input=UserInputPayload(text=input_content),
208
- )
209
- )
210
- await components.executor.wait_for(op_id)
211
- await components.event_queue.join()
212
- except KeyboardInterrupt:
213
- await handle_keyboard_interrupt(components.executor)
214
- finally:
215
- await cleanup_app_components(components)
@@ -13,44 +13,6 @@ from klaude_code.session import Session
13
13
  from klaude_code.tui.command.resume_cmd import select_session_sync
14
14
  from klaude_code.ui.terminal.title import update_terminal_title
15
15
 
16
-
17
- def read_input_content(cli_argument: str) -> str | None:
18
- """Read and merge input from stdin and CLI argument.
19
-
20
- Args:
21
- cli_argument: The input content passed as CLI argument.
22
-
23
- Returns:
24
- The merged input content, or None if no input was provided.
25
- """
26
- from klaude_code.log import log
27
-
28
- parts: list[str] = []
29
-
30
- # Handle stdin input
31
- if not sys.stdin.isatty():
32
- try:
33
- stdin = sys.stdin.read().rstrip("\n")
34
- if stdin:
35
- parts.append(stdin)
36
- except (OSError, ValueError) as e:
37
- # Expected I/O-related errors when reading from stdin (e.g. broken pipe, closed stream).
38
- log((f"Error reading from stdin: {e}", "red"))
39
- except Exception as e:
40
- # Unexpected errors are still reported but kept from crashing the CLI.
41
- log((f"Unexpected error reading from stdin: {e}", "red"))
42
-
43
- if cli_argument:
44
- parts.append(cli_argument)
45
-
46
- content = "\n".join(parts)
47
- if len(content) == 0:
48
- log(("Error: No input content provided", "red"))
49
- return None
50
-
51
- return content
52
-
53
-
54
16
  ENV_HELP = """\
55
17
  Environment Variables:
56
18
 
@@ -76,101 +38,6 @@ register_cost_commands(app)
76
38
  register_self_update_commands(app)
77
39
 
78
40
 
79
- @app.command("exec")
80
- def exec_command(
81
- input_content: str = typer.Argument("", help="Input message to execute"),
82
- model: str | None = typer.Option(
83
- None,
84
- "--model",
85
- "-m",
86
- help="Override model config name (uses main model by default)",
87
- rich_help_panel="LLM",
88
- ),
89
- select_model: bool = typer.Option(
90
- False,
91
- "--select-model",
92
- "-s",
93
- help="Interactively choose a model at startup",
94
- rich_help_panel="LLM",
95
- ),
96
- debug: bool = typer.Option(
97
- False,
98
- "--debug",
99
- "-d",
100
- help="Enable debug mode",
101
- rich_help_panel="Debug",
102
- ),
103
- debug_filter: str | None = typer.Option(
104
- None,
105
- "--debug-filter",
106
- help=DEBUG_FILTER_HELP,
107
- rich_help_panel="Debug",
108
- ),
109
- vanilla: bool = typer.Option(
110
- False,
111
- "--vanilla",
112
- help="Vanilla mode exposes the model's raw API behavior: it provides only minimal tools (Bash, Read & Edit) and omits system prompts and reminders.",
113
- ),
114
- stream_json: bool = typer.Option(
115
- False,
116
- "--stream-json",
117
- help="Stream all events as JSON lines to stdout.",
118
- ),
119
- ) -> None:
120
- """Execute non-interactively with provided input."""
121
- update_terminal_title()
122
-
123
- merged_input = read_input_content(input_content)
124
- if merged_input is None:
125
- raise typer.Exit(1)
126
-
127
- from klaude_code.app.runtime import AppInitConfig, run_exec
128
- from klaude_code.config import load_config
129
- from klaude_code.tui.command.model_select import select_model_interactive
130
-
131
- chosen_model = model
132
- if model or select_model:
133
- chosen_model = select_model_interactive(preferred=model)
134
- if chosen_model is None:
135
- raise typer.Exit(1)
136
- else:
137
- # Check if main_model is configured; if not, trigger interactive selection
138
- config = load_config()
139
- if config.main_model is None:
140
- chosen_model = select_model_interactive()
141
- if chosen_model is None:
142
- raise typer.Exit(1)
143
- # Save the selection as default
144
- config.main_model = chosen_model
145
- from klaude_code.config.config import config_path
146
- from klaude_code.log import log
147
-
148
- asyncio.run(config.save())
149
- log(f"Saved main_model={chosen_model} to {config_path}", style="cyan")
150
-
151
- debug_enabled, debug_filters, log_path = prepare_debug_logging(debug, debug_filter)
152
-
153
- init_config = AppInitConfig(
154
- model=chosen_model,
155
- debug=debug_enabled,
156
- vanilla=vanilla,
157
- debug_filters=debug_filters,
158
- stream_json=stream_json,
159
- )
160
-
161
- if log_path:
162
- from klaude_code.log import log
163
-
164
- log(f"Debug log: {log_path}", style="dim")
165
-
166
- asyncio.run(
167
- run_exec(
168
- init_config=init_config,
169
- input_content=merged_input,
170
- )
171
- )
172
-
173
-
174
41
  @app.callback(invoke_without_command=True)
175
42
  def main_callback(
176
43
  ctx: typer.Context,
@@ -220,13 +87,23 @@ def main_callback(
220
87
  vanilla: bool = typer.Option(
221
88
  False,
222
89
  "--vanilla",
223
- help="Vanilla mode exposes the model's raw API behavior: it provides only minimal tools (Bash, Read & Edit) and omits system prompts and reminders.",
90
+ help="Vanilla mode exposes the model's raw API behavior: it provides only minimal tools (Bash, Read, Write & Edit) and omits system prompts and reminders.",
91
+ ),
92
+ banana: bool = typer.Option(
93
+ False,
94
+ "--banana",
95
+ help="Image generation mode with Nano Banana",
96
+ rich_help_panel="LLM",
224
97
  ),
225
98
  ) -> None:
226
99
  # Only run interactive mode when no subcommand is invoked
227
100
  if ctx.invoked_subcommand is None:
228
101
  from klaude_code.log import log
229
102
 
103
+ if vanilla and banana:
104
+ log(("Error: --banana cannot be combined with --vanilla", "red"))
105
+ raise typer.Exit(2)
106
+
230
107
  resume_by_id_value = resume_by_id.strip() if resume_by_id is not None else None
231
108
  if resume_by_id_value == "":
232
109
  log(("Error: --resume-by-id cannot be empty", "red"))
@@ -241,24 +118,10 @@ def main_callback(
241
118
  log(("Hint: run `klaude --resume` to select an existing session", "yellow"))
242
119
  raise typer.Exit(2)
243
120
 
244
- # In non-interactive environments, default to exec-mode behavior.
245
- # This allows: echo "…" | klaude
246
121
  if not sys.stdin.isatty() or not sys.stdout.isatty():
247
- if continue_ or resume or resume_by_id is not None:
248
- log(("Error: --continue/--resume options require a TTY", "red"))
249
- log(("Hint: use `klaude exec` for non-interactive usage", "yellow"))
250
- raise typer.Exit(2)
251
-
252
- exec_command(
253
- input_content="",
254
- model=model,
255
- select_model=select_model,
256
- debug=debug,
257
- debug_filter=debug_filter,
258
- vanilla=vanilla,
259
- stream_json=False,
260
- )
261
- return
122
+ log(("Error: interactive mode requires a TTY", "red"))
123
+ log(("Hint: run klaude from an interactive terminal", "yellow"))
124
+ raise typer.Exit(2)
262
125
 
263
126
  from klaude_code.app.runtime import AppInitConfig
264
127
  from klaude_code.tui.command.model_select import select_model_interactive
@@ -267,7 +130,10 @@ def main_callback(
267
130
  update_terminal_title()
268
131
 
269
132
  chosen_model = model
270
- if model or select_model:
133
+ if banana:
134
+ # Banana mode always uses the built-in Nano Banana Pro image model.
135
+ chosen_model = "nano-banana-pro@or"
136
+ elif model or select_model:
271
137
  chosen_model = select_model_interactive(preferred=model)
272
138
  if chosen_model is None:
273
139
  return
@@ -340,6 +206,7 @@ def main_callback(
340
206
  model=chosen_model,
341
207
  debug=debug_enabled,
342
208
  vanilla=vanilla,
209
+ banana=banana,
343
210
  debug_filters=debug_filters,
344
211
  )
345
212
 
@@ -250,6 +250,18 @@ provider_list:
250
250
  input: 0.5
251
251
  output: 3.0
252
252
  cache_read: 0.05
253
+ - model_name: nano-banana-pro@google
254
+ model_params:
255
+ model: gemini-3-pro-image-preview
256
+ context_limit: 1048576
257
+ modalities:
258
+ - image
259
+ - text
260
+ cost:
261
+ input: 2
262
+ output: 12
263
+ cache_read: 0.2
264
+ image: 120
253
265
 
254
266
  - provider_name: bedrock
255
267
  protocol: bedrock
@@ -266,6 +278,7 @@ provider_list:
266
278
  output: 15.0
267
279
  cache_read: 0.3
268
280
  cache_write: 3.75
281
+
269
282
  - provider_name: deepseek
270
283
  protocol: anthropic
271
284
  api_key: ${DEEPSEEK_API_KEY}