klaude-code 2.27.0__tar.gz → 2.28.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.
Files changed (771) hide show
  1. {klaude_code-2.27.0 → klaude_code-2.28.0}/PKG-INFO +18 -6
  2. {klaude_code-2.27.0 → klaude_code-2.28.0}/README.md +16 -5
  3. {klaude_code-2.27.0 → klaude_code-2.28.0}/pyproject.toml +2 -1
  4. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/agent.py +24 -1
  5. klaude_code-2.28.0/src/klaude_code/agent/attachments/__init__.py +46 -0
  6. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/attachments/files.py +47 -7
  7. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/attachments/memory.py +33 -15
  8. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/attachments/skills.py +53 -2
  9. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/attachments/state.py +12 -0
  10. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/away_summary.py +3 -29
  11. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/cache_safe.py +6 -2
  12. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/compaction/overflow.py +1 -0
  13. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/prompt_suggestion/prompt_suggestion.py +6 -5
  14. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/runtime/agent_ops.py +27 -9
  15. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/runtime/config_ops.py +22 -9
  16. klaude_code-2.28.0/src/klaude_code/agent/runtime/llm.py +247 -0
  17. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/runtime/sub_agent.py +7 -2
  18. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/session_stats.py +1 -0
  19. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/session_title.py +8 -28
  20. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/system_prompt.py +27 -2
  21. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/task.py +211 -37
  22. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/runtime.py +3 -2
  23. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/main.py +27 -23
  24. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/__init__.py +2 -0
  25. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/assets/builtin_config.yaml +183 -8
  26. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/config.py +185 -59
  27. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/loader.py +1 -0
  28. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/model_matcher.py +68 -9
  29. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/sub_agent_model.py +15 -1
  30. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/const.py +18 -1
  31. klaude_code-2.28.0/src/klaude_code/llm/AGENTS.md +29 -0
  32. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/anthropic/client.py +30 -2
  33. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/anthropic/input.py +47 -38
  34. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/bedrock_anthropic/client.py +25 -1
  35. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/google/input.py +4 -2
  36. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/image.py +237 -9
  37. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/input_common.py +173 -2
  38. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openai_compatible/input.py +4 -1
  39. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openai_responses/input.py +4 -2
  40. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openrouter/input.py +4 -1
  41. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/usage.py +3 -1
  42. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/attachments.py +29 -1
  43. klaude_code-2.28.0/src/klaude_code/prompts/away_summary.py +24 -0
  44. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/messages.py +3 -1
  45. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/prompt_suggestion.py +2 -1
  46. klaude_code-2.28.0/src/klaude_code/prompts/session_title.py +23 -0
  47. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/system/auto-memory-prompt.md +23 -2
  48. klaude_code-2.28.0/src/klaude_code/prompts/system/base-system-prompt-gpt.md +145 -0
  49. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/system/base-system-prompt.md +1 -8
  50. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/events.py +18 -0
  51. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/message.py +23 -0
  52. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/model_id.py +11 -4
  53. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/__init__.py +7 -1
  54. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/file_tracking.py +15 -1
  55. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/tool_ui.py +1 -0
  56. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/usage.py +14 -1
  57. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/session/session.py +23 -3
  58. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/gpt-image-gen/SKILL.md +60 -25
  59. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/gpt-image-gen/references/cli.md +26 -22
  60. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/gpt-image-gen/references/image-api.md +8 -1
  61. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/gpt-image-gen/references/prompting.md +33 -10
  62. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/klaude-config/SKILL.md +5 -2
  63. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/klaude-config/references/config-file.md +9 -1
  64. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/playwright/NOTICE.txt +1 -1
  65. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/playwright/SKILL.md +3 -3
  66. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/playwright/references/cli.md +3 -3
  67. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/SKILL.md +0 -2
  68. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/references/cli.md +3 -3
  69. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/loader.py +13 -4
  70. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/apply_patch_tool.py +2 -0
  71. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/diff_builder.py +77 -11
  72. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/read_tool.py +17 -8
  73. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/write_tool.md +1 -0
  74. klaude_code-2.28.0/src/klaude_code/tui/AGENTS.md +39 -0
  75. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/export_session_cmd.py +2 -1
  76. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/export_session_html.py +38 -6
  77. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/model_cmd.py +1 -1
  78. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/model_picker.py +10 -13
  79. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/commands.py +6 -1
  80. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/command_output.py +7 -2
  81. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/diffs.py +39 -11
  82. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/rich/markdown.py +7 -1
  83. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/rich/theme.py +2 -0
  84. klaude_code-2.28.0/src/klaude_code/tui/components/task_file_changes.py +58 -0
  85. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/_question.py +7 -1
  86. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/welcome.py +101 -9
  87. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/display.py +45 -15
  88. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/input/key_bindings.py +6 -0
  89. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/input/paste.py +8 -3
  90. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/input/prompt_toolkit.py +50 -14
  91. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/machine.py +50 -5
  92. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/renderer.py +36 -12
  93. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/runner.py +26 -0
  94. klaude_code-2.28.0/src/klaude_code/tui/terminal/prevent_sleep.py +160 -0
  95. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/selector.py +2 -1
  96. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/title.py +2 -2
  97. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/update.py +34 -0
  98. klaude_code-2.27.0/src/klaude_code/web/dist/assets/highlighted-body-B3W2YXNL-Bh-pK9Qu.js → klaude_code-2.28.0/src/klaude_code/web/dist/assets/highlighted-body-B3W2YXNL-DTuyBW20.js +1 -1
  99. klaude_code-2.27.0/src/klaude_code/web/dist/assets/index-D7bSbpcc.js → klaude_code-2.28.0/src/klaude_code/web/dist/assets/index-CoapfQ1q.js +2 -2
  100. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/index.html +1 -1
  101. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/routes/config.py +4 -2
  102. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/routes/sessions.py +1 -0
  103. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/session_index.py +7 -0
  104. klaude_code-2.27.0/src/klaude_code/agent/attachments/__init__.py +0 -1
  105. klaude_code-2.27.0/src/klaude_code/agent/runtime/llm.py +0 -131
  106. klaude_code-2.27.0/src/klaude_code/prompts/system/base-system-prompt-gpt.md +0 -155
  107. klaude_code-2.27.0/src/klaude_code/skill/assets/gpt-image-gen/references/codex-network.md +0 -28
  108. klaude_code-2.27.0/src/klaude_code/skill/assets/playwright/agents/openai.yaml +0 -6
  109. klaude_code-2.27.0/src/klaude_code/skill/assets/sora/agents/openai.yaml +0 -6
  110. klaude_code-2.27.0/src/klaude_code/skill/assets/sora/references/codex-network.md +0 -28
  111. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/.DS_Store +0 -0
  112. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/__init__.py +0 -0
  113. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/__init__.py +0 -0
  114. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/agent_profile.py +0 -0
  115. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/attachments/collection.py +0 -0
  116. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/attachments/todo.py +0 -0
  117. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/bash_mode.py +0 -0
  118. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/cache_break_detection.py +0 -0
  119. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/compaction/AGENTS.md +0 -0
  120. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/compaction/__init__.py +0 -0
  121. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/compaction/compaction.py +0 -0
  122. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/handoff/__init__.py +0 -0
  123. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/handoff/handoff.py +0 -0
  124. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/handoff/manager.py +0 -0
  125. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/prompt_suggestion/__init__.py +0 -0
  126. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/rewind/__init__.py +0 -0
  127. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/rewind/manager.py +0 -0
  128. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/runtime/__init__.py +0 -0
  129. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/runtime/away_summary.py +0 -0
  130. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/runtime/dispatcher.py +0 -0
  131. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/skill_inventory.py +0 -0
  132. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/agent/turn.py +0 -0
  133. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/__init__.py +0 -0
  134. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/auth_flow.py +0 -0
  135. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/log_viewer.html +0 -0
  136. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/log_viewer.py +0 -0
  137. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/ports/__init__.py +0 -0
  138. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/ports/display.py +0 -0
  139. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/ports/input.py +0 -0
  140. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/ports/interaction.py +0 -0
  141. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/app/runtime_facade.py +0 -0
  142. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/AGENTS.md +0 -0
  143. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/__init__.py +0 -0
  144. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/base.py +0 -0
  145. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/codex/__init__.py +0 -0
  146. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/codex/exceptions.py +0 -0
  147. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
  148. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/codex/oauth.py +0 -0
  149. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/codex/token_manager.py +0 -0
  150. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/copilot/__init__.py +0 -0
  151. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/copilot/exceptions.py +0 -0
  152. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/copilot/oauth.py +0 -0
  153. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/copilot/token_manager.py +0 -0
  154. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/auth/env.py +0 -0
  155. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/__init__.py +0 -0
  156. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/auth_cmd.py +0 -0
  157. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/config_cmd.py +0 -0
  158. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/cost_cmd.py +0 -0
  159. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/debug.py +0 -0
  160. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/list_model.py +0 -0
  161. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/oauth_usage.py +0 -0
  162. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/self_update.py +0 -0
  163. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/cli/web_cmd.py +0 -0
  164. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/assets/__init__.py +0 -0
  165. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/builtin_config.py +0 -0
  166. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/formatters.py +0 -0
  167. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/merge.py +0 -0
  168. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/config/thinking.py +0 -0
  169. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/control/__init__.py +0 -0
  170. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/control/event_bus.py +0 -0
  171. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/control/event_relay.py +0 -0
  172. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/control/runtime/__init__.py +0 -0
  173. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/control/runtime/actor.py +0 -0
  174. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/control/runtime/registry.py +0 -0
  175. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/control/session_meta_relay.py +0 -0
  176. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/control/user_interaction.py +0 -0
  177. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/__init__.py +0 -0
  178. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/anthropic/__init__.py +0 -0
  179. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/bedrock_anthropic/__init__.py +0 -0
  180. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/client.py +0 -0
  181. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/copilot/__init__.py +0 -0
  182. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/copilot/client.py +0 -0
  183. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/google/__init__.py +0 -0
  184. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/google/client.py +0 -0
  185. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/google_vertex/__init__.py +0 -0
  186. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/google_vertex/client.py +0 -0
  187. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/json_stable.py +0 -0
  188. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openai_codex/__init__.py +0 -0
  189. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openai_codex/client.py +0 -0
  190. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
  191. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openai_compatible/client.py +0 -0
  192. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openai_compatible/stream.py +0 -0
  193. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openai_responses/__init__.py +0 -0
  194. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openai_responses/client.py +0 -0
  195. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openrouter/__init__.py +0 -0
  196. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openrouter/client.py +0 -0
  197. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/openrouter/reasoning.py +0 -0
  198. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/registry.py +0 -0
  199. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/llm/stream_parts.py +0 -0
  200. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/log.py +0 -0
  201. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/__init__.py +0 -0
  202. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/compaction.py +0 -0
  203. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/handoff.py +0 -0
  204. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/sub_agents/prompt-sub-agent-finder.md +0 -0
  205. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/sub_agents/prompt-sub-agent-review.md +0 -0
  206. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/sub_agents/prompt-sub-agent-simplifier.md +0 -0
  207. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/sub_agents.py +0 -0
  208. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/system/extended-thinking-prompt.md +0 -0
  209. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/system/following-conventions-prompt.md +0 -0
  210. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/prompts/system/git-workspace-hygiene-prompt.md +0 -0
  211. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/__init__.py +0 -0
  212. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/llm_param.py +0 -0
  213. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/common.py +0 -0
  214. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/developer_ui.py +0 -0
  215. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/session_runtime.py +0 -0
  216. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/sub_agent.py +0 -0
  217. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/task_metadata.py +0 -0
  218. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/models/todo.py +0 -0
  219. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/op.py +0 -0
  220. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/op_handler.py +0 -0
  221. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/sub_agent/AGENTS.md +0 -0
  222. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/sub_agent/__init__.py +0 -0
  223. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/sub_agent/finder.py +0 -0
  224. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/sub_agent/general_purpose.py +0 -0
  225. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/sub_agent/review.py +0 -0
  226. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/sub_agent/simplifier.py +0 -0
  227. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/system_prompt.py +0 -0
  228. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/tools.py +0 -0
  229. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/protocol/user_interaction.py +0 -0
  230. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/session/__init__.py +0 -0
  231. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/session/codec.py +0 -0
  232. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/session/history.py +0 -0
  233. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/session/meta.py +0 -0
  234. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/session/selector.py +0 -0
  235. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/session/store.py +0 -0
  236. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/session/store_registry.py +0 -0
  237. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/AGENTS.md +0 -0
  238. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/__init__.py +0 -0
  239. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/.git +0 -0
  240. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/.gitignore +0 -0
  241. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/SOURCES.md +0 -0
  242. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/SKILL.md +0 -0
  243. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/references/authentication.md +0 -0
  244. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/references/commands.md +0 -0
  245. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/references/profiling.md +0 -0
  246. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/references/proxy-support.md +0 -0
  247. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/references/session-management.md +0 -0
  248. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/references/snapshot-refs.md +0 -0
  249. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/references/video-recording.md +0 -0
  250. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/templates/authenticated-session.sh +0 -0
  251. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/templates/capture-workflow.sh +0 -0
  252. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/agent-browser/templates/form-automation.sh +0 -0
  253. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/frontend-design/SKILL.md +0 -0
  254. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/gpt-image-gen/LICENSE.txt +0 -0
  255. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/gpt-image-gen/references/sample-prompts.md +0 -0
  256. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/gpt-image-gen/scripts/image_gen.py +0 -0
  257. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/klaude-config/references/builtin-providers.md +0 -0
  258. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/klaude-config/references/memory-files.md +0 -0
  259. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/klaude-config/references/skill-system.md +0 -0
  260. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/nano-banana-image-gen/SKILL.md +0 -0
  261. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/cli.md +0 -0
  262. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/gemini-api.md +0 -0
  263. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/prompting.md +0 -0
  264. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/sample-prompts.md +0 -0
  265. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/nano-banana-image-gen/references/vertex-setup.md +0 -0
  266. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/nano-banana-image-gen/scripts/gemini_image_gen.py +0 -0
  267. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/SKILL.md +0 -0
  268. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/forms.md +0 -0
  269. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/reference.md +0 -0
  270. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/scripts/check_bounding_boxes.py +0 -0
  271. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/scripts/check_fillable_fields.py +0 -0
  272. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/scripts/convert_pdf_to_images.py +0 -0
  273. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/scripts/create_validation_image.py +0 -0
  274. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/scripts/extract_form_field_info.py +0 -0
  275. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/scripts/extract_form_structure.py +0 -0
  276. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/scripts/fill_fillable_fields.py +0 -0
  277. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/pdf/scripts/fill_pdf_form_with_annotations.py +0 -0
  278. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/playwright/LICENSE.txt +0 -0
  279. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/playwright/assets/playwright-small.svg +0 -0
  280. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/playwright/assets/playwright.png +0 -0
  281. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/playwright/references/workflows.md +0 -0
  282. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/playwright/scripts/playwright_cli.sh +0 -0
  283. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/SKILL.md +0 -0
  284. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/3d.md +0 -0
  285. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/animations.md +0 -0
  286. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/assets/charts-bar-chart.tsx +0 -0
  287. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +0 -0
  288. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +0 -0
  289. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/assets.md +0 -0
  290. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/audio-visualization.md +0 -0
  291. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/audio.md +0 -0
  292. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/calculate-metadata.md +0 -0
  293. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/can-decode.md +0 -0
  294. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/charts.md +0 -0
  295. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/compositions.md +0 -0
  296. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/display-captions.md +0 -0
  297. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/extract-frames.md +0 -0
  298. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/ffmpeg.md +0 -0
  299. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/fonts.md +0 -0
  300. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/get-audio-duration.md +0 -0
  301. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/get-video-dimensions.md +0 -0
  302. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/get-video-duration.md +0 -0
  303. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/gifs.md +0 -0
  304. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/images.md +0 -0
  305. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/import-srt-captions.md +0 -0
  306. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/light-leaks.md +0 -0
  307. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/lottie.md +0 -0
  308. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/maps.md +0 -0
  309. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/measuring-dom-nodes.md +0 -0
  310. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/measuring-text.md +0 -0
  311. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/parameters.md +0 -0
  312. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/sequencing.md +0 -0
  313. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/sfx.md +0 -0
  314. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/subtitles.md +0 -0
  315. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/tailwind.md +0 -0
  316. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/text-animations.md +0 -0
  317. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/timing.md +0 -0
  318. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/transcribe-captions.md +0 -0
  319. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/transitions.md +0 -0
  320. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/transparent-videos.md +0 -0
  321. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/trimming.md +0 -0
  322. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/videos.md +0 -0
  323. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/remotion-best-practices/rules/voiceover.md +0 -0
  324. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/render-mermaid/.gitignore +0 -0
  325. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/render-mermaid/SKILL.md +0 -0
  326. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/render-mermaid/package.json +0 -0
  327. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/render-mermaid/references/config/first-time-setup.md +0 -0
  328. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/render-mermaid/references/config/preferences-schema.md +0 -0
  329. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/render-mermaid/references/templates/standalone.html +0 -0
  330. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/render-mermaid/references/troubleshooting.md +0 -0
  331. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/render-mermaid/scripts/render_mermaid.js +0 -0
  332. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/render-mermaid/scripts/setup.sh +0 -0
  333. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/session-logs/SKILL.md +0 -0
  334. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/skill-creator/SKILL.md +0 -0
  335. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/skills-lock.json +0 -0
  336. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/LICENSE.txt +0 -0
  337. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/assets/sora-small.svg +0 -0
  338. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/assets/sora.png +0 -0
  339. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/references/cinematic-shots.md +0 -0
  340. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/references/prompting.md +0 -0
  341. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/references/sample-prompts.md +0 -0
  342. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/references/social-ads.md +0 -0
  343. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/references/troubleshooting.md +0 -0
  344. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/references/video-api.md +0 -0
  345. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/sora/scripts/sora.py +0 -0
  346. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/svg-animations/SKILL.md +0 -0
  347. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/svg-animations/examples/index.html +0 -0
  348. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/assets/web-search/SKILL.md +0 -0
  349. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/manager.py +0 -0
  350. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/skill/system_skills.py +0 -0
  351. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/AGENTS.md +0 -0
  352. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/__init__.py +0 -0
  353. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/agent_tool.md +0 -0
  354. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/agent_tool.py +0 -0
  355. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/ask_user_question_tool.md +0 -0
  356. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/ask_user_question_tool.py +0 -0
  357. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/core/__init__.py +0 -0
  358. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/core/abc.py +0 -0
  359. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/core/context.py +0 -0
  360. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/core/offload.py +0 -0
  361. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/core/registry.py +0 -0
  362. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/core/runner.py +0 -0
  363. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/__init__.py +0 -0
  364. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/_utils.py +0 -0
  365. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/apply_patch.py +0 -0
  366. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/apply_patch_tool.md +0 -0
  367. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/edit_tool.md +0 -0
  368. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/edit_tool.py +0 -0
  369. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/read_tool.md +0 -0
  370. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/file/write_tool.py +0 -0
  371. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/handoff_tool.md +0 -0
  372. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/handoff_tool.py +0 -0
  373. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/rewind_tool.md +0 -0
  374. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/rewind_tool.py +0 -0
  375. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/shell/__init__.py +0 -0
  376. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/shell/bash_tool.md +0 -0
  377. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/shell/bash_tool.py +0 -0
  378. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/shell/command_safety.py +0 -0
  379. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/todo/__init__.py +0 -0
  380. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/todo/todo_write_tool.md +0 -0
  381. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/todo/todo_write_tool.py +0 -0
  382. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/todo/todo_write_tool_raw.md +0 -0
  383. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/web/__init__.py +0 -0
  384. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/web/external_content.py +0 -0
  385. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/web/ssrf.py +0 -0
  386. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/web/web_cache.py +0 -0
  387. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/web/web_fetch_tool.md +0 -0
  388. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/web/web_fetch_tool.py +0 -0
  389. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/web/web_search_tool.md +0 -0
  390. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tool/web/web_search_tool.py +0 -0
  391. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/__init__.py +0 -0
  392. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/AGENTS.md +0 -0
  393. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/__init__.py +0 -0
  394. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/auth_selector.py +0 -0
  395. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/command_abc.py +0 -0
  396. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/compact_cmd.py +0 -0
  397. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/continue_cmd.py +0 -0
  398. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/copy_cmd.py +0 -0
  399. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/debug_cmd.py +0 -0
  400. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/fork_session_cmd.py +0 -0
  401. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/login_cmd.py +0 -0
  402. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/logout_cmd.py +0 -0
  403. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/new_cmd.py +0 -0
  404. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/recap_cmd.py +0 -0
  405. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/refresh_cmd.py +0 -0
  406. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/registry.py +0 -0
  407. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/status_cmd.py +0 -0
  408. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/sub_agent_model_cmd.py +0 -0
  409. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/thinking_cmd.py +0 -0
  410. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/types.py +0 -0
  411. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/command/web_cmd.py +0 -0
  412. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/__init__.py +0 -0
  413. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/away_summary.py +0 -0
  414. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/bash_syntax.py +0 -0
  415. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/common.py +0 -0
  416. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/developer.py +0 -0
  417. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/errors.py +0 -0
  418. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/metadata.py +0 -0
  419. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/rich/__init__.py +0 -0
  420. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/rich/cjk_wrap.py +0 -0
  421. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/rich/live.py +0 -0
  422. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/rich/quote.py +0 -0
  423. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/rich/status.py +0 -0
  424. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/sub_agent.py +0 -0
  425. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/thinking.py +0 -0
  426. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/__init__.py +0 -0
  427. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/_bash.py +0 -0
  428. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/_common.py +0 -0
  429. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/_dispatch.py +0 -0
  430. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/_file.py +0 -0
  431. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/_read.py +0 -0
  432. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/_rewind.py +0 -0
  433. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/_todo.py +0 -0
  434. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/tools/_web.py +0 -0
  435. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/components/user_input.py +0 -0
  436. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/input/AGENTS.md +0 -0
  437. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/input/__init__.py +0 -0
  438. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/input/completers.py +0 -0
  439. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/input/drag_drop.py +0 -0
  440. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/input/images.py +0 -0
  441. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/input/pt_theme.py +0 -0
  442. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/status_runtime.py +0 -0
  443. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/__init__.py +0 -0
  444. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/ask_user_question.py +0 -0
  445. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/color.py +0 -0
  446. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/control.py +0 -0
  447. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/focus_tracker.py +0 -0
  448. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/image.py +0 -0
  449. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/notifier.py +0 -0
  450. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/tui/terminal/session_selector.py +0 -0
  451. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/__init__.py +0 -0
  452. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/app.py +0 -0
  453. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/display.py +0 -0
  454. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/abap-BdImnpbu.js +0 -0
  455. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/actionscript-3-CoDkCxhg.js +0 -0
  456. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ada-bCR0ucgS.js +0 -0
  457. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/andromeeda-C4gqWexZ.js +0 -0
  458. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/angular-html-CU67Zn6k.js +0 -0
  459. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/angular-ts-BwZT4LLn.js +0 -0
  460. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/apache-Pmp26Uib.js +0 -0
  461. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/apex-D8_7TLub.js +0 -0
  462. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/apl-dKokRX4l.js +0 -0
  463. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/applescript-Co6uUVPk.js +0 -0
  464. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ara-BRHolxvo.js +0 -0
  465. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/asciidoc-Ve4PFQV2.js +0 -0
  466. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/asm-D_Q5rh1f.js +0 -0
  467. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/astro-CbQHKStN.js +0 -0
  468. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/aurora-x-D-2ljcwZ.js +0 -0
  469. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/awk-DMzUqQB5.js +0 -0
  470. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ayu-dark-DYE7WIF3.js +0 -0
  471. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ayu-light-BA47KaF1.js +0 -0
  472. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ayu-mirage-32ctXXKs.js +0 -0
  473. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ballerina-BFfxhgS-.js +0 -0
  474. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/bat-BkioyH1T.js +0 -0
  475. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/beancount-k_qm7-4y.js +0 -0
  476. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/berry-uYugtg8r.js +0 -0
  477. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/bibtex-CHM0blh-.js +0 -0
  478. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/bicep-Bmn6On1c.js +0 -0
  479. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/bird2-DPOp833l.js +0 -0
  480. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/blade-D4QpJJKB.js +0 -0
  481. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/bsl-BO_Y6i37.js +0 -0
  482. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/c-BIGW1oBm.js +0 -0
  483. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/c3-eo99z4R2.js +0 -0
  484. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/cadence-Bv_4Rxtq.js +0 -0
  485. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/cairo-KRGpt6FW.js +0 -0
  486. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/catppuccin-frappe-DFWUc33u.js +0 -0
  487. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/catppuccin-latte-C9dUb6Cb.js +0 -0
  488. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/catppuccin-macchiato-DQyhUUbL.js +0 -0
  489. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/catppuccin-mocha-D87Tk5Gz.js +0 -0
  490. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/clarity-D53aC0YG.js +0 -0
  491. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/clojure-P80f7IUj.js +0 -0
  492. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/cmake-D1j8_8rp.js +0 -0
  493. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/cobol-nwyudZeR.js +0 -0
  494. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/codeowners-Bp6g37R7.js +0 -0
  495. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/codeql-DsOJ9woJ.js +0 -0
  496. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/coffee-Ch7k5sss.js +0 -0
  497. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/common-lisp-Cg-RD9OK.js +0 -0
  498. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/coq-DkFqJrB1.js +0 -0
  499. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/cpp-CofmeUqb.js +0 -0
  500. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/crystal-tKQVLTB8.js +0 -0
  501. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/csharp-COcwbKMJ.js +0 -0
  502. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/css-DPfMkruS.js +0 -0
  503. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/csv-fuZLfV_i.js +0 -0
  504. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/cue-D82EKSYY.js +0 -0
  505. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/cypher-COkxafJQ.js +0 -0
  506. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/d-85-TOEBH.js +0 -0
  507. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/dark-plus-C3mMm8J8.js +0 -0
  508. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/dart-CF10PKvl.js +0 -0
  509. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/dax-CEL-wOlO.js +0 -0
  510. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/desktop-BmXAJ9_W.js +0 -0
  511. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/diff-D97Zzqfu.js +0 -0
  512. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/docker-BcOcwvcX.js +0 -0
  513. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/dotenv-Da5cRb03.js +0 -0
  514. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/dracula-BzJJZx-M.js +0 -0
  515. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/dracula-soft-BXkSAIEj.js +0 -0
  516. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/dream-maker-BtqSS_iP.js +0 -0
  517. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/edge-BkV0erSs.js +0 -0
  518. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/elixir-CDX3lj18.js +0 -0
  519. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/elm-DbKCFpqz.js +0 -0
  520. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/emacs-lisp-C9XAeP06.js +0 -0
  521. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/erb-B12qg9BL.js +0 -0
  522. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/erlang-DsQrWhSR.js +0 -0
  523. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/everforest-dark-BgDCqdQA.js +0 -0
  524. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/everforest-light-C8M2exoo.js +0 -0
  525. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/fennel-BYunw83y.js +0 -0
  526. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/fish-BvzEVeQv.js +0 -0
  527. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/fluent-C4IJs8-o.js +0 -0
  528. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/fortran-fixed-form-CkoXwp7k.js +0 -0
  529. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/fortran-free-form-BxgE0vQu.js +0 -0
  530. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/fsharp-CXgrBDvD.js +0 -0
  531. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gdresource-BOOCDP_w.js +0 -0
  532. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gdscript-C5YyOfLZ.js +0 -0
  533. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gdshader-DkwncUOv.js +0 -0
  534. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/genie-D0YGMca9.js +0 -0
  535. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gherkin-DyxjwDmM.js +0 -0
  536. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/git-commit-F4YmCXRG.js +0 -0
  537. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/git-rebase-r7XF79zn.js +0 -0
  538. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/github-dark-DHJKELXO.js +0 -0
  539. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/github-dark-default-Cuk6v7N8.js +0 -0
  540. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/github-dark-dimmed-DH5Ifo-i.js +0 -0
  541. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -0
  542. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/github-light-DAi9KRSo.js +0 -0
  543. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/github-light-default-D7oLnXFd.js +0 -0
  544. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/github-light-high-contrast-BfjtVDDH.js +0 -0
  545. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gleam-BspZqrRM.js +0 -0
  546. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/glimmer-js-Rg0-pVw9.js +0 -0
  547. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/glimmer-ts-U6CK756n.js +0 -0
  548. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/glsl-DplSGwfg.js +0 -0
  549. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gn-n2N0HUVH.js +0 -0
  550. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gnuplot-DdkO51Og.js +0 -0
  551. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/go-CxLEBnE3.js +0 -0
  552. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/graphql-ChdNCCLP.js +0 -0
  553. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/groovy-gcz8RCvz.js +0 -0
  554. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -0
  555. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gruvbox-dark-medium-GsRaNv29.js +0 -0
  556. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gruvbox-dark-soft-CVdnzihN.js +0 -0
  557. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gruvbox-light-hard-CH1njM8p.js +0 -0
  558. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gruvbox-light-medium-DRw_LuNl.js +0 -0
  559. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/gruvbox-light-soft-hJgmCMqR.js +0 -0
  560. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/hack-CaT9iCJl.js +0 -0
  561. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/haml-B8DHNrY2.js +0 -0
  562. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/handlebars-BL8al0AC.js +0 -0
  563. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/haskell-Df6bDoY_.js +0 -0
  564. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/haxe-CzTSHFRz.js +0 -0
  565. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/hcl-BWvSN4gD.js +0 -0
  566. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/hjson-D5-asLiD.js +0 -0
  567. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/hlsl-D3lLCCz7.js +0 -0
  568. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/horizon-BUw7H-hv.js +0 -0
  569. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/horizon-bright-Cn-bp-IR.js +0 -0
  570. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/houston-DnULxvSX.js +0 -0
  571. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/html-GMplVEZG.js +0 -0
  572. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/html-derivative-BFtXZ54Q.js +0 -0
  573. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/http-jrhK8wxY.js +0 -0
  574. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/hurl-irOxFIW8.js +0 -0
  575. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/hxml-Bvhsp5Yf.js +0 -0
  576. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/hy-DFXneXwc.js +0 -0
  577. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/imba-DGztddWO.js +0 -0
  578. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/index-TK8frDq8.css +0 -0
  579. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ini-BEwlwnbL.js +0 -0
  580. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/java-CylS5w8V.js +0 -0
  581. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/javascript-wDzz0qaB.js +0 -0
  582. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/jinja-4LBKfQ-Z.js +0 -0
  583. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/jison-wvAkD_A8.js +0 -0
  584. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/json-Cp-IABpG.js +0 -0
  585. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/json5-C9tS-k6U.js +0 -0
  586. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/jsonc-Des-eS-w.js +0 -0
  587. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/jsonl-DcaNXYhu.js +0 -0
  588. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/jsonnet-DFQXde-d.js +0 -0
  589. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/jssm-C2t-YnRu.js +0 -0
  590. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/jsx-g9-lgVsj.js +0 -0
  591. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/julia-CxzCAyBv.js +0 -0
  592. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/just-Cw27pwNe.js +0 -0
  593. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/kanagawa-dragon-CkXjmgJE.js +0 -0
  594. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/kanagawa-lotus-CfQXZHmo.js +0 -0
  595. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/kanagawa-wave-DWedfzmr.js +0 -0
  596. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/kdl-DV7GczEv.js +0 -0
  597. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/kotlin-BdnUsdx6.js +0 -0
  598. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/kusto-DZf3V79B.js +0 -0
  599. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/laserwave-DUszq2jm.js +0 -0
  600. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/latex-CWtU0Tv5.js +0 -0
  601. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/lean-BZvkOJ9d.js +0 -0
  602. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/less-B1dDrJ26.js +0 -0
  603. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/light-plus-B7mTdjB0.js +0 -0
  604. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/liquid-DYVedYrR.js +0 -0
  605. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/llvm-DjAJT7YJ.js +0 -0
  606. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/log-2UxHyX5q.js +0 -0
  607. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/logo-BtOb2qkB.js +0 -0
  608. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/lua-BaeVxFsk.js +0 -0
  609. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/luau-C-HG3fhB.js +0 -0
  610. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/make-CHLpvVh8.js +0 -0
  611. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/markdown-Cvjx9yec.js +0 -0
  612. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/marko-CnJfTvn9.js +0 -0
  613. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/material-theme-D5KoaKCx.js +0 -0
  614. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/material-theme-darker-BfHTSMKl.js +0 -0
  615. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/material-theme-lighter-B0m2ddpp.js +0 -0
  616. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/material-theme-ocean-CyktbL80.js +0 -0
  617. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/material-theme-palenight-Csfq5Kiy.js +0 -0
  618. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/matlab-D7o27uSR.js +0 -0
  619. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/mdc-BMNejdWA.js +0 -0
  620. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/mdx-Cmh6b_Ma.js +0 -0
  621. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/mermaid-mWjccvbQ.js +0 -0
  622. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/min-dark-CafNBF8u.js +0 -0
  623. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/min-light-CTRr51gU.js +0 -0
  624. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/mipsasm-CKIfxQSi.js +0 -0
  625. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/mojo-rZm6bMo-.js +0 -0
  626. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/monokai-D4h5O-jR.js +0 -0
  627. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/moonbit-_H4v1dQx.js +0 -0
  628. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/move-IF9eRakj.js +0 -0
  629. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/narrat-DRg8JJMk.js +0 -0
  630. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/nextflow-Zz6hmt5N.js +0 -0
  631. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/nextflow-groovy-BeH2EWoN.js +0 -0
  632. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/nginx-BpAMiNFr.js +0 -0
  633. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/night-owl-C39BiMTA.js +0 -0
  634. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/night-owl-light-CMTm3GFP.js +0 -0
  635. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/nim-CVrawwO9.js +0 -0
  636. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/nix-CwoSXNpI.js +0 -0
  637. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/nord-Ddv68eIx.js +0 -0
  638. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/nushell-Cz2AlsmD.js +0 -0
  639. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/objective-c-DXmwc3jG.js +0 -0
  640. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/objective-cpp-CLxacb5B.js +0 -0
  641. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ocaml-C0hk2d4L.js +0 -0
  642. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/odin-BBf5iR-q.js +0 -0
  643. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/one-dark-pro-DVMEJ2y_.js +0 -0
  644. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/one-light-C3Wv6jpd.js +0 -0
  645. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/openscad-C4EeE6gA.js +0 -0
  646. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/pascal-D93ZcfNL.js +0 -0
  647. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/perl-C0TMdlhV.js +0 -0
  648. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/php-Dhbhpdrm.js +0 -0
  649. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/pierre-dark-BXuwtOqb.js +0 -0
  650. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/pierre-light-dckrK0oj.js +0 -0
  651. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/pkl-u5AG7uiY.js +0 -0
  652. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/plastic-3e1v2bzS.js +0 -0
  653. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/plsql-ChMvpjG-.js +0 -0
  654. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/po-BTJTHyun.js +0 -0
  655. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/poimandres-CS3Unz2-.js +0 -0
  656. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/polar-C0HS_06l.js +0 -0
  657. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/postcss-CXtECtnM.js +0 -0
  658. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/powerquery-CEu0bR-o.js +0 -0
  659. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/powershell-Dpen1YoG.js +0 -0
  660. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/prisma-Dd19v3D-.js +0 -0
  661. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/prolog-CbFg5uaA.js +0 -0
  662. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/proto-C7zT0LnQ.js +0 -0
  663. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/pug-CGlum2m_.js +0 -0
  664. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/puppet-BMWR74SV.js +0 -0
  665. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/purescript-CklMAg4u.js +0 -0
  666. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/python-B6aJPvgy.js +0 -0
  667. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/qml-3beO22l8.js +0 -0
  668. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/qmldir-C8lEn-DE.js +0 -0
  669. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/qss-IeuSbFQv.js +0 -0
  670. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/r-Dspwwk_N.js +0 -0
  671. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/racket-BqYA7rlc.js +0 -0
  672. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/raku-DXvB9xmW.js +0 -0
  673. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/razor-Uh8Bk_45.js +0 -0
  674. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/red-bN70gL4F.js +0 -0
  675. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/reg-C-SQnVFl.js +0 -0
  676. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/regexp-CDVJQ6XC.js +0 -0
  677. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/rel-C3B-1QV4.js +0 -0
  678. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/riscv-BM1_JUlF.js +0 -0
  679. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ron-D8l8udqQ.js +0 -0
  680. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/rose-pine-dawn-DHQR4-dF.js +0 -0
  681. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/rose-pine-moon-D4_iv3hh.js +0 -0
  682. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/rose-pine-qdsjHGoJ.js +0 -0
  683. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/rosmsg-BJDFO7_C.js +0 -0
  684. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/rst-BrH8l1NY.js +0 -0
  685. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ruby-Dw2BHqvy.js +0 -0
  686. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/rust-B1yitclQ.js +0 -0
  687. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/sas-cz2c8ADy.js +0 -0
  688. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/sass-Cj5Yp3dK.js +0 -0
  689. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/scala-C151Ov-r.js +0 -0
  690. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/scheme-C98Dy4si.js +0 -0
  691. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/scss-OYdSNvt2.js +0 -0
  692. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/sdbl-DVxCFoDh.js +0 -0
  693. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/shaderlab-Dg9Lc6iA.js +0 -0
  694. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/shellscript-Yzrsuije.js +0 -0
  695. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/shellsession-BADoaaVG.js +0 -0
  696. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/slack-dark-BthQWCQV.js +0 -0
  697. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/slack-ochin-DqwNpetd.js +0 -0
  698. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/smalltalk-BERRCDM3.js +0 -0
  699. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/snazzy-light-Bw305WKR.js +0 -0
  700. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/solarized-dark-DXbdFlpD.js +0 -0
  701. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/solarized-light-L9t79GZl.js +0 -0
  702. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/solidity-rGO070M0.js +0 -0
  703. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/soy-Brmx7dQM.js +0 -0
  704. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/sparql-rVzFXLq3.js +0 -0
  705. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/splunk-BtCnVYZw.js +0 -0
  706. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/sql-BLtJtn59.js +0 -0
  707. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ssh-config-_ykCGR6B.js +0 -0
  708. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/stata-BH5u7GGu.js +0 -0
  709. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/stylus-BEDo0Tqx.js +0 -0
  710. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/surrealql-Bq5Q-fJD.js +0 -0
  711. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/svelte-C_ipcX3V.js +0 -0
  712. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/swift-D82vCrfD.js +0 -0
  713. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/synthwave-84-CbfX1IO0.js +0 -0
  714. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/system-verilog-CnnmHF94.js +0 -0
  715. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/systemd-4A_iFExJ.js +0 -0
  716. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/talonscript-CkByrt1z.js +0 -0
  717. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/tasl-QIJgUcNo.js +0 -0
  718. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/tcl-dwOrl1Do.js +0 -0
  719. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/templ-P3uqSqPl.js +0 -0
  720. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/terraform-BETggiCN.js +0 -0
  721. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/tex-idrVyKtj.js +0 -0
  722. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/tokyo-night-hegEt444.js +0 -0
  723. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/toml-vGWfd6FD.js +0 -0
  724. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/ts-tags-zn1MmPIZ.js +0 -0
  725. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/tsv-B_m7g4N7.js +0 -0
  726. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/tsx-COt5Ahok.js +0 -0
  727. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/turtle-BsS91CYL.js +0 -0
  728. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/twig-DNn4PbVi.js +0 -0
  729. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/typescript-BPQ3VLAy.js +0 -0
  730. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/typespec-BGHnOYBU.js +0 -0
  731. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/typst-DHCkPAjA.js +0 -0
  732. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/v-BcVCzyr7.js +0 -0
  733. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vala-CsfeWuGM.js +0 -0
  734. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vb-D17OF-Vu.js +0 -0
  735. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/verilog-BQ8w6xss.js +0 -0
  736. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vesper-DU1UobuO.js +0 -0
  737. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vhdl-CeAyd5Ju.js +0 -0
  738. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/viml-CJc9bBzg.js +0 -0
  739. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vitesse-black-Bkuqu6BP.js +0 -0
  740. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vitesse-dark-D0r3Knsf.js +0 -0
  741. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vitesse-light-CVO1_9PV.js +0 -0
  742. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vue-DN_0RTcg.js +0 -0
  743. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vue-html-AaS7Mt5G.js +0 -0
  744. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vue-vine-CQOfvN7w.js +0 -0
  745. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/vyper-CDx5xZoG.js +0 -0
  746. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/wasm-CG6Dc4jp.js +0 -0
  747. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/wasm-MzD3tlZU.js +0 -0
  748. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/wenyan-BV7otONQ.js +0 -0
  749. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/wgsl-Dx-B1_4e.js +0 -0
  750. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/wikitext-BhOHFoWU.js +0 -0
  751. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/wit-5i3qLPDT.js +0 -0
  752. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/wolfram-lXgVvXCa.js +0 -0
  753. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/xml-sdJ4AIDG.js +0 -0
  754. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/xsl-CtQFsRM5.js +0 -0
  755. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/yaml-Buea-lGh.js +0 -0
  756. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/zenscript-DVFEvuxE.js +0 -0
  757. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/assets/zig-VOosw3JB.js +0 -0
  758. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/favicon.svg +0 -0
  759. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/fonts/InterVariable-Italic.woff2 +0 -0
  760. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/dist/fonts/InterVariable.woff2 +0 -0
  761. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/file_access.py +0 -0
  762. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/interaction.py +0 -0
  763. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/live_events.py +0 -0
  764. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/routes/__init__.py +0 -0
  765. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/routes/files.py +0 -0
  766. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/routes/skills.py +0 -0
  767. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/routes/ws.py +0 -0
  768. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/server.py +0 -0
  769. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/session_access.py +0 -0
  770. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/session_live.py +0 -0
  771. {klaude_code-2.27.0 → klaude_code-2.28.0}/src/klaude_code/web/state.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: klaude-code
