kolega-code 0.15.0__tar.gz → 0.16.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 (495) hide show
  1. {kolega_code-0.15.0 → kolega_code-0.16.0}/.gitignore +1 -0
  2. {kolega_code-0.15.0 → kolega_code-0.16.0}/CHANGELOG.md +29 -0
  3. {kolega_code-0.15.0 → kolega_code-0.16.0}/PKG-INFO +2 -2
  4. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/astro.config.mjs +4 -0
  5. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/assets/coverage.svg +1 -1
  6. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/providers-and-models.mdx +2 -0
  7. kolega_code-0.16.0/docs/src/content/docs/troubleshooting/terminal-tmux.md +67 -0
  8. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/composer.md +21 -1
  9. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/interface.md +4 -2
  10. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/slash-commands.md +2 -0
  11. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/__init__.py +1 -1
  12. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/__init__.py +1 -1
  13. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/edit_tool.py +53 -5
  14. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/lsp_tool.py +60 -8
  15. kolega_code-0.16.0/kolega_code/agent/tool_backend/snapshot_tool.py +191 -0
  16. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tools.py +124 -0
  17. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/app.py +21 -2
  18. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/messages.py +11 -0
  19. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/provider_registry.py +2 -1
  20. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/slash_commands.py +5 -1
  21. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/command_handlers.py +10 -8
  22. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/widgets.py +33 -10
  23. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/openai.py +13 -1
  24. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/xai.py +13 -0
  25. kolega_code-0.16.0/kolega_code/services/snapshots.py +600 -0
  26. {kolega_code-0.15.0 → kolega_code-0.16.0}/pyproject.toml +2 -2
  27. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_model_specs.py +12 -0
  28. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_reasoning_replay.py +1 -0
  29. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_supports_vision.py +1 -0
  30. kolega_code-0.16.0/tests/agent/llm/test_xai_prompt_cache_header.py +38 -0
  31. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_agent_tools_inventory.py +1 -1
  32. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_config.py +3 -0
  33. kolega_code-0.16.0/tests/agent/tool_backend/test_snapshot_tool.py +345 -0
  34. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_composer_input.py +99 -0
  35. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_image_vision_warning.py +3 -3
  36. kolega_code-0.16.0/tests/cli/test_app_tmux_shortcuts.py +193 -0
  37. kolega_code-0.16.0/tests/services/test_snapshots.py +138 -0
  38. {kolega_code-0.15.0 → kolega_code-0.16.0}/uv.lock +104 -104
  39. {kolega_code-0.15.0 → kolega_code-0.16.0}/.env.example +0 -0
  40. {kolega_code-0.15.0 → kolega_code-0.16.0}/.githooks/pre-commit +0 -0
  41. {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  42. {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  43. {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  44. {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/workflows/ci.yml +0 -0
  45. {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/workflows/docs.yml +0 -0
  46. {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/workflows/release.yml +0 -0
  47. {kolega_code-0.15.0 → kolega_code-0.16.0}/.pre-commit-config.yaml +0 -0
  48. {kolega_code-0.15.0 → kolega_code-0.16.0}/CONTRIBUTING.md +0 -0
  49. {kolega_code-0.15.0 → kolega_code-0.16.0}/LICENSE +0 -0
  50. {kolega_code-0.15.0 → kolega_code-0.16.0}/README.md +0 -0
  51. {kolega_code-0.15.0 → kolega_code-0.16.0}/RELEASING.md +0 -0
  52. {kolega_code-0.15.0 → kolega_code-0.16.0}/SECURITY.md +0 -0
  53. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/.gitignore +0 -0
  54. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/README.md +0 -0
  55. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/package-lock.json +0 -0
  56. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/package.json +0 -0
  57. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/public/favicon.svg +0 -0
  58. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/assets/demo.gif +0 -0
  59. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/assets/kolega-dark.svg +0 -0
  60. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/assets/kolega-light.svg +0 -0
  61. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/cli/ask.md +0 -0
  62. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/cli/doctor.md +0 -0
  63. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/cli/overview.md +0 -0
  64. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/cli/sessions.md +0 -0
  65. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/concepts/agents.md +0 -0
  66. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/concepts/how-it-works.md +0 -0
  67. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/concepts/tools.md +0 -0
  68. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/environment-variables.md +0 -0
  69. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/lsp.md +0 -0
  70. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/mcp.md +0 -0
  71. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/prompt-overrides.md +0 -0
  72. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/settings-and-api-keys.mdx +0 -0
  73. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/sign-in-with-chatgpt.mdx +0 -0
  74. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/getting-started/installation.mdx +0 -0
  75. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/getting-started/quick-start.mdx +0 -0
  76. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/gigacode.mdx +0 -0
  77. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/goal.md +0 -0
  78. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/hooks.md +0 -0
  79. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/index.mdx +0 -0
  80. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/skills.mdx +0 -0
  81. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/troubleshooting/diagnostics.md +0 -0
  82. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/modes.md +0 -0
  83. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/sessions-and-resume.md +0 -0
  84. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content.config.ts +0 -0
  85. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/styles/brand.css +0 -0
  86. {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/tsconfig.json +0 -0
  87. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/baseagent.py +0 -0
  88. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/browseragent.py +0 -0
  89. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/coder.py +0 -0
  90. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/common.py +0 -0
  91. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/compression.py +0 -0
  92. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/context.py +0 -0
  93. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/conversation.py +0 -0
  94. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/errors.py +0 -0
  95. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/generalagent.py +0 -0
  96. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/goal.py +0 -0
  97. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/investigationagent.py +0 -0
  98. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/__init__.py +0 -0
  99. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/budget.py +0 -0
  100. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/errors.py +0 -0
  101. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/executor.py +0 -0
  102. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/guide.py +0 -0
  103. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/journal.py +0 -0
  104. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/runtime.py +0 -0
  105. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/types.py +0 -0
  106. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/planningagent.py +0 -0
  107. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_dump.py +0 -0
  108. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_overrides.py +0 -0
  109. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_provider.py +0 -0
  110. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
  111. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
  112. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
  113. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
  114. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +0 -0
  115. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/extensions/cli/current_plan_artifact.md.j2 +0 -0
  116. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
  117. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
  118. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
  119. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
  120. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +0 -0
  121. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
  122. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
  123. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
  124. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
  125. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
  126. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
  127. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
  128. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
  129. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
  130. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
  131. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
  132. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
  133. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompts.py +0 -0
  134. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/agent_tool.py +0 -0
  135. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/base_tool.py +0 -0
  136. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
  137. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/build_tool.py +0 -0
  138. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
  139. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/glob_tool.py +0 -0
  140. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/list_directory_tool.py +0 -0
  141. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
  142. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
  143. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
  144. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
  145. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
  146. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
  147. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
  148. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
  149. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
  150. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
  151. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
  152. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_codebase_tool.py +0 -0
  153. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
  154. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
  155. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/think_hard_tool.py +0 -0
  156. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
  157. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
  158. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/workflow_tool.py +0 -0
  159. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/utils/commands.py +0 -0
  160. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/__init__.py +0 -0
  161. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/_jwt.py +0 -0
  162. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/chatgpt_oauth.py +0 -0
  163. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/constants.py +0 -0
  164. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/tokens.py +0 -0
  165. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/__init__.py +0 -0
  166. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/clipboard_image.py +0 -0
  167. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/config.py +0 -0
  168. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/connection.py +0 -0
  169. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/diagnostics.py +0 -0
  170. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/file_index.py +0 -0
  171. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/goal.py +0 -0
  172. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/main.py +0 -0
  173. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/mentions.py +0 -0
  174. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/plan_artifacts.py +0 -0
  175. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/session_store.py +0 -0
  176. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/settings.py +0 -0
  177. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/skills.py +0 -0
  178. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/theme.py +0 -0
  179. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/__init__.py +0 -0
  180. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/agent_runtime.py +0 -0
  181. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/app_base.py +0 -0
  182. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/changes_screen.py +0 -0
  183. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/constants.py +0 -0
  184. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/prompt_flows.py +0 -0
  185. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/session_diff.py +0 -0
  186. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/settings_panel.py +0 -0
  187. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/state.py +0 -0
  188. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/status_dashboard.py +0 -0
  189. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/styles.tcss +0 -0
  190. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/sub_agent_screen.py +0 -0
  191. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/terminal_display.py +0 -0
  192. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/transcript.py +0 -0
  193. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/updater.py +0 -0
  194. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/config.py +0 -0
  195. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/events.py +0 -0
  196. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/__init__.py +0 -0
  197. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/backends.py +0 -0
  198. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/config.py +0 -0
  199. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/dispatcher.py +0 -0
  200. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/events.py +0 -0
  201. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/matcher.py +0 -0
  202. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/outcome.py +0 -0
  203. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/client.py +0 -0
  204. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/exceptions.py +0 -0
  205. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/instrumented_client.py +0 -0
  206. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/models.py +0 -0
  207. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/__init__.py +0 -0
  208. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/anthropic.py +0 -0
  209. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/base.py +0 -0
  210. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
  211. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/google.py +0 -0
  212. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/models.py +0 -0
  213. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/openai_responses.py +0 -0
  214. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/responses_common.py +0 -0
  215. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/ratelimit.py +0 -0
  216. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/__init__.py +0 -0
  217. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/accessors.py +0 -0
  218. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/__init__.py +0 -0
  219. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/anthropic.py +0 -0
  220. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/dashscope.py +0 -0
  221. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/deepseek.py +0 -0
  222. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/fireworks.py +0 -0
  223. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/google.py +0 -0
  224. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/kimi_coding.py +0 -0
  225. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/moonshot.py +0 -0
  226. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/ollama_cloud.py +0 -0
  227. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/openai.py +0 -0
  228. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/openai_chatgpt.py +0 -0
  229. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/together.py +0 -0
  230. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/zai.py +0 -0
  231. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/thinking.py +0 -0
  232. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/types.py +0 -0
  233. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/timeouts.py +0 -0
  234. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/tool_execution_ids.py +0 -0
  235. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/local_state.py +0 -0
  236. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/__init__.py +0 -0
  237. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/config.py +0 -0
  238. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/oauth.py +0 -0
  239. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/service.py +0 -0
  240. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/state.py +0 -0
  241. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/tools.py +0 -0
  242. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/transport.py +0 -0
  243. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/models/__init__.py +0 -0
  244. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/models/sandbox_terminal_state.py +0 -0
  245. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/permissions.py +0 -0
  246. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/runtime.py +0 -0
  247. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/README.md +0 -0
  248. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/__init__.py +0 -0
  249. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/async_filesystem.py +0 -0
  250. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/base.py +0 -0
  251. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/browser.py +0 -0
  252. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/event_loop.py +0 -0
  253. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/filesystem.py +0 -0
  254. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/local.py +0 -0
  255. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/serializer.py +0 -0
  256. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/terminal.py +0 -0
  257. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/utils.py +0 -0
  258. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/base.py +0 -0
  259. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/browser.py +0 -0
  260. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/file_system.py +0 -0
  261. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/html.py +0 -0
  262. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/__init__.py +0 -0
  263. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/client.py +0 -0
  264. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/config.py +0 -0
  265. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/detector.py +0 -0
  266. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/diagnostics.py +0 -0
  267. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/edits.py +0 -0
  268. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/manager.py +0 -0
  269. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/registry.py +0 -0
  270. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/registry.yaml +0 -0
  271. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/terminal.py +0 -0
  272. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/terminal_buffer.py +0 -0
  273. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/tools/__init__.py +0 -0
  274. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/tools/core.py +0 -0
  275. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/tools/definitions.py +0 -0
  276. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/tools/registry.py +0 -0
  277. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/utils/__init__.py +0 -0
  278. {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/utils/images.py +0 -0
  279. {kolega_code-0.15.0 → kolega_code-0.16.0}/run_tests.sh +0 -0
  280. {kolega_code-0.15.0 → kolega_code-0.16.0}/scripts/bench_hotpaths.py +0 -0
  281. {kolega_code-0.15.0 → kolega_code-0.16.0}/scripts/check-dev-hooks.sh +0 -0
  282. {kolega_code-0.15.0 → kolega_code-0.16.0}/scripts/install-kolega-code.sh +0 -0
  283. {kolega_code-0.15.0 → kolega_code-0.16.0}/scripts/setup-dev.sh +0 -0
  284. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/__init__.py +0 -0
  285. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/__init__.py +0 -0
  286. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/compaction_helpers.py +0 -0
  287. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/conftest.py +0 -0
  288. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/__init__.py +0 -0
  289. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/_token_counting_utils.py +0 -0
  290. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_anthropic_local_token_counting_incremental.py +0 -0
  291. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_anthropic_token_counting.py +0 -0
  292. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_billing_openai_cache.py +0 -0
  293. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_live.py +0 -0
  294. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_auth_config.py +0 -0
  295. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_conversion.py +0 -0
  296. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_provider.py +0 -0
  297. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_provider_generate.py +0 -0
  298. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_streaming.py +0 -0
  299. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_client.py +0 -0
  300. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_client_live.py +0 -0
  301. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_client_runtime.py +0 -0
  302. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_dashscope_mapping.py +0 -0
  303. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_error_boundary.py +0 -0
  304. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_exceptions.py +0 -0
  305. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_google_thought_signature.py +0 -0
  306. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_google_tool_signature_live.py +0 -0
  307. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_instrumented_client.py +0 -0
  308. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_instrumented_client_integration.py +0 -0
  309. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_instrumented_client_stream.py +0 -0
  310. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_langfuse_normalization.py +0 -0
  311. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_live_providers.py +0 -0
  312. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_message_conversion.py +0 -0
  313. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_cached_tokens.py +0 -0
  314. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_cached_tokens_stream.py +0 -0
  315. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_message_conversion.py +0 -0
  316. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_responses_provider.py +0 -0
  317. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_stream_accumulation.py +0 -0
  318. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_token_counting.py +0 -0
  319. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_token_counting_incremental.py +0 -0
  320. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_provider_usage_mapping.py +0 -0
  321. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_streaming_timeouts.py +0 -0
  322. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_thinking_effort.py +0 -0
  323. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_tool_execution_ids.py +0 -0
  324. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/orchestration/__init__.py +0 -0
  325. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/orchestration/test_orchestration.py +0 -0
  326. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/__init__.py +0 -0
  327. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser.py +0 -0
  328. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser_console_logs.py +0 -0
  329. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser_content.py +0 -0
  330. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser_integration.py +0 -0
  331. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser_parity.py +0 -0
  332. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_file_system.py +0 -0
  333. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_file_system_integration.py +0 -0
  334. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_file_system_path.py +0 -0
  335. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_local_file_system.py +0 -0
  336. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_sandbox_terminal_input.py +0 -0
  337. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_terminal.py +0 -0
  338. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_terminal_buffer.py +0 -0
  339. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_terminal_state_serializer.py +0 -0
  340. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent.py +0 -0
  341. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_anthropic_history_validation.py +0 -0
  342. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_compaction.py +0 -0
  343. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_effective_history.py +0 -0
  344. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_history_serialization.py +0 -0
  345. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_prompt_context.py +0 -0
  346. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_role_overrides.py +0 -0
  347. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_runtime.py +0 -0
  348. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_tool_call_repair.py +0 -0
  349. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_tool_call_repair_integration.py +0 -0
  350. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_tool_execution.py +0 -0
  351. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_coder_attachments.py +0 -0
  352. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_coder_prompt_extensions.py +0 -0
  353. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_commands.py +0 -0
  354. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compaction_integration.py +0 -0
  355. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compaction_persistence.py +0 -0
  356. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compaction_subagent.py +0 -0
  357. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compaction_tui_events.py +0 -0
  358. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compress_command.py +0 -0
  359. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compression.py +0 -0
  360. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_conversation_compaction.py +0 -0
  361. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_duplicate_tool_results.py +0 -0
  362. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_empty_message_handling.py +0 -0
  363. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_event_emitter.py +0 -0
  364. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_general_agent.py +0 -0
  365. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_gigacode_gating.py +0 -0
  366. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_goal.py +0 -0
  367. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_goal_evaluate.py +0 -0
  368. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_history_adapter_thinking.py +0 -0
  369. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_history_image_blocks.py +0 -0
  370. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_hooks_integration.py +0 -0
  371. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_html.py +0 -0
  372. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_image_compat.py +0 -0
  373. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_parallel_tool_calls.py +0 -0
  374. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_permissions.py +0 -0
  375. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_planning_agent.py +0 -0
  376. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_prompt_dump.py +0 -0
  377. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_prompt_overrides.py +0 -0
  378. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_prompt_provider.py +0 -0
  379. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_prompts.py +0 -0
  380. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_read_image_tool.py +0 -0
  381. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_builtin_dispatch.py +0 -0
  382. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_extensions.py +0 -0
  383. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_initialization.py +0 -0
  384. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_memory.py +0 -0
  385. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_registry.py +0 -0
  386. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tools.py +0 -0
  387. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/__init__.py +0 -0
  388. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_agent_tool.py +0 -0
  389. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_base_tool.py +0 -0
  390. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_browser_tool.py +0 -0
  391. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_build_tool.py +0 -0
  392. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_edit_preview.py +0 -0
  393. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_edit_tool.py +0 -0
  394. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_glob_tool.py +0 -0
  395. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_glob_tool_sandbox_parity.py +0 -0
  396. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_list_directory_tool.py +0 -0
  397. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_lsp_tool.py +0 -0
  398. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_read_file_tool.py +0 -0
  399. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_search_codebase_tool.py +0 -0
  400. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_terminal_tool.py +0 -0
  401. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_integration.py +0 -0
  402. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_streaming.py +0 -0
  403. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_streaming_content.py +0 -0
  404. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_streaming_errors.py +0 -0
  405. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_streaming_updates.py +0 -0
  406. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_web_fetch_tool.py +0 -0
  407. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_web_search_tool.py +0 -0
  408. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_workflow_tool.py +0 -0
  409. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/auth/__init__.py +0 -0
  410. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/auth/test_chatgpt_oauth.py +0 -0
  411. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/auth/test_tokens.py +0 -0
  412. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/__init__.py +0 -0
  413. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/_app_test_utils.py +0 -0
  414. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app.py +0 -0
  415. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_agent_wiring.py +0 -0
  416. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_bootstrap_settings.py +0 -0
  417. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_changes_inspector.py +0 -0
  418. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_compaction_restore.py +0 -0
  419. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_composer_commands.py +0 -0
  420. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_conversation_rendering.py +0 -0
  421. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_diagnostics.py +0 -0
  422. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_focus_behavior.py +0 -0
  423. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_goal_command.py +0 -0
  424. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_lsp_settings_status.py +0 -0
  425. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_mention_dropdown.py +0 -0
  426. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_misc_commands.py +0 -0
  427. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_model_effort_commands.py +0 -0
  428. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_model_switch_vision.py +0 -0
  429. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_modes_planning.py +0 -0
  430. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_navigation_commands.py +0 -0
  431. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_permission_prompts.py +0 -0
  432. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_persistence_history.py +0 -0
  433. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_plan_lifecycle.py +0 -0
  434. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_planning_questions.py +0 -0
  435. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_planning_restore.py +0 -0
  436. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_entries.py +0 -0
  437. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_errors.py +0 -0
  438. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_scroll.py +0 -0
  439. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_selection.py +0 -0
  440. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_status.py +0 -0
  441. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_streaming.py +0 -0
  442. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_terminal_logs.py +0 -0
  443. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_tools.py +0 -0
  444. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_session_diff_async.py +0 -0
  445. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_skill_commands.py +0 -0
  446. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_slash_dropdown.py +0 -0
  447. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_status_modes.py +0 -0
  448. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_sub_agents_workflows.py +0 -0
  449. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_ask_goal.py +0 -0
  450. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_cli_config.py +0 -0
  451. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_clipboard_image.py +0 -0
  452. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_connection.py +0 -0
  453. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_diagnostics.py +0 -0
  454. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_file_index.py +0 -0
  455. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_main.py +0 -0
  456. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_mcp_cli.py +0 -0
  457. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_mcp_settings_formatting.py +0 -0
  458. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_mentions.py +0 -0
  459. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_plan_artifacts.py +0 -0
  460. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_provider_registry.py +0 -0
  461. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_session_diff.py +0 -0
  462. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_session_store.py +0 -0
  463. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_settings.py +0 -0
  464. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_skills.py +0 -0
  465. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_slash_commands.py +0 -0
  466. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_sub_agent_stream_accumulation.py +0 -0
  467. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_terminal_display.py +0 -0
  468. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_themes.py +0 -0
  469. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_transcript_streaming_render.py +0 -0
  470. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_tui_stylesheet.py +0 -0
  471. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_updater.py +0 -0
  472. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/conftest.py +0 -0
  473. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/hooks/__init__.py +0 -0
  474. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/hooks/test_hooks.py +0 -0
  475. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/mcp/test_config_state_tools.py +0 -0
  476. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/_fake_server.py +0 -0
  477. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/conftest.py +0 -0
  478. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_client.py +0 -0
  479. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_detector.py +0 -0
  480. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_diagnostics.py +0 -0
  481. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_edits.py +0 -0
  482. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_integration.py +0 -0
  483. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_lsp_edit_tool_integration.py +0 -0
  484. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_manager.py +0 -0
  485. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_project_config.py +0 -0
  486. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_registry.py +0 -0
  487. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_trust.py +0 -0
  488. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/test_agent_config_serialization.py +0 -0
  489. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/test_mcp_permissions.py +0 -0
  490. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/test_mcp_transport.py +0 -0
  491. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/tools/__init__.py +0 -0
  492. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/tools/test_definitions.py +0 -0
  493. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/utils/__init__.py +0 -0
  494. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/utils/test_images.py +0 -0
  495. {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/utils/test_images_ascii.py +0 -0
@@ -15,3 +15,4 @@ build/
15
15
  coverage.xml
16
16
  htmlcov/
17
17
  docs/kolega_reskin_project/
18
+ docs/agent-harness-frontier-roadmap.md
@@ -6,6 +6,35 @@ This project uses GitHub Releases for detailed generated release notes. This fil
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.16.0 - 2026-07-09
10
+
11
+ ### Added
12
+
13
+ - Added support for xAI Grok 4.5 (`grok-4.5`): 500K-token context, vision input,
14
+ and `low`/`medium`/`high` reasoning effort. Selectable in the Settings UI,
15
+ `/model` picker, CLI flags, and env vars; now the default `xai` model.
16
+ - Send a stable `x-grok-conv-id` header on xAI Chat Completions requests so
17
+ multi-turn agent loops pin to a cache-warm server (xAI prompt-caching guidance).
18
+ - Added session-scoped workspace snapshots for agent file mutations: `snapshot`
19
+ (list/show/create/restore, including `snapshot_id='latest'` undo) and `resolve`
20
+ for applying or discarding pending `lsp_edit` preview actions. Restore refuses
21
+ on post-snapshot drift unless `force=true`.
22
+ - Improved TUI usability inside tmux/screen when Shift-modified keys never reach
23
+ the app: `/attach` with no path pastes an image from the system clipboard,
24
+ `Alt+V` is a portable image-paste binding alongside `Ctrl+Shift+V`, startup
25
+ help highlights `Ctrl+J` / `/plan` / `/build` fallbacks, and a one-time
26
+ startup hint appears under tmux. Documented optional tmux extended-keys config
27
+ under Troubleshooting.
28
+
29
+ ### Fixed
30
+
31
+ - Prevented a TUI crash when pasting long multi-line text into the composer
32
+ (`OSError: File name too long` from treating paste content as a path).
33
+ - Stopped advertising host lifecycle `initialize` as a model-callable tool while
34
+ keeping it available for CLI/TUI startup (LSP setup).
35
+ - Bumped `lxml-html-clean` to 0.4.5 (and transitive `lxml` to 6.1.1) to clear
36
+ GHSA-4jhm-jv67-739f from the dependency audit.
37
+
9
38
  ## 0.15.0 - 2026-07-07
10
39
 
11
40
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kolega-code
3
- Version: 0.15.0
3
+ Version: 0.16.0
4
4
  Summary: Multi-agent coding in the terminal
5
5
  Project-URL: Homepage, https://kolega-ai.github.io/kolega-code/
6
6
  Project-URL: Documentation, https://kolega-ai.github.io/kolega-code/
@@ -234,7 +234,7 @@ Requires-Dist: google-genai==2.0.1
234
234
  Requires-Dist: httpx==0.28.1
235
235
  Requires-Dist: jinja2==3.1.6
236
236
  Requires-Dist: langfuse==3.14.5
237
- Requires-Dist: lxml-html-clean==0.4.4
237
+ Requires-Dist: lxml-html-clean==0.4.5
238
238
  Requires-Dist: mcp>=1.21.2
239
239
  Requires-Dist: nest-asyncio==1.6.0
240
240
  Requires-Dist: openai==1.109.1
@@ -120,6 +120,10 @@ export default defineConfig({
120
120
  label: "Diagnostics & Bug Reports",
121
121
  slug: "troubleshooting/diagnostics",
122
122
  },
123
+ {
124
+ label: "Terminal & tmux shortcuts",
125
+ slug: "troubleshooting/terminal-tmux",
126
+ },
123
127
  ],
124
128
  },
125
129
  {
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 79.72%"><title>coverage: 79.72%</title><filter id="blur"><feGaussianBlur stdDeviation="16"/></filter><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#67ac09"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="315" y="150" fill-opacity=".8" filter="url(#blur)" textLength="510">coverage</text><text x="315" y="150" fill-opacity=".3" textLength="510">coverage</text></g><text x="315" y="140" textLength="510">coverage</text></g><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="865" y="150" fill-opacity=".8" filter="url(#blur)" textLength="430">79.72%</text><text x="865" y="150" fill-opacity=".3" textLength="430">79.72%</text></g><text x="865" y="140" textLength="430">79.72%</text></g></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 79.93%"><title>coverage: 79.93%</title><filter id="blur"><feGaussianBlur stdDeviation="16"/></filter><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#67ac09"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="315" y="150" fill-opacity=".8" filter="url(#blur)" textLength="510">coverage</text><text x="315" y="150" fill-opacity=".3" textLength="510">coverage</text></g><text x="315" y="140" textLength="510">coverage</text></g><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="865" y="150" fill-opacity=".8" filter="url(#blur)" textLength="430">79.93%</text><text x="865" y="150" fill-opacity=".3" textLength="430">79.93%</text></g><text x="865" y="140" textLength="430">79.93%</text></g></g></svg>
@@ -184,6 +184,8 @@ models in the TUI.
184
184
  | Ollama Cloud `gpt-oss:*` | `low`, `medium`, `high` | `medium` |
185
185
  | Google `gemini-2.5-pro` | `auto`, `low`, `medium`, `high` | `medium` |
186
186
  | OpenAI reasoning models | `low`, `medium`, `high` | `medium` |
187
+ | xAI `grok-4.5` | `low`, `medium`, `high` | `medium` |
188
+ | xAI `grok-4.3` | `none`, `low`, `medium`, `high` | `low` |
187
189
 
188
190
  ## Check what's active
189
191
 
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: Terminal & tmux shortcuts
3
+ description: Why Shift chords fail in tmux/screen and the portable fallbacks Kolega Code supports.
4
+ ---
5
+
6
+ Kolega Code’s TUI uses some Shift-modified shortcuts (`Shift+Enter`, `Shift+Tab`,
7
+ `Ctrl+Shift+V`). In a modern terminal with the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/),
8
+ those chords reach the app. Inside **tmux** or **GNU screen**, the multiplexer
9
+ often sits between the terminal and the app and either drops modifiers or
10
+ never forwards the extended key sequences — so Shift chords look like plain
11
+ keys, or never arrive at all.
12
+
13
+ Kolega Code cannot invent modifier information the terminal never sends. Instead
14
+ it provides **portable fallbacks** that work without Shift, plus optional tmux
15
+ config if you want the original chords restored.
16
+
17
+ ## Portable shortcuts
18
+
19
+ | Action | Preferred (capable terminals) | Portable fallback |
20
+ | --- | --- | --- |
21
+ | Send prompt | `Enter` | — |
22
+ | Insert newline | `Shift+Enter` | `Ctrl+J` or `Ctrl+Enter` |
23
+ | Toggle Plan ⇄ Build | `Shift+Tab` | `/plan` or `/build` |
24
+ | Paste image from system clipboard | `Ctrl+Shift+V` | `Alt+V` (Option+V on macOS when the terminal treats Option as Meta) or `/attach` with no path |
25
+ | Attach image from a file | — | `/attach <path>` or `@image.png` |
26
+
27
+ On session start inside tmux/screen, the startup block prints a short reminder
28
+ of these fallbacks.
29
+
30
+ ### Image paste notes
31
+
32
+ - `/attach` with **no path** reads an image from the **system** clipboard (same
33
+ path as `Ctrl+Shift+V` / `Alt+V`). This is the most reliable option under
34
+ plain tmux.
35
+ - Clipboard image reading uses host tools independent of tmux:
36
+ - **macOS:** `osascript` (built-in), or `pngpaste` if installed
37
+ - **Linux:** `xclip` or `wl-paste`
38
+ - **Windows / WSL:** PowerShell clipboard APIs
39
+ - If Option+V types a special character (e.g. `√`) instead of pasting an image,
40
+ your terminal is not sending Alt as a modifier. Prefer `/attach`, or enable
41
+ “Option as Meta” / “Left Option key acts as +Esc” in the terminal settings.
42
+
43
+ ## Optional: restore Shift+Enter in tmux
44
+
45
+ With **tmux 3.2+** and an outer terminal that supports extended keys, add to
46
+ `~/.tmux.conf`:
47
+
48
+ ```tmux
49
+ set -g extended-keys always
50
+ set -g extended-keys-format csi-u
51
+ set -as terminal-features 'xterm*:extkeys'
52
+ ```
53
+
54
+ Then reload (`tmux source-file ~/.tmux.conf`) or restart tmux.
55
+
56
+ Also make sure `default-terminal` / `terminal-overrides` match the outer
57
+ terminal’s `$TERM` family (`xterm-256color`, `xterm-ghostty`, etc.) so the
58
+ `extkeys` feature actually applies.
59
+
60
+ After that, `Shift+Enter` and similar chords often work again inside Kolega Code.
61
+ If they still do not, keep using the portable fallbacks above.
62
+
63
+ ## Related
64
+
65
+ - [Chat Composer](../../tui/composer/) — full composer key reference
66
+ - [Interface Tour](../../tui/interface/) — key bindings at a glance
67
+ - [Slash Commands](../../tui/slash-commands/) — `/attach`, `/plan`, `/build`
@@ -13,17 +13,24 @@ multi-line input, and drives the option lists the agent shows you.
13
13
  | --- | --- |
14
14
  | `Enter` | Send the prompt |
15
15
  | `Shift+Enter` | Insert a newline (keep typing) |
16
- | `Ctrl+J` | Insert a newline (alternative) |
16
+ | `Ctrl+J` / `Ctrl+Enter` | Insert a newline (portable alternatives; prefer these inside tmux) |
17
17
  | `Ctrl+L` | Select all composer text |
18
18
  | `Cmd+A` / `⌘A` | Select all composer text on macOS, when forwarded by the terminal |
19
19
  | `Ctrl+A` | Move to the start of the current line (intentionally not select-all) |
20
20
  | `Ctrl+U` | Delete backward to the start of the line; at line start, delete the previous line |
21
+ | `Ctrl+Shift+V` | Paste an image from the system clipboard |
22
+ | `Alt+V` | Paste an image from the system clipboard (portable alternative when Shift chords fail) |
21
23
 
22
24
  `Ctrl+L` is the portable select-all shortcut because `Ctrl+A` is preserved for
23
25
  terminal-style line navigation. Some macOS terminal emulators reserve `Cmd+A` for
24
26
  terminal scrollback selection before the TUI can see it; `Ctrl+L` still works in
25
27
  the composer.
26
28
 
29
+ Inside **tmux** or **screen**, Shift-modified keys often never reach the app.
30
+ Use `Ctrl+J` for newlines and `Alt+V` or `/attach` for images. See
31
+ [Terminal & tmux shortcuts](../../troubleshooting/terminal-tmux/) for optional
32
+ tmux config to restore Shift+Enter.
33
+
27
34
  ## Queuing follow-up prompts
28
35
 
29
36
  You can keep typing while the agent is still generating. Pressing `Enter` during
@@ -45,6 +52,19 @@ If you cancel the active turn with `Ctrl+C` or `Escape`, queued follow-ups are
45
52
  restored into the composer instead of being silently sent. To discard pending
46
53
  follow-ups without stopping the active turn, run [`/queue-clear`](../slash-commands/).
47
54
 
55
+ ## Attaching images
56
+
57
+ You can attach images for vision-capable models in several ways:
58
+
59
+ | Method | How |
60
+ | --- | --- |
61
+ | System clipboard | `Ctrl+Shift+V` or `Alt+V`, or run `/attach` with no path |
62
+ | File path | `/attach path/to/image.png` |
63
+ | File mention | `@screenshot.png` (supported image extensions only) |
64
+
65
+ Use `/detach` to clear pending attachments before sending. On a non-vision
66
+ model, Kolega Code warns and blocks the send until you detach or switch models.
67
+
48
68
  ## File mentions with `@`
49
69
 
50
70
  Type `@` to reference a file. A fuzzy-searchable dropdown of project files appears
@@ -82,14 +82,16 @@ the turn keeps running while you look around.
82
82
 
83
83
  | Keys | Action |
84
84
  | --- | --- |
85
- | `Shift+Tab` | Toggle Build ⇄ Plan mode |
85
+ | `Shift+Tab` | Toggle Build ⇄ Plan mode (`/plan` / `/build` if Shift is unavailable) |
86
86
  | `Ctrl+P` | Toggle shell/edit permissions between Ask ⇄ Auto |
87
87
  | `Ctrl+O` | Show or hide the side panel |
88
88
  | `Ctrl+G` | Open the sub-agent inspector |
89
89
  | `Enter` | Send the prompt |
90
90
  | `Shift+Enter` / `Ctrl+J` | Insert a newline |
91
+ | `Ctrl+Shift+V` / `Alt+V` | Paste an image from the system clipboard (`/attach` also works) |
91
92
  | `Ctrl+C` / `Escape` | Cancel the current generation |
92
93
  | `Ctrl+Q` | Save the session and quit |
93
94
 
94
95
  A complete composer-and-completion key reference is in
95
- [Chat Composer](../composer/).
96
+ [Chat Composer](../composer/). If Shift chords fail inside tmux, see
97
+ [Terminal & tmux shortcuts](../../troubleshooting/terminal-tmux/).
@@ -34,6 +34,8 @@ These control the app and your session.
34
34
  | --- | --- |
35
35
  | `/skills` | List available Agent Skills |
36
36
  | `/init` | Create or update `AGENTS.md` for this repository |
37
+ | `/attach` | Attach an image: clipboard if no path, or `/attach <path>` for a file |
38
+ | `/detach` | Remove pending image attachments |
37
39
  | `/plan` | Switch to [Plan mode](../modes/) |
38
40
  | `/build` | Switch to [Build mode](../modes/) |
39
41
  | `/sidebar` | Show or hide the side panel |
@@ -151,4 +151,4 @@ __all__ = [
151
151
  "parse_git_status_output",
152
152
  ]
153
153
 
154
- __version__ = "0.15.0"
154
+ __version__ = "0.16.0"
@@ -44,4 +44,4 @@ __all__ = [
44
44
  "ToolExtension",
45
45
  ]
46
46
 
47
- __version__ = "0.15.0"
47
+ __version__ = "0.16.0"
@@ -9,6 +9,7 @@ from .edit_preview import build_diff_preview, build_head_preview
9
9
 
10
10
  if TYPE_CHECKING:
11
11
  from kolega_code.services.lsp import LspManager
12
+ from kolega_code.services.snapshots import SnapshotService
12
13
 
13
14
 
14
15
  _BLOCK_PATTERN = re.compile(r"<<<<<<< SEARCH\r?\n(.*?)\r?\n=======\r?\n(.*?)\r?\n>>>>>>> REPLACE", re.DOTALL)
@@ -43,9 +44,16 @@ class ResolvedReplacement:
43
44
 
44
45
 
45
46
  class EditTool(BaseTool):
46
- def __init__(self, *args, lsp_manager: Optional["LspManager"] = None, **kwargs) -> None:
47
+ def __init__(
48
+ self,
49
+ *args,
50
+ lsp_manager: Optional["LspManager"] = None,
51
+ snapshot_service: Optional["SnapshotService"] = None,
52
+ **kwargs,
53
+ ) -> None:
47
54
  super().__init__(*args, **kwargs)
48
55
  self._lsp_manager = lsp_manager
56
+ self._snapshot_service = snapshot_service
49
57
 
50
58
  async def edit(self, path: str, block: str) -> str:
51
59
  """
@@ -115,8 +123,6 @@ class EditTool(BaseTool):
115
123
  old_content = None
116
124
 
117
125
  parent_dir = self.filesystem.get_parent(path)
118
- if parent_dir and parent_dir != "." and not self.filesystem.exists(parent_dir):
119
- self.filesystem.create_directory(parent_dir)
120
126
 
121
127
  # Preserve the file's dominant line ending on overwrite; new files
122
128
  # keep the line endings the caller provided (typically LF).
@@ -124,7 +130,17 @@ class EditTool(BaseTool):
124
130
  line_ending = self._detect_dominant_line_ending(path, old_content)
125
131
  content = self._normalize_line_endings(content, line_ending)
126
132
 
127
- self.filesystem.write_text(path, content)
133
+ def _write() -> None:
134
+ if parent_dir and parent_dir != "." and not self.filesystem.exists(parent_dir):
135
+ self.filesystem.create_directory(parent_dir)
136
+ self.filesystem.write_text(path, content)
137
+
138
+ self._record_snapshot_mutation(
139
+ tool_name="write",
140
+ reason=f"write {path}",
141
+ paths=self._snapshot_paths_for_write(path),
142
+ mutate=_write,
143
+ )
128
144
 
129
145
  preview = (
130
146
  build_diff_preview(old_content, content, path)
@@ -180,7 +196,12 @@ class EditTool(BaseTool):
180
196
  blocked_msg = self._enforce_vibe_edit_policy(path)
181
197
  if blocked_msg:
182
198
  return blocked_msg
183
- self.filesystem.write_text(path, normalized_updated)
199
+ self._record_snapshot_mutation(
200
+ tool_name=tool_name,
201
+ reason=f"{tool_name} {path}",
202
+ paths=[path],
203
+ mutate=lambda: self.filesystem.write_text(path, normalized_updated),
204
+ )
184
205
 
185
206
  await self.send_edit_preview(
186
207
  build_diff_preview(original_content, normalized_updated, path),
@@ -223,6 +244,33 @@ class EditTool(BaseTool):
223
244
  )
224
245
  return parsed_blocks
225
246
 
247
+ def _record_snapshot_mutation(
248
+ self,
249
+ *,
250
+ tool_name: str,
251
+ reason: str,
252
+ paths: list[str],
253
+ mutate: Callable[[], None],
254
+ ) -> None:
255
+ if self._snapshot_service is None or not self._snapshot_service.can_snapshot_paths(paths):
256
+ mutate()
257
+ return
258
+ self._snapshot_service.record_mutation(
259
+ tool_name=tool_name,
260
+ tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
261
+ reason=reason,
262
+ paths=paths,
263
+ mutate=mutate,
264
+ )
265
+
266
+ def _snapshot_paths_for_write(self, path: str) -> list[str]:
267
+ paths = [path]
268
+ parent = self.filesystem.get_parent(path)
269
+ while parent and parent != "." and not self.filesystem.exists(parent):
270
+ paths.append(parent)
271
+ parent = self.filesystem.get_parent(parent)
272
+ return paths
273
+
226
274
  def _resolve_replacement(self, content: str, block: SearchReplaceBlock) -> ResolvedReplacement:
227
275
  passes: list[tuple[str, Callable[[str, str], list[tuple[int, int]]]]] = [
228
276
  ("exact", self._exact_spans),
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import hashlib
6
6
  import json
7
7
  from pathlib import Path
8
- from typing import Any, Optional, cast
8
+ from typing import TYPE_CHECKING, Any, Optional, cast
9
9
  from urllib.parse import unquote, urlparse
10
10
 
11
11
  from .base_tool import BaseTool
@@ -13,6 +13,9 @@ from .edit_preview import build_diff_preview
13
13
  from kolega_code.services.lsp import LspManager, format_diagnostics, format_no_diagnostics
14
14
  from kolega_code.services.lsp.edits import WorkspaceEditApplier, WorkspaceEditError, WorkspaceEditResult
15
15
 
16
+ if TYPE_CHECKING:
17
+ from kolega_code.services.snapshots import SnapshotService
18
+
16
19
 
17
20
  class LspTool(BaseTool):
18
21
  """Exposes read-only LSP operations as an agent-callable tool."""
@@ -563,9 +566,16 @@ class LspEditTool(BaseTool):
563
566
 
564
567
  _ALL_OPS = {"rename", "rename_file", "format_document", "format_range", "apply_code_action"}
565
568
 
566
- def __init__(self, *args, lsp_manager: Optional[LspManager] = None, **kwargs) -> None:
569
+ def __init__(
570
+ self,
571
+ *args,
572
+ lsp_manager: Optional[LspManager] = None,
573
+ snapshot_service: Optional["SnapshotService"] = None,
574
+ **kwargs,
575
+ ) -> None:
567
576
  super().__init__(*args, **kwargs)
568
577
  self._lsp_manager = lsp_manager
578
+ self._snapshot_service = snapshot_service
569
579
 
570
580
  async def lsp_edit(
571
581
  self,
@@ -842,7 +852,17 @@ class LspEditTool(BaseTool):
842
852
  blocked = self._first_blocked_path(preview.touched_paths)
843
853
  if blocked:
844
854
  return {"applied": False, "failureReason": blocked}
845
- applied = applier.apply(workspace_edit)
855
+ if self._snapshot_service is not None:
856
+ mutation = self._snapshot_service.record_mutation(
857
+ tool_name="lsp_edit",
858
+ tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
859
+ reason="lsp apply_code_action workspace/applyEdit",
860
+ paths=preview.touched_paths,
861
+ mutate=lambda: applier.apply(workspace_edit),
862
+ )
863
+ applied = mutation.result
864
+ else:
865
+ applied = applier.apply(workspace_edit)
846
866
  server_results.append(applied)
847
867
  return {"applied": True}
848
868
  except WorkspaceEditError as exc:
@@ -896,9 +916,33 @@ class LspEditTool(BaseTool):
896
916
  if should_apply and blocked:
897
917
  return blocked
898
918
 
899
- result = applier.apply(edit) if should_apply else preview
919
+ if should_apply:
920
+ if self._snapshot_service is not None:
921
+ mutation = self._snapshot_service.record_mutation(
922
+ tool_name="lsp_edit",
923
+ tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
924
+ reason=f"lsp_edit {operation}",
925
+ paths=preview.touched_paths,
926
+ mutate=lambda: applier.apply(edit),
927
+ )
928
+ result = mutation.result
929
+ else:
930
+ result = applier.apply(edit)
931
+ else:
932
+ result = preview
900
933
  await self._send_previews(result, operation)
901
934
  lines = [self._format_workspace_edit_result(operation, result)]
935
+ if not should_apply and self._snapshot_service is not None:
936
+ pending = self._snapshot_service.create_pending_workspace_edit(
937
+ tool_name="lsp_edit",
938
+ tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
939
+ operation=operation,
940
+ workspace_edit=edit,
941
+ touched_paths=preview.touched_paths,
942
+ summaries=preview.summaries,
943
+ previews=self._preview_payloads(preview),
944
+ )
945
+ lines.append(f'Pending action: `{pending.action_id}`. Use resolve(decision="apply") to apply it.')
902
946
  if should_apply and include_diagnostics:
903
947
  diagnostics = await self._diagnostics_for_paths(result.touched_paths)
904
948
  if diagnostics:
@@ -909,15 +953,23 @@ class LspEditTool(BaseTool):
909
953
  return WorkspaceEditApplier(self.project_path, self.filesystem).preview(edit)
910
954
 
911
955
  async def _send_previews(self, result: WorkspaceEditResult, operation: str) -> None:
912
- for change in result.text_changes:
913
- if change.old_text == change.new_text:
914
- continue
956
+ for preview in self._preview_payloads(result):
915
957
  await self.send_edit_preview(
916
- build_diff_preview(change.old_text, change.new_text, change.path),
958
+ preview,
917
959
  tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
918
960
  tool_name="lsp_edit",
919
961
  )
920
962
 
963
+ def _preview_payloads(self, result: WorkspaceEditResult) -> list[dict[str, Any]]:
964
+ previews: list[dict[str, Any]] = []
965
+ for change in result.text_changes:
966
+ if change.old_text == change.new_text:
967
+ continue
968
+ preview = build_diff_preview(change.old_text, change.new_text, change.path)
969
+ if preview:
970
+ previews.append(preview)
971
+ return previews
972
+
921
973
  def _format_workspace_edit_result(self, operation: str, result: WorkspaceEditResult) -> str:
922
974
  label = "Applied" if result.applied else "Preview"
923
975
  lines = [f"{label} LSP edit `{operation}`."]
@@ -0,0 +1,191 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any, Optional
4
+
5
+ from kolega_code.services.lsp.edits import WorkspaceEditApplier
6
+ from kolega_code.services.snapshots import PendingAction, SnapshotError, SnapshotRecord, SnapshotService
7
+ from kolega_code.tools import ToolError
8
+
9
+ from .base_tool import BaseTool
10
+ from .edit_preview import build_diff_preview
11
+
12
+ if TYPE_CHECKING:
13
+ from kolega_code.services.lsp.edits import WorkspaceEditResult
14
+
15
+
16
+ class SnapshotTool(BaseTool):
17
+ def __init__(self, *args, snapshot_service: SnapshotService, **kwargs) -> None:
18
+ super().__init__(*args, **kwargs)
19
+ self.snapshot_service = snapshot_service
20
+
21
+ async def snapshot(
22
+ self,
23
+ action: str = "list",
24
+ snapshot_id: str = "",
25
+ paths: Optional[list[str]] = None,
26
+ force: bool = False,
27
+ limit: int = 20,
28
+ ) -> str:
29
+ """Manage file snapshots for undo, inspection, and manual checkpoints.
30
+
31
+ Actions:
32
+ - list: show recent snapshots for this session.
33
+ - show: show one snapshot's metadata and touched paths.
34
+ - create: create a manual checkpoint for the provided paths.
35
+ - restore: restore a snapshot's before-state. Use snapshot_id="latest" for undo.
36
+
37
+ Args:
38
+ action: One of list, show, create, or restore.
39
+ snapshot_id: Snapshot id to show or restore. Use latest for the newest snapshot.
40
+ paths: Project-relative paths for create.
41
+ force: Restore even when tracked files changed after the snapshot.
42
+ limit: Maximum number of snapshots to list.
43
+
44
+ Returns:
45
+ Markdown summary of the requested snapshot operation.
46
+ """
47
+ try:
48
+ normalized_action = action.strip().lower()
49
+ if normalized_action == "list":
50
+ return self._format_snapshot_list(self.snapshot_service.list_snapshots(limit=limit))
51
+ if normalized_action == "show":
52
+ if not snapshot_id:
53
+ raise SnapshotError("snapshot_id is required for action=show.")
54
+ return self._format_snapshot_detail(self.snapshot_service.load_snapshot(snapshot_id))
55
+ if normalized_action == "create":
56
+ record = self.snapshot_service.create_manual_snapshot(
57
+ paths=paths or (),
58
+ reason="manual snapshot",
59
+ tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
60
+ )
61
+ return f"Created manual snapshot `{record.snapshot_id}` for {', '.join(record.touched_paths)}."
62
+ if normalized_action == "restore":
63
+ target_id = snapshot_id or "latest"
64
+ result = self.snapshot_service.restore_snapshot(target_id, force=force)
65
+ forced = " with force=true" if result.forced else ""
66
+ return (
67
+ f"Restored snapshot `{result.snapshot_id}`{forced}.\n\n"
68
+ f"Touched paths: {', '.join(result.restored_paths) or '(none)'}"
69
+ )
70
+ raise SnapshotError("action must be one of: list, show, create, restore.")
71
+ except SnapshotError as exc:
72
+ raise ToolError(str(exc)) from exc
73
+
74
+ async def resolve(self, action_id: str, decision: str, force: bool = False) -> str:
75
+ """Apply or discard a pending preview action.
76
+
77
+ Pending actions are created by preview-only tools such as lsp_edit(apply=false).
78
+ Applying a pending action checks that the source files still match the preview
79
+ inputs before writing, unless force=true is explicitly provided.
80
+
81
+ Args:
82
+ action_id: Pending action id returned by a preview-only tool.
83
+ decision: apply or discard.
84
+ force: Apply even if source hashes no longer match.
85
+
86
+ Returns:
87
+ Markdown summary of the resolve decision.
88
+ """
89
+ try:
90
+ action = self.snapshot_service.load_pending_action(action_id)
91
+ normalized_decision = decision.strip().lower()
92
+ if normalized_decision == "discard":
93
+ updated = self.snapshot_service.update_pending_action(action, status="discarded", message="discarded")
94
+ return f"Discarded pending action `{updated.action_id}`."
95
+ if normalized_decision != "apply":
96
+ raise SnapshotError("decision must be apply or discard.")
97
+ if action.status != "pending":
98
+ raise SnapshotError(f"Pending action `{action.action_id}` is already {action.status}.")
99
+
100
+ mismatches = self.snapshot_service.diff_expected_current(action.source)
101
+ if mismatches and not force:
102
+ message = self.snapshot_service._format_mismatch_error(action.action_id, mismatches)
103
+ self.snapshot_service.update_pending_action(action, status="stale", message=message)
104
+ raise SnapshotError(message)
105
+
106
+ applier = WorkspaceEditApplier(self.project_path, self.filesystem)
107
+ preview = applier.preview(action.workspace_edit)
108
+
109
+ def _apply() -> "WorkspaceEditResult":
110
+ return applier.apply(action.workspace_edit)
111
+
112
+ mutation = self.snapshot_service.record_mutation(
113
+ tool_name=action.tool_name or "resolve",
114
+ tool_call_id=getattr(self.caller, "current_tool_execution_id", None) or action.tool_call_id,
115
+ reason=f"resolve {action.action_id} ({action.operation})",
116
+ paths=preview.touched_paths,
117
+ mutate=_apply,
118
+ )
119
+ result = mutation.result
120
+ await self._send_previews(result, action)
121
+ updated = self.snapshot_service.update_pending_action(
122
+ action,
123
+ status="applied",
124
+ snapshot_id=mutation.snapshot.snapshot_id if mutation.snapshot else None,
125
+ message="applied",
126
+ )
127
+ snapshot_line = f"\nSnapshot: `{updated.snapshot_id}`" if updated.snapshot_id else ""
128
+ forced = " with force=true" if force else ""
129
+ return (
130
+ f"Applied pending action `{updated.action_id}`{forced}.\n\n"
131
+ + self._format_workspace_edit_result(action.operation, result)
132
+ + snapshot_line
133
+ )
134
+ except SnapshotError as exc:
135
+ raise ToolError(str(exc)) from exc
136
+
137
+ async def _send_previews(self, result: "WorkspaceEditResult", action: PendingAction) -> None:
138
+ for change in result.text_changes:
139
+ if change.old_text == change.new_text:
140
+ continue
141
+ await self.send_edit_preview(
142
+ build_diff_preview(change.old_text, change.new_text, change.path),
143
+ tool_call_id=getattr(self.caller, "current_tool_execution_id", None) or action.tool_call_id,
144
+ tool_name="resolve",
145
+ )
146
+
147
+ @staticmethod
148
+ def _format_snapshot_list(records: list[SnapshotRecord]) -> str:
149
+ if not records:
150
+ return "No snapshots recorded for this session."
151
+ lines = ["# Snapshots", ""]
152
+ for record in records:
153
+ marker = " manual" if record.manual else ""
154
+ lines.append(
155
+ f"- `{record.snapshot_id}`{marker} - {record.tool_name} - "
156
+ f"{record.created_at} - {', '.join(record.touched_paths) or '(none)'}"
157
+ )
158
+ return "\n".join(lines)
159
+
160
+ @staticmethod
161
+ def _format_snapshot_detail(record: SnapshotRecord) -> str:
162
+ lines = [
163
+ f"# Snapshot `{record.snapshot_id}`",
164
+ "",
165
+ f"- Tool: `{record.tool_name}`",
166
+ f"- Tool call: `{record.tool_call_id or '-'}`",
167
+ f"- Created: {record.created_at}",
168
+ f"- Reason: {record.reason or '-'}",
169
+ f"- Manual: {str(record.manual).lower()}",
170
+ "",
171
+ "## Paths",
172
+ ]
173
+ for path in record.touched_paths:
174
+ before = record.before.get(path)
175
+ after = record.after.get(path)
176
+ lines.append(f"- `{path}`: {SnapshotTool._state_label(before)} -> {SnapshotTool._state_label(after)}")
177
+ return "\n".join(lines)
178
+
179
+ @staticmethod
180
+ def _format_workspace_edit_result(operation: str, result: Any) -> str:
181
+ lines = [f"Applied LSP edit `{operation}`."]
182
+ for summary in result.summaries:
183
+ lines.append(f"- {summary}")
184
+ return "\n".join(lines)
185
+
186
+ @staticmethod
187
+ def _state_label(state: Any) -> str:
188
+ if state is None:
189
+ return "missing"
190
+ suffix = f":{state.sha256[:12]}" if getattr(state, "sha256", None) else ""
191
+ return f"{state.kind}{suffix}"