klaude-code 2.10.2__tar.gz → 2.10.3__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.10.2 → klaude_code-2.10.3}/PKG-INFO +1 -1
- {klaude_code-2.10.2 → klaude_code-2.10.3}/pyproject.toml +1 -1
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/config/assets/builtin_config.yaml +7 -7
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/anthropic/input.py +28 -4
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/developer.py +1 -1
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/errors.py +2 -4
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/metadata.py +5 -10
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/rich/markdown.py +5 -1
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/rich/theme.py +2 -2
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/user_input.py +1 -1
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/input/completers.py +51 -17
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/input/images.py +127 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/input/prompt_toolkit.py +1 -1
- {klaude_code-2.10.2 → klaude_code-2.10.3}/README.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/.DS_Store +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/app/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/app/runtime.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/AGENTS.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/antigravity/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/antigravity/exceptions.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/antigravity/oauth.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/antigravity/pkce.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/antigravity/token_manager.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/base.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/claude/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/claude/exceptions.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/claude/oauth.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/claude/token_manager.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/codex/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/codex/exceptions.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/codex/oauth.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/codex/token_manager.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/auth/env.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/cli/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/cli/auth_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/cli/config_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/cli/cost_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/cli/debug.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/cli/list_model.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/cli/main.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/cli/self_update.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/config/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/config/assets/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/config/builtin_config.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/config/config.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/config/model_matcher.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/config/sub_agent_model_helper.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/config/thinking.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/const.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/agent.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/agent_profile.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/bash_mode.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/compaction/AGENTS.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/compaction/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/compaction/compaction.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/compaction/overflow.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/compaction/prompts.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/executor.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/loaded_skills.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/manager/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/manager/llm_clients.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/manager/llm_clients_builder.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/manager/sub_agent_manager.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/memory.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-antigravity.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-codex-gpt-5-2.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-codex.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-sub-agent-image-gen.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-sub-agent-web.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/reminders.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/task.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/context.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/_utils.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/diff_builder.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/read_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/read_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/write_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/file/write_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/offload.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/report_back_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/shell/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/shell/bash_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/sub_agent/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/sub_agent/image_gen.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/sub_agent/image_gen.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/sub_agent/task.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/sub_agent/task.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/todo/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/tool_abc.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/tool_registry.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/tool_runner.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/web/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/web/web_fetch_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/tool/web/web_search_tool.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/turn.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/anthropic/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/anthropic/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/antigravity/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/antigravity/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/antigravity/input.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/bedrock_anthropic/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/bedrock_anthropic/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/claude/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/claude/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/google/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/google/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/google/input.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/image.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/input_common.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/json_stable.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openai_codex/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openai_codex/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openai_compatible/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openai_compatible/input.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openai_compatible/stream.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openai_responses/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openai_responses/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openai_responses/input.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openrouter/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openrouter/client.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openrouter/input.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/openrouter/reasoning.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/partial_message.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/registry.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/stream_parts.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/llm/usage.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/log.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/commands.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/events.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/llm_param.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/message.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/model.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/op.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/op_handler.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/sub_agent/AGENTS.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/sub_agent/explore.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/sub_agent/image_gen.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/sub_agent/task.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/sub_agent/web.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/protocol/tools.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/session/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/session/codec.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/session/export.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/session/selector.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/session/session.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/session/store.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/session/templates/export_session.html +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/session/templates/mermaid_viewer.html +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/.DS_Store +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/assets/.DS_Store +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/assets/create-plan/SKILL.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/assets/deslop/SKILL.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/assets/handoff/SKILL.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/assets/skill-creator/SKILL.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/loader.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/manager.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/skill/system_skills.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/clear_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/command_abc.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/compact_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/continue_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/copy_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/debug_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/export_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/export_online_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/fork_session_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/model_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/model_picker.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/prompt-init.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/prompt_command.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/refresh_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/registry.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/resume_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/status_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/sub_agent_model_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/command/thinking_cmd.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/commands.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/bash_syntax.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/command_output.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/common.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/diffs.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/mermaid_viewer.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/rich/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/rich/cjk_wrap.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/rich/code_panel.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/rich/live.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/rich/quote.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/rich/status.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/sub_agent.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/thinking.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/tools.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/components/welcome.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/display.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/input/AGENTS.md +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/input/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/input/drag_drop.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/input/key_bindings.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/input/paste.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/machine.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/renderer.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/runner.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/terminal/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/terminal/color.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/terminal/control.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/terminal/image.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/terminal/notifier.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/terminal/progress_bar.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/tui/terminal/selector.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/ui/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/ui/common.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/ui/core/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/ui/core/display.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/ui/core/input.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/ui/debug_mode.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/ui/terminal/__init__.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/ui/terminal/title.py +0 -0
- {klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/update.py +0 -0
|
@@ -102,12 +102,12 @@ provider_list:
|
|
|
102
102
|
cost: {input: 1.75, output: 14, cache_read: 0.17}
|
|
103
103
|
|
|
104
104
|
- model_name: kimi
|
|
105
|
-
model_id: moonshotai/kimi-k2
|
|
105
|
+
model_id: moonshotai/kimi-k2.5
|
|
106
106
|
context_limit: 262144
|
|
107
|
-
provider_routing:
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
cost: {input: 0.6, output:
|
|
107
|
+
# provider_routing:
|
|
108
|
+
# only:
|
|
109
|
+
# - moonshotai/turbo
|
|
110
|
+
cost: {input: 0.6, output: 3, cache_read: 0.1}
|
|
111
111
|
|
|
112
112
|
- model_name: haiku
|
|
113
113
|
model_id: anthropic/claude-haiku-4.5
|
|
@@ -272,12 +272,12 @@ provider_list:
|
|
|
272
272
|
model_list:
|
|
273
273
|
|
|
274
274
|
- model_name: kimi
|
|
275
|
-
model_id: kimi-k2
|
|
275
|
+
model_id: kimi-k2.5
|
|
276
276
|
context_limit: 262144
|
|
277
277
|
thinking:
|
|
278
278
|
type: enabled
|
|
279
279
|
budget_tokens: 8192
|
|
280
|
-
cost: {input: 4, output:
|
|
280
|
+
cost: {input: 4, output: 21, cache_read: 0.7, currency: CNY}
|
|
281
281
|
|
|
282
282
|
|
|
283
283
|
- provider_name: cerebras
|
|
@@ -107,11 +107,20 @@ def _tool_blocks_to_message(blocks: list[BetaToolResultBlockParam]) -> BetaMessa
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
|
|
110
|
+
def _model_supports_unsigned_thinking(model_name: str | None) -> bool:
|
|
111
|
+
"""Check if the model supports thinking blocks without signature (e.g., kimi, deepseek)."""
|
|
112
|
+
if not model_name:
|
|
113
|
+
return False
|
|
114
|
+
model_lower = model_name.lower()
|
|
115
|
+
return "kimi" in model_lower or "deepseek" in model_lower
|
|
116
|
+
|
|
117
|
+
|
|
110
118
|
def _assistant_message_to_message(msg: message.AssistantMessage, model_name: str | None) -> BetaMessageParam:
|
|
111
119
|
content: list[BetaContentBlockParam] = []
|
|
112
120
|
current_thinking_content: str | None = None
|
|
113
121
|
native_thinking_parts, _ = split_thinking_parts(msg, model_name)
|
|
114
122
|
native_thinking_ids = {id(part) for part in native_thinking_parts}
|
|
123
|
+
supports_unsigned = _model_supports_unsigned_thinking(model_name)
|
|
115
124
|
|
|
116
125
|
def _degraded_thinking_block(text: str) -> BetaTextBlockParam | None:
|
|
117
126
|
stripped = text.strip()
|
|
@@ -125,11 +134,18 @@ def _assistant_message_to_message(msg: message.AssistantMessage, model_name: str
|
|
|
125
134
|
},
|
|
126
135
|
)
|
|
127
136
|
|
|
128
|
-
def
|
|
137
|
+
def _flush_thinking() -> None:
|
|
129
138
|
nonlocal current_thinking_content
|
|
130
139
|
if current_thinking_content is None:
|
|
131
140
|
return
|
|
132
|
-
if
|
|
141
|
+
if supports_unsigned:
|
|
142
|
+
content.append(
|
|
143
|
+
cast(
|
|
144
|
+
BetaContentBlockParam,
|
|
145
|
+
{"type": "thinking", "thinking": current_thinking_content},
|
|
146
|
+
)
|
|
147
|
+
)
|
|
148
|
+
elif block := _degraded_thinking_block(current_thinking_content):
|
|
133
149
|
content.append(block)
|
|
134
150
|
current_thinking_content = None
|
|
135
151
|
|
|
@@ -156,9 +172,17 @@ def _assistant_message_to_message(msg: message.AssistantMessage, model_name: str
|
|
|
156
172
|
)
|
|
157
173
|
)
|
|
158
174
|
current_thinking_content = None
|
|
175
|
+
elif supports_unsigned:
|
|
176
|
+
content.append(
|
|
177
|
+
cast(
|
|
178
|
+
BetaContentBlockParam,
|
|
179
|
+
{"type": "thinking", "thinking": current_thinking_content or ""},
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
current_thinking_content = None
|
|
159
183
|
continue
|
|
160
184
|
|
|
161
|
-
|
|
185
|
+
_flush_thinking()
|
|
162
186
|
if isinstance(part, message.TextPart):
|
|
163
187
|
content.append(cast(BetaTextBlockParam, {"type": "text", "text": part.text}))
|
|
164
188
|
elif isinstance(part, message.ToolCallPart):
|
|
@@ -182,7 +206,7 @@ def _assistant_message_to_message(msg: message.AssistantMessage, model_name: str
|
|
|
182
206
|
)
|
|
183
207
|
)
|
|
184
208
|
|
|
185
|
-
|
|
209
|
+
_flush_thinking()
|
|
186
210
|
|
|
187
211
|
return {"role": "assistant", "content": content}
|
|
188
212
|
|
|
@@ -6,7 +6,7 @@ from klaude_code.tui.components.common import create_grid
|
|
|
6
6
|
from klaude_code.tui.components.rich.theme import ThemeKey
|
|
7
7
|
from klaude_code.tui.components.tools import render_path
|
|
8
8
|
|
|
9
|
-
REMINDER_BULLET = "
|
|
9
|
+
REMINDER_BULLET = " +"
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def need_render_developer_message(e: events.DeveloperMessageEvent) -> bool:
|
|
@@ -9,8 +9,7 @@ def render_error(error_msg: Text) -> RenderableType:
|
|
|
9
9
|
"""Render error with X mark for error events."""
|
|
10
10
|
grid = create_grid()
|
|
11
11
|
error_msg.style = ThemeKey.ERROR
|
|
12
|
-
error_msg.overflow = "
|
|
13
|
-
error_msg.no_wrap = True
|
|
12
|
+
error_msg.overflow = "fold"
|
|
14
13
|
grid.add_row(Text("✘", style=ThemeKey.ERROR_BOLD), error_msg)
|
|
15
14
|
return grid
|
|
16
15
|
|
|
@@ -19,7 +18,6 @@ def render_tool_error(error_msg: Text) -> RenderableType:
|
|
|
19
18
|
"""Render error with indent for tool results."""
|
|
20
19
|
grid = create_grid()
|
|
21
20
|
error_msg.style = ThemeKey.ERROR
|
|
22
|
-
error_msg.overflow = "
|
|
23
|
-
error_msg.no_wrap = True
|
|
21
|
+
error_msg.overflow = "fold"
|
|
24
22
|
grid.add_row(Text(" "), error_msg)
|
|
25
23
|
return grid
|
|
@@ -32,9 +32,6 @@ def _render_task_metadata_block(
|
|
|
32
32
|
|
|
33
33
|
# Second column: provider/model description / tokens / cost / …
|
|
34
34
|
content = Text()
|
|
35
|
-
if metadata.provider is not None:
|
|
36
|
-
content.append_text(Text(metadata.provider.lower().replace(" ", "-"), style=ThemeKey.METADATA))
|
|
37
|
-
content.append_text(Text("/", style=ThemeKey.METADATA))
|
|
38
35
|
content.append_text(Text(metadata.model_name, style=ThemeKey.METADATA))
|
|
39
36
|
if metadata.description:
|
|
40
37
|
content.append_text(Text(" ", style=ThemeKey.METADATA)).append_text(
|
|
@@ -129,7 +126,7 @@ def _render_task_metadata_block(
|
|
|
129
126
|
|
|
130
127
|
if parts:
|
|
131
128
|
content.append_text(Text(" ", style=ThemeKey.METADATA))
|
|
132
|
-
content.append_text(Text(" ", style=ThemeKey.
|
|
129
|
+
content.append_text(Text(" ", style=ThemeKey.METADATA_DIM).join(parts))
|
|
133
130
|
|
|
134
131
|
grid.add_row(mark, content)
|
|
135
132
|
return grid
|
|
@@ -140,15 +137,14 @@ def render_task_metadata(e: events.TaskMetadataEvent) -> RenderableType:
|
|
|
140
137
|
renderables: list[RenderableType] = []
|
|
141
138
|
|
|
142
139
|
has_sub_agents = len(e.metadata.sub_agent_task_metadata) > 0
|
|
143
|
-
|
|
144
|
-
main_mark_text = "●"
|
|
140
|
+
main_mark_text = "•"
|
|
145
141
|
main_mark = Text(main_mark_text, style=ThemeKey.METADATA)
|
|
146
142
|
|
|
147
143
|
renderables.append(_render_task_metadata_block(e.metadata.main_agent, mark=main_mark, show_context_and_time=True))
|
|
148
144
|
|
|
149
145
|
# Render each sub-agent metadata block
|
|
150
146
|
for meta in e.metadata.sub_agent_task_metadata:
|
|
151
|
-
sub_mark = Text("
|
|
147
|
+
sub_mark = Text(" •", style=ThemeKey.METADATA)
|
|
152
148
|
renderables.append(_render_task_metadata_block(meta, mark=sub_mark, show_context_and_time=True))
|
|
153
149
|
|
|
154
150
|
# Add total cost line when there are sub-agents
|
|
@@ -165,9 +161,8 @@ def render_task_metadata(e: events.TaskMetadataEvent) -> RenderableType:
|
|
|
165
161
|
|
|
166
162
|
currency_symbol = "¥" if currency == "CNY" else "$"
|
|
167
163
|
total_line = Text.assemble(
|
|
168
|
-
("
|
|
169
|
-
("
|
|
170
|
-
("total ", ThemeKey.METADATA),
|
|
164
|
+
(" •", ThemeKey.METADATA),
|
|
165
|
+
(" total ", ThemeKey.METADATA),
|
|
171
166
|
(currency_symbol, ThemeKey.METADATA),
|
|
172
167
|
(f"{total_cost:.4f}", ThemeKey.METADATA),
|
|
173
168
|
)
|
|
@@ -609,7 +609,11 @@ class MarkdownStream:
|
|
|
609
609
|
|
|
610
610
|
live_text_to_set: Text | None = None
|
|
611
611
|
if not final and MARKDOWN_STREAM_LIVE_REPAINT_ENABLED and self._live_sink is not None:
|
|
612
|
-
# Only update live area after we have rendered at least one stable block
|
|
612
|
+
# Only update the live area after we have rendered at least one stable block.
|
|
613
|
+
#
|
|
614
|
+
# This keeps the bottom "live" region anchored to stable scrollback, and
|
|
615
|
+
# avoids showing a live frame that would later need to be retroactively
|
|
616
|
+
# re-rendered once stable content exists.
|
|
613
617
|
if not self._stable_rendered_lines:
|
|
614
618
|
return
|
|
615
619
|
# When nothing is stable yet, we still want to show incremental output.
|
|
@@ -262,8 +262,8 @@ def get_theme(theme: str | None = None) -> Themes:
|
|
|
262
262
|
ThemeKey.ERROR_DIM.value: "dim " + palette.red,
|
|
263
263
|
ThemeKey.INTERRUPT.value: palette.red,
|
|
264
264
|
# USER_INPUT
|
|
265
|
-
ThemeKey.USER_INPUT.value: f"{palette.
|
|
266
|
-
ThemeKey.USER_INPUT_PROMPT.value: f"bold {palette.
|
|
265
|
+
ThemeKey.USER_INPUT.value: f"{palette.cyan} on {palette.user_message_background}",
|
|
266
|
+
ThemeKey.USER_INPUT_PROMPT.value: f"bold {palette.cyan} on {palette.user_message_background}",
|
|
267
267
|
ThemeKey.USER_INPUT_AT_PATTERN.value: f"{palette.purple} on {palette.user_message_background}",
|
|
268
268
|
ThemeKey.USER_INPUT_SLASH_COMMAND.value: f"bold {palette.blue} on {palette.user_message_background}",
|
|
269
269
|
ThemeKey.USER_INPUT_SKILL.value: f"bold {palette.green} on {palette.user_message_background}",
|
|
@@ -673,34 +673,68 @@ class _AtFilesCompleter(Completer):
|
|
|
673
673
|
all_files_lower = self._git_file_list_lower or []
|
|
674
674
|
kn = keyword_norm
|
|
675
675
|
|
|
676
|
-
# Bound per-keystroke work
|
|
676
|
+
# Bound per-keystroke work.
|
|
677
|
+
#
|
|
678
|
+
# Important: When the keyword is common (e.g. "tools"), truncating the
|
|
679
|
+
# scan purely by number of matching *files* can accidentally hide valid
|
|
680
|
+
# directory completions that appear later in the git path order.
|
|
681
|
+
#
|
|
682
|
+
# Example: multiple */tools/ directories under different parents.
|
|
683
|
+
file_quota = max_results
|
|
684
|
+
dir_quota = max_results
|
|
685
|
+
scan_cap = max(2000, max_results * 200)
|
|
686
|
+
|
|
687
|
+
keyword_stripped = keyword_norm.strip("/")
|
|
688
|
+
keyword_basename = os.path.basename(keyword_stripped)
|
|
689
|
+
explicit_parent = "/" in keyword_stripped
|
|
690
|
+
|
|
691
|
+
def dir_matches_keyword(dir_path: str) -> bool:
|
|
692
|
+
if not keyword_basename:
|
|
693
|
+
return False
|
|
694
|
+
if explicit_parent:
|
|
695
|
+
# When user typed an explicit parent segment, match against the
|
|
696
|
+
# whole directory path (not just basename).
|
|
697
|
+
return kn in f"{dir_path}/".lower()
|
|
698
|
+
# Otherwise prioritize directories by basename match.
|
|
699
|
+
return keyword_basename in os.path.basename(dir_path).lower()
|
|
700
|
+
|
|
677
701
|
matching_files: list[str] = []
|
|
702
|
+
dir_list: list[str] = []
|
|
703
|
+
dir_seen: set[str] = set()
|
|
678
704
|
scan_truncated = False
|
|
705
|
+
scanned = 0
|
|
706
|
+
|
|
679
707
|
for p, pl in zip(all_files, all_files_lower, strict=False):
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
if
|
|
708
|
+
scanned += 1
|
|
709
|
+
if kn not in pl:
|
|
710
|
+
if scanned >= scan_cap and (matching_files or dir_list):
|
|
683
711
|
scan_truncated = True
|
|
684
712
|
break
|
|
713
|
+
continue
|
|
714
|
+
|
|
715
|
+
if len(matching_files) < file_quota:
|
|
716
|
+
matching_files.append(p)
|
|
685
717
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
for p in matching_files[: max_results * 3]:
|
|
718
|
+
# Collect matching parent directories, walking upwards until repo root.
|
|
719
|
+
# This allows completing into directories like "image/tools/" even
|
|
720
|
+
# when the matching file is nested deeper.
|
|
690
721
|
parent = os.path.dirname(p)
|
|
691
722
|
while parent and parent != ".":
|
|
692
|
-
|
|
723
|
+
if dir_matches_keyword(parent):
|
|
724
|
+
cand = f"{parent}/"
|
|
725
|
+
if cand not in dir_seen:
|
|
726
|
+
dir_seen.add(cand)
|
|
727
|
+
dir_list.append(cand)
|
|
728
|
+
if len(dir_list) >= dir_quota:
|
|
729
|
+
break
|
|
693
730
|
parent = os.path.dirname(parent)
|
|
694
731
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
dir_list = dir_list[:max_results]
|
|
699
|
-
dir_truncated = True
|
|
732
|
+
if len(matching_files) >= file_quota and len(dir_list) >= dir_quota:
|
|
733
|
+
scan_truncated = True
|
|
734
|
+
break
|
|
700
735
|
|
|
701
|
-
candidates =
|
|
702
|
-
|
|
703
|
-
return candidates, truncated
|
|
736
|
+
candidates = dir_list + matching_files
|
|
737
|
+
return candidates, scan_truncated
|
|
704
738
|
|
|
705
739
|
def _get_git_repo_root(self, cwd: Path) -> Path | None:
|
|
706
740
|
if not self._has_cmd("git"):
|
|
@@ -28,6 +28,9 @@ from klaude_code.protocol.message import ImageFilePart
|
|
|
28
28
|
|
|
29
29
|
IMAGE_SUFFIXES = frozenset({".png", ".jpg", ".jpeg", ".gif", ".webp"})
|
|
30
30
|
|
|
31
|
+
# Claude API limit is 5MB, we use 4.5MB to have some margin
|
|
32
|
+
MAX_IMAGE_SIZE_BYTES = 4_500_000
|
|
33
|
+
|
|
31
34
|
IMAGE_MARKER_RE = re.compile(r'\[image (?P<path>"[^"]+"|[^\]]+)\]')
|
|
32
35
|
|
|
33
36
|
|
|
@@ -159,6 +162,127 @@ def _grab_clipboard_image(dest_path: Path) -> bool:
|
|
|
159
162
|
return _grab_clipboard_image_linux(dest_path)
|
|
160
163
|
|
|
161
164
|
|
|
165
|
+
# ---------------------------------------------------------------------------
|
|
166
|
+
# Image resizing for size limits
|
|
167
|
+
# ---------------------------------------------------------------------------
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _get_image_dimensions_macos(path: Path) -> tuple[int, int] | None:
|
|
171
|
+
"""Get image dimensions using sips on macOS."""
|
|
172
|
+
try:
|
|
173
|
+
result = subprocess.run(
|
|
174
|
+
["sips", "-g", "pixelWidth", "-g", "pixelHeight", str(path)],
|
|
175
|
+
capture_output=True,
|
|
176
|
+
text=True,
|
|
177
|
+
)
|
|
178
|
+
if result.returncode != 0:
|
|
179
|
+
return None
|
|
180
|
+
width = height = 0
|
|
181
|
+
for line in result.stdout.splitlines():
|
|
182
|
+
if "pixelWidth" in line:
|
|
183
|
+
width = int(line.split(":")[-1].strip())
|
|
184
|
+
elif "pixelHeight" in line:
|
|
185
|
+
height = int(line.split(":")[-1].strip())
|
|
186
|
+
if width > 0 and height > 0:
|
|
187
|
+
return (width, height)
|
|
188
|
+
except (OSError, ValueError):
|
|
189
|
+
pass
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _resize_image_macos(path: Path, scale: float) -> bool:
|
|
194
|
+
"""Resize image using sips on macOS. Modifies file in place."""
|
|
195
|
+
dims = _get_image_dimensions_macos(path)
|
|
196
|
+
if dims is None:
|
|
197
|
+
return False
|
|
198
|
+
new_width = max(1, int(dims[0] * scale))
|
|
199
|
+
try:
|
|
200
|
+
result = subprocess.run(
|
|
201
|
+
["sips", "--resampleWidth", str(new_width), str(path)],
|
|
202
|
+
capture_output=True,
|
|
203
|
+
)
|
|
204
|
+
return result.returncode == 0
|
|
205
|
+
except OSError:
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _resize_image_linux(path: Path, scale: float) -> bool:
|
|
210
|
+
"""Resize image using ImageMagick convert on Linux."""
|
|
211
|
+
if not shutil.which("convert"):
|
|
212
|
+
return False
|
|
213
|
+
percent = int(scale * 100)
|
|
214
|
+
try:
|
|
215
|
+
result = subprocess.run(
|
|
216
|
+
["convert", str(path), "-resize", f"{percent}%", str(path)],
|
|
217
|
+
capture_output=True,
|
|
218
|
+
)
|
|
219
|
+
return result.returncode == 0
|
|
220
|
+
except OSError:
|
|
221
|
+
return False
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _resize_image_windows(path: Path, scale: float) -> bool:
|
|
225
|
+
"""Resize image using PowerShell on Windows."""
|
|
226
|
+
script = f'''
|
|
227
|
+
Add-Type -AssemblyName System.Drawing
|
|
228
|
+
$img = [System.Drawing.Image]::FromFile("{path}")
|
|
229
|
+
$newWidth = [int]($img.Width * {scale})
|
|
230
|
+
$newHeight = [int]($img.Height * {scale})
|
|
231
|
+
$bmp = New-Object System.Drawing.Bitmap($newWidth, $newHeight)
|
|
232
|
+
$graphics = [System.Drawing.Graphics]::FromImage($bmp)
|
|
233
|
+
$graphics.DrawImage($img, 0, 0, $newWidth, $newHeight)
|
|
234
|
+
$img.Dispose()
|
|
235
|
+
$bmp.Save("{path}", [System.Drawing.Imaging.ImageFormat]::Png)
|
|
236
|
+
$bmp.Dispose()
|
|
237
|
+
$graphics.Dispose()
|
|
238
|
+
Write-Output "ok"
|
|
239
|
+
'''
|
|
240
|
+
try:
|
|
241
|
+
result = subprocess.run(
|
|
242
|
+
["powershell", "-Command", script],
|
|
243
|
+
capture_output=True,
|
|
244
|
+
text=True,
|
|
245
|
+
)
|
|
246
|
+
return result.returncode == 0 and "ok" in result.stdout
|
|
247
|
+
except OSError:
|
|
248
|
+
return False
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _resize_image(path: Path, scale: float) -> bool:
|
|
252
|
+
"""Resize image by scale factor. Modifies file in place."""
|
|
253
|
+
if sys.platform == "darwin":
|
|
254
|
+
return _resize_image_macos(path, scale)
|
|
255
|
+
elif sys.platform == "win32":
|
|
256
|
+
return _resize_image_windows(path, scale)
|
|
257
|
+
else:
|
|
258
|
+
return _resize_image_linux(path, scale)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def _ensure_image_size_limit(path: Path, max_bytes: int = MAX_IMAGE_SIZE_BYTES) -> None:
|
|
262
|
+
"""Resize image if it exceeds the size limit. Modifies file in place."""
|
|
263
|
+
try:
|
|
264
|
+
current_size = path.stat().st_size
|
|
265
|
+
if current_size <= max_bytes:
|
|
266
|
+
return
|
|
267
|
+
|
|
268
|
+
# Calculate scale factor based on size ratio
|
|
269
|
+
# We use sqrt because area scales with square of linear dimensions
|
|
270
|
+
scale = (max_bytes / current_size) ** 0.5
|
|
271
|
+
# Be a bit more aggressive to ensure we get under the limit
|
|
272
|
+
scale *= 0.9
|
|
273
|
+
|
|
274
|
+
for _ in range(5): # Max 5 resize attempts
|
|
275
|
+
if not _resize_image(path, scale):
|
|
276
|
+
return
|
|
277
|
+
new_size = path.stat().st_size
|
|
278
|
+
if new_size <= max_bytes:
|
|
279
|
+
return
|
|
280
|
+
# Still too large, reduce more
|
|
281
|
+
scale = 0.8
|
|
282
|
+
except OSError:
|
|
283
|
+
pass
|
|
284
|
+
|
|
285
|
+
|
|
162
286
|
def capture_clipboard_tag() -> str | None:
|
|
163
287
|
"""Capture an image from clipboard and return an [image ...] marker."""
|
|
164
288
|
|
|
@@ -174,6 +298,9 @@ def capture_clipboard_tag() -> str | None:
|
|
|
174
298
|
if not _grab_clipboard_image(path):
|
|
175
299
|
return None
|
|
176
300
|
|
|
301
|
+
# Resize if image exceeds size limit
|
|
302
|
+
_ensure_image_size_limit(path)
|
|
303
|
+
|
|
177
304
|
return format_image_marker(str(path))
|
|
178
305
|
|
|
179
306
|
|
|
@@ -61,7 +61,7 @@ COMPLETION_SELECTED_DARK_BG = "ansigreen"
|
|
|
61
61
|
COMPLETION_SELECTED_LIGHT_BG = "ansigreen"
|
|
62
62
|
COMPLETION_SELECTED_UNKNOWN_BG = "ansigreen"
|
|
63
63
|
COMPLETION_MENU = "ansibrightblack"
|
|
64
|
-
INPUT_PROMPT_STYLE = "
|
|
64
|
+
INPUT_PROMPT_STYLE = "ansicyan bold"
|
|
65
65
|
INPUT_PROMPT_BASH_STYLE = "ansigreen bold"
|
|
66
66
|
PLACEHOLDER_TEXT_STYLE_DARK_BG = "fg:#5a5a5a"
|
|
67
67
|
PLACEHOLDER_TEXT_STYLE_LIGHT_BG = "fg:#7a7a7a"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/manager/llm_clients_builder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-antigravity.md
RENAMED
|
File without changes
|
{klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-claude-code.md
RENAMED
|
File without changes
|
{klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md
RENAMED
|
File without changes
|
{klaude_code-2.10.2 → klaude_code-2.10.3}/src/klaude_code/core/prompts/prompt-codex-gpt-5-2.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|