3
- Version: 2.27.0
3
+ Version: 2.28.0
4
4
  Summary: Minimal code agent CLI
5
5
  Requires-Dist: anthropic[bedrock]>=0.66.0
6
6
  Requires-Dist: chardet>=5.2.0,<6
@@ -20,6 +20,7 @@ Requires-Dist: trafilatura>=2.0.0
20
20
  Requires-Dist: typer>=0.17.3
21
21
  Requires-Dist: uvicorn
22
22
  Requires-Dist: readability-lxml>=0.8.4.1
23
+ Requires-Dist: pillow>=12.2.0
23
24
  Requires-Python: >=3.13
24
25
  Description-Content-Type: text/markdown
25
26
 
@@ -132,9 +133,14 @@ klaude
132
133
 
133
134
  On first run, you'll be prompted to select a model. Your choice is saved as `main_model`.
134
135
 
135
- You can also configure fallback lists for helper models:
136
+ You can also configure fallback lists for the main model and helper models:
136
137
 
137
138
  ```yaml
139
+ main_model:
140
+ - gpt-5.5
141
+ - gpt-5.4
142
+ - opus
143
+
138
144
  fast_model:
139
145
  - haiku
140
146
  - gemini-flash
@@ -145,7 +151,9 @@ compact_model:
145
151
  - haiku
146
152
  ```
