klaude-code 2.5.3__tar.gz → 2.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {klaude_code-2.5.3 → klaude_code-2.7.0}/PKG-INFO +32 -40
- {klaude_code-2.5.3 → klaude_code-2.7.0}/README.md +30 -36
- {klaude_code-2.5.3 → klaude_code-2.7.0}/pyproject.toml +2 -4
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/app/runtime.py +1 -1
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/__init__.py +10 -0
- klaude_code-2.7.0/src/klaude_code/auth/env.py +81 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/cli/auth_cmd.py +87 -8
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/cli/config_cmd.py +5 -5
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/cli/cost_cmd.py +159 -60
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/cli/main.py +146 -65
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/cli/self_update.py +7 -7
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/config/builtin_config.py +23 -9
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/config/config.py +19 -9
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/const.py +10 -1
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/reminders.py +4 -5
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/turn.py +8 -9
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/google/client.py +12 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/openai_compatible/stream.py +5 -1
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/openrouter/client.py +1 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/commands.py +0 -1
- klaude_code-2.7.0/src/klaude_code/protocol/events.py +214 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/sub_agent/image_gen.py +0 -4
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/session/session.py +51 -18
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/loader.py +12 -13
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/manager.py +3 -3
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/__init__.py +1 -4
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/copy_cmd.py +1 -1
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/fork_session_cmd.py +4 -4
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/commands.py +0 -5
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/command_output.py +1 -1
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/metadata.py +4 -5
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/rich/markdown.py +60 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/rich/theme.py +8 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/sub_agent.py +6 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/user_input.py +38 -27
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/display.py +11 -1
- klaude_code-2.7.0/src/klaude_code/tui/input/AGENTS.md +44 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/input/completers.py +21 -21
- klaude_code-2.7.0/src/klaude_code/tui/input/drag_drop.py +197 -0
- klaude_code-2.7.0/src/klaude_code/tui/input/images.py +227 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/input/key_bindings.py +173 -19
- klaude_code-2.7.0/src/klaude_code/tui/input/paste.py +71 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/input/prompt_toolkit.py +13 -3
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/machine.py +90 -56
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/renderer.py +1 -62
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/runner.py +1 -1
- klaude_code-2.7.0/src/klaude_code/tui/terminal/image.py +65 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/terminal/selector.py +52 -2
- klaude_code-2.5.3/src/klaude_code/cli/session_cmd.py +0 -87
- klaude_code-2.5.3/src/klaude_code/protocol/events/__init__.py +0 -63
- klaude_code-2.5.3/src/klaude_code/protocol/events/base.py +0 -18
- klaude_code-2.5.3/src/klaude_code/protocol/events/chat.py +0 -30
- klaude_code-2.5.3/src/klaude_code/protocol/events/lifecycle.py +0 -23
- klaude_code-2.5.3/src/klaude_code/protocol/events/metadata.py +0 -16
- klaude_code-2.5.3/src/klaude_code/protocol/events/streaming.py +0 -43
- klaude_code-2.5.3/src/klaude_code/protocol/events/system.py +0 -56
- klaude_code-2.5.3/src/klaude_code/protocol/events/tools.py +0 -27
- klaude_code-2.5.3/src/klaude_code/tui/command/terminal_setup_cmd.py +0 -248
- klaude_code-2.5.3/src/klaude_code/tui/input/clipboard.py +0 -152
- klaude_code-2.5.3/src/klaude_code/tui/terminal/image.py +0 -34
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/.DS_Store +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/app/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/base.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/claude/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/claude/exceptions.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/claude/oauth.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/claude/token_manager.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/codex/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/codex/exceptions.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/codex/oauth.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/auth/codex/token_manager.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/cli/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/cli/debug.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/cli/list_model.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/config/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/config/assets/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/config/assets/builtin_config.yaml +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/config/model_matcher.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/config/sub_agent_model_helper.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/config/thinking.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/agent.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/agent_profile.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/executor.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/loaded_skills.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/manager/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/manager/llm_clients.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/manager/llm_clients_builder.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/manager/sub_agent_manager.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-codex.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-sub-agent-image-gen.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-sub-agent-web.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/task.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/context.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/_utils.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/diff_builder.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/read_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/read_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/write_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/file/write_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/offload.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/report_back_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/shell/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/shell/bash_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/sub_agent_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/todo/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/tool_abc.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/tool_registry.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/tool_runner.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/web/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/web/web_fetch_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/core/tool/web/web_search_tool.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/anthropic/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/anthropic/client.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/anthropic/input.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/bedrock/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/bedrock/client.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/claude/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/claude/client.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/client.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/codex/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/codex/client.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/google/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/google/input.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/image.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/input_common.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/openai_compatible/client.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/openai_compatible/input.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/openrouter/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/openrouter/input.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/openrouter/reasoning.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/partial_message.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/registry.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/responses/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/responses/client.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/responses/input.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/stream_parts.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/llm/usage.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/log.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/llm_param.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/message.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/model.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/op.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/op_handler.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/sub_agent/AGENTS.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/sub_agent/explore.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/sub_agent/task.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/sub_agent/web.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/protocol/tools.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/session/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/session/codec.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/session/export.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/session/selector.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/session/store.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/session/templates/export_session.html +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/session/templates/mermaid_viewer.html +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/.DS_Store +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/assets/.DS_Store +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/assets/create-plan/SKILL.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/assets/deslop/SKILL.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/assets/handoff/SKILL.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/assets/skill-creator/SKILL.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/skill/system_skills.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/clear_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/command_abc.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/debug_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/export_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/export_online_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/model_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/model_picker.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/prompt-init.md +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/prompt_command.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/refresh_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/registry.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/resume_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/status_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/sub_agent_model_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/command/thinking_cmd.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/assistant.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/bash_syntax.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/common.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/developer.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/diffs.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/errors.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/mermaid_viewer.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/rich/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/rich/cjk_wrap.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/rich/code_panel.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/rich/live.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/rich/quote.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/rich/searchable_text.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/rich/status.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/thinking.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/tools.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/components/welcome.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/input/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/terminal/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/terminal/color.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/terminal/control.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/terminal/notifier.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/tui/terminal/progress_bar.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/ui/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/ui/common.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/ui/core/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/ui/core/display.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/ui/core/input.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/ui/debug_mode.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/ui/terminal/__init__.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/ui/terminal/title.py +0 -0
- {klaude_code-2.5.3 → klaude_code-2.7.0}/src/klaude_code/update.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: klaude-code
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: Minimal code agent CLI
|
|
5
5
|
Requires-Dist: anthropic>=0.66.0
|
|
6
6
|
Requires-Dist: chardet>=5.2.0
|
|
@@ -9,15 +9,13 @@ Requires-Dist: diff-match-patch>=20241021
|
|
|
9
9
|
Requires-Dist: google-genai>=1.56.0
|
|
10
10
|
Requires-Dist: markdown-it-py>=4.0.0
|
|
11
11
|
Requires-Dist: openai>=1.102.0
|
|
12
|
-
Requires-Dist: pillow>=9.1,<11.0
|
|
13
12
|
Requires-Dist: prompt-toolkit>=3.0.52
|
|
14
13
|
Requires-Dist: pydantic>=2.11.7
|
|
15
14
|
Requires-Dist: pyyaml>=6.0.2
|
|
16
15
|
Requires-Dist: rich>=14.1.0
|
|
17
|
-
Requires-Dist: term-image>=0.7.2
|
|
18
16
|
Requires-Dist: trafilatura>=2.0.0
|
|
19
17
|
Requires-Dist: typer>=0.17.3
|
|
20
|
-
Requires-Python: >=3.13
|
|
18
|
+
Requires-Python: >=3.13
|
|
21
19
|
Description-Content-Type: text/markdown
|
|
22
20
|
|
|
23
21
|
# Klaude Code
|
|
@@ -52,32 +50,31 @@ To update:
|
|
|
52
50
|
uv tool upgrade klaude-code
|
|
53
51
|
```
|
|
54
52
|
|
|
55
|
-
Or use the built-in
|
|
53
|
+
Or use the built-in command:
|
|
56
54
|
|
|
57
55
|
```bash
|
|
58
|
-
klaude update
|
|
59
56
|
klaude upgrade
|
|
60
|
-
klaude --version
|
|
61
|
-
|
|
62
57
|
```
|
|
63
58
|
|
|
64
59
|
## Usage
|
|
65
60
|
|
|
66
61
|
```bash
|
|
67
|
-
klaude [--model <name>] [--
|
|
62
|
+
klaude [--model [<name>]] [--continue] [--resume [<id>]]
|
|
68
63
|
```
|
|
69
64
|
|
|
70
65
|
**Options:**
|
|
71
|
-
- `--model`/`-m`:
|
|
72
|
-
- `--
|
|
66
|
+
- `--model`/`-m`: Choose a model.
|
|
67
|
+
- `--model` (no value): opens the interactive selector.
|
|
68
|
+
- `--model <value>`: resolves `<value>` to a single model; if it can't, it opens the interactive selector filtered by `<value>`.
|
|
73
69
|
- `--continue`/`-c`: Resume the most recent session.
|
|
74
|
-
- `--resume`/`-r`:
|
|
75
|
-
- `--resume
|
|
70
|
+
- `--resume`/`-r`: Resume a session.
|
|
71
|
+
- `--resume` (no value): select a session to resume for this project.
|
|
72
|
+
- `--resume <id>`: resume a session by its ID directly.
|
|
76
73
|
- `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit, Write) and no system prompts.
|
|
77
74
|
|
|
78
75
|
**Model selection behavior:**
|
|
79
76
|
- Default: uses `main_model` from config.
|
|
80
|
-
- `--
|
|
77
|
+
- `--model` (no value): always prompts you to pick.
|
|
81
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).
|
|
82
79
|
|
|
83
80
|
**Debug Options:**
|
|
@@ -125,24 +122,34 @@ klaude list
|
|
|
125
122
|
|
|
126
123
|
Models from providers without a valid API key are shown as dimmed/unavailable.
|
|
127
124
|
|
|
128
|
-
####
|
|
125
|
+
#### Authentication
|
|
129
126
|
|
|
130
|
-
|
|
127
|
+
Use the auth command to configure API keys or login to subscription-based providers:
|
|
131
128
|
|
|
132
129
|
```bash
|
|
133
130
|
# Interactive provider selection
|
|
134
|
-
klaude login
|
|
135
|
-
|
|
136
|
-
#
|
|
137
|
-
klaude login
|
|
138
|
-
klaude login
|
|
131
|
+
klaude auth login
|
|
132
|
+
|
|
133
|
+
# Configure API keys
|
|
134
|
+
klaude auth login anthropic # Set ANTHROPIC_API_KEY
|
|
135
|
+
klaude auth login openai # Set OPENAI_API_KEY
|
|
136
|
+
klaude auth login google # Set GOOGLE_API_KEY
|
|
137
|
+
klaude auth login openrouter # Set OPENROUTER_API_KEY
|
|
138
|
+
klaude auth login deepseek # Set DEEPSEEK_API_KEY
|
|
139
|
+
klaude auth login moonshot # Set MOONSHOT_API_KEY
|
|
140
|
+
|
|
141
|
+
# OAuth login for subscription-based providers
|
|
142
|
+
klaude auth login claude # Claude Pro/Max subscription
|
|
143
|
+
klaude auth login codex # ChatGPT Pro subscription
|
|
139
144
|
```
|
|
140
145
|
|
|
141
|
-
|
|
146
|
+
API keys are stored in `~/.klaude/klaude-auth.json` and used as fallback when environment variables are not set.
|
|
147
|
+
|
|
148
|
+
To logout from OAuth providers:
|
|
142
149
|
|
|
143
150
|
```bash
|
|
144
|
-
klaude logout claude
|
|
145
|
-
klaude logout codex
|
|
151
|
+
klaude auth logout claude
|
|
152
|
+
klaude auth logout codex
|
|
146
153
|
```
|
|
147
154
|
|
|
148
155
|
#### Custom Configuration
|
|
@@ -152,7 +159,7 @@ User config file: `~/.klaude/klaude-config.yaml`
|
|
|
152
159
|
Open in editor:
|
|
153
160
|
|
|
154
161
|
```bash
|
|
155
|
-
klaude
|
|
162
|
+
klaude conf
|
|
156
163
|
```
|
|
157
164
|
|
|
158
165
|
##### Model Configuration
|
|
@@ -208,21 +215,6 @@ List configured providers and models:
|
|
|
208
215
|
klaude list
|
|
209
216
|
```
|
|
210
217
|
|
|
211
|
-
### Session Management
|
|
212
|
-
|
|
213
|
-
Clean up sessions with few messages:
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
# Remove sessions with fewer than 5 messages (default)
|
|
217
|
-
klaude session clean
|
|
218
|
-
|
|
219
|
-
# Remove sessions with fewer than 10 messages
|
|
220
|
-
klaude session clean --min 10
|
|
221
|
-
|
|
222
|
-
# Remove all sessions for the current project
|
|
223
|
-
klaude session clean-all
|
|
224
|
-
```
|
|
225
|
-
|
|
226
218
|
### Cost Tracking
|
|
227
219
|
|
|
228
220
|
View aggregated usage statistics across all sessions:
|
|
@@ -30,32 +30,31 @@ To update:
|
|
|
30
30
|
uv tool upgrade klaude-code
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
Or use the built-in
|
|
33
|
+
Or use the built-in command:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
klaude update
|
|
37
36
|
klaude upgrade
|
|
38
|
-
klaude --version
|
|
39
|
-
|
|
40
37
|
```
|
|
41
38
|
|
|
42
39
|
## Usage
|
|
43
40
|
|
|
44
41
|
```bash
|
|
45
|
-
klaude [--model <name>] [--
|
|
42
|
+
klaude [--model [<name>]] [--continue] [--resume [<id>]]
|
|
46
43
|
```
|
|
47
44
|
|
|
48
45
|
**Options:**
|
|
49
|
-
- `--model`/`-m`:
|
|
50
|
-
- `--
|
|
46
|
+
- `--model`/`-m`: Choose a model.
|
|
47
|
+
- `--model` (no value): opens the interactive selector.
|
|
48
|
+
- `--model <value>`: resolves `<value>` to a single model; if it can't, it opens the interactive selector filtered by `<value>`.
|
|
51
49
|
- `--continue`/`-c`: Resume the most recent session.
|
|
52
|
-
- `--resume`/`-r`:
|
|
53
|
-
- `--resume
|
|
50
|
+
- `--resume`/`-r`: Resume a session.
|
|
51
|
+
- `--resume` (no value): select a session to resume for this project.
|
|
52
|
+
- `--resume <id>`: resume a session by its ID directly.
|
|
54
53
|
- `--vanilla`: Minimal mode with only basic tools (Bash, Read, Edit, Write) and no system prompts.
|
|
55
54
|
|
|
56
55
|
**Model selection behavior:**
|
|
57
56
|
- Default: uses `main_model` from config.
|
|
58
|
-
- `--
|
|
57
|
+
- `--model` (no value): always prompts you to pick.
|
|
59
58
|
- `--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).
|
|
60
59
|
|
|
61
60
|
**Debug Options:**
|
|
@@ -103,24 +102,34 @@ klaude list
|
|
|
103
102
|
|
|
104
103
|
Models from providers without a valid API key are shown as dimmed/unavailable.
|
|
105
104
|
|
|
106
|
-
####
|
|
105
|
+
#### Authentication
|
|
107
106
|
|
|
108
|
-
|
|
107
|
+
Use the auth command to configure API keys or login to subscription-based providers:
|
|
109
108
|
|
|
110
109
|
```bash
|
|
111
110
|
# Interactive provider selection
|
|
112
|
-
klaude login
|
|
113
|
-
|
|
114
|
-
#
|
|
115
|
-
klaude login
|
|
116
|
-
klaude login
|
|
111
|
+
klaude auth login
|
|
112
|
+
|
|
113
|
+
# Configure API keys
|
|
114
|
+
klaude auth login anthropic # Set ANTHROPIC_API_KEY
|
|
115
|
+
klaude auth login openai # Set OPENAI_API_KEY
|
|
116
|
+
klaude auth login google # Set GOOGLE_API_KEY
|
|
117
|
+
klaude auth login openrouter # Set OPENROUTER_API_KEY
|
|
118
|
+
klaude auth login deepseek # Set DEEPSEEK_API_KEY
|
|
119
|
+
klaude auth login moonshot # Set MOONSHOT_API_KEY
|
|
120
|
+
|
|
121
|
+
# OAuth login for subscription-based providers
|
|
122
|
+
klaude auth login claude # Claude Pro/Max subscription
|
|
123
|
+
klaude auth login codex # ChatGPT Pro subscription
|
|
117
124
|
```
|
|
118
125
|
|
|
119
|
-
|
|
126
|
+
API keys are stored in `~/.klaude/klaude-auth.json` and used as fallback when environment variables are not set.
|
|
127
|
+
|
|
128
|
+
To logout from OAuth providers:
|
|
120
129
|
|
|
121
130
|
```bash
|
|
122
|
-
klaude logout claude
|
|
123
|
-
klaude logout codex
|
|
131
|
+
klaude auth logout claude
|
|
132
|
+
klaude auth logout codex
|
|
124
133
|
```
|
|
125
134
|
|
|
126
135
|
#### Custom Configuration
|
|
@@ -130,7 +139,7 @@ User config file: `~/.klaude/klaude-config.yaml`
|
|
|
130
139
|
Open in editor:
|
|
131
140
|
|
|
132
141
|
```bash
|
|
133
|
-
klaude
|
|
142
|
+
klaude conf
|
|
134
143
|
```
|
|
135
144
|
|
|
136
145
|
##### Model Configuration
|
|
@@ -186,21 +195,6 @@ List configured providers and models:
|
|
|
186
195
|
klaude list
|
|
187
196
|
```
|
|
188
197
|
|
|
189
|
-
### Session Management
|
|
190
|
-
|
|
191
|
-
Clean up sessions with few messages:
|
|
192
|
-
|
|
193
|
-
```bash
|
|
194
|
-
# Remove sessions with fewer than 5 messages (default)
|
|
195
|
-
klaude session clean
|
|
196
|
-
|
|
197
|
-
# Remove sessions with fewer than 10 messages
|
|
198
|
-
klaude session clean --min 10
|
|
199
|
-
|
|
200
|
-
# Remove all sessions for the current project
|
|
201
|
-
klaude session clean-all
|
|
202
|
-
```
|
|
203
|
-
|
|
204
198
|
### Cost Tracking
|
|
205
199
|
|
|
206
200
|
View aggregated usage statistics across all sessions:
|
|
@@ -4,10 +4,10 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "klaude-code"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.7.0"
|
|
8
8
|
description = "Minimal code agent CLI"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.13
|
|
10
|
+
requires-python = ">=3.13"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"anthropic>=0.66.0",
|
|
13
13
|
"chardet>=5.2.0",
|
|
@@ -16,12 +16,10 @@ dependencies = [
|
|
|
16
16
|
"google-genai>=1.56.0",
|
|
17
17
|
"markdown-it-py>=4.0.0",
|
|
18
18
|
"openai>=1.102.0",
|
|
19
|
-
"pillow>=9.1,<11.0",
|
|
20
19
|
"prompt-toolkit>=3.0.52",
|
|
21
20
|
"pydantic>=2.11.7",
|
|
22
21
|
"pyyaml>=6.0.2",
|
|
23
22
|
"rich>=14.1.0",
|
|
24
|
-
"term-image>=0.7.2",
|
|
25
23
|
"trafilatura>=2.0.0",
|
|
26
24
|
"typer>=0.17.3",
|
|
27
25
|
]
|
|
@@ -178,6 +178,6 @@ async def handle_keyboard_interrupt(executor: Executor) -> None:
|
|
|
178
178
|
log("Bye!")
|
|
179
179
|
session_id = executor.context.current_session_id()
|
|
180
180
|
if session_id and Session.exists(session_id):
|
|
181
|
-
log(("Resume with:", "dim"), (f"klaude --resume
|
|
181
|
+
log(("Resume with:", "dim"), (f"klaude --resume {session_id}", "green"))
|
|
182
182
|
with contextlib.suppress(Exception):
|
|
183
183
|
await executor.submit(op.InterruptOperation(target_session_id=None))
|
|
@@ -12,6 +12,12 @@ from klaude_code.auth.codex import (
|
|
|
12
12
|
CodexTokenExpiredError,
|
|
13
13
|
CodexTokenManager,
|
|
14
14
|
)
|
|
15
|
+
from klaude_code.auth.env import (
|
|
16
|
+
delete_auth_env,
|
|
17
|
+
get_auth_env,
|
|
18
|
+
list_auth_env,
|
|
19
|
+
set_auth_env,
|
|
20
|
+
)
|
|
15
21
|
|
|
16
22
|
__all__ = [
|
|
17
23
|
"CodexAuthError",
|
|
@@ -21,4 +27,8 @@ __all__ = [
|
|
|
21
27
|
"CodexOAuthError",
|
|
22
28
|
"CodexTokenExpiredError",
|
|
23
29
|
"CodexTokenManager",
|
|
30
|
+
"delete_auth_env",
|
|
31
|
+
"get_auth_env",
|
|
32
|
+
"list_auth_env",
|
|
33
|
+
"set_auth_env",
|
|
24
34
|
]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Environment variable configuration stored in klaude-auth.json."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import Any, cast
|
|
5
|
+
|
|
6
|
+
from klaude_code.auth.base import KLAUDE_AUTH_FILE
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _load_store() -> dict[str, Any]:
|
|
10
|
+
"""Load the auth store from file."""
|
|
11
|
+
if not KLAUDE_AUTH_FILE.exists():
|
|
12
|
+
return {}
|
|
13
|
+
try:
|
|
14
|
+
data = json.loads(KLAUDE_AUTH_FILE.read_text())
|
|
15
|
+
if isinstance(data, dict):
|
|
16
|
+
return cast(dict[str, Any], data)
|
|
17
|
+
return {}
|
|
18
|
+
except (json.JSONDecodeError, ValueError):
|
|
19
|
+
return {}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _save_store(data: dict[str, Any]) -> None:
|
|
23
|
+
"""Save the auth store to file."""
|
|
24
|
+
KLAUDE_AUTH_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
25
|
+
KLAUDE_AUTH_FILE.write_text(json.dumps(data, indent=2))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _get_env_section(store: dict[str, Any]) -> dict[str, Any] | None:
|
|
29
|
+
"""Extract and validate the 'env' section from store."""
|
|
30
|
+
env_section = store.get("env")
|
|
31
|
+
if isinstance(env_section, dict):
|
|
32
|
+
return cast(dict[str, Any], env_section)
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_auth_env(env_var: str) -> str | None:
|
|
37
|
+
"""Get environment variable value from klaude-auth.json 'env' section.
|
|
38
|
+
|
|
39
|
+
This provides a fallback for API keys when real environment variables are not set.
|
|
40
|
+
Priority: os.environ > klaude-auth.json env
|
|
41
|
+
"""
|
|
42
|
+
env_section = _get_env_section(_load_store())
|
|
43
|
+
if env_section is None:
|
|
44
|
+
return None
|
|
45
|
+
value = env_section.get(env_var)
|
|
46
|
+
return str(value) if value is not None else None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def set_auth_env(env_var: str, value: str) -> None:
|
|
50
|
+
"""Set environment variable value in klaude-auth.json 'env' section."""
|
|
51
|
+
store = _load_store()
|
|
52
|
+
env_section = _get_env_section(store) or {}
|
|
53
|
+
env_section[env_var] = value
|
|
54
|
+
store["env"] = env_section
|
|
55
|
+
_save_store(store)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def delete_auth_env(env_var: str) -> None:
|
|
59
|
+
"""Delete environment variable from klaude-auth.json 'env' section."""
|
|
60
|
+
store = _load_store()
|
|
61
|
+
env_section = _get_env_section(store)
|
|
62
|
+
if env_section is None:
|
|
63
|
+
return
|
|
64
|
+
env_section.pop(env_var, None)
|
|
65
|
+
if len(env_section) == 0:
|
|
66
|
+
store.pop("env", None)
|
|
67
|
+
else:
|
|
68
|
+
store["env"] = env_section
|
|
69
|
+
if len(store) == 0:
|
|
70
|
+
if KLAUDE_AUTH_FILE.exists():
|
|
71
|
+
KLAUDE_AUTH_FILE.unlink()
|
|
72
|
+
else:
|
|
73
|
+
_save_store(store)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def list_auth_env() -> dict[str, str]:
|
|
77
|
+
"""List all environment variables in klaude-auth.json 'env' section."""
|
|
78
|
+
env_section = _get_env_section(_load_store())
|
|
79
|
+
if env_section is None:
|
|
80
|
+
return {}
|
|
81
|
+
return {k: str(v) for k, v in env_section.items() if v is not None}
|
|
@@ -11,10 +11,30 @@ from klaude_code.tui.terminal.selector import DEFAULT_PICKER_STYLE, SelectItem,
|
|
|
11
11
|
|
|
12
12
|
def _select_provider() -> str | None:
|
|
13
13
|
"""Display provider selection menu and return selected provider."""
|
|
14
|
+
from klaude_code.config.builtin_config import SUPPORTED_API_KEYS
|
|
15
|
+
|
|
14
16
|
items: list[SelectItem[str]] = [
|
|
15
|
-
SelectItem(
|
|
16
|
-
|
|
17
|
+
SelectItem(
|
|
18
|
+
title=[("", "Claude Max/Pro Subscription "), ("ansibrightblack", "[OAuth]\n")],
|
|
19
|
+
value="claude",
|
|
20
|
+
search_text="claude",
|
|
21
|
+
),
|
|
22
|
+
SelectItem(
|
|
23
|
+
title=[("", "ChatGPT Codex Subscription "), ("ansibrightblack", "[OAuth]\n")],
|
|
24
|
+
value="codex",
|
|
25
|
+
search_text="codex",
|
|
26
|
+
),
|
|
17
27
|
]
|
|
28
|
+
# Add API key options
|
|
29
|
+
for key_info in SUPPORTED_API_KEYS:
|
|
30
|
+
items.append(
|
|
31
|
+
SelectItem(
|
|
32
|
+
title=[("", f"{key_info.name} "), ("ansibrightblack", "[API key]\n")],
|
|
33
|
+
value=key_info.env_var,
|
|
34
|
+
search_text=key_info.env_var,
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
|
|
18
38
|
return select_one(
|
|
19
39
|
message="Select provider to login:",
|
|
20
40
|
items=items,
|
|
@@ -24,10 +44,41 @@ def _select_provider() -> str | None:
|
|
|
24
44
|
)
|
|
25
45
|
|
|
26
46
|
|
|
47
|
+
def _configure_api_key(env_var: str) -> None:
|
|
48
|
+
"""Configure a specific API key."""
|
|
49
|
+
import os
|
|
50
|
+
|
|
51
|
+
from klaude_code.auth.env import get_auth_env, set_auth_env
|
|
52
|
+
|
|
53
|
+
# Check if already configured
|
|
54
|
+
current_value = os.environ.get(env_var) or get_auth_env(env_var)
|
|
55
|
+
if current_value:
|
|
56
|
+
masked = current_value[:8] + "..." if len(current_value) > 8 else "***"
|
|
57
|
+
log(f"Current {env_var}: {masked}")
|
|
58
|
+
if not typer.confirm("Do you want to update it?"):
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
api_key = typer.prompt(f"Enter {env_var}", hide_input=True)
|
|
62
|
+
if not api_key.strip():
|
|
63
|
+
log(("Error: API key cannot be empty", "red"))
|
|
64
|
+
raise typer.Exit(1)
|
|
65
|
+
|
|
66
|
+
set_auth_env(env_var, api_key.strip())
|
|
67
|
+
log((f"{env_var} saved successfully!", "green"))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _build_provider_help() -> str:
|
|
71
|
+
from klaude_code.config.builtin_config import SUPPORTED_API_KEYS
|
|
72
|
+
|
|
73
|
+
# Use first word of name for brevity (e.g., "google" instead of "google gemini")
|
|
74
|
+
names = ["codex", "claude"] + [k.name.split()[0].lower() for k in SUPPORTED_API_KEYS]
|
|
75
|
+
return f"Provider name ({', '.join(names)})"
|
|
76
|
+
|
|
77
|
+
|
|
27
78
|
def login_command(
|
|
28
|
-
provider: str | None = typer.Argument(None, help=
|
|
79
|
+
provider: str | None = typer.Argument(None, help=_build_provider_help()),
|
|
29
80
|
) -> None:
|
|
30
|
-
"""Login to a provider
|
|
81
|
+
"""Login to a provider or configure API keys."""
|
|
31
82
|
if provider is None:
|
|
32
83
|
provider = _select_provider()
|
|
33
84
|
if provider is None:
|
|
@@ -99,8 +150,27 @@ def login_command(
|
|
|
99
150
|
log((f"Login failed: {e}", "red"))
|
|
100
151
|
raise typer.Exit(1) from None
|
|
101
152
|
case _:
|
|
102
|
-
|
|
103
|
-
|
|
153
|
+
from klaude_code.config.builtin_config import SUPPORTED_API_KEYS
|
|
154
|
+
|
|
155
|
+
# Match by env var (e.g., OPENAI_API_KEY) or name (e.g., openai, google)
|
|
156
|
+
env_var: str | None = None
|
|
157
|
+
provider_lower = provider.lower()
|
|
158
|
+
provider_upper = provider.upper()
|
|
159
|
+
for key_info in SUPPORTED_API_KEYS:
|
|
160
|
+
name_lower = key_info.name.lower()
|
|
161
|
+
# Exact match or starts with (for "google" -> "google gemini")
|
|
162
|
+
if key_info.env_var == provider_upper or name_lower == provider_lower:
|
|
163
|
+
env_var = key_info.env_var
|
|
164
|
+
break
|
|
165
|
+
if name_lower.startswith(provider_lower) or provider_lower in name_lower.split():
|
|
166
|
+
env_var = key_info.env_var
|
|
167
|
+
break
|
|
168
|
+
|
|
169
|
+
if env_var:
|
|
170
|
+
_configure_api_key(env_var)
|
|
171
|
+
else:
|
|
172
|
+
log((f"Error: Unknown provider '{provider}'", "red"))
|
|
173
|
+
raise typer.Exit(1)
|
|
104
174
|
|
|
105
175
|
|
|
106
176
|
def logout_command(
|
|
@@ -139,5 +209,14 @@ def logout_command(
|
|
|
139
209
|
|
|
140
210
|
def register_auth_commands(app: typer.Typer) -> None:
|
|
141
211
|
"""Register auth commands to the given Typer app."""
|
|
142
|
-
|
|
143
|
-
|
|
212
|
+
auth_app = typer.Typer(help="Login/logout", invoke_without_command=True)
|
|
213
|
+
|
|
214
|
+
@auth_app.callback()
|
|
215
|
+
def auth_callback(ctx: typer.Context) -> None: # pyright: ignore[reportUnusedFunction]
|
|
216
|
+
"""Authentication commands for managing provider logins."""
|
|
217
|
+
if ctx.invoked_subcommand is None:
|
|
218
|
+
typer.echo(ctx.get_help())
|
|
219
|
+
|
|
220
|
+
auth_app.command("login")(login_command)
|
|
221
|
+
auth_app.command("logout")(logout_command)
|
|
222
|
+
app.add_typer(auth_app, name="auth")
|
|
@@ -11,9 +11,9 @@ from klaude_code.log import log
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def list_models(
|
|
14
|
-
show_all: bool = typer.Option(False, "--all", "-a", help="
|
|
14
|
+
show_all: bool = typer.Option(False, "--all", "-a", help="Include unavailable providers"),
|
|
15
15
|
) -> None:
|
|
16
|
-
"""List
|
|
16
|
+
"""List available models"""
|
|
17
17
|
from klaude_code.cli.list_model import display_models_and_providers
|
|
18
18
|
from klaude_code.tui.terminal.color import is_light_terminal_background
|
|
19
19
|
|
|
@@ -31,7 +31,7 @@ def list_models(
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
def edit_config() -> None:
|
|
34
|
-
"""
|
|
34
|
+
"""Edit config file"""
|
|
35
35
|
editor = os.environ.get("EDITOR")
|
|
36
36
|
|
|
37
37
|
# If no EDITOR is set, prioritize TextEdit on macOS
|
|
@@ -89,5 +89,5 @@ def edit_config() -> None:
|
|
|
89
89
|
def register_config_commands(app: typer.Typer) -> None:
|
|
90
90
|
"""Register config commands to the given Typer app."""
|
|
91
91
|
app.command("list")(list_models)
|
|
92
|
-
app.command("
|
|
93
|
-
app.command("
|
|
92
|
+
app.command("conf")(edit_config)
|
|
93
|
+
app.command("config", hidden=True)(edit_config)
|