klaude-code 2.21.0__tar.gz → 2.22.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.21.0 → klaude_code-2.22.0}/PKG-INFO +18 -5
- {klaude_code-2.21.0 → klaude_code-2.22.0}/README.md +16 -3
- {klaude_code-2.21.0 → klaude_code-2.22.0}/pyproject.toml +2 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/app/auth_flow.py +7 -7
- {klaude_code-2.21.0/src/klaude_code/cli → klaude_code-2.22.0/src/klaude_code/app}/log_viewer.html +107 -4
- klaude_code-2.21.0/src/klaude_code/cli/log_server.py → klaude_code-2.22.0/src/klaude_code/app/log_viewer.py +71 -8
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/copilot/oauth.py +3 -1
- klaude_code-2.22.0/src/klaude_code/auth/copilot/token_manager.py +64 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/cli/auth_cmd.py +2 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/cli/list_model.py +85 -24
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/cli/main.py +2 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/cli/oauth_usage.py +8 -8
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/config/assets/builtin_config.yaml +28 -36
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/config/builtin_config.py +1 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/config/config.py +89 -28
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/config/sub_agent_model_helper.py +15 -15
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/config/thinking.py +5 -5
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/agent.py +16 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/agent_profile.py +16 -21
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/executor.py +48 -46
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/manager/llm_clients.py +0 -5
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/manager/llm_clients_builder.py +5 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/manager/sub_agent_manager.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/memory.py +4 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/prompts/base-system-prompt.md +2 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/prompts/system_prompt.py +11 -4
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/reminders.py +0 -91
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/task.py +17 -3
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/__init__.py +14 -3
- klaude_code-2.21.0/src/klaude_code/core/tool/task_tool.md → klaude_code-2.22.0/src/klaude_code/core/tool/agent_tool.md +3 -3
- klaude_code-2.21.0/src/klaude_code/core/tool/task_tool.py → klaude_code-2.22.0/src/klaude_code/core/tool/agent_tool.py +19 -17
- klaude_code-2.22.0/src/klaude_code/core/tool/ask_user_question_tool.md +9 -0
- klaude_code-2.22.0/src/klaude_code/core/tool/ask_user_question_tool.py +255 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/context.py +15 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/rewind_tool.md +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/turn.py +21 -1
- klaude_code-2.22.0/src/klaude_code/core/user_interaction/__init__.py +3 -0
- klaude_code-2.22.0/src/klaude_code/core/user_interaction/manager.py +114 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/anthropic/client.py +3 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/anthropic/input.py +6 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/copilot/client.py +4 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/google/input.py +11 -3
- klaude_code-2.22.0/src/klaude_code/llm/image.py +323 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/input_common.py +7 -7
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openai_responses/input.py +2 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/registry.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/__init__.py +1 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/commands.py +1 -3
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/events.py +9 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/llm_param.py +18 -4
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/message.py +3 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/model.py +7 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/op.py +14 -11
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/op_handler.py +5 -5
- klaude_code-2.22.0/src/klaude_code/protocol/sub_agent/AGENTS.md +18 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/sub_agent/__init__.py +4 -4
- klaude_code-2.21.0/src/klaude_code/protocol/sub_agent/task.py → klaude_code-2.22.0/src/klaude_code/protocol/sub_agent/general_purpose.py +2 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/tools.py +2 -1
- klaude_code-2.22.0/src/klaude_code/protocol/user_interaction.py +50 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/session/session.py +4 -4
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/nano-banana-image-gen/SKILL.md +8 -7
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/cli.md +16 -7
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/gemini-api.md +15 -6
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/prompting.md +4 -3
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/sample-prompts.md +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/nano-banana-image-gen/scripts/gemini_image_gen.py +118 -49
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/__init__.py +9 -15
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/auth_selector.py +15 -9
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/compact_cmd.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/continue_cmd.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/debug_cmd.py +9 -14
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/export_cmd.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/fork_session_cmd.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/model_cmd.py +1 -1
- klaude_code-2.21.0/src/klaude_code/tui/command/clear_cmd.py → klaude_code-2.22.0/src/klaude_code/tui/command/new_cmd.py +4 -4
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/registry.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/status_cmd.py +61 -55
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/sub_agent_model_cmd.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/thinking_cmd.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/command_output.py +56 -15
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/developer.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/metadata.py +87 -12
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/rich/theme.py +14 -7
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/tools.py +80 -20
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/welcome.py +13 -4
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/display.py +19 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/input/completers.py +107 -23
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/input/images.py +0 -127
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/input/key_bindings.py +1 -1
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/input/prompt_toolkit.py +53 -2
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/machine.py +22 -7
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/renderer.py +1 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/runner.py +163 -49
- klaude_code-2.22.0/src/klaude_code/tui/terminal/ask_user_question.py +772 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/terminal/control.py +27 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/terminal/notifier.py +1 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/terminal/selector.py +63 -20
- klaude_code-2.21.0/src/klaude_code/tui/command/resume_cmd.py → klaude_code-2.22.0/src/klaude_code/tui/terminal/session_selector.py +0 -46
- klaude_code-2.21.0/src/klaude_code/.DS_Store +0 -0
- klaude_code-2.21.0/src/klaude_code/auth/copilot/token_manager.py +0 -27
- klaude_code-2.21.0/src/klaude_code/llm/image.py +0 -67
- klaude_code-2.21.0/src/klaude_code/protocol/sub_agent/AGENTS.md +0 -19
- klaude_code-2.21.0/src/klaude_code/skill/.DS_Store +0 -0
- klaude_code-2.21.0/src/klaude_code/skill/assets/.DS_Store +0 -0
- klaude_code-2.21.0/src/klaude_code/skill/assets/gpt-image-gen/.DS_Store +0 -0
- klaude_code-2.21.0/src/klaude_code/tui/command/export_online_cmd.py +0 -150
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/app/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/app/runtime.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/AGENTS.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/base.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/claude/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/claude/exceptions.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/claude/oauth.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/claude/token_manager.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/codex/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/codex/exceptions.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/codex/oauth.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/codex/token_manager.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/copilot/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/copilot/exceptions.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/auth/env.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/cli/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/cli/config_cmd.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/cli/cost_cmd.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/cli/debug.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/cli/self_update.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/config/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/config/assets/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/config/model_matcher.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/const.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/bash_mode.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/compaction/AGENTS.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/compaction/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/compaction/compaction.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/compaction/overflow.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/compaction/prompts.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/loaded_skills.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/manager/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/prompts/auto-memory-prompt.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/rewind/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/rewind/manager.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/_utils.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/diff_builder.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/read_tool.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/read_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/write_tool.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/file/write_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/offload.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/report_back_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/rewind_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/shell/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/shell/bash_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/todo/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/tool_abc.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/tool_registry.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/tool_runner.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/web/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/web/external_content.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/web/ssrf.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/web/web_cache.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/web/web_fetch_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/web/web_search_tool.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/core/tool/web/web_search_tool.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/anthropic/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/bedrock_anthropic/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/bedrock_anthropic/client.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/claude/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/claude/client.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/client.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/copilot/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/google/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/google/client.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/google_vertex/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/google_vertex/client.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/json_stable.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openai_codex/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openai_codex/client.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openai_compatible/client.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openai_compatible/input.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openai_compatible/stream.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openai_responses/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openai_responses/client.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openrouter/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openrouter/client.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openrouter/input.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/openrouter/reasoning.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/partial_message.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/stream_parts.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/llm/usage.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/log.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/model_id.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/protocol/sub_agent/explore.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/session/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/session/codec.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/session/export.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/session/selector.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/session/store.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/session/templates/export_session.html +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/deslop/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/executing-plans/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/frontend-design/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/gpt-image-gen/LICENSE.txt +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/gpt-image-gen/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/gpt-image-gen/references/cli.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/gpt-image-gen/references/codex-network.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/gpt-image-gen/references/image-api.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/gpt-image-gen/references/prompting.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/gpt-image-gen/references/sample-prompts.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/gpt-image-gen/scripts/image_gen.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/vertex-setup.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/forms.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/reference.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/scripts/check_bounding_boxes.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/scripts/check_fillable_fields.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/scripts/convert_pdf_to_images.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/scripts/create_validation_image.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/scripts/extract_form_field_info.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/scripts/extract_form_structure.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/scripts/fill_fillable_fields.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/pdf/scripts/fill_pdf_form_with_annotations.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/render-mermaid/.gitignore +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/render-mermaid/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/render-mermaid/bun.lock +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/render-mermaid/package.json +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/render-mermaid/scripts/render_mermaid.js +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/session-logs/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/skill-creator/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/web-search/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/assets/writing-plans/SKILL.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/loader.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/manager.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/skill/system_skills.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/command_abc.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/copy_cmd.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/login_cmd.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/logout_cmd.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/model_picker.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/prompt-init.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/prompt_command.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/command/refresh_cmd.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/commands.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/bash_syntax.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/common.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/diffs.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/errors.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/rich/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/rich/cjk_wrap.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/rich/code_panel.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/rich/live.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/rich/markdown.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/rich/quote.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/rich/status.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/sub_agent.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/thinking.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/components/user_input.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/input/AGENTS.md +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/input/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/input/drag_drop.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/input/paste.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/terminal/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/terminal/color.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/terminal/image.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/tui/terminal/progress_bar.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/ui/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/ui/common.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/ui/core/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/ui/core/display.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/ui/core/input.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/ui/terminal/__init__.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.0}/src/klaude_code/ui/terminal/title.py +0 -0
- {klaude_code-2.21.0 → klaude_code-2.22.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.22.0
|
|
4
4
|
Summary: Minimal code agent CLI
|
|
5
5
|
Requires-Dist: anthropic>=0.66.0
|
|
6
6
|
Requires-Dist: chardet>=5.2.0,<6
|
|
@@ -9,7 +9,7 @@ Requires-Dist: diff-match-patch>=20241021
|
|
|
9
9
|
Requires-Dist: filelock>=3.20.3
|
|
10
10
|
Requires-Dist: google-genai>=1.56.0
|
|
11
11
|
Requires-Dist: markdown-it-py>=4.0.0
|
|
12
|
-
Requires-Dist: openai>=
|
|
12
|
+
Requires-Dist: openai>=2.24.0
|
|
13
13
|
Requires-Dist: prompt-toolkit>=3.0.52
|
|
14
14
|
Requires-Dist: pydantic>=2.11.7
|
|
15
15
|
Requires-Dist: python-socks>=2.8.1
|
|
@@ -29,7 +29,7 @@ Minimal code agent CLI.
|
|
|
29
29
|
- **Keep reasoning item in context**: Interleaved thinking support
|
|
30
30
|
- **Model-aware tools**: Claude Code tool set for Opus, `apply_patch` for GPT-5/Codex
|
|
31
31
|
- **Reminders**: Cooldown-based todo tracking, instruction reinforcement and external file change reminder
|
|
32
|
-
- **Sub-agents**: Task, Explore
|
|
32
|
+
- **Sub-agents**: Task, Explore
|
|
33
33
|
- **Structured sub-agent output**: Main agent defines JSON schema and get schema-compliant responses via constrained decoding
|
|
34
34
|
- **Recursive `@file` mentions**: Circular dependency protection, relative path resolution
|
|
35
35
|
- **External file sync**: Monitoring for external edits (linter, manual)
|
|
@@ -197,6 +197,21 @@ provider_list:
|
|
|
197
197
|
- **Overriding**: Use the same `model_name` as a built-in model to override its parameters.
|
|
198
198
|
- **Environment Variables**: Use `${VAR_NAME}` syntax for secrets.
|
|
199
199
|
|
|
200
|
+
##### Sub-agent Model Configuration
|
|
201
|
+
|
|
202
|
+
`sub_agent_models` only accepts sub-agent types. Current supported keys are:
|
|
203
|
+
|
|
204
|
+
- `general-purpose` (Task sub-agent)
|
|
205
|
+
- `explore` (Explore sub-agent)
|
|
206
|
+
|
|
207
|
+
If a sub-agent type is not configured, it falls back to the main agent model.
|
|
208
|
+
|
|
209
|
+
```yaml
|
|
210
|
+
sub_agent_models:
|
|
211
|
+
general-purpose: sonnet
|
|
212
|
+
explore: haiku
|
|
213
|
+
```
|
|
214
|
+
|
|
200
215
|
##### Supported Protocols
|
|
201
216
|
|
|
202
217
|
- `anthropic` - Anthropic Messages API
|
|
@@ -243,7 +258,6 @@ Inside the interactive session (`klaude`), use these commands to streamline your
|
|
|
243
258
|
- `/resume` - Select and resume a previous session.
|
|
244
259
|
- `/fork-session` - Fork current session to a new session ID (supports interactive fork point selection).
|
|
245
260
|
- `/export` - Export last assistant message to a temp Markdown file.
|
|
246
|
-
- `/export-online` - Export and deploy session to surge.sh as a static webpage.
|
|
247
261
|
- `/debug [filters]` - Toggle debug mode and configure debug filters.
|
|
248
262
|
- `/init` - Bootstrap a new project structure or module.
|
|
249
263
|
- `/dev-doc [feature]` - Generate a comprehensive execution plan for a feature.
|
|
@@ -273,4 +287,3 @@ The main agent can spawn specialized sub-agents for specific tasks:
|
|
|
273
287
|
|-----------|---------|
|
|
274
288
|
| **Explore** | Fast codebase exploration - find files, search code, answer questions about the codebase |
|
|
275
289
|
| **Task** | Handle complex multi-step tasks autonomously |
|
|
276
|
-
| **WebAgent** | Search the web, fetch pages, and analyze content. Uses Brave LLM Context API when `BRAVE_API_KEY` is set, otherwise falls back to DuckDuckGo |
|
|
@@ -7,7 +7,7 @@ Minimal code agent CLI.
|
|
|
7
7
|
- **Keep reasoning item in context**: Interleaved thinking support
|
|
8
8
|
- **Model-aware tools**: Claude Code tool set for Opus, `apply_patch` for GPT-5/Codex
|
|
9
9
|
- **Reminders**: Cooldown-based todo tracking, instruction reinforcement and external file change reminder
|
|
10
|
-
- **Sub-agents**: Task, Explore
|
|
10
|
+
- **Sub-agents**: Task, Explore
|
|
11
11
|
- **Structured sub-agent output**: Main agent defines JSON schema and get schema-compliant responses via constrained decoding
|
|
12
12
|
- **Recursive `@file` mentions**: Circular dependency protection, relative path resolution
|
|
13
13
|
- **External file sync**: Monitoring for external edits (linter, manual)
|
|
@@ -175,6 +175,21 @@ provider_list:
|
|
|
175
175
|
- **Overriding**: Use the same `model_name` as a built-in model to override its parameters.
|
|
176
176
|
- **Environment Variables**: Use `${VAR_NAME}` syntax for secrets.
|
|
177
177
|
|
|
178
|
+
##### Sub-agent Model Configuration
|
|
179
|
+
|
|
180
|
+
`sub_agent_models` only accepts sub-agent types. Current supported keys are:
|
|
181
|
+
|
|
182
|
+
- `general-purpose` (Task sub-agent)
|
|
183
|
+
- `explore` (Explore sub-agent)
|
|
184
|
+
|
|
185
|
+
If a sub-agent type is not configured, it falls back to the main agent model.
|
|
186
|
+
|
|
187
|
+
```yaml
|
|
188
|
+
sub_agent_models:
|
|
189
|
+
general-purpose: sonnet
|
|
190
|
+
explore: haiku
|
|
191
|
+
```
|
|
192
|
+
|
|
178
193
|
##### Supported Protocols
|
|
179
194
|
|
|
180
195
|
- `anthropic` - Anthropic Messages API
|
|
@@ -221,7 +236,6 @@ Inside the interactive session (`klaude`), use these commands to streamline your
|
|
|
221
236
|
- `/resume` - Select and resume a previous session.
|
|
222
237
|
- `/fork-session` - Fork current session to a new session ID (supports interactive fork point selection).
|
|
223
238
|
- `/export` - Export last assistant message to a temp Markdown file.
|
|
224
|
-
- `/export-online` - Export and deploy session to surge.sh as a static webpage.
|
|
225
239
|
- `/debug [filters]` - Toggle debug mode and configure debug filters.
|
|
226
240
|
- `/init` - Bootstrap a new project structure or module.
|
|
227
241
|
- `/dev-doc [feature]` - Generate a comprehensive execution plan for a feature.
|
|
@@ -251,4 +265,3 @@ The main agent can spawn specialized sub-agents for specific tasks:
|
|
|
251
265
|
|-----------|---------|
|
|
252
266
|
| **Explore** | Fast codebase exploration - find files, search code, answer questions about the codebase |
|
|
253
267
|
| **Task** | Handle complex multi-step tasks autonomously |
|
|
254
|
-
| **WebAgent** | Search the web, fetch pages, and analyze content. Uses Brave LLM Context API when `BRAVE_API_KEY` is set, otherwise falls back to DuckDuckGo |
|
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "klaude-code"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.22.0"
|
|
8
8
|
description = "Minimal code agent CLI"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13"
|
|
@@ -16,7 +16,7 @@ dependencies = [
|
|
|
16
16
|
"filelock>=3.20.3",
|
|
17
17
|
"google-genai>=1.56.0",
|
|
18
18
|
"markdown-it-py>=4.0.0",
|
|
19
|
-
"openai>=
|
|
19
|
+
"openai>=2.24.0",
|
|
20
20
|
"prompt-toolkit>=3.0.52",
|
|
21
21
|
"pydantic>=2.11.7",
|
|
22
22
|
"python-socks>=2.8.1",
|
|
@@ -136,7 +136,7 @@ def execute_login(provider: str) -> None:
|
|
|
136
136
|
except Exception as e:
|
|
137
137
|
log((f"Login failed: {e}", "red"))
|
|
138
138
|
raise typer.Exit(1) from None
|
|
139
|
-
case "copilot":
|
|
139
|
+
case "github-copilot" | "copilot":
|
|
140
140
|
from klaude_code.auth.copilot.oauth import CopilotOAuth
|
|
141
141
|
from klaude_code.auth.copilot.token_manager import CopilotTokenManager
|
|
142
142
|
|
|
@@ -145,7 +145,7 @@ def execute_login(provider: str) -> None:
|
|
|
145
145
|
if token_manager.is_logged_in():
|
|
146
146
|
state = token_manager.get_state()
|
|
147
147
|
if state and not state.is_expired():
|
|
148
|
-
log(("You are already logged in to Copilot.", "green"))
|
|
148
|
+
log(("You are already logged in to GitHub Copilot.", "green"))
|
|
149
149
|
domain = state.enterprise_domain or "github.com"
|
|
150
150
|
expires_dt = datetime.datetime.fromtimestamp(state.expires_at, tz=datetime.UTC)
|
|
151
151
|
log(f" Domain: {domain}")
|
|
@@ -232,18 +232,18 @@ def execute_logout(provider: str) -> None:
|
|
|
232
232
|
if typer.confirm("Are you sure you want to logout from Claude?"):
|
|
233
233
|
token_manager.delete()
|
|
234
234
|
log(("Logged out from Claude.", "green"))
|
|
235
|
-
case "copilot":
|
|
235
|
+
case "github-copilot" | "copilot":
|
|
236
236
|
from klaude_code.auth.copilot.token_manager import CopilotTokenManager
|
|
237
237
|
|
|
238
238
|
token_manager = CopilotTokenManager()
|
|
239
239
|
|
|
240
240
|
if not token_manager.is_logged_in():
|
|
241
|
-
log("You are not logged in to Copilot.")
|
|
241
|
+
log("You are not logged in to GitHub Copilot.")
|
|
242
242
|
return
|
|
243
243
|
|
|
244
|
-
if typer.confirm("Are you sure you want to logout from Copilot?"):
|
|
244
|
+
if typer.confirm("Are you sure you want to logout from GitHub Copilot?"):
|
|
245
245
|
token_manager.delete()
|
|
246
|
-
log(("Logged out from Copilot.", "green"))
|
|
246
|
+
log(("Logged out from GitHub Copilot.", "green"))
|
|
247
247
|
case _:
|
|
248
|
-
log((f"Error: Unknown provider '{provider}'. Supported: codex, claude, copilot", "red"))
|
|
248
|
+
log((f"Error: Unknown provider '{provider}'. Supported: codex, claude, github-copilot", "red"))
|
|
249
249
|
raise typer.Exit(1)
|
{klaude_code-2.21.0/src/klaude_code/cli → klaude_code-2.22.0/src/klaude_code/app}/log_viewer.html
RENAMED
|
@@ -86,6 +86,25 @@ body {
|
|
|
86
86
|
flex: 1;
|
|
87
87
|
letter-spacing: -0.01em;
|
|
88
88
|
}
|
|
89
|
+
.nav-btn {
|
|
90
|
+
background: var(--bg-surface);
|
|
91
|
+
border: 1px solid var(--border);
|
|
92
|
+
color: var(--fg-secondary);
|
|
93
|
+
padding: 4px 10px;
|
|
94
|
+
border-radius: 6px;
|
|
95
|
+
font-size: 16px;
|
|
96
|
+
font-weight: 700;
|
|
97
|
+
font-family: var(--font-sans);
|
|
98
|
+
cursor: pointer;
|
|
99
|
+
transition: all 0.2s ease;
|
|
100
|
+
white-space: nowrap;
|
|
101
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.02);
|
|
102
|
+
}
|
|
103
|
+
.nav-btn:hover {
|
|
104
|
+
background: var(--bg-hover);
|
|
105
|
+
color: var(--fg);
|
|
106
|
+
border-color: var(--border-strong);
|
|
107
|
+
}
|
|
89
108
|
#toolbar .filter-group {
|
|
90
109
|
display: flex;
|
|
91
110
|
gap: 6px;
|
|
@@ -379,6 +398,7 @@ body {
|
|
|
379
398
|
<div id="container">
|
|
380
399
|
<div id="left">
|
|
381
400
|
<div id="toolbar">
|
|
401
|
+
<button class="nav-btn" id="btn-back-list" title="Back to log files">Logs</button>
|
|
382
402
|
<span class="title" id="log-title">No log loaded</span>
|
|
383
403
|
<input type="text" id="search-box" placeholder="Search... (/)">
|
|
384
404
|
<div class="filter-group" id="filter-group"></div>
|
|
@@ -408,15 +428,76 @@ let selectedIdx = -1;
|
|
|
408
428
|
let activeFilters = new Set();
|
|
409
429
|
let searchQuery = '';
|
|
410
430
|
let showRaw = false;
|
|
431
|
+
let viewerMode = 'files';
|
|
432
|
+
|
|
433
|
+
function setViewerMode(mode) {
|
|
434
|
+
viewerMode = mode;
|
|
435
|
+
const isLogMode = mode === 'log';
|
|
436
|
+
document.getElementById('btn-back-list').style.display = isLogMode ? '' : 'none';
|
|
437
|
+
document.getElementById('search-box').style.display = isLogMode ? '' : 'none';
|
|
438
|
+
document.getElementById('filter-group').style.display = isLogMode ? '' : 'none';
|
|
439
|
+
for (const id of ['btn-copy', 'btn-expand-all', 'btn-collapse-all', 'btn-raw']) {
|
|
440
|
+
document.getElementById(id).disabled = !isLogMode;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
document.getElementById('btn-back-list').addEventListener('click', () => {
|
|
445
|
+
location.search = '';
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
async function loadLogList() {
|
|
449
|
+
setViewerMode('files');
|
|
450
|
+
const title = document.getElementById('log-title');
|
|
451
|
+
const list = document.getElementById('log-list');
|
|
452
|
+
const label = document.getElementById('right-label');
|
|
453
|
+
const view = document.getElementById('json-view');
|
|
454
|
+
title.textContent = 'Log files';
|
|
455
|
+
label.textContent = 'Select a log file';
|
|
456
|
+
view.innerHTML = '<span class="empty-hint">Choose a log file from the left list</span>';
|
|
457
|
+
list.innerHTML = '<div class="log-line"><span class="msg">Loading...</span></div>';
|
|
458
|
+
|
|
459
|
+
try {
|
|
460
|
+
const resp = await fetch('/api/logs');
|
|
461
|
+
if (!resp.ok) throw new Error(resp.statusText);
|
|
462
|
+
const files = await resp.json();
|
|
463
|
+
list.innerHTML = '';
|
|
464
|
+
|
|
465
|
+
if (files.length === 0) {
|
|
466
|
+
list.innerHTML = '<div class="log-line"><span class="msg">No log files found</span></div>';
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const frag = document.createDocumentFragment();
|
|
471
|
+
files.forEach((file, idx) => {
|
|
472
|
+
const div = document.createElement('div');
|
|
473
|
+
div.className = 'log-line';
|
|
474
|
+
const mtime = new Date(file.mtime * 1000).toLocaleString();
|
|
475
|
+
div.innerHTML =
|
|
476
|
+
'<span class="lineno">' + (idx + 1) + '</span>' +
|
|
477
|
+
'<span class="ts">' + esc(mtime) + '</span> ' +
|
|
478
|
+
'<span class="msg">' + esc(file.relative_path) + '</span> ' +
|
|
479
|
+
'<span class="json-inline">' + esc(formatBytes(file.size_bytes)) + '</span>';
|
|
480
|
+
div.addEventListener('click', () => {
|
|
481
|
+
location.search = '?log=' + encodeURIComponent(file.path);
|
|
482
|
+
});
|
|
483
|
+
frag.appendChild(div);
|
|
484
|
+
});
|
|
485
|
+
list.appendChild(frag);
|
|
486
|
+
} catch (e) {
|
|
487
|
+
title.textContent = 'Error: ' + e.message;
|
|
488
|
+
list.innerHTML = '<div class="log-line"><span class="msg">Failed to load log files</span></div>';
|
|
489
|
+
}
|
|
490
|
+
}
|
|
411
491
|
|
|
412
492
|
// --- Data loading ---
|
|
413
493
|
async function loadLog() {
|
|
414
494
|
const params = new URLSearchParams(location.search);
|
|
415
495
|
const logPath = params.get('log');
|
|
416
496
|
if (!logPath) {
|
|
417
|
-
|
|
497
|
+
await loadLogList();
|
|
418
498
|
return;
|
|
419
499
|
}
|
|
500
|
+
setViewerMode('log');
|
|
420
501
|
document.getElementById('log-title').textContent = logPath.split('/').slice(-2).join('/');
|
|
421
502
|
try {
|
|
422
503
|
const resp = await fetch('/api/log?path=' + encodeURIComponent(logPath));
|
|
@@ -495,13 +576,28 @@ function toggleFilter(type, btn) {
|
|
|
495
576
|
btn.classList.add('active');
|
|
496
577
|
}
|
|
497
578
|
applyFilters();
|
|
579
|
+
|
|
580
|
+
if (selectedIdx >= 0) {
|
|
581
|
+
const list = document.getElementById('log-list');
|
|
582
|
+
const selected = list.children[selectedIdx];
|
|
583
|
+
if (selected && !selected.classList.contains('hidden')) {
|
|
584
|
+
const listRect = list.getBoundingClientRect();
|
|
585
|
+
const rowRect = selected.getBoundingClientRect();
|
|
586
|
+
const fullyVisible = rowRect.top >= listRect.top && rowRect.bottom <= listRect.bottom;
|
|
587
|
+
if (!fullyVisible) {
|
|
588
|
+
selected.scrollIntoView({ block: 'center' });
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
498
592
|
}
|
|
499
593
|
|
|
500
594
|
function applyFilters() {
|
|
595
|
+
if (viewerMode !== 'log') return;
|
|
501
596
|
const list = document.getElementById('log-list');
|
|
502
597
|
const items = list.children;
|
|
503
598
|
for (let i = 0; i < items.length; i++) {
|
|
504
599
|
const entry = logLines[i];
|
|
600
|
+
if (!entry) continue;
|
|
505
601
|
let visible = true;
|
|
506
602
|
if (activeFilters.size > 0 && entry.type && !activeFilters.has(entry.type)) {
|
|
507
603
|
visible = false;
|
|
@@ -776,11 +872,12 @@ document.getElementById('btn-raw').addEventListener('click', () => {
|
|
|
776
872
|
// --- Search ---
|
|
777
873
|
const searchBox = document.getElementById('search-box');
|
|
778
874
|
searchBox.addEventListener('input', () => {
|
|
875
|
+
if (viewerMode !== 'log') return;
|
|
779
876
|
searchQuery = searchBox.value.toLowerCase();
|
|
780
877
|
applyFilters();
|
|
781
878
|
});
|
|
782
879
|
document.addEventListener('keydown', (e) => {
|
|
783
|
-
if (e.key === '/' && document.activeElement !== searchBox) {
|
|
880
|
+
if (viewerMode === 'log' && e.key === '/' && document.activeElement !== searchBox) {
|
|
784
881
|
e.preventDefault();
|
|
785
882
|
searchBox.focus();
|
|
786
883
|
}
|
|
@@ -788,16 +885,17 @@ document.addEventListener('keydown', (e) => {
|
|
|
788
885
|
searchBox.value = '';
|
|
789
886
|
searchQuery = '';
|
|
790
887
|
searchBox.blur();
|
|
791
|
-
applyFilters();
|
|
888
|
+
if (viewerMode === 'log') applyFilters();
|
|
792
889
|
}
|
|
793
890
|
// Arrow keys for navigation
|
|
794
|
-
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
|
|
891
|
+
if (viewerMode === 'log' && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
|
|
795
892
|
e.preventDefault();
|
|
796
893
|
navigateLine(e.key === 'ArrowDown' ? 1 : -1);
|
|
797
894
|
}
|
|
798
895
|
});
|
|
799
896
|
|
|
800
897
|
function navigateLine(direction) {
|
|
898
|
+
if (viewerMode !== 'log') return;
|
|
801
899
|
const list = document.getElementById('log-list');
|
|
802
900
|
let next = selectedIdx + direction;
|
|
803
901
|
// Skip hidden lines
|
|
@@ -952,6 +1050,11 @@ function badgeify(s) {
|
|
|
952
1050
|
return esc(s).replace(/\[([\w.]+)\]/g, '<span class="badge">$1</span>');
|
|
953
1051
|
}
|
|
954
1052
|
function truncate(s, n) { return s.length <= n ? s : s.slice(0, n) + '...'; }
|
|
1053
|
+
function formatBytes(bytes) {
|
|
1054
|
+
if (bytes < 1024) return bytes + ' B';
|
|
1055
|
+
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
|
1056
|
+
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
1057
|
+
}
|
|
955
1058
|
|
|
956
1059
|
// --- Init ---
|
|
957
1060
|
buildFilters();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Minimal HTTP server for the debug log viewer."""
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import errno
|
|
4
|
+
import json
|
|
4
5
|
import threading
|
|
5
6
|
import webbrowser
|
|
6
7
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
@@ -10,6 +11,7 @@ from urllib.parse import parse_qs, urlparse
|
|
|
10
11
|
from klaude_code.const import DEFAULT_DEBUG_LOG_DIR
|
|
11
12
|
|
|
12
13
|
_VIEWER_HTML = Path(__file__).parent / "log_viewer.html"
|
|
14
|
+
_DEFAULT_LOG_VIEWER_PORT = 8765
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class _LogViewerHandler(BaseHTTPRequestHandler):
|
|
@@ -27,6 +29,8 @@ class _LogViewerHandler(BaseHTTPRequestHandler):
|
|
|
27
29
|
self._serve_log(paths[0])
|
|
28
30
|
else:
|
|
29
31
|
self._error(400, "missing path parameter")
|
|
32
|
+
elif parsed.path == "/api/logs":
|
|
33
|
+
self._serve_logs()
|
|
30
34
|
else:
|
|
31
35
|
self._error(404, "not found")
|
|
32
36
|
|
|
@@ -41,7 +45,7 @@ class _LogViewerHandler(BaseHTTPRequestHandler):
|
|
|
41
45
|
def _serve_log(self, raw_path: str) -> None:
|
|
42
46
|
log_path = Path(raw_path).resolve()
|
|
43
47
|
log_dir = DEFAULT_DEBUG_LOG_DIR.resolve()
|
|
44
|
-
if not
|
|
48
|
+
if not _is_path_within(log_path, log_dir):
|
|
45
49
|
self._error(403, "access denied: path outside log directory")
|
|
46
50
|
return
|
|
47
51
|
if not log_path.is_file():
|
|
@@ -54,6 +58,15 @@ class _LogViewerHandler(BaseHTTPRequestHandler):
|
|
|
54
58
|
self.end_headers()
|
|
55
59
|
self.wfile.write(content)
|
|
56
60
|
|
|
61
|
+
def _serve_logs(self) -> None:
|
|
62
|
+
logs = _list_log_files(DEFAULT_DEBUG_LOG_DIR.resolve())
|
|
63
|
+
body = json.dumps(logs).encode()
|
|
64
|
+
self.send_response(200)
|
|
65
|
+
self.send_header("Content-Type", "application/json; charset=utf-8")
|
|
66
|
+
self.send_header("Content-Length", str(len(body)))
|
|
67
|
+
self.end_headers()
|
|
68
|
+
self.wfile.write(body)
|
|
69
|
+
|
|
57
70
|
def _error(self, code: int, msg: str) -> None:
|
|
58
71
|
body = msg.encode()
|
|
59
72
|
self.send_response(code)
|
|
@@ -66,10 +79,61 @@ class _LogViewerHandler(BaseHTTPRequestHandler):
|
|
|
66
79
|
pass
|
|
67
80
|
|
|
68
81
|
|
|
69
|
-
def
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
def _create_server_with_fallback(start_port: int) -> tuple[HTTPServer, int]:
|
|
83
|
+
for port in range(start_port, 65536):
|
|
84
|
+
try:
|
|
85
|
+
server = HTTPServer(("127.0.0.1", port), _LogViewerHandler)
|
|
86
|
+
except OSError as exc:
|
|
87
|
+
if exc.errno == errno.EADDRINUSE:
|
|
88
|
+
continue
|
|
89
|
+
raise
|
|
90
|
+
return server, port
|
|
91
|
+
raise RuntimeError(f"no available port from {start_port} to 65535")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _is_path_within(path: Path, root: Path) -> bool:
|
|
95
|
+
try:
|
|
96
|
+
path.relative_to(root)
|
|
97
|
+
return True
|
|
98
|
+
except ValueError:
|
|
99
|
+
return False
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _list_log_files(log_dir: Path) -> list[dict[str, object]]:
|
|
103
|
+
if not log_dir.exists():
|
|
104
|
+
return []
|
|
105
|
+
|
|
106
|
+
files: list[tuple[float, dict[str, object]]] = []
|
|
107
|
+
seen_paths: set[Path] = set()
|
|
108
|
+
for path in log_dir.rglob("*.log"):
|
|
109
|
+
if not path.is_file():
|
|
110
|
+
continue
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
stat = path.stat()
|
|
114
|
+
resolved = path.resolve()
|
|
115
|
+
relative_path = str(resolved.relative_to(log_dir))
|
|
116
|
+
except (OSError, ValueError):
|
|
117
|
+
continue
|
|
118
|
+
|
|
119
|
+
if resolved in seen_paths:
|
|
120
|
+
continue
|
|
121
|
+
seen_paths.add(resolved)
|
|
122
|
+
|
|
123
|
+
files.append(
|
|
124
|
+
(
|
|
125
|
+
stat.st_mtime,
|
|
126
|
+
{
|
|
127
|
+
"path": str(resolved),
|
|
128
|
+
"relative_path": relative_path,
|
|
129
|
+
"size_bytes": stat.st_size,
|
|
130
|
+
"mtime": stat.st_mtime,
|
|
131
|
+
},
|
|
132
|
+
)
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
files.sort(key=lambda item: item[0], reverse=True)
|
|
136
|
+
return [item[1] for item in files]
|
|
73
137
|
|
|
74
138
|
|
|
75
139
|
def start_log_viewer(log_path: Path) -> str:
|
|
@@ -77,8 +141,7 @@ def start_log_viewer(log_path: Path) -> str:
|
|
|
77
141
|
|
|
78
142
|
Returns the URL of the viewer.
|
|
79
143
|
"""
|
|
80
|
-
port =
|
|
81
|
-
server = HTTPServer(("127.0.0.1", port), _LogViewerHandler)
|
|
144
|
+
server, port = _create_server_with_fallback(_DEFAULT_LOG_VIEWER_PORT)
|
|
82
145
|
thread = threading.Thread(target=server.serve_forever, daemon=True)
|
|
83
146
|
thread.start()
|
|
84
147
|
|
|
@@ -224,7 +224,9 @@ class CopilotOAuth:
|
|
|
224
224
|
"""Ensure we have a valid Copilot token and return (token, base_url)."""
|
|
225
225
|
state = self.token_manager.get_state()
|
|
226
226
|
if state is None:
|
|
227
|
-
raise CopilotNotLoggedInError(
|
|
227
|
+
raise CopilotNotLoggedInError(
|
|
228
|
+
"Not logged in to GitHub Copilot. Run 'klaude auth login github-copilot' first."
|
|
229
|
+
)
|
|
228
230
|
|
|
229
231
|
if state.is_expired():
|
|
230
232
|
state = self.refresh()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Token storage and management for GitHub Copilot authentication."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, cast
|
|
5
|
+
|
|
6
|
+
from klaude_code.auth.base import BaseAuthState, BaseTokenManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CopilotAuthState(BaseAuthState):
|
|
10
|
+
"""Stored authentication state for GitHub Copilot."""
|
|
11
|
+
|
|
12
|
+
enterprise_domain: str | None = None
|
|
13
|
+
copilot_base_url: str = "https://api.individual.githubcopilot.com"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CopilotTokenManager(BaseTokenManager[CopilotAuthState]):
|
|
17
|
+
"""Manage GitHub Copilot OAuth tokens."""
|
|
18
|
+
|
|
19
|
+
_LEGACY_STORAGE_KEY = "copilot"
|
|
20
|
+
|
|
21
|
+
def __init__(self, auth_file: Path | None = None):
|
|
22
|
+
super().__init__(auth_file)
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def storage_key(self) -> str:
|
|
26
|
+
return "github-copilot"
|
|
27
|
+
|
|
28
|
+
def load(self) -> CopilotAuthState | None:
|
|
29
|
+
state = super().load()
|
|
30
|
+
if state is not None:
|
|
31
|
+
return state
|
|
32
|
+
|
|
33
|
+
store = self._load_store()
|
|
34
|
+
legacy_data = store.get(self._LEGACY_STORAGE_KEY)
|
|
35
|
+
if not isinstance(legacy_data, dict):
|
|
36
|
+
return None
|
|
37
|
+
legacy_payload = cast(dict[str, Any], legacy_data)
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
migrated = self._create_state(legacy_payload)
|
|
41
|
+
except ValueError:
|
|
42
|
+
return None
|
|
43
|
+
|
|
44
|
+
store[self.storage_key] = migrated.model_dump(mode="json")
|
|
45
|
+
store.pop(self._LEGACY_STORAGE_KEY, None)
|
|
46
|
+
self._save_store(store)
|
|
47
|
+
self._state = migrated
|
|
48
|
+
return migrated
|
|
49
|
+
|
|
50
|
+
def delete(self) -> None:
|
|
51
|
+
store = self._load_store()
|
|
52
|
+
store.pop(self.storage_key, None)
|
|
53
|
+
store.pop(self._LEGACY_STORAGE_KEY, None)
|
|
54
|
+
|
|
55
|
+
if len(store) == 0:
|
|
56
|
+
if self.auth_file.exists():
|
|
57
|
+
self.auth_file.unlink()
|
|
58
|
+
else:
|
|
59
|
+
self._save_store(store)
|
|
60
|
+
|
|
61
|
+
self._state = None
|
|
62
|
+
|
|
63
|
+
def _create_state(self, data: dict[str, Any]) -> CopilotAuthState:
|
|
64
|
+
return CopilotAuthState.model_validate(data)
|
|
@@ -9,7 +9,7 @@ from klaude_code.tui.command.auth_selector import select_provider
|
|
|
9
9
|
def _build_provider_help() -> str:
|
|
10
10
|
from klaude_code.config.builtin_config import SUPPORTED_API_KEYS
|
|
11
11
|
|
|
12
|
-
names = ["codex", "claude", "copilot"] + [k.name.split()[0].lower() for k in SUPPORTED_API_KEYS]
|
|
12
|
+
names = ["codex", "claude", "github-copilot", "copilot"] + [k.name.split()[0].lower() for k in SUPPORTED_API_KEYS]
|
|
13
13
|
return f"Provider name ({', '.join(names)})"
|
|
14
14
|
|
|
15
15
|
|
|
@@ -26,7 +26,7 @@ def login_command(
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def logout_command(
|
|
29
|
-
provider: str | None = typer.Argument(None, help="Provider to logout (codex|claude|copilot)"),
|
|
29
|
+
provider: str | None = typer.Argument(None, help="Provider to logout (codex|claude|github-copilot|copilot)"),
|
|
30
30
|
) -> None:
|
|
31
31
|
"""Logout from a provider."""
|
|
32
32
|
if provider is None:
|