147
153
 
148
- Klaude tries these entries in order and uses the first available model. `fast_model` is used for session-title generation; `compact_model` is used for compact/helper tasks.
154
+ Klaude expands each entry into concrete provider candidates in `provider_list` order, then falls through to the next model in the list. For example, `gpt-5.4` will try available providers such as `gpt-5.4@openai`, `gpt-5.4@github-copilot`, and `gpt-5.4@openrouter` before moving to the next model. Runtime fallback is used for non-retryable provider/model failures such as quota, billing, permission, or model-unavailable errors. `fast_model` is used for session-title generation; `compact_model` is used for compact/helper tasks.
155
+
156
+ When you switch models with `/model`, Klaude updates `main_model` without discarding the fallback chain: the selected model is moved to the front if it already exists, or inserted at the front otherwise.
149
157
 
150
158
  #### Built-in Providers
151
159
 
@@ -221,7 +229,10 @@ You can add custom models to built-in providers or define new ones. Configuratio
221
229
 
222
230
  ```yaml
223
231
  # ~/.klaude/klaude-config.yaml
224
- main_model: opus
232
+ main_model:
233
+ - gpt-5.5
234
+ - gpt-5.4
235
+ - opus
225
236
 
226
237
  fast_model:
227
238
  - haiku
@@ -261,7 +272,8 @@ provider_list:
261
272
  - **Merging**: If `provider_name` matches a built-in provider, settings like `protocol` and `api_key` are inherited.
262
273
  - **Overriding**: Use the same `model_name` as a built-in model to override its parameters.
263
274
  - **Environment Variables**: Use `${VAR_NAME}` syntax for secrets.
264
- - **Model Preference Lists**: `fast_model` and `compact_model` accept either a single string or a list of model selectors. When you provide a list, Klaude tries them in order and picks the first available one.
275
+ - **Model Preference Lists**: `main_model`, `fast_model`, and `compact_model` accept either a single string or a list of model selectors. When you provide a list, Klaude first tries matching providers in `provider_list` order for each selector, then moves to the next selector.
276
+ - **Updating Defaults**: `/model` keeps saving the selected model back to `main_model`, but preserves fallback order by moving or inserting the selected model at the front of the list.
265
277
 
266
278
  ##### Sub-agent Model Configuration
267
279
 
@@ -332,7 +344,7 @@ Inside the interactive session (`klaude`), use these commands to streamline your
332
344
  - `/refresh-terminal` - Refresh terminal display.
333
345
  - `/web` - Switch to web UI mode.
334
346
  - `/new` - Start a new session (clears context).
335
- - `/model` - Switch the active LLM during the session.
347
+ - `/model` - Switch the active LLM and update `main_model` in config while preserving fallback order (the selected model is moved/inserted to the front).
336
348
  - `/sub-agent-model` - Configure sub-agent models at runtime.
337
349
  - `/thinking` - Change thinking/reasoning level.
338
350
  - `/status` - Show session usage statistics (cost, tokens, model breakdown).
@@ -107,9 +107,14 @@ klaude
107
107
 
108
108
  On first run, you'll be prompted to select a model. Your choice is saved as `main_model`.
109
109
 
110
- You can also configure fallback lists for helper models:
110
+ You can also configure fallback lists for the main model and helper models:
111
111
 
112
112
  ```yaml
