kolega-code 0.3.1__tar.gz → 0.4.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 (248) hide show
  1. {kolega_code-0.3.1 → kolega_code-0.4.0}/.gitignore +1 -0
  2. {kolega_code-0.3.1 → kolega_code-0.4.0}/PKG-INFO +1 -1
  3. {kolega_code-0.3.1 → kolega_code-0.4.0}/RELEASING.md +28 -12
  4. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/astro.config.mjs +4 -0
  5. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/cli/ask.md +8 -0
  6. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/cli/overview.md +1 -0
  7. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/concepts/agents.md +6 -3
  8. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/concepts/tools.md +4 -0
  9. kolega_code-0.4.0/docs/src/content/docs/hooks.md +247 -0
  10. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/tui/interface.md +36 -5
  11. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/tui/modes.md +8 -0
  12. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/tui/slash-commands.md +11 -0
  13. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/__init__.py +1 -1
  14. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/__init__.py +1 -1
  15. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/baseagent.py +327 -5
  16. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/browseragent.py +7 -1
  17. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/coder.py +6 -0
  18. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/compression.py +2 -2
  19. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/context.py +7 -0
  20. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/generalagent.py +6 -0
  21. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/investigationagent.py +7 -1
  22. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/planningagent.py +8 -43
  23. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/prompt_provider.py +5 -5
  24. kolega_code-0.4.0/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +59 -0
  25. kolega_code-0.4.0/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +18 -0
  26. kolega_code-0.4.0/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +23 -0
  27. kolega_code-0.4.0/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +23 -0
  28. kolega_code-0.4.0/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +13 -0
  29. kolega_code-0.4.0/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +2 -0
  30. kolega_code-0.4.0/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +7 -0
  31. kolega_code-0.4.0/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +7 -0
  32. kolega_code-0.3.1/kolega_code/agent/prompt_templates/agents/coder_cli_mode.j2 → kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +5 -5
  33. kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +39 -0
  34. kolega_code-0.3.1/kolega_code/agent/prompt_templates/common/kolega_md_instructions.md → kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +3 -3
  35. kolega_code-0.4.0/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +3 -0
  36. kolega_code-0.4.0/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +144 -0
  37. kolega_code-0.4.0/kolega_code/agent/prompts.py +92 -0
  38. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_agent_tools_inventory.py +2 -2
  39. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_coder_prompt_extensions.py +2 -2
  40. kolega_code-0.4.0/kolega_code/agent/tests/test_hooks_integration.py +231 -0
  41. kolega_code-0.4.0/kolega_code/agent/tests/test_permissions.py +138 -0
  42. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_prompt_provider.py +10 -10
  43. kolega_code-0.4.0/kolega_code/agent/tests/test_prompts.py +71 -0
  44. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/agent_tool.py +42 -4
  45. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/app.py +1398 -161
  46. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/main.py +166 -21
  47. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/messages.py +22 -0
  48. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/session_store.py +3 -0
  49. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/settings.py +21 -1
  50. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/skills.py +2 -9
  51. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/slash_commands.py +4 -0
  52. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_app.py +830 -40
  53. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_main.py +20 -4
  54. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_session_store.py +5 -0
  55. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_slash_commands.py +6 -2
  56. kolega_code-0.4.0/kolega_code/cli/tests/test_themes.py +233 -0
  57. kolega_code-0.4.0/kolega_code/cli/theme.py +539 -0
  58. kolega_code-0.4.0/kolega_code/hooks/__init__.py +60 -0
  59. kolega_code-0.4.0/kolega_code/hooks/backends.py +218 -0
  60. kolega_code-0.4.0/kolega_code/hooks/config.py +203 -0
  61. kolega_code-0.4.0/kolega_code/hooks/dispatcher.py +82 -0
  62. kolega_code-0.4.0/kolega_code/hooks/events.py +90 -0
  63. kolega_code-0.4.0/kolega_code/hooks/matcher.py +37 -0
  64. kolega_code-0.4.0/kolega_code/hooks/outcome.py +81 -0
  65. kolega_code-0.4.0/kolega_code/hooks/tests/test_hooks.py +410 -0
  66. kolega_code-0.4.0/kolega_code/permissions.py +378 -0
  67. kolega_code-0.4.0/kolega_code/tools/tests/__init__.py +0 -0
  68. {kolega_code-0.3.1 → kolega_code-0.4.0}/pyproject.toml +1 -1
  69. {kolega_code-0.3.1 → kolega_code-0.4.0}/uv.lock +53 -50
  70. kolega_code-0.3.1/kolega_code/agent/prompts.py +0 -154
  71. kolega_code-0.3.1/kolega_code/cli/theme.py +0 -180
  72. {kolega_code-0.3.1 → kolega_code-0.4.0}/.env.example +0 -0
  73. {kolega_code-0.3.1 → kolega_code-0.4.0}/.github/workflows/ci.yml +0 -0
  74. {kolega_code-0.3.1 → kolega_code-0.4.0}/.github/workflows/docs.yml +0 -0
  75. {kolega_code-0.3.1 → kolega_code-0.4.0}/.github/workflows/release.yml +0 -0
  76. {kolega_code-0.3.1 → kolega_code-0.4.0}/CONTRIBUTING.md +0 -0
  77. {kolega_code-0.3.1 → kolega_code-0.4.0}/LICENSE +0 -0
  78. {kolega_code-0.3.1 → kolega_code-0.4.0}/README.md +0 -0
  79. {kolega_code-0.3.1 → kolega_code-0.4.0}/SECURITY.md +0 -0
  80. {kolega_code-0.3.1 → kolega_code-0.4.0}/conftest.py +0 -0
  81. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/.gitignore +0 -0
  82. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/README.md +0 -0
  83. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/package-lock.json +0 -0
  84. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/package.json +0 -0
  85. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/public/favicon.svg +0 -0
  86. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/assets/kolega-dark.svg +0 -0
  87. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/assets/kolega-light.svg +0 -0
  88. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/cli/doctor.md +0 -0
  89. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/cli/sessions.md +0 -0
  90. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/concepts/how-it-works.md +0 -0
  91. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/configuration/environment-variables.md +0 -0
  92. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/configuration/providers-and-models.mdx +0 -0
  93. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/configuration/settings-and-api-keys.mdx +0 -0
  94. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/getting-started/installation.mdx +0 -0
  95. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/getting-started/introduction.md +0 -0
  96. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/getting-started/quick-start.mdx +0 -0
  97. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/index.mdx +0 -0
  98. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/skills.mdx +0 -0
  99. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/tui/composer.md +0 -0
  100. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content/docs/tui/sessions-and-resume.md +0 -0
  101. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/content.config.ts +0 -0
  102. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/src/styles/brand.css +0 -0
  103. {kolega_code-0.3.1 → kolega_code-0.4.0}/docs/tsconfig.json +0 -0
  104. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/common.py +0 -0
  105. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/conversation.py +0 -0
  106. /kolega_code-0.3.1/kolega_code/agent/prompt_templates/agents/browser.j2 → /kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
  107. /kolega_code-0.3.1/kolega_code/agent/prompt_templates/agents/general.j2 → /kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
  108. /kolega_code-0.3.1/kolega_code/agent/prompt_templates/agents/investigation.j2 → /kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
  109. {kolega_code-0.3.1/kolega_code/agent/prompt_templates → kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/includes}/environment_variables/workspace_env_vars.md +0 -0
  110. {kolega_code-0.3.1/kolega_code/agent/prompt_templates/common → kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/includes}/frontend_guidance.md +0 -0
  111. /kolega_code-0.3.1/kolega_code/agent/prompt_templates/template_guidance/expo-template.md → /kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
  112. /kolega_code-0.3.1/kolega_code/agent/prompt_templates/template_guidance/html-website-template.md → /kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
  113. /kolega_code-0.3.1/kolega_code/agent/prompt_templates/template_guidance/mern-stack-template.md → /kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
  114. /kolega_code-0.3.1/kolega_code/agent/prompt_templates/template_guidance/react-vite-shadcdn-template.md → /kolega_code-0.4.0/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
  115. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/__init__.py +0 -0
  116. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/__init__.py +0 -0
  117. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_anthropic_token_counting.py +0 -0
  118. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_billing_openai_cache.py +0 -0
  119. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_client.py +0 -0
  120. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_dashscope_mapping.py +0 -0
  121. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_error_boundary.py +0 -0
  122. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_exceptions.py +0 -0
  123. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_google_thought_signature.py +0 -0
  124. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_google_tool_signature_live.py +0 -0
  125. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_instrumented_client.py +0 -0
  126. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_instrumented_client_integration.py +0 -0
  127. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_langfuse_normalization.py +0 -0
  128. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_live_providers.py +0 -0
  129. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_model_specs.py +0 -0
  130. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_openai_cached_tokens.py +0 -0
  131. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_openai_cached_tokens_stream.py +0 -0
  132. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_openai_message_conversion.py +0 -0
  133. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_openai_token_counting.py +0 -0
  134. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_thinking_effort.py +0 -0
  135. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/llm/test_tool_execution_ids.py +0 -0
  136. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/services/__init__.py +0 -0
  137. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/services/test_browser.py +0 -0
  138. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/services/test_browser_parity.py +0 -0
  139. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/services/test_file_system.py +0 -0
  140. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/services/test_sandbox_terminal_input.py +0 -0
  141. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/services/test_terminal.py +0 -0
  142. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/services/test_terminal_command_tracking.py +0 -0
  143. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/services/test_terminal_state_serializer.py +0 -0
  144. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_base_agent.py +0 -0
  145. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_coder_attachments.py +0 -0
  146. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_commands.py +0 -0
  147. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_duplicate_tool_results.py +0 -0
  148. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_empty_message_handling.py +0 -0
  149. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_general_agent.py +0 -0
  150. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_html.py +0 -0
  151. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_parallel_tool_calls.py +0 -0
  152. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_planning_agent.py +0 -0
  153. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_tool_registry.py +0 -0
  154. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/test_tools.py +0 -0
  155. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/__init__.py +0 -0
  156. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_agent_tool.py +0 -0
  157. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_base_tool.py +0 -0
  158. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_browser_tool.py +0 -0
  159. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_build_tool.py +0 -0
  160. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_create_file_tool.py +0 -0
  161. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_glob_tool.py +0 -0
  162. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_glob_tool_sandbox_parity.py +0 -0
  163. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_list_directory_tool.py +0 -0
  164. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_read_file_tool.py +0 -0
  165. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_replace_entire_file_tool.py +0 -0
  166. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_replace_lines_tool.py +0 -0
  167. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_search_and_replace_tool.py +0 -0
  168. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_search_codebase_tool.py +0 -0
  169. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_terminal_tool.py +0 -0
  170. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_think_hard_integration.py +0 -0
  171. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_think_hard_streaming.py +0 -0
  172. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tests/tool_backend/test_web_fetch_tool.py +0 -0
  173. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/apply_patch_tool.py +0 -0
  174. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/base_tool.py +0 -0
  175. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
  176. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/build_tool.py +0 -0
  177. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/create_file_tool.py +0 -0
  178. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/glob_tool.py +0 -0
  179. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/list_directory_tool.py +0 -0
  180. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
  181. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
  182. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/replace_entire_file_tool.py +0 -0
  183. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/replace_lines_tool.py +0 -0
  184. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/search_and_replace_tool.py +0 -0
  185. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/search_codebase_tool.py +0 -0
  186. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
  187. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
  188. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/think_hard_tool.py +0 -0
  189. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
  190. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/tools.py +0 -0
  191. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/agent/utils/commands.py +0 -0
  192. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/__init__.py +0 -0
  193. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/config.py +0 -0
  194. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/connection.py +0 -0
  195. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/file_index.py +0 -0
  196. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/mentions.py +0 -0
  197. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/provider_registry.py +0 -0
  198. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/__init__.py +0 -0
  199. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_cli_config.py +0 -0
  200. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_connection.py +0 -0
  201. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_file_index.py +0 -0
  202. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_mentions.py +0 -0
  203. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_settings.py +0 -0
  204. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_skills.py +0 -0
  205. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/tests/test_updater.py +0 -0
  206. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/cli/updater.py +0 -0
  207. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/config.py +0 -0
  208. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/events.py +0 -0
  209. {kolega_code-0.3.1/kolega_code/llm/providers → kolega_code-0.4.0/kolega_code/hooks/tests}/__init__.py +0 -0
  210. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/client.py +0 -0
  211. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/exceptions.py +0 -0
  212. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/instrumented_client.py +0 -0
  213. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/models.py +0 -0
  214. {kolega_code-0.3.1/kolega_code/tools/tests → kolega_code-0.4.0/kolega_code/llm/providers}/__init__.py +0 -0
  215. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/providers/anthropic.py +0 -0
  216. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/providers/base.py +0 -0
  217. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/providers/google.py +0 -0
  218. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/providers/models.py +0 -0
  219. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/providers/openai.py +0 -0
  220. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/ratelimit.py +0 -0
  221. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/specs.py +0 -0
  222. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/llm/tool_execution_ids.py +0 -0
  223. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/models/__init__.py +0 -0
  224. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/models/sandbox_terminal_state.py +0 -0
  225. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/runtime.py +0 -0
  226. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/README.md +0 -0
  227. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/__init__.py +0 -0
  228. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/async_filesystem.py +0 -0
  229. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/base.py +0 -0
  230. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/browser.py +0 -0
  231. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/event_loop.py +0 -0
  232. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/filesystem.py +0 -0
  233. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/local.py +0 -0
  234. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/serializer.py +0 -0
  235. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/terminal.py +0 -0
  236. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/sandbox/utils.py +0 -0
  237. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/services/base.py +0 -0
  238. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/services/browser.py +0 -0
  239. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/services/file_system.py +0 -0
  240. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/services/html.py +0 -0
  241. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/services/terminal.py +0 -0
  242. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/tools/__init__.py +0 -0
  243. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/tools/core.py +0 -0
  244. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/tools/definitions.py +0 -0
  245. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/tools/registry.py +0 -0
  246. {kolega_code-0.3.1 → kolega_code-0.4.0}/kolega_code/tools/tests/test_definitions.py +0 -0
  247. {kolega_code-0.3.1 → kolega_code-0.4.0}/run_tests.sh +0 -0
  248. {kolega_code-0.3.1 → kolega_code-0.4.0}/scripts/install-kolega-code.sh +0 -0
