klaude-code 2.0.1__tar.gz → 2.1.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.
- {klaude_code-2.0.1 → klaude_code-2.1.0}/PKG-INFO +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/pyproject.toml +4 -3
- klaude_code-2.1.0/src/klaude_code/app/__init__.py +12 -0
- klaude_code-2.1.0/src/klaude_code/app/runtime.py +215 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/cli/auth_cmd.py +2 -2
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/cli/config_cmd.py +2 -2
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/cli/cost_cmd.py +1 -1
- klaude_code-2.1.0/src/klaude_code/cli/debug.py +54 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/cli/list_model.py +3 -3
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/cli/main.py +17 -60
- klaude_code-2.1.0/src/klaude_code/cli/self_update.py +87 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/cli/session_cmd.py +2 -2
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/config/config.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/config/select_model.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/const.py +10 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/agent.py +9 -62
- klaude_code-2.1.0/src/klaude_code/core/agent_profile.py +284 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/executor.py +343 -230
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/manager/llm_clients_builder.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/manager/sub_agent_manager.py +16 -29
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/reminders.py +107 -155
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/task.py +12 -20
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/__init__.py +5 -19
- klaude_code-2.1.0/src/klaude_code/core/tool/context.py +84 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/apply_patch_tool.py +18 -21
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/edit_tool.py +42 -44
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/read_tool.py +14 -9
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/write_tool.py +12 -13
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/report_back_tool.py +4 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/shell/bash_tool.py +6 -11
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/skill/skill_tool.py +3 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/sub_agent_tool.py +8 -7
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/todo/todo_write_tool.py +3 -9
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/todo/update_plan_tool.py +3 -5
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/tool_abc.py +2 -1
- klaude_code-2.1.0/src/klaude_code/core/tool/tool_registry.py +47 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/tool_runner.py +13 -10
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/web/mermaid_tool.py +3 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/web/web_fetch_tool.py +5 -3
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/web/web_search_tool.py +5 -3
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/turn.py +86 -26
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/anthropic/client.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/bedrock/client.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/claude/client.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/codex/client.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/google/client.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/openai_compatible/client.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/openrouter/client.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/openrouter/reasoning.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/responses/client.py +1 -1
- klaude_code-2.1.0/src/klaude_code/protocol/events/__init__.py +57 -0
- klaude_code-2.1.0/src/klaude_code/protocol/events/base.py +18 -0
- klaude_code-2.1.0/src/klaude_code/protocol/events/chat.py +20 -0
- klaude_code-2.1.0/src/klaude_code/protocol/events/lifecycle.py +22 -0
- klaude_code-2.1.0/src/klaude_code/protocol/events/metadata.py +15 -0
- klaude_code-2.1.0/src/klaude_code/protocol/events/streaming.py +43 -0
- klaude_code-2.1.0/src/klaude_code/protocol/events/system.py +53 -0
- klaude_code-2.1.0/src/klaude_code/protocol/events/tools.py +23 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/message.py +3 -11
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/model.py +78 -9
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/op.py +5 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/sub_agent/explore.py +0 -15
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/sub_agent/task.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/sub_agent/web.py +1 -17
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/tools.py +0 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/session/session.py +6 -5
- klaude_code-2.1.0/src/klaude_code/skill/assets/create-plan/SKILL.md +76 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/skill/loader.py +1 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/skill/system_skills.py +1 -1
- klaude_code-2.1.0/src/klaude_code/tui/__init__.py +8 -0
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/clear_cmd.py +2 -1
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/debug_cmd.py +4 -3
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/export_cmd.py +2 -1
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/export_online_cmd.py +6 -5
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/fork_session_cmd.py +10 -9
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/help_cmd.py +3 -2
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/model_cmd.py +5 -4
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/model_select.py +2 -2
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/prompt_command.py +4 -3
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/refresh_cmd.py +3 -1
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/registry.py +16 -6
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/release_notes_cmd.py +3 -2
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/resume_cmd.py +6 -5
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/status_cmd.py +4 -3
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/terminal_setup_cmd.py +4 -3
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/thinking_cmd.py +4 -3
- klaude_code-2.1.0/src/klaude_code/tui/commands.py +164 -0
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/assistant.py +3 -3
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/bash_syntax.py +2 -2
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/common.py +1 -1
- klaude_code-2.1.0/src/klaude_code/tui/components/developer.py +231 -0
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/diffs.py +2 -2
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/errors.py +2 -2
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/metadata.py +34 -21
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui/components}/rich/markdown.py +78 -34
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui/components}/rich/status.py +2 -2
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui/components}/rich/theme.py +12 -5
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/sub_agent.py +23 -43
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/thinking.py +3 -3
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/tools.py +11 -48
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/user_input.py +3 -20
- klaude_code-2.1.0/src/klaude_code/tui/display.py +85 -0
- {klaude_code-2.0.1/src/klaude_code/ui/modes/repl → klaude_code-2.1.0/src/klaude_code/tui/input}/__init__.py +1 -1
- {klaude_code-2.0.1/src/klaude_code/ui/modes/repl → klaude_code-2.1.0/src/klaude_code/tui/input}/completers.py +1 -1
- klaude_code-2.0.1/src/klaude_code/ui/modes/repl/input_prompt_toolkit.py → klaude_code-2.1.0/src/klaude_code/tui/input/prompt_toolkit.py +11 -7
- klaude_code-2.1.0/src/klaude_code/tui/machine.py +606 -0
- klaude_code-2.1.0/src/klaude_code/tui/renderer.py +707 -0
- klaude_code-2.1.0/src/klaude_code/tui/runner.py +321 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui}/terminal/color.py +1 -1
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui}/terminal/control.py +1 -1
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui}/terminal/notifier.py +1 -1
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui}/terminal/selector.py +36 -17
- klaude_code-2.1.0/src/klaude_code/ui/__init__.py +42 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/ui/core/display.py +3 -3
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/ui/core/input.py +2 -1
- klaude_code-2.0.1/src/klaude_code/ui/modes/debug/display.py → klaude_code-2.1.0/src/klaude_code/ui/debug_mode.py +1 -1
- klaude_code-2.0.1/src/klaude_code/ui/modes/exec/display.py → klaude_code-2.1.0/src/klaude_code/ui/exec_mode.py +1 -4
- klaude_code-2.1.0/src/klaude_code/ui/terminal/__init__.py +8 -0
- klaude_code-2.1.0/src/klaude_code/ui/terminal/title.py +31 -0
- klaude_code-2.0.1/src/klaude_code/cli/self_update.py → klaude_code-2.1.0/src/klaude_code/update.py +9 -118
- klaude_code-2.0.1/src/klaude_code/cli/debug.py +0 -78
- klaude_code-2.0.1/src/klaude_code/cli/runtime.py +0 -525
- klaude_code-2.0.1/src/klaude_code/core/prompt.py +0 -108
- klaude_code-2.0.1/src/klaude_code/core/tool/file/move_tool.md +0 -41
- klaude_code-2.0.1/src/klaude_code/core/tool/file/move_tool.py +0 -435
- klaude_code-2.0.1/src/klaude_code/core/tool/tool_context.py +0 -148
- klaude_code-2.0.1/src/klaude_code/core/tool/tool_registry.py +0 -78
- klaude_code-2.0.1/src/klaude_code/protocol/events.py +0 -194
- klaude_code-2.0.1/src/klaude_code/skill/assets/dev-docs/SKILL.md +0 -108
- klaude_code-2.0.1/src/klaude_code/trace/__init__.py +0 -21
- klaude_code-2.0.1/src/klaude_code/ui/__init__.py +0 -86
- klaude_code-2.0.1/src/klaude_code/ui/core/stage_manager.py +0 -48
- klaude_code-2.0.1/src/klaude_code/ui/modes/__init__.py +0 -1
- klaude_code-2.0.1/src/klaude_code/ui/modes/debug/__init__.py +0 -1
- klaude_code-2.0.1/src/klaude_code/ui/modes/exec/__init__.py +0 -1
- klaude_code-2.0.1/src/klaude_code/ui/modes/repl/display.py +0 -61
- klaude_code-2.0.1/src/klaude_code/ui/modes/repl/event_handler.py +0 -634
- klaude_code-2.0.1/src/klaude_code/ui/modes/repl/renderer.py +0 -463
- klaude_code-2.0.1/src/klaude_code/ui/renderers/developer.py +0 -215
- klaude_code-2.0.1/src/klaude_code/ui/utils/__init__.py +0 -1
- {klaude_code-2.0.1 → klaude_code-2.1.0}/README.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/base.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/claude/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/claude/exceptions.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/claude/oauth.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/claude/token_manager.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/codex/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/codex/exceptions.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/codex/oauth.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/auth/codex/token_manager.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/cli/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/config/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/config/assets/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/config/assets/builtin_config.yaml +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/config/builtin_config.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/config/thinking.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/manager/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/manager/llm_clients.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-codex.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-sub-agent-image-gen.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-sub-agent-web.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/_utils.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/diff_builder.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/read_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/file/write_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/shell/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/skill/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/skill/skill_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/todo/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/truncation.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/web/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/anthropic/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/anthropic/input.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/bedrock/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/claude/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/client.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/codex/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/google/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/google/input.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/image.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/input_common.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/openai_compatible/input.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/openai_compatible/stream.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/openrouter/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/openrouter/input.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/registry.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/responses/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/responses/input.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/llm/usage.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/trace → klaude_code-2.1.0/src/klaude_code}/log.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/commands.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/llm_param.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/op_handler.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/protocol/sub_agent/image_gen.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/session/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/session/codec.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/session/export.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/session/selector.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/session/store.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/session/templates/export_session.html +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/session/templates/mermaid_viewer.html +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/skill/__init__.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/skill/assets/deslop/SKILL.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/skill/assets/handoff/SKILL.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/skill/assets/jj-workspace/SKILL.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/skill/assets/skill-creator/SKILL.md +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/skill/manager.py +0 -0
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/__init__.py +0 -0
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/command_abc.py +0 -0
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/prompt-commit.md +0 -0
- {klaude_code-2.0.1/src/klaude_code → klaude_code-2.1.0/src/klaude_code/tui}/command/prompt-init.md +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/__init__.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui/renderers → klaude_code-2.1.0/src/klaude_code/tui/components}/mermaid_viewer.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui/components}/rich/__init__.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui/components}/rich/cjk_wrap.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui/components}/rich/code_panel.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui/components}/rich/live.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui/components}/rich/quote.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui/components}/rich/searchable_text.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui/modes/repl → klaude_code-2.1.0/src/klaude_code/tui/input}/clipboard.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui/modes/repl → klaude_code-2.1.0/src/klaude_code/tui/input}/key_bindings.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui}/terminal/__init__.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui}/terminal/image.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui → klaude_code-2.1.0/src/klaude_code/tui}/terminal/progress_bar.py +0 -0
- {klaude_code-2.0.1/src/klaude_code/ui/utils → klaude_code-2.1.0/src/klaude_code/ui}/common.py +0 -0
- {klaude_code-2.0.1 → klaude_code-2.1.0}/src/klaude_code/ui/core/__init__.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "klaude-code"
|
|
7
|
-
version = "2.0
|
|
7
|
+
version = "2.1.0"
|
|
8
8
|
description = "Minimal code agent CLI"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13"
|
|
@@ -83,7 +83,8 @@ name = "Layered architecture"
|
|
|
83
83
|
type = "layers"
|
|
84
84
|
layers = [
|
|
85
85
|
"klaude_code.cli",
|
|
86
|
-
"klaude_code.
|
|
86
|
+
"klaude_code.tui",
|
|
87
|
+
"klaude_code.app",
|
|
87
88
|
"klaude_code.ui",
|
|
88
89
|
"klaude_code.core",
|
|
89
90
|
"klaude_code.skill",
|
|
@@ -91,7 +92,7 @@ layers = [
|
|
|
91
92
|
"klaude_code.config",
|
|
92
93
|
"klaude_code.llm",
|
|
93
94
|
"klaude_code.protocol",
|
|
94
|
-
"klaude_code.trace",
|
|
95
95
|
"klaude_code.auth",
|
|
96
|
+
"klaude_code.log",
|
|
96
97
|
"klaude_code.const",
|
|
97
98
|
]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Application-layer runtime helpers.
|
|
2
|
+
|
|
3
|
+
This package coordinates core execution (Executor) with frontend displays.
|
|
4
|
+
Terminal-specific rendering and input handling live in `klaude_code.tui`.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .runtime import AppInitConfig, run_exec
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"AppInitConfig",
|
|
11
|
+
"run_exec",
|
|
12
|
+
]
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import contextlib
|
|
3
|
+
import sys
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
from klaude_code import ui
|
|
10
|
+
from klaude_code.config import Config, load_config
|
|
11
|
+
from klaude_code.core.agent import Agent
|
|
12
|
+
from klaude_code.core.agent_profile import DefaultModelProfileProvider, VanillaModelProfileProvider
|
|
13
|
+
from klaude_code.core.executor import Executor
|
|
14
|
+
from klaude_code.core.manager import build_llm_clients
|
|
15
|
+
from klaude_code.log import DebugType, log, set_debug_logging
|
|
16
|
+
from klaude_code.protocol import events, op
|
|
17
|
+
from klaude_code.protocol.message import UserInputPayload
|
|
18
|
+
from klaude_code.session.session import Session, close_default_store
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class AppInitConfig:
|
|
23
|
+
"""Configuration for initializing the application runtime."""
|
|
24
|
+
|
|
25
|
+
model: str | None
|
|
26
|
+
debug: bool
|
|
27
|
+
vanilla: bool
|
|
28
|
+
debug_filters: set[DebugType] | None = None
|
|
29
|
+
stream_json: bool = False
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class AppComponents:
|
|
34
|
+
"""Initialized runtime components."""
|
|
35
|
+
|
|
36
|
+
config: Config
|
|
37
|
+
executor: Executor
|
|
38
|
+
executor_task: asyncio.Task[None]
|
|
39
|
+
event_queue: asyncio.Queue[events.Event]
|
|
40
|
+
display: ui.DisplayABC
|
|
41
|
+
display_task: asyncio.Task[None]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
async def initialize_app_components(
|
|
45
|
+
*,
|
|
46
|
+
init_config: AppInitConfig,
|
|
47
|
+
display: ui.DisplayABC,
|
|
48
|
+
on_model_change: Callable[[str], None] | None = None,
|
|
49
|
+
) -> AppComponents:
|
|
50
|
+
"""Initialize LLM clients, executor, and display task."""
|
|
51
|
+
set_debug_logging(init_config.debug, filters=init_config.debug_filters)
|
|
52
|
+
|
|
53
|
+
config = load_config()
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
llm_clients = build_llm_clients(
|
|
57
|
+
config,
|
|
58
|
+
model_override=init_config.model,
|
|
59
|
+
)
|
|
60
|
+
except ValueError as exc:
|
|
61
|
+
if init_config.model:
|
|
62
|
+
log(
|
|
63
|
+
(
|
|
64
|
+
f"Error: model '{init_config.model}' is not defined in the config",
|
|
65
|
+
"red",
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
log(("Hint: run `klaude list` to view available models", "yellow"))
|
|
69
|
+
else:
|
|
70
|
+
log((f"Error: failed to load the default model configuration: {exc}", "red"))
|
|
71
|
+
raise typer.Exit(2) from None
|
|
72
|
+
|
|
73
|
+
model_profile_provider = VanillaModelProfileProvider() if init_config.vanilla else DefaultModelProfileProvider()
|
|
74
|
+
|
|
75
|
+
event_queue: asyncio.Queue[events.Event] = asyncio.Queue()
|
|
76
|
+
|
|
77
|
+
executor = Executor(
|
|
78
|
+
event_queue,
|
|
79
|
+
llm_clients,
|
|
80
|
+
model_profile_provider=model_profile_provider,
|
|
81
|
+
on_model_change=on_model_change,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
if on_model_change is not None:
|
|
85
|
+
on_model_change(llm_clients.main.model_name)
|
|
86
|
+
|
|
87
|
+
executor_task = asyncio.create_task(executor.start())
|
|
88
|
+
|
|
89
|
+
def _drain_background_task_exception(task: asyncio.Task[None], *, label: str) -> None:
|
|
90
|
+
def _on_done(t: asyncio.Task[None]) -> None:
|
|
91
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
92
|
+
exc = t.exception()
|
|
93
|
+
if exc is None:
|
|
94
|
+
return
|
|
95
|
+
if isinstance(exc, KeyboardInterrupt):
|
|
96
|
+
return
|
|
97
|
+
log((f"Background task '{label}' failed: {exc}", "red"))
|
|
98
|
+
|
|
99
|
+
task.add_done_callback(_on_done)
|
|
100
|
+
|
|
101
|
+
_drain_background_task_exception(executor_task, label="executor")
|
|
102
|
+
|
|
103
|
+
display_task = asyncio.create_task(display.consume_event_loop(event_queue))
|
|
104
|
+
_drain_background_task_exception(display_task, label="display")
|
|
105
|
+
|
|
106
|
+
return AppComponents(
|
|
107
|
+
config=config,
|
|
108
|
+
executor=executor,
|
|
109
|
+
executor_task=executor_task,
|
|
110
|
+
event_queue=event_queue,
|
|
111
|
+
display=display,
|
|
112
|
+
display_task=display_task,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
async def initialize_session(
|
|
117
|
+
executor: Executor,
|
|
118
|
+
event_queue: asyncio.Queue[events.Event],
|
|
119
|
+
session_id: str | None = None,
|
|
120
|
+
) -> str | None:
|
|
121
|
+
"""Initialize a session and return the active session id."""
|
|
122
|
+
await executor.submit_and_wait(op.InitAgentOperation(session_id=session_id))
|
|
123
|
+
await event_queue.join()
|
|
124
|
+
|
|
125
|
+
active_session_id = executor.context.current_session_id()
|
|
126
|
+
return active_session_id or session_id
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def backfill_session_model_config(
|
|
130
|
+
agent: Agent | None,
|
|
131
|
+
model_override: str | None,
|
|
132
|
+
default_model: str | None,
|
|
133
|
+
*,
|
|
134
|
+
is_new_session: bool,
|
|
135
|
+
) -> None:
|
|
136
|
+
"""Backfill model_config_name and model_thinking on newly created sessions."""
|
|
137
|
+
if agent is None or agent.session.model_config_name is not None:
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
if model_override is not None:
|
|
141
|
+
agent.session.model_config_name = model_override
|
|
142
|
+
elif is_new_session and default_model is not None:
|
|
143
|
+
agent.session.model_config_name = default_model
|
|
144
|
+
else:
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
if agent.session.model_thinking is None and agent.profile:
|
|
148
|
+
agent.session.model_thinking = agent.profile.llm_client.get_llm_config().thinking
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
async def cleanup_app_components(components: AppComponents) -> None:
|
|
152
|
+
"""Clean up all runtime components."""
|
|
153
|
+
try:
|
|
154
|
+
await components.executor.stop()
|
|
155
|
+
components.executor_task.cancel()
|
|
156
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
157
|
+
await components.executor_task
|
|
158
|
+
with contextlib.suppress(Exception):
|
|
159
|
+
await close_default_store()
|
|
160
|
+
|
|
161
|
+
await components.event_queue.put(events.EndEvent())
|
|
162
|
+
await components.display_task
|
|
163
|
+
finally:
|
|
164
|
+
# Ensure the terminal cursor is visible even if Rich's spinner did not stop cleanly.
|
|
165
|
+
with contextlib.suppress(Exception):
|
|
166
|
+
stream = getattr(sys, "__stdout__", None) or sys.stdout
|
|
167
|
+
stream.write("\033[?25h")
|
|
168
|
+
stream.flush()
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
async def handle_keyboard_interrupt(executor: Executor) -> None:
|
|
172
|
+
"""Handle Ctrl+C by logging and sending a global interrupt."""
|
|
173
|
+
log("Bye!")
|
|
174
|
+
session_id = executor.context.current_session_id()
|
|
175
|
+
if session_id and Session.exists(session_id):
|
|
176
|
+
log(("Resume with:", "dim"), (f"klaude --resume-by-id {session_id}", "green"))
|
|
177
|
+
with contextlib.suppress(Exception):
|
|
178
|
+
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)
|
|
@@ -6,8 +6,8 @@ import webbrowser
|
|
|
6
6
|
import typer
|
|
7
7
|
from prompt_toolkit.styles import Style
|
|
8
8
|
|
|
9
|
-
from klaude_code.
|
|
10
|
-
from klaude_code.
|
|
9
|
+
from klaude_code.log import log
|
|
10
|
+
from klaude_code.tui.terminal.selector import SelectItem, select_one
|
|
11
11
|
|
|
12
12
|
_SELECT_STYLE = Style(
|
|
13
13
|
[
|
|
@@ -7,7 +7,7 @@ import sys
|
|
|
7
7
|
import typer
|
|
8
8
|
|
|
9
9
|
from klaude_code.config import config_path, create_example_config, example_config_path, load_config
|
|
10
|
-
from klaude_code.
|
|
10
|
+
from klaude_code.log import log
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def list_models(
|
|
@@ -15,7 +15,7 @@ def list_models(
|
|
|
15
15
|
) -> None:
|
|
16
16
|
"""List all models and providers configuration"""
|
|
17
17
|
from klaude_code.cli.list_model import display_models_and_providers
|
|
18
|
-
from klaude_code.
|
|
18
|
+
from klaude_code.tui.terminal.color import is_light_terminal_background
|
|
19
19
|
|
|
20
20
|
config = load_config()
|
|
21
21
|
|
|
@@ -10,9 +10,9 @@ from rich.box import Box
|
|
|
10
10
|
from rich.console import Console
|
|
11
11
|
from rich.table import Table
|
|
12
12
|
|
|
13
|
-
from klaude_code.command.status_cmd import format_cost, format_tokens
|
|
14
13
|
from klaude_code.protocol import model
|
|
15
14
|
from klaude_code.session.codec import decode_jsonl_line
|
|
15
|
+
from klaude_code.tui.command.status_cmd import format_cost, format_tokens
|
|
16
16
|
|
|
17
17
|
ASCII_HORIZONAL = Box(" -- \n \n -- \n \n -- \n -- \n \n -- \n")
|
|
18
18
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Debug utilities for CLI."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from klaude_code.log import DebugType, log, prepare_debug_log_file
|
|
8
|
+
|
|
9
|
+
DEBUG_FILTER_HELP = "Comma-separated debug types: " + ", ".join(dt.value for dt in DebugType)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def parse_debug_filters(raw: str | None) -> set[DebugType] | None:
|
|
13
|
+
"""Parse comma-separated debug filter string into a set of DebugType."""
|
|
14
|
+
if raw is None:
|
|
15
|
+
return None
|
|
16
|
+
filters: set[DebugType] = set()
|
|
17
|
+
for chunk in raw.split(","):
|
|
18
|
+
normalized = chunk.strip().lower().replace("-", "_")
|
|
19
|
+
if not normalized:
|
|
20
|
+
continue
|
|
21
|
+
try:
|
|
22
|
+
filters.add(DebugType(normalized))
|
|
23
|
+
except ValueError: # pragma: no cover - user input validation
|
|
24
|
+
valid_options = ", ".join(dt.value for dt in DebugType)
|
|
25
|
+
log(
|
|
26
|
+
(
|
|
27
|
+
f"Invalid debug filter '{normalized}'. Valid options: {valid_options}",
|
|
28
|
+
"red",
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
raise typer.Exit(2) from None
|
|
32
|
+
return filters or None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def resolve_debug_settings(flag: bool, raw_filters: str | None) -> tuple[bool, set[DebugType] | None]:
|
|
36
|
+
"""Resolve debug flag and filters into effective settings."""
|
|
37
|
+
filters = parse_debug_filters(raw_filters)
|
|
38
|
+
effective_flag = flag or (filters is not None)
|
|
39
|
+
return effective_flag, filters
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def prepare_debug_logging(debug: bool, debug_filter: str | None) -> tuple[bool, set[DebugType] | None, Path | None]:
|
|
43
|
+
"""Resolve debug settings and prepare log file if enabled.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
A tuple of (debug_enabled, debug_filters, log_path).
|
|
47
|
+
log_path is None if debugging is disabled.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
debug_enabled, debug_filters = resolve_debug_settings(debug, debug_filter)
|
|
51
|
+
log_path: Path | None = None
|
|
52
|
+
if debug_enabled:
|
|
53
|
+
log_path = prepare_debug_log_file()
|
|
54
|
+
return debug_enabled, debug_filters, log_path
|
|
@@ -9,9 +9,9 @@ from klaude_code.config import Config
|
|
|
9
9
|
from klaude_code.config.config import ModelConfig, ProviderConfig, parse_env_var_syntax
|
|
10
10
|
from klaude_code.protocol.llm_param import LLMClientProtocol
|
|
11
11
|
from klaude_code.protocol.sub_agent import iter_sub_agent_profiles
|
|
12
|
-
from klaude_code.
|
|
13
|
-
from klaude_code.
|
|
14
|
-
from klaude_code.ui.
|
|
12
|
+
from klaude_code.tui.components.rich.quote import Quote
|
|
13
|
+
from klaude_code.tui.components.rich.theme import ThemeKey, get_theme
|
|
14
|
+
from klaude_code.ui.common import format_model_params
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def _get_codex_status_rows() -> list[tuple[Text, Text]]:
|
|
@@ -1,62 +1,17 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
import contextlib
|
|
3
|
-
import os
|
|
4
2
|
import sys
|
|
5
|
-
from pathlib import Path
|
|
6
3
|
|
|
7
4
|
import typer
|
|
8
5
|
|
|
9
6
|
from klaude_code.cli.auth_cmd import register_auth_commands
|
|
10
7
|
from klaude_code.cli.config_cmd import register_config_commands
|
|
11
8
|
from klaude_code.cli.cost_cmd import register_cost_commands
|
|
12
|
-
from klaude_code.cli.debug import DEBUG_FILTER_HELP,
|
|
9
|
+
from klaude_code.cli.debug import DEBUG_FILTER_HELP, prepare_debug_logging
|
|
13
10
|
from klaude_code.cli.self_update import register_self_update_commands, version_option_callback
|
|
14
11
|
from klaude_code.cli.session_cmd import register_session_commands
|
|
15
|
-
from klaude_code.command.resume_cmd import select_session_sync
|
|
16
12
|
from klaude_code.session import Session
|
|
17
|
-
from klaude_code.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def set_terminal_title(title: str) -> None:
|
|
21
|
-
"""Set terminal window title using ANSI escape sequence."""
|
|
22
|
-
# Never write terminal control sequences when stdout is not a TTY (pipes/CI/redirects).
|
|
23
|
-
# This avoids corrupting machine-readable output (e.g., JSON streaming) and log captures.
|
|
24
|
-
#
|
|
25
|
-
# Use the original stdout to bypass prompt_toolkit's `patch_stdout()`. Writing OSC
|
|
26
|
-
# sequences to the patched stdout can cause them to appear as visible text.
|
|
27
|
-
stream = getattr(sys, "__stdout__", None) or sys.stdout
|
|
28
|
-
try:
|
|
29
|
-
if not stream.isatty():
|
|
30
|
-
return
|
|
31
|
-
except Exception:
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
stream.write(f"\033]0;{title}\007")
|
|
35
|
-
with contextlib.suppress(Exception):
|
|
36
|
-
stream.flush()
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def update_terminal_title(model_name: str | None = None) -> None:
|
|
40
|
-
"""Update terminal title with folder name and optional model name."""
|
|
41
|
-
folder_name = os.path.basename(os.getcwd())
|
|
42
|
-
if model_name:
|
|
43
|
-
set_terminal_title(f"{folder_name}: klaude ✳ {model_name}")
|
|
44
|
-
else:
|
|
45
|
-
set_terminal_title(f"{folder_name}: klaude")
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def prepare_debug_logging(debug: bool, debug_filter: str | None) -> tuple[bool, set[DebugType] | None, Path | None]:
|
|
49
|
-
"""Resolve debug settings and prepare log file if debugging is enabled.
|
|
50
|
-
|
|
51
|
-
Returns:
|
|
52
|
-
A tuple of (debug_enabled, debug_filters, log_path).
|
|
53
|
-
log_path is None if debugging is disabled.
|
|
54
|
-
"""
|
|
55
|
-
debug_enabled, debug_filters = resolve_debug_settings(debug, debug_filter)
|
|
56
|
-
log_path: Path | None = None
|
|
57
|
-
if debug_enabled:
|
|
58
|
-
log_path = prepare_debug_log_file()
|
|
59
|
-
return debug_enabled, debug_filters, log_path
|
|
13
|
+
from klaude_code.tui.command.resume_cmd import select_session_sync
|
|
14
|
+
from klaude_code.ui.terminal.title import update_terminal_title
|
|
60
15
|
|
|
61
16
|
|
|
62
17
|
def read_input_content(cli_argument: str) -> str | None:
|
|
@@ -68,7 +23,7 @@ def read_input_content(cli_argument: str) -> str | None:
|
|
|
68
23
|
Returns:
|
|
69
24
|
The merged input content, or None if no input was provided.
|
|
70
25
|
"""
|
|
71
|
-
from klaude_code.
|
|
26
|
+
from klaude_code.log import log
|
|
72
27
|
|
|
73
28
|
parts: list[str] = []
|
|
74
29
|
|
|
@@ -169,9 +124,9 @@ def exec_command(
|
|
|
169
124
|
if merged_input is None:
|
|
170
125
|
raise typer.Exit(1)
|
|
171
126
|
|
|
172
|
-
from klaude_code.
|
|
173
|
-
from klaude_code.command.model_select import select_model_interactive
|
|
127
|
+
from klaude_code.app.runtime import AppInitConfig, run_exec
|
|
174
128
|
from klaude_code.config import load_config
|
|
129
|
+
from klaude_code.tui.command.model_select import select_model_interactive
|
|
175
130
|
|
|
176
131
|
chosen_model = model
|
|
177
132
|
if model or select_model:
|
|
@@ -188,7 +143,7 @@ def exec_command(
|
|
|
188
143
|
# Save the selection as default
|
|
189
144
|
config.main_model = chosen_model
|
|
190
145
|
from klaude_code.config.config import config_path
|
|
191
|
-
from klaude_code.
|
|
146
|
+
from klaude_code.log import log
|
|
192
147
|
|
|
193
148
|
asyncio.run(config.save())
|
|
194
149
|
log(f"Saved main_model={chosen_model} to {config_path}", style="cyan")
|
|
@@ -199,13 +154,14 @@ def exec_command(
|
|
|
199
154
|
model=chosen_model,
|
|
200
155
|
debug=debug_enabled,
|
|
201
156
|
vanilla=vanilla,
|
|
202
|
-
is_exec_mode=True,
|
|
203
157
|
debug_filters=debug_filters,
|
|
204
158
|
stream_json=stream_json,
|
|
205
159
|
)
|
|
206
160
|
|
|
207
161
|
if log_path:
|
|
208
|
-
|
|
162
|
+
from klaude_code.log import log
|
|
163
|
+
|
|
164
|
+
log(f"Debug log: {log_path}", style="dim")
|
|
209
165
|
|
|
210
166
|
asyncio.run(
|
|
211
167
|
run_exec(
|
|
@@ -269,7 +225,7 @@ def main_callback(
|
|
|
269
225
|
) -> None:
|
|
270
226
|
# Only run interactive mode when no subcommand is invoked
|
|
271
227
|
if ctx.invoked_subcommand is None:
|
|
272
|
-
from klaude_code.
|
|
228
|
+
from klaude_code.log import log
|
|
273
229
|
|
|
274
230
|
resume_by_id_value = resume_by_id.strip() if resume_by_id is not None else None
|
|
275
231
|
if resume_by_id_value == "":
|
|
@@ -304,8 +260,9 @@ def main_callback(
|
|
|
304
260
|
)
|
|
305
261
|
return
|
|
306
262
|
|
|
307
|
-
from klaude_code.
|
|
308
|
-
from klaude_code.command.model_select import select_model_interactive
|
|
263
|
+
from klaude_code.app.runtime import AppInitConfig
|
|
264
|
+
from klaude_code.tui.command.model_select import select_model_interactive
|
|
265
|
+
from klaude_code.tui.runner import run_interactive
|
|
309
266
|
|
|
310
267
|
update_terminal_title()
|
|
311
268
|
|
|
@@ -333,7 +290,7 @@ def main_callback(
|
|
|
333
290
|
|
|
334
291
|
if session_id is not None and chosen_model is None:
|
|
335
292
|
from klaude_code.config import load_config
|
|
336
|
-
from klaude_code.
|
|
293
|
+
from klaude_code.log import log
|
|
337
294
|
|
|
338
295
|
session_meta = Session.load_meta(session_id)
|
|
339
296
|
cfg = load_config()
|
|
@@ -372,7 +329,7 @@ def main_callback(
|
|
|
372
329
|
# Save the selection as default
|
|
373
330
|
cfg.main_model = chosen_model
|
|
374
331
|
from klaude_code.config.config import config_path
|
|
375
|
-
from klaude_code.
|
|
332
|
+
from klaude_code.log import log
|
|
376
333
|
|
|
377
334
|
asyncio.run(cfg.save())
|
|
378
335
|
log(f"Saved main_model={chosen_model} to {config_path}", style="dim")
|
|
@@ -387,7 +344,7 @@ def main_callback(
|
|
|
387
344
|
)
|
|
388
345
|
|
|
389
346
|
if log_path:
|
|
390
|
-
|
|
347
|
+
log(f"Debug log: {log_path}", style="dim")
|
|
391
348
|
|
|
392
349
|
asyncio.run(
|
|
393
350
|
run_interactive(
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Self-update and version utilities for klaude-code."""
|
|
2
|
+
|
|
3
|
+
import shutil
|
|
4
|
+
import subprocess
|
|
5
|
+
from importlib.metadata import PackageNotFoundError
|
|
6
|
+
from importlib.metadata import version as pkg_version
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
|
|
10
|
+
from klaude_code.log import log
|
|
11
|
+
from klaude_code.update import PACKAGE_NAME, check_for_updates_blocking
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _print_version() -> None:
|
|
15
|
+
try:
|
|
16
|
+
ver = pkg_version(PACKAGE_NAME)
|
|
17
|
+
except PackageNotFoundError:
|
|
18
|
+
ver = "unknown"
|
|
19
|
+
except (ValueError, TypeError):
|
|
20
|
+
# Catch invalid package name format or type errors
|
|
21
|
+
ver = "unknown"
|
|
22
|
+
print(f"{PACKAGE_NAME} {ver}")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def version_option_callback(value: bool) -> None:
|
|
26
|
+
"""Show version and exit."""
|
|
27
|
+
if value:
|
|
28
|
+
_print_version()
|
|
29
|
+
raise typer.Exit(0)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def version_command() -> None:
|
|
33
|
+
"""Show version and exit."""
|
|
34
|
+
|
|
35
|
+
_print_version()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def update_command(
|
|
39
|
+
check: bool = typer.Option(
|
|
40
|
+
False,
|
|
41
|
+
"--check",
|
|
42
|
+
help="Check for updates and exit without upgrading",
|
|
43
|
+
),
|
|
44
|
+
) -> None:
|
|
45
|
+
"""Upgrade klaude-code when installed via `uv tool`."""
|
|
46
|
+
|
|
47
|
+
info = check_for_updates_blocking()
|
|
48
|
+
|
|
49
|
+
if check:
|
|
50
|
+
if info is None:
|
|
51
|
+
log(("Error: `uv` is not available; cannot check for updates.", "red"))
|
|
52
|
+
log(f"Install uv, then run `uv tool upgrade {PACKAGE_NAME}`.")
|
|
53
|
+
raise typer.Exit(1)
|
|
54
|
+
|
|
55
|
+
installed_display = info.installed or "unknown"
|
|
56
|
+
latest_display = info.latest or "unknown"
|
|
57
|
+
status = "update available" if info.update_available else "up to date"
|
|
58
|
+
|
|
59
|
+
log(f"{PACKAGE_NAME} installed: {installed_display}")
|
|
60
|
+
log(f"{PACKAGE_NAME} latest: {latest_display}")
|
|
61
|
+
log(f"Status: {status}")
|
|
62
|
+
|
|
63
|
+
if info.update_available:
|
|
64
|
+
log("Run `klaude upgrade` to upgrade.")
|
|
65
|
+
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
if shutil.which("uv") is None:
|
|
69
|
+
log(("Error: `uv` not found in PATH.", "red"))
|
|
70
|
+
log(f"To update, install uv and run `uv tool upgrade {PACKAGE_NAME}`.")
|
|
71
|
+
raise typer.Exit(1)
|
|
72
|
+
|
|
73
|
+
log(f"Running `uv tool upgrade {PACKAGE_NAME}`…")
|
|
74
|
+
result = subprocess.run(["uv", "tool", "upgrade", PACKAGE_NAME], check=False)
|
|
75
|
+
if result.returncode != 0:
|
|
76
|
+
log((f"Error: update failed (exit code {result.returncode}).", "red"))
|
|
77
|
+
raise typer.Exit(result.returncode or 1)
|
|
78
|
+
|
|
79
|
+
log("Update complete. Please re-run `klaude` to use the new version.")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def register_self_update_commands(app: typer.Typer) -> None:
|
|
83
|
+
"""Register self-update and version subcommands to the given Typer app."""
|
|
84
|
+
|
|
85
|
+
app.command("update")(update_command)
|
|
86
|
+
app.command("upgrade", help="Alias for `klaude update`.")(update_command)
|
|
87
|
+
app.command("version", help="Alias for `klaude --version`.")(version_command)
|
|
@@ -2,8 +2,8 @@ import time
|
|
|
2
2
|
|
|
3
3
|
import typer
|
|
4
4
|
|
|
5
|
+
from klaude_code.log import log
|
|
5
6
|
from klaude_code.session import Session
|
|
6
|
-
from klaude_code.trace import log
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def _session_confirm(sessions: list[Session.SessionMetaBrief], message: str) -> bool:
|
|
@@ -11,7 +11,7 @@ def _session_confirm(sessions: list[Session.SessionMetaBrief], message: str) ->
|
|
|
11
11
|
|
|
12
12
|
from prompt_toolkit.styles import Style
|
|
13
13
|
|
|
14
|
-
from klaude_code.
|
|
14
|
+
from klaude_code.tui.terminal.selector import SelectItem, select_one
|
|
15
15
|
|
|
16
16
|
def _fmt(ts: float) -> str:
|
|
17
17
|
try:
|
|
@@ -13,9 +13,9 @@ from klaude_code.config.builtin_config import (
|
|
|
13
13
|
get_builtin_provider_configs,
|
|
14
14
|
get_builtin_sub_agent_models,
|
|
15
15
|
)
|
|
16
|
+
from klaude_code.log import log
|
|
16
17
|
from klaude_code.protocol import llm_param
|
|
17
18
|
from klaude_code.protocol.sub_agent import iter_sub_agent_profiles
|
|
18
|
-
from klaude_code.trace import log
|
|
19
19
|
|
|
20
20
|
# Pattern to match ${ENV_VAR} syntax
|
|
21
21
|
_ENV_VAR_PATTERN = re.compile(r"^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$")
|