113
+ main_model:
114
+ - gpt-5.5
115
+ - gpt-5.4
116
+ - opus
117
+
113
118
  fast_model:
114
119
  - haiku
115
120
  - gemini-flash
@@ -120,7 +125,9 @@ compact_model:
120
125
  - haiku
121
126
  ```
122
127
 
123
- Klaude tries these entries in order and uses the first available model. `fast_model` is used for session-title generation; `compact_model` is used for compact/helper tasks.
128
+ Klaude expands each entry into concrete provider candidates in `provider_list` order, then falls through to the next model in the list. For example, `gpt-5.4` will try available providers such as `gpt-5.4@openai`, `gpt-5.4@github-copilot`, and `gpt-5.4@openrouter` before moving to the next model. Runtime fallback is used for non-retryable provider/model failures such as quota, billing, permission, or model-unavailable errors. `fast_model` is used for session-title generation; `compact_model` is used for compact/helper tasks.
129
+
130
+ When you switch models with `/model`, Klaude updates `main_model` without discarding the fallback chain: the selected model is moved to the front if it already exists, or inserted at the front otherwise.
124
131
 
125
132
  #### Built-in Providers
126
133
 
@@ -196,7 +203,10 @@ You can add custom models to built-in providers or define new ones. Configuratio
196
203
 
197
204
  ```yaml