@@ -7,6 +7,7 @@ __pycache__/
7
7
  .env
8
8
  .env.*
9
9
  !.env.example
10
+ .kolega/permissions.json
10
11
  dist/
11
12
  build/
12
13
  *.egg-info/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kolega-code
3
- Version: 0.3.1
3
+ Version: 0.4.0
4
4
  Summary: Local-first AI coding agent for 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/
@@ -6,38 +6,54 @@ version should also have a GitHub Release for its matching tag.
6
6
 
7
7
  ## Release process
8
8
 
9
- 1. Confirm `pyproject.toml`, `uv.lock`, and package `__version__` values have
10
- the release version.
9
+ Release version bumps must happen in a pull request. Do not tag an unmerged
10
+ release branch.
11
11
 
12
- 2. Run the fast test suite:
12
+ 1. Create a release branch from the latest `main`:
13
+
14
+ ```bash
15
+ git checkout main
16
+ git pull origin main
17
+ git checkout -b chore/release-v0.3.2
18
+ ```
19
+
20
+ 2. Update `pyproject.toml`, `uv.lock`, and package `__version__` values to the
21
+ release version.
22
+
23
+ 3. Run the fast test suite:
13
24
 
14
25
  ```bash
15
26
  uv run pytest -ra --durations=50 --import-mode=importlib -m "not slow"
16
27
  ```
