klaude-code 1.2.18__tar.gz → 1.2.20__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.18 → klaude_code-1.2.20}/PKG-INFO +18 -2
- {klaude_code-1.2.18 → klaude_code-1.2.20}/README.md +16 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/pyproject.toml +2 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/cli/main.py +42 -22
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/cli/runtime.py +46 -2
- klaude_code-1.2.18/src/klaude_code/version.py → klaude_code-1.2.20/src/klaude_code/cli/self_update.py +110 -2
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/__init__.py +1 -3
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/clear_cmd.py +5 -4
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/command_abc.py +5 -40
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/debug_cmd.py +2 -2
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/diff_cmd.py +2 -1
- klaude_code-1.2.20/src/klaude_code/command/export_cmd.py +52 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/export_online_cmd.py +10 -4
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/help_cmd.py +2 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/model_cmd.py +7 -5
- klaude_code-1.2.20/src/klaude_code/command/prompt-jj-workspace.md +18 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/prompt_command.py +16 -9
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/refresh_cmd.py +3 -2
- klaude_code-1.2.20/src/klaude_code/command/registry.py +186 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/release_notes_cmd.py +2 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/status_cmd.py +2 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/terminal_setup_cmd.py +2 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/thinking_cmd.py +6 -4
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/executor.py +187 -180
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/manager/sub_agent_manager.py +3 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompt.py +4 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +14 -2
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompts/prompt-sub-agent-web.md +3 -3
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/reminders.py +70 -26
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/task.py +13 -12
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/__init__.py +2 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/apply_patch_tool.py +3 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/edit_tool.py +7 -5
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/multi_edit_tool.py +7 -5
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/read_tool.md +1 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/read_tool.py +8 -4
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/write_tool.py +8 -6
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/memory/skill_loader.py +12 -10
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/shell/bash_tool.py +89 -17
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/sub_agent_tool.py +5 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/tool_abc.py +18 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/tool_context.py +6 -6
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/tool_registry.py +1 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/tool_runner.py +7 -7
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/web/web_fetch_tool.py +77 -22
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/web/web_search_tool.py +5 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/anthropic/client.py +25 -9
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/openai_compatible/client.py +5 -2
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/openrouter/client.py +7 -3
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/responses/client.py +6 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/model.py +8 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/op.py +47 -0
- klaude_code-1.2.20/src/klaude_code/protocol/op_handler.py +52 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/sub_agent/web.py +1 -1
- klaude_code-1.2.20/src/klaude_code/session/codec.py +71 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/session/export.py +21 -11
- klaude_code-1.2.20/src/klaude_code/session/session.py +401 -0
- klaude_code-1.2.20/src/klaude_code/session/store.py +215 -0
- klaude_code-1.2.20/src/klaude_code/session/templates/export_session.html +1726 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/repl/completers.py +211 -71
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/repl/event_handler.py +7 -23
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/repl/input_prompt_toolkit.py +5 -7
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/repl/renderer.py +2 -2
- klaude_code-1.2.20/src/klaude_code/ui/renderers/common.py +62 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/developer.py +2 -3
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/errors.py +1 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/metadata.py +10 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/tools.py +3 -4
- klaude_code-1.2.20/src/klaude_code/ui/rich/__init__.py +10 -0
- klaude_code-1.2.20/src/klaude_code/ui/rich/cjk_wrap.py +228 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/rich/status.py +0 -1
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/utils/common.py +0 -18
- klaude_code-1.2.18/src/klaude_code/command/export_cmd.py +0 -87
- klaude_code-1.2.18/src/klaude_code/command/registry.py +0 -116
- klaude_code-1.2.18/src/klaude_code/protocol/op_handler.py +0 -28
- klaude_code-1.2.18/src/klaude_code/session/session.py +0 -537
- klaude_code-1.2.18/src/klaude_code/session/templates/export_session.html +0 -1725
- klaude_code-1.2.18/src/klaude_code/ui/renderers/common.py +0 -8
- klaude_code-1.2.18/src/klaude_code/ui/rich/__init__.py +0 -1
- klaude_code-1.2.18/src/klaude_code/ui/utils/debouncer.py +0 -42
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/auth/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/auth/codex/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/auth/codex/exceptions.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/auth/codex/oauth.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/auth/codex/token_manager.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/cli/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/cli/auth_cmd.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/cli/config_cmd.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/cli/debug.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/cli/list_model.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/cli/session_cmd.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/prompt-deslop.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/prompt-dev-docs-update.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/prompt-dev-docs.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/prompt-handoff.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/command/prompt-init.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/config/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/config/config.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/config/select_model.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/const/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/agent.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/manager/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/manager/llm_clients.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/manager/llm_clients_builder.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompts/prompt-sub-agent-oracle.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/_utils.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/multi_edit_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/file/write_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/memory/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/memory/memory_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/memory/memory_tool.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/memory/skill_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/memory/skill_tool.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/report_back_tool.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/shell/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/todo/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/truncation.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/web/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/core/turn.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/anthropic/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/anthropic/input.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/client.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/codex/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/codex/client.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/input_common.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/openai_compatible/input.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/openai_compatible/stream_processor.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/openrouter/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/openrouter/input.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/openrouter/reasoning_handler.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/registry.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/responses/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/responses/input.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/llm/usage.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/commands.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/events.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/llm_param.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/sub_agent/explore.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/sub_agent/oracle.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/sub_agent/task.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/protocol/tools.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/session/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/session/selector.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/trace/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/trace/log.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/core/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/core/display.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/core/input.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/core/stage_manager.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/debug/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/debug/display.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/exec/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/exec/display.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/repl/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/repl/clipboard.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/repl/display.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/modes/repl/key_bindings.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/assistant.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/diffs.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/sub_agent.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/thinking.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/renderers/user_input.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/rich/code_panel.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/rich/live.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/rich/markdown.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/rich/quote.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/rich/searchable_text.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/rich/theme.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/terminal/__init__.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/terminal/color.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/terminal/control.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/terminal/notifier.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/terminal/progress_bar.py +0 -0
- {klaude_code-1.2.18 → klaude_code-1.2.20}/src/klaude_code/ui/utils/__init__.py +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: klaude-code
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.20
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Requires-Dist: anthropic>=0.66.0
|
|
6
|
+
Requires-Dist: chardet>=5.2.0
|
|
6
7
|
Requires-Dist: ddgs>=9.9.3
|
|
7
8
|
Requires-Dist: openai>=1.102.0
|
|
8
9
|
Requires-Dist: pillow>=12.0.0
|
|
@@ -41,6 +42,21 @@ To update:
|
|
|
41
42
|
uv tool upgrade klaude-code
|
|
42
43
|
```
|
|
43
44
|
|
|
45
|
+
Or use the built-in alias command:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
klaude update
|
|
49
|
+
klaude upgrade
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
To show version:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
klaude --version
|
|
56
|
+
klaude -v
|
|
57
|
+
klaude version
|
|
58
|
+
```
|
|
59
|
+
|
|
44
60
|
## Usage
|
|
45
61
|
|
|
46
62
|
### Interactive Mode
|
|
@@ -50,7 +66,7 @@ klaude [--model <name>] [--select-model]
|
|
|
50
66
|
```
|
|
51
67
|
|
|
52
68
|
**Options:**
|
|
53
|
-
- `--version`/`-V`: Show version and exit.
|
|
69
|
+
- `--version`/`-V`/`-v`: Show version and exit.
|
|
54
70
|
- `--model`/`-m`: Preferred model name (exact match picks immediately; otherwise opens the interactive selector filtered by this value).
|
|
55
71
|
- `--select-model`/`-s`: Open the interactive model selector at startup (shows all models unless `--model` is also provided).
|
|
56
72
|
- `--continue`/`-c`: Resume the most recent session.
|
|
@@ -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,7 +47,7 @@ klaude [--model <name>] [--select-model]
|
|
|
32
47
|
```
|
|
33
48
|
|
|
34
49
|
**Options:**
|
|
35
|
-
- `--version`/`-V`: Show version and exit.
|
|
50
|
+
- `--version`/`-V`/`-v`: Show version and exit.
|
|
36
51
|
- `--model`/`-m`: Preferred model name (exact match picks immediately; otherwise opens the interactive selector filtered by this value).
|
|
37
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.
|
|
@@ -4,12 +4,13 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "klaude-code"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.20"
|
|
8
8
|
description = "Add your description here"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"anthropic>=0.66.0",
|
|
13
|
+
"chardet>=5.2.0",
|
|
13
14
|
"ddgs>=9.9.3",
|
|
14
15
|
"openai>=1.102.0",
|
|
15
16
|
"pillow>=12.0.0",
|
|
@@ -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,6 +8,7 @@ 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
13
|
from klaude_code.session import Session, resume_select_session
|
|
15
14
|
from klaude_code.trace import DebugType, prepare_debug_log_file
|
|
@@ -21,10 +20,13 @@ def set_terminal_title(title: str) -> None:
|
|
|
21
20
|
sys.stdout.flush()
|
|
22
21
|
|
|
23
22
|
|
|
24
|
-
def
|
|
25
|
-
"""
|
|
23
|
+
def update_terminal_title(model_name: str | None = None) -> None:
|
|
24
|
+
"""Update terminal title with folder name and optional model name."""
|
|
26
25
|
folder_name = os.path.basename(os.getcwd())
|
|
27
|
-
|
|
26
|
+
if model_name:
|
|
27
|
+
set_terminal_title(f"{folder_name}: klaude ✳ {model_name}")
|
|
28
|
+
else:
|
|
29
|
+
set_terminal_title(f"{folder_name}: klaude")
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
def prepare_debug_logging(debug: bool, debug_filter: str | None) -> tuple[bool, set[DebugType] | None, Path | None]:
|
|
@@ -78,20 +80,6 @@ def read_input_content(cli_argument: str) -> str | None:
|
|
|
78
80
|
return content
|
|
79
81
|
|
|
80
82
|
|
|
81
|
-
def _version_callback(value: bool) -> None:
|
|
82
|
-
"""Show version and exit."""
|
|
83
|
-
if value:
|
|
84
|
-
try:
|
|
85
|
-
ver = pkg_version("klaude-code")
|
|
86
|
-
except PackageNotFoundError:
|
|
87
|
-
# Package is not installed or has no metadata; show a generic version string.
|
|
88
|
-
ver = "unknown"
|
|
89
|
-
except Exception:
|
|
90
|
-
ver = "unknown"
|
|
91
|
-
print(f"klaude-code {ver}")
|
|
92
|
-
raise typer.Exit(0)
|
|
93
|
-
|
|
94
|
-
|
|
95
83
|
app = typer.Typer(
|
|
96
84
|
add_completion=False,
|
|
97
85
|
pretty_exceptions_enable=False,
|
|
@@ -103,6 +91,8 @@ register_session_commands(app)
|
|
|
103
91
|
register_auth_commands(app)
|
|
104
92
|
register_config_commands(app)
|
|
105
93
|
|
|
94
|
+
register_self_update_commands(app)
|
|
95
|
+
|
|
106
96
|
|
|
107
97
|
@app.command("exec")
|
|
108
98
|
def exec_command(
|
|
@@ -146,7 +136,7 @@ def exec_command(
|
|
|
146
136
|
),
|
|
147
137
|
) -> None:
|
|
148
138
|
"""Execute non-interactively with provided input."""
|
|
149
|
-
|
|
139
|
+
update_terminal_title()
|
|
150
140
|
|
|
151
141
|
merged_input = read_input_content(input_content)
|
|
152
142
|
if merged_input is None:
|
|
@@ -190,8 +180,9 @@ def main_callback(
|
|
|
190
180
|
False,
|
|
191
181
|
"--version",
|
|
192
182
|
"-V",
|
|
183
|
+
"-v",
|
|
193
184
|
help="Show version and exit",
|
|
194
|
-
callback=
|
|
185
|
+
callback=version_option_callback,
|
|
195
186
|
is_eager=True,
|
|
196
187
|
),
|
|
197
188
|
model: str | None = typer.Option(
|
|
@@ -234,7 +225,7 @@ def main_callback(
|
|
|
234
225
|
from klaude_code.cli.runtime import AppInitConfig, run_interactive
|
|
235
226
|
from klaude_code.config.select_model import select_model_from_config
|
|
236
227
|
|
|
237
|
-
|
|
228
|
+
update_terminal_title()
|
|
238
229
|
|
|
239
230
|
chosen_model = model
|
|
240
231
|
if model or select_model:
|
|
@@ -254,6 +245,35 @@ def main_callback(
|
|
|
254
245
|
session_id = Session.most_recent_session_id()
|
|
255
246
|
# If still no session_id, leave as None to create a new session
|
|
256
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
|
+
|
|
257
277
|
debug_enabled, debug_filters, log_path = prepare_debug_logging(debug, debug_filter)
|
|
258
278
|
|
|
259
279
|
init_config = AppInitConfig(
|
|
@@ -8,20 +8,22 @@ 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
|
-
from klaude_code.core.agent import DefaultModelProfileProvider, VanillaModelProfileProvider
|
|
15
|
+
from klaude_code.core.agent import Agent, DefaultModelProfileProvider, VanillaModelProfileProvider
|
|
14
16
|
from klaude_code.core.executor import Executor
|
|
15
17
|
from klaude_code.core.manager import build_llm_clients
|
|
16
18
|
from klaude_code.protocol import events, op
|
|
17
19
|
from klaude_code.protocol.model import UserInputPayload
|
|
20
|
+
from klaude_code.session.session import close_default_store
|
|
18
21
|
from klaude_code.trace import DebugType, log, set_debug_logging
|
|
19
22
|
from klaude_code.ui.modes.repl import build_repl_status_snapshot
|
|
20
23
|
from klaude_code.ui.modes.repl.input_prompt_toolkit import REPLStatusSnapshot
|
|
21
24
|
from klaude_code.ui.terminal.color import is_light_terminal_background
|
|
22
25
|
from klaude_code.ui.terminal.control import install_sigint_double_press_exit, start_esc_interrupt_monitor
|
|
23
26
|
from klaude_code.ui.terminal.progress_bar import OSC94States, emit_osc94
|
|
24
|
-
from klaude_code.version import get_update_message
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
class PrintCapable(Protocol):
|
|
@@ -92,8 +94,12 @@ async def initialize_app_components(init_config: AppInitConfig) -> AppComponents
|
|
|
92
94
|
event_queue,
|
|
93
95
|
llm_clients,
|
|
94
96
|
model_profile_provider=model_profile_provider,
|
|
97
|
+
on_model_change=update_terminal_title,
|
|
95
98
|
)
|
|
96
99
|
|
|
100
|
+
# Update terminal title with initial model name
|
|
101
|
+
update_terminal_title(llm_clients.main.model_name)
|
|
102
|
+
|
|
97
103
|
# Start executor in background
|
|
98
104
|
executor_task = asyncio.create_task(executor.start())
|
|
99
105
|
|
|
@@ -151,12 +157,38 @@ async def initialize_session(
|
|
|
151
157
|
return active_session_id or session_id
|
|
152
158
|
|
|
153
159
|
|
|
160
|
+
def _backfill_session_model_config(
|
|
161
|
+
agent: Agent | None,
|
|
162
|
+
model_override: str | None,
|
|
163
|
+
default_model: str,
|
|
164
|
+
is_new_session: bool,
|
|
165
|
+
) -> None:
|
|
166
|
+
"""Backfill model_config_name and model_thinking on newly created sessions."""
|
|
167
|
+
if agent is None or agent.session.model_config_name is not None:
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
if model_override is not None:
|
|
171
|
+
agent.session.model_config_name = model_override
|
|
172
|
+
elif is_new_session:
|
|
173
|
+
agent.session.model_config_name = default_model
|
|
174
|
+
else:
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
if agent.session.model_thinking is None and agent.profile:
|
|
178
|
+
agent.session.model_thinking = agent.profile.llm_client.get_llm_config().thinking
|
|
179
|
+
# Don't save here - session will be saved when first message is sent via append_history()
|
|
180
|
+
|
|
181
|
+
|
|
154
182
|
async def cleanup_app_components(components: AppComponents) -> None:
|
|
155
183
|
"""Clean up all application components."""
|
|
156
184
|
try:
|
|
157
185
|
# Clean shutdown
|
|
158
186
|
await components.executor.stop()
|
|
159
187
|
components.executor_task.cancel()
|
|
188
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
189
|
+
await components.executor_task
|
|
190
|
+
with contextlib.suppress(Exception):
|
|
191
|
+
await close_default_store()
|
|
160
192
|
|
|
161
193
|
# Signal UI to stop
|
|
162
194
|
await components.event_queue.put(events.EndEvent())
|
|
@@ -192,6 +224,12 @@ async def run_exec(init_config: AppInitConfig, input_content: str) -> None:
|
|
|
192
224
|
|
|
193
225
|
try:
|
|
194
226
|
session_id = await initialize_session(components.executor, components.event_queue)
|
|
227
|
+
_backfill_session_model_config(
|
|
228
|
+
components.executor.context.current_agent,
|
|
229
|
+
init_config.model,
|
|
230
|
+
components.config.main_model,
|
|
231
|
+
is_new_session=True,
|
|
232
|
+
)
|
|
195
233
|
|
|
196
234
|
# Submit the input content directly
|
|
197
235
|
await components.executor.submit_and_wait(
|
|
@@ -260,6 +298,12 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
|
|
|
260
298
|
|
|
261
299
|
try:
|
|
262
300
|
await initialize_session(components.executor, components.event_queue, session_id=session_id)
|
|
301
|
+
_backfill_session_model_config(
|
|
302
|
+
components.executor.context.current_agent,
|
|
303
|
+
init_config.model,
|
|
304
|
+
components.config.main_model,
|
|
305
|
+
is_new_session=session_id is None,
|
|
306
|
+
)
|
|
263
307
|
|
|
264
308
|
def _get_active_session_id() -> str | None:
|
|
265
309
|
"""Get the current active session ID dynamically.
|
|
@@ -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
|
+
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from .command_abc import CommandABC, CommandResult
|
|
1
|
+
from .command_abc import CommandABC, CommandResult
|
|
2
2
|
from .registry import (
|
|
3
3
|
dispatch_command,
|
|
4
4
|
get_commands,
|
|
@@ -89,8 +89,6 @@ __all__ = [
|
|
|
89
89
|
# "StatusCommand", "TerminalSetupCommand",
|
|
90
90
|
"CommandABC",
|
|
91
91
|
"CommandResult",
|
|
92
|
-
"InputAction",
|
|
93
|
-
"InputActionType",
|
|
94
92
|
"dispatch_command",
|
|
95
93
|
"ensure_commands_loaded",
|
|
96
94
|
"get_commands",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
2
|
-
from klaude_code.protocol import commands
|
|
1
|
+
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
2
|
+
from klaude_code.protocol import commands, model, op
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class ClearCommand(CommandABC):
|
|
@@ -13,5 +13,6 @@ class ClearCommand(CommandABC):
|
|
|
13
13
|
def summary(self) -> str:
|
|
14
14
|
return "Clear conversation history and free up context"
|
|
15
15
|
|
|
16
|
-
async def run(self,
|
|
17
|
-
|
|
16
|
+
async def run(self, agent: Agent, user_input: model.UserInputPayload) -> CommandResult:
|
|
17
|
+
del user_input # unused
|
|
18
|
+
return CommandResult(operations=[op.ClearSessionOperation(session_id=agent.session.id)])
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
-
from enum import Enum
|
|
3
2
|
from typing import Protocol
|
|
4
3
|
|
|
5
4
|
from pydantic import BaseModel
|
|
6
5
|
|
|
7
6
|
from klaude_code.llm import LLMClientABC
|
|
8
|
-
from klaude_code.protocol import commands, llm_param
|
|
7
|
+
from klaude_code.protocol import commands, llm_param, model, op
|
|
9
8
|
from klaude_code.protocol import events as protocol_events
|
|
10
9
|
from klaude_code.session.session import Session
|
|
11
10
|
|
|
@@ -34,40 +33,6 @@ class Agent(Protocol):
|
|
|
34
33
|
def get_llm_client(self) -> LLMClientABC: ...
|
|
35
34
|
|
|
36
35
|
|
|
37
|
-
class InputActionType(str, Enum):
|
|
38
|
-
"""Supported input action kinds."""
|
|
39
|
-
|
|
40
|
-
RUN_AGENT = "run_agent"
|
|
41
|
-
CHANGE_MODEL = "change_model"
|
|
42
|
-
CLEAR = "clear"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class InputAction(BaseModel):
|
|
46
|
-
"""Structured executor action derived from a user input."""
|
|
47
|
-
|
|
48
|
-
type: InputActionType
|
|
49
|
-
text: str = ""
|
|
50
|
-
model_name: str | None = None
|
|
51
|
-
|
|
52
|
-
@classmethod
|
|
53
|
-
def run_agent(cls, text: str) -> "InputAction":
|
|
54
|
-
"""Create a RunAgent action preserving the provided text."""
|
|
55
|
-
|
|
56
|
-
return cls(type=InputActionType.RUN_AGENT, text=text)
|
|
57
|
-
|
|
58
|
-
@classmethod
|
|
59
|
-
def change_model(cls, model_name: str) -> "InputAction":
|
|
60
|
-
"""Create a ChangeModel action for the provided model name."""
|
|
61
|
-
|
|
62
|
-
return cls(type=InputActionType.CHANGE_MODEL, model_name=model_name)
|
|
63
|
-
|
|
64
|
-
@classmethod
|
|
65
|
-
def clear(cls) -> "InputAction":
|
|
66
|
-
"""Create a Clear action to reset the session."""
|
|
67
|
-
|
|
68
|
-
return cls(type=InputActionType.CLEAR)
|
|
69
|
-
|
|
70
|
-
|
|
71
36
|
class CommandResult(BaseModel):
|
|
72
37
|
"""Result of a command execution."""
|
|
73
38
|
|
|
@@ -75,7 +40,7 @@ class CommandResult(BaseModel):
|
|
|
75
40
|
list[protocol_events.DeveloperMessageEvent | protocol_events.WelcomeEvent | protocol_events.ReplayHistoryEvent]
|
|
76
41
|
| None
|
|
77
42
|
) = None # List of UI events to display immediately
|
|
78
|
-
|
|
43
|
+
operations: list[op.Operation] | None = None
|
|
79
44
|
|
|
80
45
|
|
|
81
46
|
class CommandABC(ABC):
|
|
@@ -109,13 +74,13 @@ class CommandABC(ABC):
|
|
|
109
74
|
return "additional instructions"
|
|
110
75
|
|
|
111
76
|
@abstractmethod
|
|
112
|
-
async def run(self,
|
|
77
|
+
async def run(self, agent: Agent, user_input: model.UserInputPayload) -> CommandResult:
|
|
113
78
|
"""
|
|
114
79
|
Execute the command.
|
|
115
80
|
|
|
116
81
|
Args:
|
|
117
|
-
|
|
118
|
-
|
|
82
|
+
agent: The agent instance
|
|
83
|
+
user_input: User input with text containing command arguments (without command name)
|
|
119
84
|
|
|
120
85
|
Returns:
|
|
121
86
|
CommandResult: Result of the command execution
|
|
@@ -45,8 +45,8 @@ class DebugCommand(CommandABC):
|
|
|
45
45
|
def placeholder(self) -> str:
|
|
46
46
|
return "filter types"
|
|
47
47
|
|
|
48
|
-
async def run(self,
|
|
49
|
-
raw =
|
|
48
|
+
async def run(self, agent: Agent, user_input: model.UserInputPayload) -> CommandResult:
|
|
49
|
+
raw = user_input.text.strip()
|
|
50
50
|
|
|
51
51
|
# /debug (no args) - enable debug
|
|
52
52
|
if not raw:
|
|
@@ -16,7 +16,8 @@ class DiffCommand(CommandABC):
|
|
|
16
16
|
def summary(self) -> str:
|
|
17
17
|
return "Show git diff"
|
|
18
18
|
|
|
19
|
-
async def run(self,
|
|
19
|
+
async def run(self, agent: Agent, user_input: model.UserInputPayload) -> CommandResult:
|
|
20
|
+
del user_input # unused
|
|
20
21
|
try:
|
|
21
22
|
# Check if current directory is in a git repository
|
|
22
23
|
git_check = subprocess.run(
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
6
|
+
from klaude_code.protocol import commands, model, op
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ExportCommand(CommandABC):
|
|
10
|
+
"""Export the current session into a standalone HTML transcript."""
|
|
11
|
+
|
|
12
|
+
@property
|
|
13
|
+
def name(self) -> commands.CommandName:
|
|
14
|
+
return commands.CommandName.EXPORT
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def summary(self) -> str:
|
|
18
|
+
return "Export current session to HTML"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def support_addition_params(self) -> bool:
|
|
22
|
+
return True
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def placeholder(self) -> str:
|
|
26
|
+
return "output path"
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def is_interactive(self) -> bool:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
async def run(self, agent: Agent, user_input: model.UserInputPayload) -> CommandResult:
|
|
33
|
+
output_path = self._normalize_output_path(user_input.text, agent)
|
|
34
|
+
return CommandResult(
|
|
35
|
+
operations=[
|
|
36
|
+
op.ExportSessionOperation(
|
|
37
|
+
session_id=agent.session.id,
|
|
38
|
+
output_path=str(output_path) if output_path is not None else None,
|
|
39
|
+
)
|
|
40
|
+
]
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def _normalize_output_path(self, raw: str, agent: Agent) -> Path | None:
|
|
44
|
+
trimmed = raw.strip()
|
|
45
|
+
if trimmed:
|
|
46
|
+
candidate = Path(trimmed).expanduser()
|
|
47
|
+
if not candidate.is_absolute():
|
|
48
|
+
candidate = Path(agent.session.work_dir) / candidate
|
|
49
|
+
if candidate.suffix.lower() != ".html":
|
|
50
|
+
candidate = candidate.with_suffix(".html")
|
|
51
|
+
return candidate
|
|
52
|
+
return None
|
|
@@ -6,6 +6,9 @@ import subprocess
|
|
|
6
6
|
import tempfile
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.text import Text
|
|
11
|
+
|
|
9
12
|
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
10
13
|
from klaude_code.protocol import commands, events, model
|
|
11
14
|
from klaude_code.session.export import build_export_html
|
|
@@ -30,7 +33,8 @@ class ExportOnlineCommand(CommandABC):
|
|
|
30
33
|
def is_interactive(self) -> bool:
|
|
31
34
|
return False
|
|
32
35
|
|
|
33
|
-
async def run(self,
|
|
36
|
+
async def run(self, agent: Agent, user_input: model.UserInputPayload) -> CommandResult:
|
|
37
|
+
del user_input # unused
|
|
34
38
|
# Check if npx or surge is available
|
|
35
39
|
surge_cmd = self._get_surge_command()
|
|
36
40
|
if not surge_cmd:
|
|
@@ -56,9 +60,11 @@ class ExportOnlineCommand(CommandABC):
|
|
|
56
60
|
return CommandResult(events=[event])
|
|
57
61
|
|
|
58
62
|
try:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
console = Console()
|
|
64
|
+
with console.status(Text("Deploying to surge.sh...", style="dim"), spinner_style="dim"):
|
|
65
|
+
html_doc = self._build_html(agent)
|
|
66
|
+
domain = self._generate_domain()
|
|
67
|
+
url = self._deploy_to_surge(surge_cmd, html_doc, domain)
|
|
62
68
|
|
|
63
69
|
event = events.DeveloperMessageEvent(
|
|
64
70
|
session_id=agent.session.id,
|
|
@@ -13,7 +13,8 @@ class HelpCommand(CommandABC):
|
|
|
13
13
|
def summary(self) -> str:
|
|
14
14
|
return "Show help and available commands"
|
|
15
15
|
|
|
16
|
-
async def run(self,
|
|
16
|
+
async def run(self, agent: Agent, user_input: model.UserInputPayload) -> CommandResult:
|
|
17
|
+
del user_input # unused
|
|
17
18
|
lines: list[str] = [
|
|
18
19
|
"""
|
|
19
20
|
Usage:
|