198
205
  # ~/.klaude/klaude-config.yaml
199
- main_model: opus
206
+ main_model:
207
+ - gpt-5.5
208
+ - gpt-5.4
209
+ - opus
200
210
 
201
211
  fast_model:
202
212
  - haiku
@@ -236,7 +246,8 @@ provider_list:
236
246
  - **Merging**: If `provider_name` matches a built-in provider, settings like `protocol` and `api_key` are inherited.
237
247
  - **Overriding**: Use the same `model_name` as a built-in model to override its parameters.
238
248
  - **Environment Variables**: Use `${VAR_NAME}` syntax for secrets.
239
- - **Model Preference Lists**: `fast_model` and `compact_model` accept either a single string or a list of model selectors. When you provide a list, Klaude tries them in order and picks the first available one.
249
+ - **Model Preference Lists**: `main_model`, `fast_model`, and `compact_model` accept either a single string or a list of model selectors. When you provide a list, Klaude first tries matching providers in `provider_list` order for each selector, then moves to the next selector.
250
+ - **Updating Defaults**: `/model` keeps saving the selected model back to `main_model`, but preserves fallback order by moving or inserting the selected model at the front of the list.
240
251
 
241
252
  ##### Sub-agent Model Configuration
242
253
 
@@ -307,7 +318,7 @@ Inside the interactive session (`klaude`), use these commands to streamline your
307
318
  - `/refresh-terminal` - Refresh terminal display.