17
28
 
18
- 3. Commit the release bump:
29
+ 4. Commit the release bump and open a pull request against `main`:
19
30
 
20
31
  ```bash
21
- git commit -m "chore: release v0.3.0"
32
+ git commit -m "chore: release v0.3.2"
33
+ git push -u origin chore/release-v0.3.2
22
34
  ```
23
35
 
24
- 4. Create and push a matching tag:
36
+ The PR must be reviewed, pass CI, and be merged before tagging.
37
+
38
+ 5. After the PR is merged, update local `main`, then create and push a matching
39
+ tag from the merge commit:
25
40
 
26
41
  ```bash
27
- git tag v0.3.0
28
- git push origin main
29
- git push origin v0.3.0
42
+ git checkout main
43
+ git pull origin main
44
+ git tag v0.3.2
45
+ git push origin v0.3.2
30
46
  ```
31
47
 
32
- 5. Confirm the `Release` GitHub Actions workflow completes. It builds and tests
48
+ 6. Confirm the `Release` GitHub Actions workflow completes. It builds and tests
33
49
  the package, publishes to PyPI, then creates the GitHub Release.
34
50
 
35
- 6. Verify the release:
51
+ 7. Verify the release:
36
52
 
37
53
  ```bash
38
54
  uv tool install --force kolega-code
39
55
  kolega-code --version
40
- gh release view v0.3.0 --repo kolega-ai/kolega-code
56
+ gh release view v0.3.2 --repo kolega-ai/kolega-code
41
57
  ```
