klaude-code 1.2.17__tar.gz → 1.2.19__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-1.2.17 → klaude_code-1.2.19}/PKG-INFO +32 -7
- {klaude_code-1.2.17 → klaude_code-1.2.19}/README.md +31 -6
- {klaude_code-1.2.17 → klaude_code-1.2.19}/pyproject.toml +5 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/cli/config_cmd.py +1 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/cli/debug.py +1 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/cli/main.py +45 -31
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/cli/runtime.py +49 -13
- klaude_code-1.2.17/src/klaude_code/version.py → klaude_code-1.2.19/src/klaude_code/cli/self_update.py +110 -2
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/__init__.py +4 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/clear_cmd.py +2 -7
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/command_abc.py +33 -5
- klaude_code-1.2.19/src/klaude_code/command/debug_cmd.py +79 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/diff_cmd.py +2 -6
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/export_cmd.py +7 -7
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/export_online_cmd.py +9 -8
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/help_cmd.py +4 -9
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/model_cmd.py +10 -6
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/prompt_command.py +2 -6
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/refresh_cmd.py +2 -7
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/registry.py +69 -26
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/release_notes_cmd.py +2 -6
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/status_cmd.py +2 -7
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/terminal_setup_cmd.py +2 -6
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/thinking_cmd.py +16 -10
- klaude_code-1.2.19/src/klaude_code/config/select_model.py +133 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/const/__init__.py +1 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/executor.py +257 -110
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/manager/__init__.py +2 -4
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompts/prompt-claude-code.md +1 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +14 -2
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompts/prompt-sub-agent-web.md +8 -5
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/reminders.py +9 -35
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/task.py +9 -7
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/read_tool.md +1 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/read_tool.py +41 -12
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/memory/skill_loader.py +12 -10
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/shell/bash_tool.py +22 -2
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/tool_registry.py +1 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/tool_runner.py +26 -23
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/truncation.py +23 -9
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/web/web_fetch_tool.md +1 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/web/web_fetch_tool.py +36 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/turn.py +28 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/anthropic/client.py +25 -9
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/openai_compatible/client.py +5 -2
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/openrouter/client.py +7 -3
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/responses/client.py +6 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/commands.py +1 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/sub_agent/web.py +3 -2
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/session/session.py +35 -15
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/session/templates/export_session.html +45 -32
- klaude_code-1.2.19/src/klaude_code/trace/__init__.py +21 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/repl/completers.py +231 -73
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/repl/event_handler.py +8 -6
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/repl/input_prompt_toolkit.py +1 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/repl/renderer.py +2 -2
- klaude_code-1.2.19/src/klaude_code/ui/renderers/common.py +62 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/renderers/developer.py +2 -3
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/renderers/errors.py +1 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/renderers/metadata.py +12 -5
- klaude_code-1.2.19/src/klaude_code/ui/renderers/thinking.py +55 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/renderers/tools.py +82 -14
- klaude_code-1.2.19/src/klaude_code/ui/rich/code_panel.py +112 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/rich/markdown.py +3 -4
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/rich/status.py +0 -2
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/rich/theme.py +10 -1
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/utils/common.py +0 -18
- klaude_code-1.2.17/src/klaude_code/config/select_model.py +0 -57
- klaude_code-1.2.17/src/klaude_code/core/manager/agent_manager.py +0 -132
- klaude_code-1.2.17/src/klaude_code/trace/__init__.py +0 -3
- klaude_code-1.2.17/src/klaude_code/ui/renderers/common.py +0 -8
- klaude_code-1.2.17/src/klaude_code/ui/renderers/thinking.py +0 -39
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/auth/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/auth/codex/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/auth/codex/exceptions.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/auth/codex/oauth.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/auth/codex/token_manager.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/cli/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/cli/auth_cmd.py +0 -0
- {klaude_code-1.2.17/src/klaude_code/config → klaude_code-1.2.19/src/klaude_code/cli}/list_model.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/cli/session_cmd.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/prompt-deslop.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/prompt-dev-docs-update.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/prompt-dev-docs.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/prompt-handoff.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/command/prompt-init.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/config/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/config/config.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/agent.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/manager/llm_clients.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/manager/llm_clients_builder.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/manager/sub_agent_manager.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompt.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompts/prompt-sub-agent-oracle.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/_utils.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/multi_edit_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/multi_edit_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/write_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/file/write_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/memory/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/memory/memory_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/memory/memory_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/memory/skill_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/memory/skill_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/report_back_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/shell/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/sub_agent_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/todo/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/tool_abc.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/tool_context.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/web/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/core/tool/web/web_search_tool.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/anthropic/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/anthropic/input.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/client.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/codex/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/codex/client.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/input_common.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/openai_compatible/input.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/openai_compatible/stream_processor.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/openrouter/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/openrouter/input.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/openrouter/reasoning_handler.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/registry.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/responses/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/responses/input.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/llm/usage.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/events.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/llm_param.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/model.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/op.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/op_handler.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/sub_agent/explore.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/sub_agent/oracle.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/sub_agent/task.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/protocol/tools.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/session/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/session/export.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/session/selector.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/trace/log.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/core/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/core/display.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/core/input.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/core/stage_manager.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/debug/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/debug/display.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/exec/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/exec/display.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/repl/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/repl/clipboard.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/repl/display.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/modes/repl/key_bindings.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/renderers/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/renderers/assistant.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/renderers/diffs.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/renderers/sub_agent.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/renderers/user_input.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/rich/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/rich/live.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/rich/quote.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/rich/searchable_text.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/terminal/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/terminal/color.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/terminal/control.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/terminal/notifier.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/terminal/progress_bar.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/utils/__init__.py +0 -0
- {klaude_code-1.2.17 → klaude_code-1.2.19}/src/klaude_code/ui/utils/debouncer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: klaude-code
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.19
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Requires-Dist: anthropic>=0.66.0
|
|
6
6
|
Requires-Dist: ddgs>=9.9.3
|
|
@@ -41,6 +41,21 @@ To update:
|
|
|
41
41
|
uv tool upgrade klaude-code
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
Or use the built-in alias command:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
klaude update
|
|
48
|
+
klaude upgrade
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
To show version:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
klaude --version
|
|
55
|
+
klaude -v
|
|
56
|
+
klaude version
|
|
57
|
+
```
|
|
58
|
+
|
|
44
59
|
## Usage
|
|
45
60
|
|
|
46
61
|
### Interactive Mode
|
|
@@ -50,13 +65,18 @@ klaude [--model <name>] [--select-model]
|
|
|
50
65
|
```
|
|
51
66
|
|
|
52
67
|
**Options:**
|
|
53
|
-
- `--version`/`-V`: Show version and exit.
|
|
54
|
-
- `--model`/`-m`:
|
|
55
|
-
- `--select-model`/`-s`:
|
|
68
|
+
- `--version`/`-V`/`-v`: Show version and exit.
|
|
69
|
+
- `--model`/`-m`: Preferred model name (exact match picks immediately; otherwise opens the interactive selector filtered by this value).
|
|
70
|
+
- `--select-model`/`-s`: Open the interactive model selector at startup (shows all models unless `--model` is also provided).
|
|
56
71
|
- `--continue`/`-c`: Resume the most recent session.
|
|
57
72
|
- `--resume`/`-r`: Select a session to resume for this project.
|
|
58
73
|
- `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit) and no system prompts.
|
|
59
74
|
|
|
75
|
+
**Model selection behavior:**
|
|
76
|
+
- Default: uses `main_model` from config.
|
|
77
|
+
- `--select-model`: always prompts you to pick.
|
|
78
|
+
- `--model <value>`: tries to resolve `<value>` to a single model; if it can't, it prompts with a filtered list (and falls back to showing all models if there are no matches).
|
|
79
|
+
|
|
60
80
|
**Debug Options:**
|
|
61
81
|
- `--debug`/`-d`: Enable debug mode with verbose logging and LLM trace.
|
|
62
82
|
- `--debug-filter`: Filter debug output by type (comma-separated).
|
|
@@ -64,7 +84,7 @@ klaude [--model <name>] [--select-model]
|
|
|
64
84
|
|
|
65
85
|
### Configuration
|
|
66
86
|
|
|
67
|
-
An example config will be created in `~/.klaude/config.yaml` when first run.
|
|
87
|
+
An example config will be created in `~/.klaude/klaude-config.yaml` when first run.
|
|
68
88
|
|
|
69
89
|
Open the configuration file in editor:
|
|
70
90
|
|
|
@@ -201,7 +221,7 @@ sub_agent_models:
|
|
|
201
221
|
oracle: gpt-5.1
|
|
202
222
|
explore: haiku
|
|
203
223
|
task: opus
|
|
204
|
-
|
|
224
|
+
webagent: haiku
|
|
205
225
|
|
|
206
226
|
```
|
|
207
227
|
|
|
@@ -263,5 +283,10 @@ klaude exec "what is 2+2?"
|
|
|
263
283
|
echo "hello world" | klaude exec
|
|
264
284
|
|
|
265
285
|
# With model selection
|
|
286
|
+
|
|
287
|
+
# Exact model name (non-interactive)
|
|
266
288
|
echo "generate quicksort in python" | klaude exec --model gpt-5.1
|
|
267
|
-
|
|
289
|
+
|
|
290
|
+
# Partial/ambiguous name opens the interactive selector (filtered)
|
|
291
|
+
echo "generate quicksort in python" | klaude exec --model gpt
|
|
292
|
+
```
|
|
@@ -23,6 +23,21 @@ To update:
|
|
|
23
23
|
uv tool upgrade klaude-code
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
+
Or use the built-in alias command:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
klaude update
|
|
30
|
+
klaude upgrade
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
To show version:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
klaude --version
|
|
37
|
+
klaude -v
|
|
38
|
+
klaude version
|
|
39
|
+
```
|
|
40
|
+
|
|
26
41
|
## Usage
|
|
27
42
|
|
|
28
43
|
### Interactive Mode
|
|
@@ -32,13 +47,18 @@ klaude [--model <name>] [--select-model]
|
|
|
32
47
|
```
|
|
33
48
|
|
|
34
49
|
**Options:**
|
|
35
|
-
- `--version`/`-V`: Show version and exit.
|
|
36
|
-
- `--model`/`-m`:
|
|
37
|
-
- `--select-model`/`-s`:
|
|
50
|
+
- `--version`/`-V`/`-v`: Show version and exit.
|
|
51
|
+
- `--model`/`-m`: Preferred model name (exact match picks immediately; otherwise opens the interactive selector filtered by this value).
|
|
52
|
+
- `--select-model`/`-s`: Open the interactive model selector at startup (shows all models unless `--model` is also provided).
|
|
38
53
|
- `--continue`/`-c`: Resume the most recent session.
|
|
39
54
|
- `--resume`/`-r`: Select a session to resume for this project.
|
|
40
55
|
- `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit) and no system prompts.
|
|
41
56
|
|
|
57
|
+
**Model selection behavior:**
|
|
58
|
+
- Default: uses `main_model` from config.
|
|
59
|
+
- `--select-model`: always prompts you to pick.
|
|
60
|
+
- `--model <value>`: tries to resolve `<value>` to a single model; if it can't, it prompts with a filtered list (and falls back to showing all models if there are no matches).
|
|
61
|
+
|
|
42
62
|
**Debug Options:**
|
|
43
63
|
- `--debug`/`-d`: Enable debug mode with verbose logging and LLM trace.
|
|
44
64
|
- `--debug-filter`: Filter debug output by type (comma-separated).
|
|
@@ -46,7 +66,7 @@ klaude [--model <name>] [--select-model]
|
|
|
46
66
|
|
|
47
67
|
### Configuration
|
|
48
68
|
|
|
49
|
-
An example config will be created in `~/.klaude/config.yaml` when first run.
|
|
69
|
+
An example config will be created in `~/.klaude/klaude-config.yaml` when first run.
|
|
50
70
|
|
|
51
71
|
Open the configuration file in editor:
|
|
52
72
|
|
|
@@ -183,7 +203,7 @@ sub_agent_models:
|
|
|
183
203
|
oracle: gpt-5.1
|
|
184
204
|
explore: haiku
|
|
185
205
|
task: opus
|
|
186
|
-
|
|
206
|
+
webagent: haiku
|
|
187
207
|
|
|
188
208
|
```
|
|
189
209
|
|
|
@@ -245,5 +265,10 @@ klaude exec "what is 2+2?"
|
|
|
245
265
|
echo "hello world" | klaude exec
|
|
246
266
|
|
|
247
267
|
# With model selection
|
|
268
|
+
|
|
269
|
+
# Exact model name (non-interactive)
|
|
248
270
|
echo "generate quicksort in python" | klaude exec --model gpt-5.1
|
|
249
|
-
|
|
271
|
+
|
|
272
|
+
# Partial/ambiguous name opens the interactive selector (filtered)
|
|
273
|
+
echo "generate quicksort in python" | klaude exec --model gpt
|
|
274
|
+
```
|
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "klaude-code"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.19"
|
|
8
8
|
description = "Add your description here"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13"
|
|
@@ -77,10 +77,14 @@ name = "Layered architecture"
|
|
|
77
77
|
type = "layers"
|
|
78
78
|
layers = [
|
|
79
79
|
"klaude_code.cli",
|
|
80
|
+
"klaude_code.ui",
|
|
80
81
|
"klaude_code.core",
|
|
82
|
+
"klaude_code.command",
|
|
81
83
|
"klaude_code.session",
|
|
82
84
|
"klaude_code.config",
|
|
83
85
|
"klaude_code.llm",
|
|
84
86
|
"klaude_code.protocol",
|
|
87
|
+
"klaude_code.trace",
|
|
88
|
+
"klaude_code.auth",
|
|
85
89
|
"klaude_code.const",
|
|
86
90
|
]
|
|
@@ -12,7 +12,7 @@ from klaude_code.trace import log
|
|
|
12
12
|
|
|
13
13
|
def list_models() -> None:
|
|
14
14
|
"""List all models and providers configuration"""
|
|
15
|
-
from klaude_code.
|
|
15
|
+
from klaude_code.cli.list_model import display_models_and_providers
|
|
16
16
|
from klaude_code.ui.terminal.color import is_light_terminal_background
|
|
17
17
|
|
|
18
18
|
config = load_config()
|
|
@@ -48,7 +48,7 @@ def open_log_file_in_editor(path: Path) -> None:
|
|
|
48
48
|
editor = os.environ.get("EDITOR")
|
|
49
49
|
|
|
50
50
|
if not editor:
|
|
51
|
-
for cmd in ["open", "xdg-open", "code", "
|
|
51
|
+
for cmd in ["open", "xdg-open", "code", "TextEdit", "notepad"]:
|
|
52
52
|
try:
|
|
53
53
|
subprocess.run(["which", cmd], check=True, capture_output=True)
|
|
54
54
|
editor = cmd
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import os
|
|
3
3
|
import sys
|
|
4
|
-
from importlib.metadata import PackageNotFoundError
|
|
5
|
-
from importlib.metadata import version as pkg_version
|
|
6
4
|
from pathlib import Path
|
|
7
5
|
|
|
8
6
|
import typer
|
|
@@ -10,8 +8,8 @@ import typer
|
|
|
10
8
|
from klaude_code.cli.auth_cmd import register_auth_commands
|
|
11
9
|
from klaude_code.cli.config_cmd import register_config_commands
|
|
12
10
|
from klaude_code.cli.debug import DEBUG_FILTER_HELP, open_log_file_in_editor, resolve_debug_settings
|
|
11
|
+
from klaude_code.cli.self_update import register_self_update_commands, version_option_callback
|
|
13
12
|
from klaude_code.cli.session_cmd import register_session_commands
|
|
14
|
-
from klaude_code.config import load_config
|
|
15
13
|
from klaude_code.session import Session, resume_select_session
|
|
16
14
|
from klaude_code.trace import DebugType, prepare_debug_log_file
|
|
17
15
|
|
|
@@ -22,10 +20,13 @@ def set_terminal_title(title: str) -> None:
|
|
|
22
20
|
sys.stdout.flush()
|
|
23
21
|
|
|
24
22
|
|
|
25
|
-
def
|
|
26
|
-
"""
|
|
23
|
+
def update_terminal_title(model_name: str | None = None) -> None:
|
|
24
|
+
"""Update terminal title with folder name and optional model name."""
|
|
27
25
|
folder_name = os.path.basename(os.getcwd())
|
|
28
|
-
|
|
26
|
+
if model_name:
|
|
27
|
+
set_terminal_title(f"{folder_name}: klaude ✳ {model_name}")
|
|
28
|
+
else:
|
|
29
|
+
set_terminal_title(f"{folder_name}: klaude")
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
def prepare_debug_logging(debug: bool, debug_filter: str | None) -> tuple[bool, set[DebugType] | None, Path | None]:
|
|
@@ -79,20 +80,6 @@ def read_input_content(cli_argument: str) -> str | None:
|
|
|
79
80
|
return content
|
|
80
81
|
|
|
81
82
|
|
|
82
|
-
def _version_callback(value: bool) -> None:
|
|
83
|
-
"""Show version and exit."""
|
|
84
|
-
if value:
|
|
85
|
-
try:
|
|
86
|
-
ver = pkg_version("klaude-code")
|
|
87
|
-
except PackageNotFoundError:
|
|
88
|
-
# Package is not installed or has no metadata; show a generic version string.
|
|
89
|
-
ver = "unknown"
|
|
90
|
-
except Exception:
|
|
91
|
-
ver = "unknown"
|
|
92
|
-
print(f"klaude-code {ver}")
|
|
93
|
-
raise typer.Exit(0)
|
|
94
|
-
|
|
95
|
-
|
|
96
83
|
app = typer.Typer(
|
|
97
84
|
add_completion=False,
|
|
98
85
|
pretty_exceptions_enable=False,
|
|
@@ -104,6 +91,8 @@ register_session_commands(app)
|
|
|
104
91
|
register_auth_commands(app)
|
|
105
92
|
register_config_commands(app)
|
|
106
93
|
|
|
94
|
+
register_self_update_commands(app)
|
|
95
|
+
|
|
107
96
|
|
|
108
97
|
@app.command("exec")
|
|
109
98
|
def exec_command(
|
|
@@ -147,7 +136,7 @@ def exec_command(
|
|
|
147
136
|
),
|
|
148
137
|
) -> None:
|
|
149
138
|
"""Execute non-interactively with provided input."""
|
|
150
|
-
|
|
139
|
+
update_terminal_title()
|
|
151
140
|
|
|
152
141
|
merged_input = read_input_content(input_content)
|
|
153
142
|
if merged_input is None:
|
|
@@ -157,13 +146,8 @@ def exec_command(
|
|
|
157
146
|
from klaude_code.config.select_model import select_model_from_config
|
|
158
147
|
|
|
159
148
|
chosen_model = model
|
|
160
|
-
if select_model:
|
|
161
|
-
|
|
162
|
-
config = load_config()
|
|
163
|
-
if config is None:
|
|
164
|
-
raise typer.Exit(1)
|
|
165
|
-
default_name = model or config.main_model
|
|
166
|
-
chosen_model = select_model_from_config(preferred=default_name)
|
|
149
|
+
if model or select_model:
|
|
150
|
+
chosen_model = select_model_from_config(preferred=model)
|
|
167
151
|
if chosen_model is None:
|
|
168
152
|
return
|
|
169
153
|
|
|
@@ -196,8 +180,9 @@ def main_callback(
|
|
|
196
180
|
False,
|
|
197
181
|
"--version",
|
|
198
182
|
"-V",
|
|
183
|
+
"-v",
|
|
199
184
|
help="Show version and exit",
|
|
200
|
-
callback=
|
|
185
|
+
callback=version_option_callback,
|
|
201
186
|
is_eager=True,
|
|
202
187
|
),
|
|
203
188
|
model: str | None = typer.Option(
|
|
@@ -240,10 +225,10 @@ def main_callback(
|
|
|
240
225
|
from klaude_code.cli.runtime import AppInitConfig, run_interactive
|
|
241
226
|
from klaude_code.config.select_model import select_model_from_config
|
|
242
227
|
|
|
243
|
-
|
|
228
|
+
update_terminal_title()
|
|
244
229
|
|
|
245
230
|
chosen_model = model
|
|
246
|
-
if select_model:
|
|
231
|
+
if model or select_model:
|
|
247
232
|
chosen_model = select_model_from_config(preferred=model)
|
|
248
233
|
if chosen_model is None:
|
|
249
234
|
return
|
|
@@ -260,6 +245,35 @@ def main_callback(
|
|
|
260
245
|
session_id = Session.most_recent_session_id()
|
|
261
246
|
# If still no session_id, leave as None to create a new session
|
|
262
247
|
|
|
248
|
+
if session_id is not None and chosen_model is None:
|
|
249
|
+
from klaude_code.config import load_config
|
|
250
|
+
from klaude_code.trace import log
|
|
251
|
+
|
|
252
|
+
session_meta = Session.load_meta(session_id)
|
|
253
|
+
cfg = load_config()
|
|
254
|
+
|
|
255
|
+
if cfg is not None and session_meta.model_config_name:
|
|
256
|
+
if any(m.model_name == session_meta.model_config_name for m in cfg.model_list):
|
|
257
|
+
chosen_model = session_meta.model_config_name
|
|
258
|
+
else:
|
|
259
|
+
log(
|
|
260
|
+
(
|
|
261
|
+
f"Warning: session model '{session_meta.model_config_name}' is not defined in config; falling back to default",
|
|
262
|
+
"yellow",
|
|
263
|
+
)
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
if cfg is not None and chosen_model is None and session_meta.model_name:
|
|
267
|
+
raw_model = session_meta.model_name.strip()
|
|
268
|
+
if raw_model:
|
|
269
|
+
matches = [
|
|
270
|
+
m.model_name
|
|
271
|
+
for m in cfg.model_list
|
|
272
|
+
if (m.model_params.model or "").strip().lower() == raw_model.lower()
|
|
273
|
+
]
|
|
274
|
+
if len(matches) == 1:
|
|
275
|
+
chosen_model = matches[0]
|
|
276
|
+
|
|
263
277
|
debug_enabled, debug_filters, log_path = prepare_debug_logging(debug, debug_filter)
|
|
264
278
|
|
|
265
279
|
init_config = AppInitConfig(
|
|
@@ -8,6 +8,8 @@ import typer
|
|
|
8
8
|
from rich.text import Text
|
|
9
9
|
|
|
10
10
|
from klaude_code import ui
|
|
11
|
+
from klaude_code.cli.main import update_terminal_title
|
|
12
|
+
from klaude_code.cli.self_update import get_update_message
|
|
11
13
|
from klaude_code.command import has_interactive_command
|
|
12
14
|
from klaude_code.config import Config, load_config
|
|
13
15
|
from klaude_code.core.agent import Agent, DefaultModelProfileProvider, VanillaModelProfileProvider
|
|
@@ -21,7 +23,6 @@ from klaude_code.ui.modes.repl.input_prompt_toolkit import REPLStatusSnapshot
|
|
|
21
23
|
from klaude_code.ui.terminal.color import is_light_terminal_background
|
|
22
24
|
from klaude_code.ui.terminal.control import install_sigint_double_press_exit, start_esc_interrupt_monitor
|
|
23
25
|
from klaude_code.ui.terminal.progress_bar import OSC94States, emit_osc94
|
|
24
|
-
from klaude_code.version import get_update_message
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
class PrintCapable(Protocol):
|
|
@@ -92,14 +93,20 @@ async def initialize_app_components(init_config: AppInitConfig) -> AppComponents
|
|
|
92
93
|
event_queue,
|
|
93
94
|
llm_clients,
|
|
94
95
|
model_profile_provider=model_profile_provider,
|
|
96
|
+
on_model_change=update_terminal_title,
|
|
95
97
|
)
|
|
96
98
|
|
|
99
|
+
# Update terminal title with initial model name
|
|
100
|
+
update_terminal_title(llm_clients.main.model_name)
|
|
101
|
+
|
|
97
102
|
# Start executor in background
|
|
98
103
|
executor_task = asyncio.create_task(executor.start())
|
|
99
104
|
|
|
100
105
|
theme: str | None = config.theme
|
|
101
|
-
if theme is None:
|
|
106
|
+
if theme is None and not init_config.is_exec_mode:
|
|
102
107
|
# Auto-detect theme from terminal background when config does not specify a theme.
|
|
108
|
+
# Skip detection in exec mode to avoid TTY race conditions with parent process's
|
|
109
|
+
# ESC monitor when running as a subprocess.
|
|
103
110
|
detected = is_light_terminal_background()
|
|
104
111
|
if detected is True:
|
|
105
112
|
theme = "light"
|
|
@@ -145,8 +152,30 @@ async def initialize_session(
|
|
|
145
152
|
await executor.submit_and_wait(op.InitAgentOperation(session_id=session_id))
|
|
146
153
|
await event_queue.join()
|
|
147
154
|
|
|
148
|
-
|
|
149
|
-
return
|
|
155
|
+
active_session_id = executor.context.current_session_id()
|
|
156
|
+
return active_session_id or session_id
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _backfill_session_model_config(
|
|
160
|
+
agent: Agent | None,
|
|
161
|
+
model_override: str | None,
|
|
162
|
+
default_model: str,
|
|
163
|
+
is_new_session: bool,
|
|
164
|
+
) -> None:
|
|
165
|
+
"""Backfill model_config_name and model_thinking on newly created sessions."""
|
|
166
|
+
if agent is None or agent.session.model_config_name is not None:
|
|
167
|
+
return
|
|
168
|
+
|
|
169
|
+
if model_override is not None:
|
|
170
|
+
agent.session.model_config_name = model_override
|
|
171
|
+
elif is_new_session:
|
|
172
|
+
agent.session.model_config_name = default_model
|
|
173
|
+
else:
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
if agent.session.model_thinking is None and agent.profile:
|
|
177
|
+
agent.session.model_thinking = agent.profile.llm_client.get_llm_config().thinking
|
|
178
|
+
# Don't save here - session will be saved when first message is sent via append_history()
|
|
150
179
|
|
|
151
180
|
|
|
152
181
|
async def cleanup_app_components(components: AppComponents) -> None:
|
|
@@ -190,6 +219,12 @@ async def run_exec(init_config: AppInitConfig, input_content: str) -> None:
|
|
|
190
219
|
|
|
191
220
|
try:
|
|
192
221
|
session_id = await initialize_session(components.executor, components.event_queue)
|
|
222
|
+
_backfill_session_model_config(
|
|
223
|
+
components.executor.context.current_agent,
|
|
224
|
+
init_config.model,
|
|
225
|
+
components.config.main_model,
|
|
226
|
+
is_new_session=True,
|
|
227
|
+
)
|
|
193
228
|
|
|
194
229
|
# Submit the input content directly
|
|
195
230
|
await components.executor.submit_and_wait(
|
|
@@ -214,16 +249,12 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
|
|
|
214
249
|
|
|
215
250
|
# Create status provider for bottom toolbar
|
|
216
251
|
def _status_provider() -> REPLStatusSnapshot:
|
|
217
|
-
agent: Agent | None = None
|
|
218
|
-
# Get the first active agent (there should only be one in interactive mode)
|
|
219
|
-
active_agents = components.executor.context.active_agents
|
|
220
|
-
if active_agents:
|
|
221
|
-
agent = next(iter(active_agents.values()), None)
|
|
222
|
-
|
|
223
252
|
# Check for updates (returns None if uv not available)
|
|
224
253
|
update_message = get_update_message()
|
|
225
254
|
|
|
226
|
-
return build_repl_status_snapshot(
|
|
255
|
+
return build_repl_status_snapshot(
|
|
256
|
+
agent=components.executor.context.current_agent, update_message=update_message
|
|
257
|
+
)
|
|
227
258
|
|
|
228
259
|
# Set up input provider for interactive mode
|
|
229
260
|
input_provider: ui.InputProviderABC = ui.PromptToolkitInput(status_provider=_status_provider)
|
|
@@ -262,14 +293,19 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
|
|
|
262
293
|
|
|
263
294
|
try:
|
|
264
295
|
await initialize_session(components.executor, components.event_queue, session_id=session_id)
|
|
296
|
+
_backfill_session_model_config(
|
|
297
|
+
components.executor.context.current_agent,
|
|
298
|
+
init_config.model,
|
|
299
|
+
components.config.main_model,
|
|
300
|
+
is_new_session=session_id is None,
|
|
301
|
+
)
|
|
265
302
|
|
|
266
303
|
def _get_active_session_id() -> str | None:
|
|
267
304
|
"""Get the current active session ID dynamically.
|
|
268
305
|
|
|
269
306
|
This is necessary because /clear command creates a new session with a different ID.
|
|
270
307
|
"""
|
|
271
|
-
|
|
272
|
-
return active_ids[0] if active_ids else None
|
|
308
|
+
return components.executor.context.current_session_id()
|
|
273
309
|
|
|
274
310
|
# Input
|
|
275
311
|
await input_provider.start()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Self-update and version utilities for klaude-code."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -8,8 +8,14 @@ import subprocess
|
|
|
8
8
|
import threading
|
|
9
9
|
import time
|
|
10
10
|
import urllib.request
|
|
11
|
+
from importlib.metadata import PackageNotFoundError
|
|
12
|
+
from importlib.metadata import version as pkg_version
|
|
11
13
|
from typing import NamedTuple
|
|
12
14
|
|
|
15
|
+
import typer
|
|
16
|
+
|
|
17
|
+
from klaude_code.trace import log
|
|
18
|
+
|
|
13
19
|
PACKAGE_NAME = "klaude-code"
|
|
14
20
|
PYPI_URL = f"https://pypi.org/pypi/{PACKAGE_NAME}/json"
|
|
15
21
|
CHECK_INTERVAL_SECONDS = 3600 # Check at most once per hour
|
|
@@ -160,4 +166,106 @@ def get_update_message() -> str | None:
|
|
|
160
166
|
info = check_for_updates()
|
|
161
167
|
if info is None or not info.update_available:
|
|
162
168
|
return None
|
|
163
|
-
return f"New version available: {info.latest}. Please run `
|
|
169
|
+
return f"New version available: {info.latest}. Please run `klaude upgrade` to upgrade."
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _print_version() -> None:
|
|
173
|
+
try:
|
|
174
|
+
ver = pkg_version(PACKAGE_NAME)
|
|
175
|
+
except PackageNotFoundError:
|
|
176
|
+
ver = "unknown"
|
|
177
|
+
except Exception:
|
|
178
|
+
ver = "unknown"
|
|
179
|
+
print(f"{PACKAGE_NAME} {ver}")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def version_option_callback(value: bool) -> None:
|
|
183
|
+
"""Show version and exit."""
|
|
184
|
+
if value:
|
|
185
|
+
_print_version()
|
|
186
|
+
raise typer.Exit(0)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def version_command() -> None:
|
|
190
|
+
"""Show version and exit."""
|
|
191
|
+
|
|
192
|
+
_print_version()
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def update_command(
|
|
196
|
+
check: bool = typer.Option(
|
|
197
|
+
False,
|
|
198
|
+
"--check",
|
|
199
|
+
help="Check for updates and exit without upgrading",
|
|
200
|
+
),
|
|
201
|
+
) -> None:
|
|
202
|
+
"""Upgrade klaude-code when installed via `uv tool`."""
|
|
203
|
+
|
|
204
|
+
info = check_for_updates_blocking()
|
|
205
|
+
|
|
206
|
+
if check:
|
|
207
|
+
if info is None:
|
|
208
|
+
log(("Error: `uv` is not available; cannot check for updates.", "red"))
|
|
209
|
+
log(f"Install uv, then run `uv tool upgrade {PACKAGE_NAME}`.")
|
|
210
|
+
raise typer.Exit(1)
|
|
211
|
+
|
|
212
|
+
installed_display = info.installed or "unknown"
|
|
213
|
+
latest_display = info.latest or "unknown"
|
|
214
|
+
status = "update available" if info.update_available else "up to date"
|
|
215
|
+
|
|
216
|
+
log(f"{PACKAGE_NAME} installed: {installed_display}")
|
|
217
|
+
log(f"{PACKAGE_NAME} latest: {latest_display}")
|
|
218
|
+
log(f"Status: {status}")
|
|
219
|
+
|
|
220
|
+
if info.update_available:
|
|
221
|
+
log("Run `klaude upgrade` to upgrade.")
|
|
222
|
+
|
|
223
|
+
return
|
|
224
|
+
|
|
225
|
+
if shutil.which("uv") is None:
|
|
226
|
+
log(("Error: `uv` not found in PATH.", "red"))
|
|
227
|
+
log(f"To update, install uv and run `uv tool upgrade {PACKAGE_NAME}`.")
|
|
228
|
+
raise typer.Exit(1)
|
|
229
|
+
|
|
230
|
+
log(f"Running `uv tool upgrade {PACKAGE_NAME}`...")
|
|
231
|
+
result = subprocess.run(["uv", "tool", "upgrade", PACKAGE_NAME], check=False)
|
|
232
|
+
if result.returncode != 0:
|
|
233
|
+
log((f"Error: update failed (exit code {result.returncode}).", "red"))
|
|
234
|
+
raise typer.Exit(result.returncode or 1)
|
|
235
|
+
|
|
236
|
+
log("Update complete. Please re-run `klaude` to use the new version.")
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def register_self_update_commands(app: typer.Typer) -> None:
|
|
240
|
+
"""Register self-update and version subcommands to the given Typer app."""
|
|
241
|
+
|
|
242
|
+
app.command("update")(update_command)
|
|
243
|
+
app.command("upgrade", help="Alias for `klaude update`.")(update_command)
|
|
244
|
+
app.command("version", help="Alias for `klaude --version`.")(version_command)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def check_for_updates_blocking() -> VersionInfo | None:
|
|
248
|
+
"""Check for updates to klaude-code synchronously.
|
|
249
|
+
|
|
250
|
+
This is intended for CLI commands (e.g. `klaude update --check`) that need
|
|
251
|
+
a deterministic result instead of the async cached behavior.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
VersionInfo if uv is available, otherwise None.
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
if not _has_uv():
|
|
258
|
+
return None
|
|
259
|
+
|
|
260
|
+
installed = _get_installed_version()
|
|
261
|
+
latest = _get_latest_version()
|
|
262
|
+
|
|
263
|
+
update_available = False
|
|
264
|
+
if installed and latest:
|
|
265
|
+
update_available = _compare_versions(installed, latest)
|
|
266
|
+
|
|
267
|
+
return VersionInfo(
|
|
268
|
+
installed=installed,
|
|
269
|
+
latest=latest,
|
|
270
|
+
update_available=update_available,
|
|
271
|
+
)
|
|
@@ -28,6 +28,7 @@ def ensure_commands_loaded() -> None:
|
|
|
28
28
|
|
|
29
29
|
# Import and register commands in display order
|
|
30
30
|
from .clear_cmd import ClearCommand
|
|
31
|
+
from .debug_cmd import DebugCommand
|
|
31
32
|
from .diff_cmd import DiffCommand
|
|
32
33
|
from .export_cmd import ExportCommand
|
|
33
34
|
from .export_online_cmd import ExportOnlineCommand
|
|
@@ -46,12 +47,13 @@ def ensure_commands_loaded() -> None:
|
|
|
46
47
|
register(ThinkingCommand())
|
|
47
48
|
register(ModelCommand())
|
|
48
49
|
load_prompt_commands()
|
|
49
|
-
register(ClearCommand())
|
|
50
50
|
register(StatusCommand())
|
|
51
51
|
register(DiffCommand())
|
|
52
52
|
register(HelpCommand())
|
|
53
53
|
register(ReleaseNotesCommand())
|
|
54
54
|
register(TerminalSetupCommand())
|
|
55
|
+
register(DebugCommand())
|
|
56
|
+
register(ClearCommand())
|
|
55
57
|
|
|
56
58
|
# Load prompt-based commands (appended after built-in commands)
|
|
57
59
|
|
|
@@ -60,6 +62,7 @@ def ensure_commands_loaded() -> None:
|
|
|
60
62
|
def __getattr__(name: str) -> object:
|
|
61
63
|
_commands_map = {
|
|
62
64
|
"ClearCommand": "clear_cmd",
|
|
65
|
+
"DebugCommand": "debug_cmd",
|
|
63
66
|
"DiffCommand": "diff_cmd",
|
|
64
67
|
"ExportCommand": "export_cmd",
|
|
65
68
|
"ExportOnlineCommand": "export_online_cmd",
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from klaude_code.command.command_abc import CommandABC, CommandResult, InputAction
|
|
1
|
+
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult, InputAction
|
|
4
2
|
from klaude_code.protocol import commands
|
|
5
3
|
|
|
6
|
-
if TYPE_CHECKING:
|
|
7
|
-
from klaude_code.core.agent import Agent
|
|
8
|
-
|
|
9
4
|
|
|
10
5
|
class ClearCommand(CommandABC):
|
|
11
6
|
"""Clear current session and start a new conversation"""
|
|
@@ -18,5 +13,5 @@ class ClearCommand(CommandABC):
|
|
|
18
13
|
def summary(self) -> str:
|
|
19
14
|
return "Clear conversation history and free up context"
|
|
20
15
|
|
|
21
|
-
async def run(self, raw: str, agent:
|
|
16
|
+
async def run(self, raw: str, agent: Agent) -> CommandResult:
|
|
22
17
|
return CommandResult(actions=[InputAction.clear()])
|