308
319
  - `/web` - Switch to web UI mode.
309
320
  - `/new` - Start a new session (clears context).
310
- - `/model` - Switch the active LLM during the session.
321
+ - `/model` - Switch the active LLM and update `main_model` in config while preserving fallback order (the selected model is moved/inserted to the front).
311
322
  - `/sub-agent-model` - Configure sub-agent models at runtime.
312
323
  - `/thinking` - Change thinking/reasoning level.
313
324
  - `/status` - Show session usage statistics (cost, tokens, model breakdown).
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "klaude-code"
7
- version = "2.27.0"
7
+ version = "2.28.0"
8
8
  description = "Minimal code agent CLI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -27,6 +27,7 @@ dependencies = [
27
27
  "typer>=0.17.3",
28
28
  "uvicorn",
29
29
  "readability-lxml>=0.8.4.1",
30
+ "pillow>=12.2.0",
30
31
  ]
31
32
 
32
33
  [project.scripts]
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from collections.abc import AsyncGenerator, Awaitable, Callable, Iterable
4
4
 
5
- from klaude_code.agent.agent_profile import AgentProfile
5
+ from klaude_code.agent.agent_profile import AgentProfile, ModelProfileProvider
6
6
  from klaude_code.agent.task import SessionContext, TaskExecutionContext, TaskExecutor
7
7
  from klaude_code.llm import LLMClientABC
8
8
  from klaude_code.log import DebugType, log_debug
@@ -32,6 +32,7 @@ class Agent:
32
32
  ]
33
33
  | None
34
34
  ) = None,
35
+ model_profile_provider: ModelProfileProvider | None = None,
35
36
  ):
36
37
  self.session: Session = session
37
38
  self.profile: AgentProfile = profile
@@ -40,6 +41,7 @@ class Agent:
40
41
  self._last_interrupt_show_notice = True
41
42
  self._last_interrupt_prefill_text: str | None = None
42
43
  self.request_user_interaction = request_user_interaction
44
+ self._model_profile_provider = model_profile_provider
43
45
  if not self.session.model_name:
44
46
  self.session.model_name = profile.llm_client.model_name
45
47
 
@@ -98,6 +100,7 @@ class Agent:
98
100
  tool_registry=tool_registry,
99
101
  sub_agent_state=self.session.sub_agent_state,
100
102
  compact_llm_client=self.compact_llm_client,
103
+ apply_llm_client_change=self._apply_llm_client_change,
101
104
  )
102
105
 
103
106
  task = TaskExecutor(context)
@@ -127,6 +130,26 @@ class Agent:
127
130
  self.profile = profile
128
131
  self.session.model_name = profile.llm_client.model_name
129
132
 
133
+ def _apply_llm_client_change(self, llm_client: LLMClientABC) -> AgentProfile:
134
+ if self._model_profile_provider is None:
135
+ profile = AgentProfile(
136
+ llm_client=llm_client,
137
+ system_prompt=self.profile.system_prompt,
138
+ tools=self.profile.tools,
139
+ attachments=self.profile.attachments,
140
+ )
141
+ else:
142
+ sub_agent_type = None
143
+ if self.session.sub_agent_state is not None and not self.session.sub_agent_state.fork_context:
144
+ sub_agent_type = self.session.sub_agent_state.sub_agent_type
145
+ profile = self._model_profile_provider.build_profile(
146
+ llm_client,
147
+ sub_agent_type,
148
+ work_dir=self.session.work_dir,
149
+ )
150
+ self.set_model_profile(profile)
151
+ return profile
152
+
130
153
  def get_llm_client(self) -> LLMClientABC:
131
154
  return self.profile.llm_client
132
155
 