42
58
 
43
59
  The GitHub Release uses PyPI as the canonical package distribution and keeps
@@ -89,6 +89,10 @@ export default defineConfig({
89
89
  label: "Skills",
90
90
  items: [{ label: "Agent Skills", slug: "skills" }],
91
91
  },
92
+ {
93
+ label: "Hooks",
94
+ items: [{ label: "Lifecycle Hooks", slug: "hooks" }],
95
+ },
92
96
  {
93
97
  label: "How It Works",
94
98
  items: [
@@ -20,6 +20,7 @@ kolega-code ask "<prompt>" [options]
20
20
  | `--save` | Persist the session after the prompt completes |
21
21
  | `--json` | Emit response chunks and events as JSON |
22
22
  | `--browser-visible` | Launch visible Playwright browser windows |
23
+ | `--permission-mode <auto\|ask>` | Shell/edit permission mode (default `auto`) |
23
24
  | `--session <ID>` | Resume or create a specific session |
24
25
  | `--state-dir <PATH>` | Directory for CLI session state |
25
26
 
@@ -97,3 +98,10 @@ The stream includes:
97
98
  In plain (non-JSON) mode, the answer is written to **stdout** while sub-agent and
98
99
  tool activity is reported on **stderr** — so piping stdout gives you just the
99
100
  answer.
101
+
102
+ ## Permissions
103
+
104
+ `ask` defaults to `--permission-mode auto` so scripts do not stop for
105
+ confirmations. If you pass `--permission-mode ask`, shell commands and file edits
106
+ prompt on stderr when stdin is interactive. Persisted allow rules are stored in
107
+ the project at `.kolega/permissions.json`.
@@ -39,6 +39,7 @@ kolega-code [PROJECT_PATH]
39
39
  | `--new` | Start a new session (this is the default) |
40
40
  | `--resume [THREAD_ID]` | Resume the latest saved thread, or a specific thread/session ID |
41
41
  | `--browser-visible` | Launch visible Playwright browser windows instead of headless |
42
+ | `--permission-mode <auto\|ask>` | Shell/edit permission mode. TUI sessions default to `ask` |
42
43
  | `--session <ID>` | Legacy alias for `--resume THREAD_ID` |
43
44
 
44
45
  See [Sessions & Resuming](../../tui/sessions-and-resume/) for the full session
@@ -27,9 +27,12 @@ findings. The available dispatch targets include:
27
27
  - `dispatch_coding_agent` — hand off a self-contained coding task.
28
28
  - `dispatch_general_agent` — a general-purpose helper.
29
29
 
30
- Sub-agent activity is reported live: in the TUI you'll see it in the conversation
31
- and the **Logs** tab; with `ask` it surfaces as events (on stderr in plain mode, or
32
- as `event` objects with `--json`).
30
+ Sub-agent activity is reported live. In the TUI each sub-agent gets a live card in
31
+ the conversation, and pressing `Ctrl+G` opens the
32
+ [sub-agent inspector](../../tui/interface/#sub-agent-inspector) a full-screen view
33
+ of every sub-agent's complete trajectory: its thinking, tool calls, and results.
34
+ Lifecycle events also appear in the **Logs** tab. With `ask`, sub-agent activity
35
+ surfaces as events (on stderr in plain mode, or as `event` objects with `--json`).
33
36
 
34
37
  ## Modes vs. agents
35
38
 
@@ -62,3 +62,7 @@ files and running commands require Build mode's full toolset.
62
62
 
63
63
  This separation is what makes Plan mode safe to run against any codebase: the
64
64
  planning agent can look but not touch.
65
+
66
+ In the Textual TUI, Build mode defaults to `ask` permission mode. Shell commands
67
+ and file edits must be approved before they run unless you switch to `auto` or
68
+ save a matching allow rule in `.kolega/permissions.json`.
@@ -0,0 +1,247 @@
1
+ ---
2
+ title: Hooks
3
+ description: Run shell commands, Python callables, or LLM checks on agent lifecycle events to observe, block, or modify what the agent does.
4
+ ---
5
+
6
+ **Hooks** let you attach handlers to the agent's **lifecycle events** — points like
7
+ "before a tool runs", "a prompt was submitted", or "the agent is about to stop". A hook
8
+ can **observe** (log, notify), **block** (deny a tool, end a turn, keep the agent
9
+ working), or **modify** (rewrite a tool's input or output, inject context).
10
+
11
+ This is how you add guardrails ("never run `rm -rf`"), automation ("format files after
12
+ every edit"), and quality gates ("don't stop until the tests pass") without changing the
13
+ agent itself.
14
+
15
+ ## Where hooks live
16
+
17
+ Hooks are declared in JSON, in two places that are **merged** (global first, project last):
18
+
19
+ - **Global / user:** `hooks.json` in the Kolega Code state directory — always active. The
20
+ state directory is platform-specific:
21
+ - macOS: `~/Library/Application Support/kolega-code/hooks.json`
22
+ - Linux: `$XDG_STATE_HOME/kolega-code/hooks.json` (defaults to `~/.local/state/kolega-code/hooks.json`)
23
+ - Windows: `%LOCALAPPDATA%\kolega-code\hooks.json`
24
+
25
+ Override the location with the `KOLEGA_CODE_STATE_DIR` environment variable or the
26
+ `--state-dir <dir>` flag (the file is then `<dir>/hooks.json`).
27
+ - **Project:** `<project>/.kolega/hooks.json` — alongside `permissions.json`. Because a
28
+ project file can run arbitrary commands from a cloned repo, project hooks are
29
+ **disabled until you trust the project** (see [Trust](#trusting-project-hooks)).
30
+
31
+ Both files use the same shape:
32
+
33
+ ```json
34
+ {
35
+ "schema_version": 1,
36
+ "hooks": {
37
+ "PreToolUse": [
38
+ {
39
+ "matcher": "execute_terminal_command|run_command_tracked",
40
+ "hooks": [
41
+ { "type": "command", "command": "./.kolega/guard-bash.sh", "timeout": 30 }
42
+ ]
43
+ }
44
+ ]
45
+ }
46
+ }
47
+ ```
48
+
49
+ - The `hooks` map is keyed by **event name**.
50
+ - Each entry has a **`matcher`** and a list of **hook handlers**.
51
+ - `matcher` is tested against the tool name for tool events (or a source string for other
52
+ events): `""` or `"*"` matches everything; `"Edit|Write"` is an exact-name OR list;
53
+ anything else is a regular expression (e.g. `"mcp__.*"`).
54
+ - Handler lists from the global and project files are concatenated, so the global handler
55
+ sees the action first and the project handler last.
56
+
57
+ ## Lifecycle events
58
+
59
+ | Event | When it fires | What a "block" does |
60
+ |---|---|---|
61
+ | `SessionStart` | The agent session begins | Advisory; can inject starting context |
62
+ | `UserPromptSubmit` | You submit a prompt, before the agent sees it | Ends the turn; the reason is shown as a warning |
63
+ | `PreToolUse` | Before a tool runs (after the permission gate) | Denies the tool; the reason is returned to the agent as a tool error, so it can adjust |
64
+ | `PostToolUse` | After a tool succeeds (and on failure) | Ends the turn; the reason is shown as a warning |
65
+ | `PreCompact` | Before the conversation is compacted | Advisory |
66
+ | `Stop` | The agent is about to finish its turn | Keeps the agent working; the reason becomes its next instruction |
67
+ | `SubagentStop` | A dispatched sub-agent finished | Advisory; can annotate the result the parent sees |
68
+ | `Notification` | A permission prompt is about to be shown | Advisory (desktop notifications, sounds) |
69
+ | `SessionEnd` | The session ends | Advisory (cleanup, final logging) |
70
+
71
+ Hooks can also **modify** rather than block:
72
+
73
+ - `PreToolUse` can return `updatedInput` to rewrite the tool's arguments.
74
+ - `PostToolUse` can return `updatedToolOutput` to replace what the model sees, or
75
+ `additionalContext` to append to it.
76
+ - `SessionStart` / `UserPromptSubmit` can return `additionalContext` to inject text.
77
+
78
+ ## Hook types
79
+
80
+ ### `command` — run a shell program
81
+
82
+ The event is sent as JSON on **stdin**. The hook communicates back through its exit code:
83
+
84
+ - **exit 0** — success. Optional JSON on stdout controls behavior:
85
+ ```json
86
+ {
87
+ "hookSpecificOutput": {
88
+ "permissionDecision": "deny",
89
+ "permissionDecisionReason": "rm -rf is not allowed here",
90
+ "updatedInput": { "command": "ls" },
91
+ "updatedToolOutput": "…",
92
+ "additionalContext": "…"
93
+ },
94
+ "systemMessage": "shown to the user",
95
+ "continue": false
96
+ }
97
+ ```
98
+ - **exit 2** — block. Whatever the hook wrote to **stderr** becomes the reason.
99
+ - **any other code** — a non-blocking error: it is logged and the action proceeds.
100
+
101
+ ```json
102
+ { "type": "command", "command": "./.kolega/format.sh", "timeout": 30 }
103
+ ```
104
+
105
+ Commands run with the project directory as the working directory and are split like a
106
+ shell argument list (no shell features such as pipes — call a script if you need them).
107
+
108
+ ### `python` — run an in-process callable
109
+
110
+ Point at an importable `module.path:function`. It receives a `LifecycleEvent` and returns
111
+ a `HookOutcome` (or a dict with the same fields). Runs in the agent's process — best for
112
+ first-party checks.
113
+
114
+ ```json
115
+ { "type": "python", "callable": "myproject.hooks:block_secrets", "timeout": 15 }
116
+ ```
117
+
118
+ ```python
119
+ from kolega_code.hooks import HookOutcome
120
+
121
+ def block_secrets(event):
122
+ inputs = event.payload.get("tool_input", {})
123
+ if "AWS_SECRET" in str(inputs):
124
+ return HookOutcome.deny("Refusing to write a secret to disk.")
125
+ return HookOutcome.empty()
126
+ ```
127
+
128
+ ### `prompt` and `agent` — let an LLM decide
129
+
130
+ For judgment calls rather than deterministic rules. Both return a yes/no decision as
131
+ `{"ok": true}` (allow) or `{"ok": false, "reason": "…"}` (block); the per-event meaning of
132
+ a block is the same as the table above.
133
+
134
+ - **`prompt`** sends your prompt plus the event data to a model (the fast model by
135
+ default; `"model"` may be `"fast"`, `"long"`, or `"thinking"`). Use `$EVENT` in the
136
+ prompt to interpolate the event JSON.
137
+
138
+ ```json
139
+ {
140
+ "type": "prompt",
141
+ "prompt": "Have all of the user's requested tasks been completed? $EVENT",
142
+ "model": "fast",
143
+ "timeout": 30
144
+ }
145
+ ```
146
+
147
+ - **`agent`** spawns a full sub-agent that can read files, search the code, and run
148
+ commands to verify a condition before answering. Heavier, with a longer default timeout.
149
+ Because an agent hook uses tools, it is **not allowed on `PreToolUse`/`PostToolUse`**
150
+ (that would recurse); use it on `Stop`, `SubagentStop`, `UserPromptSubmit`, or the
151
+ session events.
152
+
153
+ ```json
154
+ {
155
+ "type": "agent",
156
+ "prompt": "Run the test suite. Only report ok:true if every test passes.",
157
+ "timeout": 120
158
+ }
159
+ ```
160
+
161
+ Tool calls made by an agent hook do **not** re-trigger tool hooks, so there is no
162
+ infinite loop.
163
+
164
+ ## Examples
165
+
166
+ **Block dangerous shell commands (project, command hook):**
167
+
168
+ ```json
169
+ {
170
+ "schema_version": 1,
171
+ "hooks": {
172
+ "PreToolUse": [
173
+ {
174
+ "matcher": "execute_terminal_command|run_command|run_command_tracked",
175
+ "hooks": [{ "type": "command", "command": "./.kolega/deny-rm.sh" }]
176
+ }
177
+ ]
178
+ }
179
+ }
180
+ ```
181
+
182
+ **Don't stop until the tests pass (prompt hook):**
183
+
184
+ ```json
185
+ {
186
+ "schema_version": 1,
187
+ "hooks": {
188
+ "Stop": [
189
+ {
190
+ "matcher": "*",
191
+ "hooks": [{
192
+ "type": "prompt",
193
+ "prompt": "Based on the conversation, did the agent finish ALL requested work AND leave the tests passing? $EVENT"
194
+ }]
195
+ }
196
+ ]
197
+ }
198
+ }
199
+ ```
200
+
201
+ **Verify tests actually pass before stopping (agent hook):**
202
+
203
+ ```json
204
+ {
205
+ "schema_version": 1,
206
+ "hooks": {
207
+ "Stop": [
208
+ {
209
+ "matcher": "*",
210
+ "hooks": [{
211
+ "type": "agent",
212
+ "prompt": "Run the project's test command and confirm it exits cleanly.",
213
+ "timeout": 120
214
+ }]
215
+ }
216
+ ]
217
+ }
218
+ }
219
+ ```
220
+
221
+ ## Trusting project hooks
222
+
223
+ A project's `.kolega/hooks.json` can run arbitrary commands, so it is **ignored until you
224
+ explicitly trust the project**. Global/user hooks are always trusted.
225
+
226
+ When an untrusted project defines hooks, Kolega Code tells you and runs only the global
227
+ hooks. To enable the project's hooks, launch with:
228
+
229
+ ```bash
230
+ kolega-code --trust-hooks # TUI
231
+ kolega-code ask "…" --trust-hooks # non-interactive
232
+ ```
233
+
234
+ Trust is recorded once (per resolved project path) in your user settings, so future runs
235
+ in that project enable its hooks automatically.
236
+
237
+ ## Safety and behavior notes
238
+
239
+ - **Failure is isolated.** A hook that crashes, times out, or prints garbage is logged and
240
+ the action proceeds — a broken hook never wedges the agent. Only a clean `exit 2`,
241
+ `permissionDecision: "deny"`, or `ok: false` blocks.
242
+ - **Each handler has a `timeout`** (seconds). On timeout the process is killed and treated
243
+ as a non-blocking error.
244
+ - **Tool hooks apply to sub-agents too**, so a `PreToolUse` guard also covers tools used by
245
+ dispatched sub-agents.
246
+ - A `Stop` hook can force the agent to keep working only a bounded number of times per
247
+ turn, so a misbehaving "don't stop" hook cannot loop forever.
@@ -15,7 +15,7 @@ The screen is split into two columns:
15
15
  stream in live, tool calls and sub-agent activity appear inline, and detailed
16
16
  tool results are collapsed by default so you can expand only what you need.
17
17
  - **Side panel** (right) — a set of tabs for status, logs, the terminal, planning,
18
- and settings.
18
+ and settings. Toggle it with `Ctrl+O` or `/sidebar`.
19
19
 
20
20
  At the bottom sits the **composer** — the text box where you type prompts. See
21
21
  [Chat Composer](../composer/) for everything it can do.
@@ -24,7 +24,7 @@ At the bottom sits the **composer** — the text box where you type prompts. See
24
24
 
25
25
  | Tab | What it shows |
26
26
  | --- | --- |
27
- | **Status** | The active provider/model and thinking effort, the current interaction mode (Build/Plan), the agent's turn state (idle, generating, thinking, running a tool, running sub-agents, waiting for input, …), token usage, and context warnings. |
27
+ | **Status** | The active provider/model and thinking effort, the current interaction mode (Build/Plan), permission mode, the agent's turn state (idle, generating, thinking, running a tool, running sub-agents, waiting for input, …), token usage, and context warnings. |
28
28
  | **Logs** | A timestamped, color-coded activity log: sub-agent lifecycle, tool calls, configuration changes. An indicator flags new entries when you're on another tab. |
29
29
  | **Terminal** | Live output from commands the agent runs. |
30
30
  | **Planning** | The current **Plan** (markdown from the planning agent) and the shared **Task List** that both modes can edit. |
@@ -37,18 +37,49 @@ At the bottom sits the **composer** — the text box where you type prompts. See
37
37
  can return to the live edge.
38
38
  - **Tool results** — shown as collapsible blocks with a state indicator
39
39
  (running / done / failed). Expand to see the full result.
40
- - **Sub-agents** — when the main agent dispatches a sub-agent, its activity is
41
- tracked live with status updates.
40
+ - **Sub-agents** — when the main agent dispatches a sub-agent, a live card tracks
41
+ it inline: the agent name, elapsed time, tool count, token usage, what it's doing
42
+ right now, and a tail of its latest output. Press `Ctrl+G` (or click the card) to
43
+ open the full [sub-agent inspector](#sub-agent-inspector).
42
44
  - **Option lists** — when the agent asks you to choose between options (including
43
- plan decisions), they render as a **vertical, arrow-key-selectable list**.
45
+ plan decisions and tool approvals), they render as a **vertical,
46
+ arrow-key-selectable list**.
44
47
  Use the arrow keys to highlight, number keys (`1`–`9`) to jump, and `Enter` to
45
48
  confirm.
46
49
 
50
+ ## Sub-agent inspector
51
+
52
+ The inline cards summarize sub-agent activity; the **inspector** shows the whole
53
+ story. Press `Ctrl+G` (or click any sub-agent card) to open a full-screen
54
+ "mission control" view:
55
+
56
+ - **Roster** (left) — every sub-agent dispatched this turn, running or finished,
57
+ each with a live spinner, status, elapsed time, tool count, and token usage.
58
+ Nested sub-agents are indented by depth.
59
+ - **Trajectory** (right) — the selected agent's full run: its thinking, each tool
60
+ call, the tool results (expandable, just like the main transcript), and its
61
+ responses, streaming live as it works.
62
+
63
+ | Keys | Action |
64
+ | --- | --- |
65
+ | `Ctrl+G` | Open the inspector (on the most recently active sub-agent) |
66
+ | `↑` / `↓` | Switch between sub-agents |
67
+ | `Tab` then `Enter` | Focus a tool call and expand it (or click it) |
68
+ | `o` | Toggle follow — auto-scroll to the newest activity |
69
+ | `y` | Copy the selected agent's trajectory to the clipboard |
70
+ | `Esc` / `q` | Close the inspector |
71
+
72
+ The inspector is read-only: opening or closing it never interrupts the agent, so
73
+ the turn keeps running while you look around.
74
+
47
75
  ## Key bindings at a glance
48
76
 
49
77
  | Keys | Action |
50
78
  | --- | --- |
51
79
  | `Shift+Tab` | Toggle Build ⇄ Plan mode |
80
+ | `Ctrl+P` | Toggle shell/edit permissions between Ask ⇄ Auto |
81
+ | `Ctrl+O` | Show or hide the side panel |
82
+ | `Ctrl+G` | Open the sub-agent inspector |
52
83
  | `Enter` | Send the prompt |
53
84
  | `Shift+Enter` / `Ctrl+J` | Insert a newline |
54
85
  | `Ctrl+C` / `Escape` | Cancel the current generation |
@@ -14,6 +14,14 @@ implementing whatever you ask.
14
14
 
15
15
  Use Build mode for hands-on work: making changes, running tests, fixing bugs.
16
16
 
17
+ Build mode is still subject to the current **permission mode**. TUI sessions
18
+ default to `ask`, so shell commands and file edits prompt before they run. Press
19
+ `Ctrl+P` to toggle between `ask` and `auto`, or use `/permissions ask`,
20
+ `/permissions auto`, and `/permissions toggle`.
21
+
22
+ When you choose an “always allow” approval, Kolega Code stores the local rule in
23
+ `.kolega/permissions.json` for that project.
24
+
17
25
  ## Plan mode
18
26
 
19
27
  A **read-only** planning pass. Plan mode uses a standalone planning agent that does
@@ -33,8 +33,11 @@ These control the app and your session.
33
33
  | Command | Description |
34
34
  | --- | --- |
35
35
  | `/skills` | List available Agent Skills |
36
+ | `/init` | Create or update `AGENTS.md` for this repository |
36
37
  | `/plan` | Switch to [Plan mode](../modes/) |
37
38
  | `/build` | Switch to [Build mode](../modes/) |
39
+ | `/sidebar` | Show or hide the side panel |
40
+ | `/permissions` | Show or switch the shell/edit permission mode |
38
41
  | `/model` | Choose the active model |
39
42
  | `/effort` | Choose the active model's thinking effort |
40
43
  | `/copy` | Copy the last response to the clipboard |
@@ -49,6 +52,14 @@ provider. You can also switch directly with `/model <name>`.
49
52
  Run `/effort` to open a selectable list of supported effort values for the
50
53
  active model. You can also switch directly with `/effort <level>`.
51
54
 
55
+ Run `/init` to have the agent inspect the repository and create or update a
56
+ concise root `AGENTS.md`. Extra text after the command is passed as focus or
57
+ constraints:
58
+
59
+ ```text
60
+ /init focus on Python packaging and test commands
61
+ ```
62
+
52
63
  ## Skills
53
64
 
54
65
  Any [skill](../../skills/) discovered in `.agents/skills/` is available as
@@ -148,4 +148,4 @@ __all__ = [
148
148
  "parse_git_status_output",
149
149
  ]
150
150
 
151
- __version__ = "0.3.1"
151
+ __version__ = "0.4.0"
@@ -39,4 +39,4 @@ __all__ = [
39
39
  "ToolExtension",
40
40
  ]
41
41
 
42
- __version__ = "0.3.1"
42
+ __version__ = "0.4.0"