@@ -0,0 +1,46 @@
1
+ """Agent attachment package.
2
+
3
+ Shared helpers for <system-reminder> content produced by attachments live here.
4
+ Each concrete attachment (files, memory, skills, …) is responsible for
5
+ truncating its own output; these helpers provide a consistent Read-tool-style
6
+ notice so the agent always knows how to fetch the full content.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from dataclasses import dataclass
12
+
13
+
14
+ @dataclass(frozen=True)
15
+ class LineTruncationResult:
16
+ """Outcome of :func:`truncate_text_by_lines`."""
17
+
18
+ text: str
19
+ total_lines: int
20
+ kept_lines: int
21
+ truncated: bool
22
+
23
+ @property
24
+ def hidden_lines(self) -> int:
25
+ return max(0, self.total_lines - self.kept_lines)
26
+
27
+
28
+ def truncate_text_by_lines(text: str, *, max_lines: int) -> LineTruncationResult:
29
+ """Keep the first ``max_lines`` lines; report total/hidden line counts.
30
+
31
+ The trailing newline (if any) is preserved only when the text was not
32
+ truncated, matching Read tool behaviour where a truncated view never
33
+ ends with a bare newline before the notice.
34
+ """
35
+ if max_lines <= 0:
36
+ return LineTruncationResult(
37
+ text="", total_lines=text.count("\n") + (1 if text else 0), kept_lines=0, truncated=bool(text)
38
+ )
39
+
40
+ lines = text.splitlines()
41
+ total = len(lines)
42
+ if total <= max_lines:
43
+ return LineTruncationResult(text=text, total_lines=total, kept_lines=total, truncated=False)
44
+
45
+ kept = "\n".join(lines[:max_lines])
46
+ return LineTruncationResult(text=kept, total_lines=total, kept_lines=max_lines, truncated=True)
@@ -5,8 +5,11 @@ import re
5
5
  import shlex
6
6
  from pathlib import Path
7
7
 
8
+ from klaude_code.const import ATTACHMENT_DIFF_MAX_LINES, ATTACHMENT_DIFF_SOURCE_MAX_BYTES
8
9
  from klaude_code.prompts.attachments import (
9
10
  FILE_ALREADY_IN_CONTEXT_TEMPLATE,
11
+ FILE_CHANGED_DIFF_SKIPPED_TEMPLATE,
12
+ FILE_CHANGED_DIFF_TRUNCATED_TEMPLATE,
10
13
  FILE_CHANGED_EXTERNALLY_TEMPLATE,
11
14
  PASTE_FILE_HINT_TEMPLATE,
12
15
  TOOL_RESULT_TEMPLATE,
@@ -28,6 +31,7 @@ from klaude_code.session import Session
28
31
  from klaude_code.skill.loader import discover_skills_near_paths
29
32
  from klaude_code.tool import BashTool, ReadTool
30
33
 
34
+ from . import truncate_text_by_lines
31
35
  from .memory import Memory, discover_memory_files_near_paths, format_memory_content
32
36
  from .skills import build_dynamic_skill_listing_attachment
33
37
  from .state import (
@@ -120,7 +124,7 @@ async def _load_at_file(
120
124
  ref: AtFileRef,
121
125
  at_ops: list[AtFileOp],
122
126
  formatted_blocks: list[str],
123
- collected_images: list[message.ImageURLPart],
127
+ collected_images: list[message.ImageURLPart | message.ImageFilePart],
124
128
  collected_image_paths: list[str],
125
129
  discovered_memories: list[Memory],
126
130
  skill_discovery_paths: list[str],
@@ -141,7 +145,7 @@ async def _load_at_file(
141
145
  limit = ref.line_end - ref.line_start + 1
142
146
  args = ReadTool.ReadArguments(file_path=path_str, offset=offset, limit=limit)
143
147
  tool_result = await ReadTool.call_with_args(args, tool_context)
144
- images = [part for part in tool_result.parts if isinstance(part, message.ImageURLPart)]
148
+ images = [part for part in tool_result.parts if isinstance(part, (message.ImageURLPart, message.ImageFilePart))]
145
149
 
146
150
  formatted_blocks.append(
147
151
  _fmt_tool_result(tools.READ, args.model_dump_json(exclude_none=True), tool_result.output_text)
@@ -210,7 +214,7 @@ async def at_file_reader_attachment(session: Session) -> message.DeveloperMessag
210
214
 
211
215
  at_ops: list[AtFileOp] = []
212
216
  formatted_blocks: list[str] = []
213
- collected_images: list[message.ImageURLPart] = []
217
+ collected_images: list[message.ImageURLPart | message.ImageFilePart] = []
214
218
  collected_image_paths: list[str] = []
215
219
  discovered_memories: list[Memory] = []
216
220
  skill_discovery_paths: list[str] = []
@@ -254,7 +258,27 @@ async def at_file_reader_attachment(session: Session) -> message.DeveloperMessag
254
258
  )
255
259
 
256
260
 
257
- def _compute_diff_snippet(old_content: str, new_content: str) -> str:
261
+ def _compute_diff_snippet(old_content: str, new_content: str, file_path: str) -> str:
262
+ """Render a small unified-style diff, capped so it cannot blow up context.
263
+
264
+ Guards (see ``const.ATTACHMENT_DIFF_*``):
265
+
266
+ * If ``old_content + new_content`` already exceeds the source size limit,
267
+ skip ``difflib`` entirely. Large HTML/minified blobs produce diffs that
268
+ approach ``2x`` the source, which in past sessions pushed the next turn
269
+ past the 1M-token ceiling even after a successful compaction.
270
+ * After the diff is built, keep only the first ``ATTACHMENT_DIFF_MAX_LINES``
271
+ lines and append a Read-tool-style notice, mirroring how the Read tool
272
+ truncates long files.
273
+ """
274
+ combined_size_bytes = len(old_content.encode("utf-8")) + len(new_content.encode("utf-8"))
275
+ if combined_size_bytes > ATTACHMENT_DIFF_SOURCE_MAX_BYTES:
276
+ return FILE_CHANGED_DIFF_SKIPPED_TEMPLATE.format(
277
+ total_bytes=combined_size_bytes,
278
+ limit_bytes=ATTACHMENT_DIFF_SOURCE_MAX_BYTES,
279
+ file_path=file_path,
280
+ )
281
+
258
282
  old_lines = old_content.splitlines(keepends=True)
259
283
  new_lines = new_content.splitlines(keepends=True)
260
284
 
@@ -280,7 +304,15 @@ def _compute_diff_snippet(old_content: str, new_content: str) -> str:
280
304
  diff_lines.append(f" {line_no:>6}+\t{line.rstrip()}")
281
305
  diff_lines.append(" ------")
282
306
 
283
- return "\n".join(diff_lines).rstrip("\n -")
307
+ rendered = "\n".join(diff_lines).rstrip("\n -")
308
+ truncation = truncate_text_by_lines(rendered, max_lines=ATTACHMENT_DIFF_MAX_LINES)
309
+ if truncation.truncated:
310
+ return truncation.text + FILE_CHANGED_DIFF_TRUNCATED_TEMPLATE.format(
311
+ hidden_lines=truncation.hidden_lines,
312
+ total_lines=truncation.total_lines,
313
+ file_path=file_path,
314
+ )
315
+ return truncation.text
284
316
 
285
317
 
286
318
  async def file_changed_externally_attachment(session: Session) -> message.DeveloperMessage | None:
@@ -316,7 +348,7 @@ async def file_changed_externally_attachment(session: Session) -> message.Develo
316
348
  if new_status is None or new_status.cached_content is None:
317
349
  continue
318
350
 
319
- snippet = _compute_diff_snippet(old_content, new_status.cached_content)
351
+ snippet = _compute_diff_snippet(old_content, new_status.cached_content, path)
320
352
  if not snippet:
321
353
  continue
322
354
  changed_files.append((path, snippet))
@@ -377,7 +409,15 @@ async def paste_file_attachment(session: Session) -> message.DeveloperMessage |
377
409
  for item in reversed(session.conversation_history):
378
410
  if isinstance(item, message.ToolResultMessage):
379
411
  return None
380
- if isinstance(item, message.UserMessage) and item.pasted_files:
412
+ if (
413
+ isinstance(item, message.DeveloperMessage)
414
+ and item.ui_extra is not None
415
+ and any(isinstance(ui_item, PasteFilesUIItem) for ui_item in item.ui_extra.items)
416
+ ):
417
+ return None
418
+ if isinstance(item, message.UserMessage):
419
+ if not item.pasted_files:
420
+ return None
381
421
  return message.DeveloperMessage(
382
422
  parts=message.text_parts_from_str(
383
423
  f"<system-reminder>{_fmt_paste_file_hint(item.pasted_files)}\n</system-reminder>"
@@ -5,11 +5,18 @@ from pathlib import Path
5
5
 
6
6
  from pydantic import BaseModel
7
7
 
8
- from klaude_code.const import ProjectPaths, find_git_repo_root, project_key_from_path
8
+ from klaude_code.const import (
9
+ ATTACHMENT_MEMORY_MAX_BYTES_PER_FILE,
10
+ ATTACHMENT_MEMORY_MAX_LINES,
11
+ ProjectPaths,
12
+ find_git_repo_root,
13
+ project_key_from_path,
14
+ )
9
15
  from klaude_code.prompts.attachments import (
10
16
  AUTO_MEMORY_HINT_TEMPLATE,
11
17
  AUTO_MEMORY_INSTRUCTION,
12
18
  DISCOVERED_MEMORY_INSTRUCTION,
19
+ MEMORY_FILE_BYTE_TRUNCATED_TEMPLATE,
13
20
  MEMORY_FILE_TRUNCATED_TEMPLATE,
14
21
  MEMORY_HEADER,
15
22
  MEMORY_TRUNCATED_TEMPLATE,
@@ -20,13 +27,16 @@ from klaude_code.protocol import message
20
27
  from klaude_code.protocol.models import DeveloperUIExtra, DeveloperUIItem, MemoryFileLoaded, MemoryLoadedUIItem
21
28
  from klaude_code.session import Session
22
29
 
30
+ from . import truncate_text_by_lines
23
31
  from .state import is_memory_loaded, mark_memory_loaded
24
32
 
25
33
  MEMORY_FILE_NAMES = ["AGENTS.md", "CLAUDE.md", "AGENT.md"]
26
34
 
27
35
  AUTO_MEMORY_FILE = "MEMORY.md"
28
- AUTO_MEMORY_MAX_LINES = 200
29
- MEMORY_MAX_BYTES_PER_FILE = 4096
36
+ # Kept as module-level aliases for backwards compatibility with existing tests
37
+ # and callers. See src/klaude_code/const.py for the canonical values.
38
+ AUTO_MEMORY_MAX_LINES = ATTACHMENT_MEMORY_MAX_LINES
39
+ MEMORY_MAX_BYTES_PER_FILE = ATTACHMENT_MEMORY_MAX_BYTES_PER_FILE
30
40
  MEMORY_MAX_SESSION_BYTES = 60 * 1024
31
41
 
32
42
 
@@ -131,23 +141,31 @@ def format_memories_attachment(memories: list[Memory], include_header: bool = Tr
131
141
 
132
142
 
133
143
  def truncate_memory_content(text: str, path: str) -> str:
134
- """Truncate memory content to the shared per-file limits used by attachments."""
144
+ """Truncate memory content to the first :data:`AUTO_MEMORY_MAX_LINES` lines.
135
145
 
136
- lines = text.splitlines()
137
- truncated = False
146
+ Mirrors Read tool behaviour: show a bounded prefix and tell the agent how
147
+ to fetch the rest. A generous byte cap still applies as a last-resort
148
+ guard against pathologically long single lines (e.g. minified JSON).
149
+ """
150
+ truncation = truncate_text_by_lines(text, max_lines=AUTO_MEMORY_MAX_LINES)
151
+ result = truncation.text
138
152
 
139
- if len(lines) > AUTO_MEMORY_MAX_LINES:
140
- lines = lines[:AUTO_MEMORY_MAX_LINES]
141
- truncated = True
142
-
143
- result = "\n".join(lines)
144
153
  if len(result.encode("utf-8")) > MEMORY_MAX_BYTES_PER_FILE:
145
154
  encoded = result.encode("utf-8")[:MEMORY_MAX_BYTES_PER_FILE]
146
155
  result = encoded.decode("utf-8", errors="ignore")
147
- truncated = True
148
-
149
- if truncated:
150
- result += MEMORY_FILE_TRUNCATED_TEMPLATE.format(max_bytes=MEMORY_MAX_BYTES_PER_FILE, path=path)
156
+ total_lines = truncation.total_lines or len(text.splitlines())
157
+ return result + MEMORY_FILE_BYTE_TRUNCATED_TEMPLATE.format(
158
+ max_bytes=MEMORY_MAX_BYTES_PER_FILE,
159
+ total_lines=total_lines,
160
+ path=path,
161
+ )
162
+
163
+ if truncation.truncated:
164
+ return result + MEMORY_FILE_TRUNCATED_TEMPLATE.format(
165
+ max_lines=AUTO_MEMORY_MAX_LINES,
166
+ total_lines=truncation.total_lines,
167
+ path=path,
168
+ )
151
169
  return result
152
170
 
153
171
 
@@ -6,15 +6,18 @@ from collections.abc import Callable, Sequence
6
6
  from pathlib import Path
7
7
  from typing import Literal, cast
8
8
 
9
+ from klaude_code.const import ATTACHMENT_SKILL_MAX_LINES
9
10
  from klaude_code.prompts.attachments import (
10
11
  AVAILABLE_SKILLS_ADDED_TEMPLATE,
11
12
  AVAILABLE_SKILLS_TEMPLATE,
12
13
  DYNAMIC_AVAILABLE_SKILLS_TEMPLATE,
14
+ SKILL_ALREADY_IN_CONTEXT_TEMPLATE,
13
15
  SKILL_BLOCK_TEMPLATE,
16
+ SKILL_CONTENT_TRUNCATED_TEMPLATE,
14
17
  SKILL_DISCOVERED_PREFACE_TEMPLATE,
15
18
  SKILL_EXPLICIT_PREFACE_TEMPLATE,
16
19
  )
17
- from klaude_code.protocol import message
20
+ from klaude_code.protocol import message, tools
18
21
  from klaude_code.protocol.models import (
19
22
  DeveloperUIExtra,
20
23
  DeveloperUIItem,
@@ -33,6 +36,7 @@ from klaude_code.skill.loader import (
33
36
  from klaude_code.skill.system_skills import install_system_skills
34
37
  from klaude_code.tool.file._utils import hash_text_sha256
35
38
 
39
+ from . import truncate_text_by_lines
36
40
  from .state import is_tracked_file_unchanged
37
41
 
38
42
  # Match /skill:xxx or //skill:xxx inline (at start of line or after whitespace).
@@ -73,6 +77,14 @@ def _fmt_available_skills_added(skills_xml: str) -> str:
73
77
  return AVAILABLE_SKILLS_ADDED_TEMPLATE.format(skills_xml=skills_xml)
74
78
 
75
79
 
80
+ def _fmt_skill_already_in_context(skill_name: str, path: str, read_tool_name: str) -> str:
81
+ return SKILL_ALREADY_IN_CONTEXT_TEMPLATE.format(
82
+ skill_name=skill_name,
83
+ path=path,
84
+ read_tool_name=read_tool_name,
85
+ )
86
+
87
+
76
88
  def get_skills_from_user_input(session: Session) -> list[str]:
77
89
  for item in reversed(session.conversation_history):
78
90
  if isinstance(item, message.ToolResultMessage):
@@ -141,6 +153,27 @@ def _read_skill_content(skill: Skill) -> str | None:
141
153
  return content or None
142
154
 
143
155
 
156
+ def _render_skill_inline_content(raw_content: str, skill: Skill) -> str:
157
+ """Cap inlined SKILL.md for the <system-reminder> block.
158
+
159
+ Mirrors Read tool behaviour: keep the first ``ATTACHMENT_SKILL_MAX_LINES``
160
+ lines and tell the agent how to fetch the rest. Returning the raw content
161
+ unchanged when it fits preserves the existing behaviour for small skills.
162
+
163
+ The raw content (not the rendered/truncated version) should still be used
164
+ when computing the skill's file-tracker sha256; otherwise a truncated skill
165
+ would be re-classified as "changed" on every turn.
166
+ """
167
+ truncation = truncate_text_by_lines(raw_content, max_lines=ATTACHMENT_SKILL_MAX_LINES)
168
+ if not truncation.truncated:
169
+ return truncation.text
170
+ return truncation.text + SKILL_CONTENT_TRUNCATED_TEMPLATE.format(
171
+ max_lines=ATTACHMENT_SKILL_MAX_LINES,
172
+ total_lines=truncation.total_lines,
173
+ path=str(skill.skill_path),
174
+ )
175
+
176
+
144
177
  def _mark_skill_loaded(session: Session, path: str, content: str, *, source: Literal["dynamic", "explicit"]) -> None:
145
178
  existing = session.file_tracker.get(path)
146
179
  try:
@@ -150,6 +183,7 @@ def _mark_skill_loaded(session: Session, path: str, content: str, *, source: Lit
150
183
  session.file_tracker[path] = FileStatus(
151
184
  mtime=mtime,
152
185
  content_sha256=hash_text_sha256(content),
186
+ cached_content=existing.cached_content if existing else None,
153
187
  is_memory=existing.is_memory if existing else False,
154
188
  is_skill=True,
155
189
  is_skill_listing=existing.is_skill_listing if existing else False,
@@ -179,11 +213,20 @@ def _format_skill_block_str(skill: Skill, skill_content: str, *, explicit: bool)
179
213
  skill_name=skill.name,
180
214
  skill_path=skill.skill_path,
181
215
  base_dir=skill.base_dir,
182
- skill_content=skill_content,
216
+ skill_content=_render_skill_inline_content(skill_content, skill),
183
217
  explicit=explicit,
184
218
  )
185
219
 
186
220
 
221
+ def _is_skill_content_already_in_context(session: Session, path: str) -> bool:
222
+ status = session.file_tracker.get(path)
223
+ if status is None:
224
+ return False
225
+ if not status.read_complete and status.skill_attachment_source != "explicit":
226
+ return False
227
+ return is_tracked_file_unchanged(session, path)
228
+
229
+
187
230
  def _build_skills_xml(skills: Sequence[Skill]) -> str:
188
231
  loader = SkillLoader()
189
232
  loader.loaded_skills = {skill.name: skill for skill in _sort_skills_for_listing(skills)}
@@ -312,6 +355,14 @@ def _collect_skill_blocks(session: Session, skills: list[Skill], *, explicit: bo
312
355
  continue
313
356
 
314
357
  skill_path = str(skill.skill_path)
358
+ if explicit and _is_skill_content_already_in_context(session, skill_path):
359
+ _mark_skill_loaded(session, skill_path, skill_content, source="explicit")
360
+ loaded_dynamic_paths_by_name[skill.name] = skill_path
361
+ loaded_all_paths_by_name[skill.name] = skill_path
362
+ skill_blocks.append(_fmt_skill_already_in_context(skill.name, skill_path, tools.READ))
363
+ activated_skills.append(skill)
364
+ continue
365
+
315
366
  if not explicit:
316
367
  non_dynamic_path = loaded_all_paths_by_name.get(skill.name)
317
368
  dynamic_path = loaded_dynamic_paths_by_name.get(skill.name)
@@ -72,6 +72,18 @@ def mark_directory_accessed(session: Session, path: str) -> None:
72
72
  )
73
73
 
74
74
 
75
+ def reset_attachment_loaded_flags(file_tracker: dict[str, FileStatus]) -> None:
76
+ """Remove attachment-only entries so transient reminders can re-inject after compaction."""
77
+
78
+ transient_paths = [
79
+ path
80
+ for path, status in file_tracker.items()
81
+ if status.is_memory or status.is_skill_listing or status.skill_attachment_source == "dynamic"
82
+ ]
83
+ for path in transient_paths:
84
+ del file_tracker[path]
85
+
86
+
75
87
  def is_memory_loaded(session: Session, path: str) -> bool:
76
88
  """Check if a memory file has already been loaded or read unchanged."""
77
89
 
@@ -13,21 +13,10 @@ import re
13
13
  from klaude_code.agent.compaction.compaction import serialize_conversation
14
14
  from klaude_code.llm.client import LLMClientABC
15
15
  from klaude_code.log import DebugType, log_debug
16
+ from klaude_code.prompts.away_summary import AWAY_SUMMARY_SYSTEM_PROMPT, AWAY_SUMMARY_USER_PROMPT
16
17
  from klaude_code.protocol import llm_param, message
17
18
  from klaude_code.session.session import Session
18
19
 
19
- _AWAY_SUMMARY_SYSTEM_PROMPT = (
20
- "You summarize an in-progress coding session for a user who stepped away. "
21
- "Write a neutral recap, not an evaluation. Do not praise, judge, agree "
22
- "with, or endorse any proposal. Do not speak in first person as the "
23
- "assistant, and do not say things like 'I will' or 'I'll'. "
24
- "Always reply in the exact same natural language the user used in their "
25
- "own messages (the lines marked [User]:). Never translate. Ignore the "
26
- "language of assistant replies, tool calls, and tool output when choosing "
27
- "your output language. "
28
- "Respond with only the recap text, no quotes, no markdown, no preamble."
29
- )
30
-
31
20
  _AWAY_SUMMARY_MAX_TOKENS = 512
32
21
 
33
22
  # Recap only needs recent context — truncate to avoid "prompt too long" on
@@ -36,22 +25,7 @@ _RECENT_MESSAGE_WINDOW = 30
36
25
 
37
26
 
38
27
  def _build_away_summary_user_message(transcript: str) -> message.UserMessage:
39
- body = (
40
- "Language rule (highest priority): detect the natural language used "
41
- "in the [User]: lines below and write your entire reply in that "
42
- "language. If the user wrote Chinese, reply in Chinese; if Japanese, "
43
- "reply in Japanese; and so on. Do not translate to English.\n\n"
44
- "The user stepped away and is coming back. Write exactly 1-3 short "
45
- "sentences. Start by stating the high-level task — what they are "
46
- "building or debugging, not implementation details. Then state the "
47
- "current progress or where the work stopped in one concrete phrase. "
48
- "End with the concrete next step. Skip status reports and commit "
49
- "recaps. Write a neutral reminder of where the work stands. Do not "
50
- "evaluate the quality of ideas, do not repeat encouragement or "
51
- "approval, do not present a numbered plan, and do not write from the "
52
- "assistant's point of view. Never say 'I', 'I'll', or 'I will'.\n\n"
53
- f"<conversation>\n{transcript}\n</conversation>"
54
- )
28
+ body = AWAY_SUMMARY_USER_PROMPT.format(transcript=transcript)
55
29
  return message.UserMessage(parts=[message.TextPart(text=body)])
56
30
 
57
31
 
@@ -95,7 +69,7 @@ async def generate_away_summary(
95
69
 
96
70
  call_param = llm_param.LLMCallParameter(
97
71
  input=[_build_away_summary_user_message(transcript)],
98
- system=_AWAY_SUMMARY_SYSTEM_PROMPT,
72
+ system=AWAY_SUMMARY_SYSTEM_PROMPT,
99
73
  session_id=None,
100
74
  )
101
75
  call_param.max_tokens = _AWAY_SUMMARY_MAX_TOKENS
@@ -107,14 +107,18 @@ def build_fork_cache_event(
107
107
  cache_hit_rate=0.0,
108
108
  fallback_used=fallback_used,
109
109
  )
110
- total = usage.cached_tokens + usage.cache_write_tokens + usage.input_tokens
110
+ # ``Usage.input_tokens`` is provider-dependent: Anthropic/OpenAI paths store it
111
+ # as the full prompt total (cached + write + non-cached), while others use only
112
+ # the non-cached portion. ``max(input_tokens, cached + write)`` normalizes to
113
+ # the true total prompt size across providers (same trick as CacheTracker).
114
+ total = max(usage.input_tokens, usage.cached_tokens + usage.cache_write_tokens)
111
115
  hit_rate = usage.cached_tokens / total if total > 0 else 0.0
112
116
  return events.ForkCacheHitRateEvent(
113
117
  session_id=session_id,
114
118
  fork_label=fork_label,
115
119
  cache_read_tokens=usage.cached_tokens,
116
120
  cache_creation_tokens=usage.cache_write_tokens,
117
- input_tokens=usage.input_tokens,
121
+ input_tokens=max(0, total - usage.cached_tokens - usage.cache_write_tokens),
118
122
  cache_hit_rate=hit_rate,
119
123
  fallback_used=fallback_used,
120
124
  )