kolega-code 0.8.1__tar.gz → 0.8.2__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 (325) hide show
  1. {kolega_code-0.8.1 → kolega_code-0.8.2}/PKG-INFO +1 -1
  2. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/cli/overview.md +1 -0
  3. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/gigacode.mdx +14 -3
  4. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/tui/interface.md +4 -3
  5. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/__init__.py +1 -1
  6. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/__init__.py +1 -1
  7. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/guide.py +20 -4
  8. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/journal.py +77 -7
  9. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/runtime.py +41 -3
  10. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/types.py +2 -0
  11. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +4 -0
  12. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_tui_events.py +4 -2
  13. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_prompts.py +8 -0
  14. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_workflow_tool.py +143 -5
  15. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/agent_tool.py +164 -12
  16. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/workflow_tool.py +193 -22
  17. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tools.py +8 -4
  18. kolega_code-0.8.2/kolega_code/cli/app.py +1384 -0
  19. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/main.py +2 -0
  20. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app.py +1380 -363
  21. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app_compaction_restore.py +4 -4
  22. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app_image_vision_warning.py +7 -6
  23. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app_model_switch_vision.py +5 -6
  24. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_main.py +8 -0
  25. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_themes.py +4 -3
  26. kolega_code-0.8.2/kolega_code/cli/tui/__init__.py +1 -0
  27. kolega_code-0.8.2/kolega_code/cli/tui/agent_runtime.py +306 -0
  28. kolega_code-0.8.2/kolega_code/cli/tui/command_handlers.py +810 -0
  29. kolega_code-0.8.2/kolega_code/cli/tui/constants.py +24 -0
  30. kolega_code-0.8.2/kolega_code/cli/tui/prompt_flows.py +430 -0
  31. kolega_code-0.8.2/kolega_code/cli/tui/settings_panel.py +408 -0
  32. kolega_code-0.8.2/kolega_code/cli/tui/state.py +199 -0
  33. kolega_code-0.8.2/kolega_code/cli/tui/status_dashboard.py +267 -0
  34. kolega_code-0.8.2/kolega_code/cli/tui/styles.py +339 -0
  35. kolega_code-0.8.2/kolega_code/cli/tui/sub_agent_screen.py +367 -0
  36. kolega_code-0.8.2/kolega_code/cli/tui/transcript.py +1397 -0
  37. kolega_code-0.8.2/kolega_code/cli/tui/widgets.py +658 -0
  38. {kolega_code-0.8.1 → kolega_code-0.8.2}/pyproject.toml +1 -1
  39. {kolega_code-0.8.1 → kolega_code-0.8.2}/uv.lock +2 -2
  40. kolega_code-0.8.1/kolega_code/cli/app.py +0 -6071
  41. {kolega_code-0.8.1 → kolega_code-0.8.2}/.env.example +0 -0
  42. {kolega_code-0.8.1 → kolega_code-0.8.2}/.github/workflows/ci.yml +0 -0
  43. {kolega_code-0.8.1 → kolega_code-0.8.2}/.github/workflows/docs.yml +0 -0
  44. {kolega_code-0.8.1 → kolega_code-0.8.2}/.github/workflows/release.yml +0 -0
  45. {kolega_code-0.8.1 → kolega_code-0.8.2}/.gitignore +0 -0
  46. {kolega_code-0.8.1 → kolega_code-0.8.2}/CONTRIBUTING.md +0 -0
  47. {kolega_code-0.8.1 → kolega_code-0.8.2}/LICENSE +0 -0
  48. {kolega_code-0.8.1 → kolega_code-0.8.2}/README.md +0 -0
  49. {kolega_code-0.8.1 → kolega_code-0.8.2}/RELEASING.md +0 -0
  50. {kolega_code-0.8.1 → kolega_code-0.8.2}/SECURITY.md +0 -0
  51. {kolega_code-0.8.1 → kolega_code-0.8.2}/conftest.py +0 -0
  52. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/.gitignore +0 -0
  53. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/README.md +0 -0
  54. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/astro.config.mjs +0 -0
  55. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/package-lock.json +0 -0
  56. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/package.json +0 -0
  57. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/public/favicon.svg +0 -0
  58. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/assets/demo.gif +0 -0
  59. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/assets/kolega-dark.svg +0 -0
  60. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/assets/kolega-light.svg +0 -0
  61. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/cli/ask.md +0 -0
  62. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/cli/doctor.md +0 -0
  63. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/cli/sessions.md +0 -0
  64. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/concepts/agents.md +0 -0
  65. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/concepts/how-it-works.md +0 -0
  66. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/concepts/tools.md +0 -0
  67. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/configuration/environment-variables.md +0 -0
  68. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/configuration/providers-and-models.mdx +0 -0
  69. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/configuration/settings-and-api-keys.mdx +0 -0
  70. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/configuration/sign-in-with-chatgpt.mdx +0 -0
  71. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/getting-started/installation.mdx +0 -0
  72. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/getting-started/quick-start.mdx +0 -0
  73. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/hooks.md +0 -0
  74. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/index.mdx +0 -0
  75. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/skills.mdx +0 -0
  76. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/tui/composer.md +0 -0
  77. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/tui/modes.md +0 -0
  78. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/tui/sessions-and-resume.md +0 -0
  79. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content/docs/tui/slash-commands.md +0 -0
  80. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/content.config.ts +0 -0
  81. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/src/styles/brand.css +0 -0
  82. {kolega_code-0.8.1 → kolega_code-0.8.2}/docs/tsconfig.json +0 -0
  83. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/baseagent.py +0 -0
  84. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/browseragent.py +0 -0
  85. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/coder.py +0 -0
  86. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/common.py +0 -0
  87. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/compression.py +0 -0
  88. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/context.py +0 -0
  89. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/conversation.py +0 -0
  90. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/errors.py +0 -0
  91. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/generalagent.py +0 -0
  92. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/investigationagent.py +0 -0
  93. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/__init__.py +0 -0
  94. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/budget.py +0 -0
  95. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/errors.py +0 -0
  96. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/executor.py +0 -0
  97. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/tests/__init__.py +0 -0
  98. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/orchestration/tests/test_orchestration.py +0 -0
  99. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/planningagent.py +0 -0
  100. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_provider.py +0 -0
  101. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
  102. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
  103. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
  104. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
  105. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +0 -0
  106. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
  107. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
  108. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
  109. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
  110. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
  111. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
  112. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
  113. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
  114. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
  115. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
  116. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
  117. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
  118. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
  119. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
  120. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
  121. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
  122. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/prompts.py +0 -0
  123. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/__init__.py +0 -0
  124. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/compaction_helpers.py +0 -0
  125. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/__init__.py +0 -0
  126. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_anthropic_token_counting.py +0 -0
  127. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_billing_openai_cache.py +0 -0
  128. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_chatgpt_live.py +0 -0
  129. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_chatgpt_oauth_provider.py +0 -0
  130. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_client.py +0 -0
  131. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_dashscope_mapping.py +0 -0
  132. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_error_boundary.py +0 -0
  133. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_exceptions.py +0 -0
  134. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_google_thought_signature.py +0 -0
  135. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_google_tool_signature_live.py +0 -0
  136. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_instrumented_client.py +0 -0
  137. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_instrumented_client_integration.py +0 -0
  138. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_langfuse_normalization.py +0 -0
  139. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_live_providers.py +0 -0
  140. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_model_specs.py +0 -0
  141. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_cached_tokens.py +0 -0
  142. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_cached_tokens_stream.py +0 -0
  143. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_message_conversion.py +0 -0
  144. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_responses_provider.py +0 -0
  145. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_token_counting.py +0 -0
  146. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_supports_vision.py +0 -0
  147. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_thinking_effort.py +0 -0
  148. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_tool_execution_ids.py +0 -0
  149. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/services/__init__.py +0 -0
  150. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_browser.py +0 -0
  151. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_browser_parity.py +0 -0
  152. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_file_system.py +0 -0
  153. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_sandbox_terminal_input.py +0 -0
  154. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_terminal.py +0 -0
  155. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_terminal_buffer.py +0 -0
  156. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_terminal_state_serializer.py +0 -0
  157. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_agent_tools_inventory.py +0 -0
  158. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_base_agent.py +0 -0
  159. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_coder_attachments.py +0 -0
  160. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_coder_prompt_extensions.py +0 -0
  161. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_commands.py +0 -0
  162. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_integration.py +0 -0
  163. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_persistence.py +0 -0
  164. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_subagent.py +0 -0
  165. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compress_command.py +0 -0
  166. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compression.py +0 -0
  167. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_conversation_compaction.py +0 -0
  168. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_duplicate_tool_results.py +0 -0
  169. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_empty_message_handling.py +0 -0
  170. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_event_emitter.py +0 -0
  171. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_general_agent.py +0 -0
  172. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_gigacode_gating.py +0 -0
  173. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_hooks_integration.py +0 -0
  174. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_html.py +0 -0
  175. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_image_compat.py +0 -0
  176. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_parallel_tool_calls.py +0 -0
  177. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_permissions.py +0 -0
  178. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_planning_agent.py +0 -0
  179. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_prompt_provider.py +0 -0
  180. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_read_image_tool.py +0 -0
  181. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_tool_registry.py +0 -0
  182. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/test_tools.py +0 -0
  183. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/__init__.py +0 -0
  184. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_agent_tool.py +0 -0
  185. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_base_tool.py +0 -0
  186. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_browser_tool.py +0 -0
  187. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_build_tool.py +0 -0
  188. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_create_file_tool.py +0 -0
  189. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_edit_preview.py +0 -0
  190. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_glob_tool.py +0 -0
  191. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_glob_tool_sandbox_parity.py +0 -0
  192. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_list_directory_tool.py +0 -0
  193. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_read_file_tool.py +0 -0
  194. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_replace_entire_file_tool.py +0 -0
  195. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_replace_lines_tool.py +0 -0
  196. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_search_and_replace_tool.py +0 -0
  197. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_search_codebase_tool.py +0 -0
  198. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_terminal_tool.py +0 -0
  199. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_think_hard_integration.py +0 -0
  200. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_think_hard_streaming.py +0 -0
  201. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_web_fetch_tool.py +0 -0
  202. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_web_search_tool.py +0 -0
  203. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/base_tool.py +0 -0
  204. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
  205. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/build_tool.py +0 -0
  206. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/create_file_tool.py +0 -0
  207. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
  208. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/glob_tool.py +0 -0
  209. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/list_directory_tool.py +0 -0
  210. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
  211. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
  212. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
  213. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/replace_entire_file_tool.py +0 -0
  214. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/replace_lines_tool.py +0 -0
  215. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_and_replace_tool.py +0 -0
  216. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
  217. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
  218. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
  219. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
  220. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
  221. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
  222. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
  223. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
  224. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_codebase_tool.py +0 -0
  225. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
  226. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
  227. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/think_hard_tool.py +0 -0
  228. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
  229. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
  230. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/agent/utils/commands.py +0 -0
  231. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/auth/__init__.py +0 -0
  232. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/auth/_jwt.py +0 -0
  233. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/auth/chatgpt_oauth.py +0 -0
  234. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/auth/constants.py +0 -0
  235. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/auth/tests/__init__.py +0 -0
  236. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/auth/tests/test_chatgpt_oauth.py +0 -0
  237. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/auth/tests/test_tokens.py +0 -0
  238. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/auth/tokens.py +0 -0
  239. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/__init__.py +0 -0
  240. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/clipboard_image.py +0 -0
  241. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/config.py +0 -0
  242. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/connection.py +0 -0
  243. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/file_index.py +0 -0
  244. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/mentions.py +0 -0
  245. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/messages.py +0 -0
  246. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/provider_registry.py +0 -0
  247. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/session_store.py +0 -0
  248. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/settings.py +0 -0
  249. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/skills.py +0 -0
  250. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/slash_commands.py +0 -0
  251. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/__init__.py +0 -0
  252. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_cli_config.py +0 -0
  253. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_clipboard_image.py +0 -0
  254. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_connection.py +0 -0
  255. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_file_index.py +0 -0
  256. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_mentions.py +0 -0
  257. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_provider_registry.py +0 -0
  258. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_session_store.py +0 -0
  259. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_settings.py +0 -0
  260. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_skills.py +0 -0
  261. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_slash_commands.py +0 -0
  262. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/tests/test_updater.py +0 -0
  263. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/theme.py +0 -0
  264. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/cli/updater.py +0 -0
  265. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/config.py +0 -0
  266. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/events.py +0 -0
  267. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/hooks/__init__.py +0 -0
  268. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/hooks/backends.py +0 -0
  269. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/hooks/config.py +0 -0
  270. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/hooks/dispatcher.py +0 -0
  271. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/hooks/events.py +0 -0
  272. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/hooks/matcher.py +0 -0
  273. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/hooks/outcome.py +0 -0
  274. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/hooks/tests/__init__.py +0 -0
  275. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/hooks/tests/test_hooks.py +0 -0
  276. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/client.py +0 -0
  277. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/exceptions.py +0 -0
  278. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/instrumented_client.py +0 -0
  279. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/models.py +0 -0
  280. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/providers/__init__.py +0 -0
  281. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/providers/anthropic.py +0 -0
  282. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/providers/base.py +0 -0
  283. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
  284. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/providers/google.py +0 -0
  285. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/providers/models.py +0 -0
  286. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/providers/openai.py +0 -0
  287. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/providers/openai_responses.py +0 -0
  288. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/providers/responses_common.py +0 -0
  289. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/ratelimit.py +0 -0
  290. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/specs.py +0 -0
  291. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/llm/tool_execution_ids.py +0 -0
  292. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/models/__init__.py +0 -0
  293. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/models/sandbox_terminal_state.py +0 -0
  294. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/permissions.py +0 -0
  295. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/runtime.py +0 -0
  296. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/README.md +0 -0
  297. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/__init__.py +0 -0
  298. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/async_filesystem.py +0 -0
  299. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/base.py +0 -0
  300. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/browser.py +0 -0
  301. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/event_loop.py +0 -0
  302. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/filesystem.py +0 -0
  303. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/local.py +0 -0
  304. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/serializer.py +0 -0
  305. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/terminal.py +0 -0
  306. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/sandbox/utils.py +0 -0
  307. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/services/base.py +0 -0
  308. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/services/browser.py +0 -0
  309. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/services/file_system.py +0 -0
  310. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/services/html.py +0 -0
  311. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/services/terminal.py +0 -0
  312. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/services/terminal_buffer.py +0 -0
  313. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/tools/__init__.py +0 -0
  314. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/tools/core.py +0 -0
  315. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/tools/definitions.py +0 -0
  316. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/tools/registry.py +0 -0
  317. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/tools/tests/__init__.py +0 -0
  318. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/tools/tests/test_definitions.py +0 -0
  319. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/utils/__init__.py +0 -0
  320. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/utils/images.py +0 -0
  321. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/utils/tests/__init__.py +0 -0
  322. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/utils/tests/test_images.py +0 -0
  323. {kolega_code-0.8.1 → kolega_code-0.8.2}/kolega_code/utils/tests/test_images_ascii.py +0 -0
  324. {kolega_code-0.8.1 → kolega_code-0.8.2}/run_tests.sh +0 -0
  325. {kolega_code-0.8.1 → kolega_code-0.8.2}/scripts/install-kolega-code.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kolega-code
3
- Version: 0.8.1
3
+ Version: 0.8.2
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/
@@ -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
+ | `--show-logs` | Show the optional diagnostic Logs side-panel tab. Hidden by default to avoid unnecessary log rendering work |
42
43
  | `--permission-mode <auto\|ask>` | Shell/edit permission mode. TUI sessions default to `ask` |
43
44
  | `--session <ID>` | Legacy alias for `--resume THREAD_ID` |
44
45
 
@@ -43,6 +43,15 @@ When the agent runs a workflow, the transcript shows **phase headers** and short
43
43
  [sub-agent inspector](../tui/interface/#sub-agent-inspector) — press `Ctrl+G` to
44
44
  watch every agent's live trajectory, grouped by phase.
45
45
 
46
+ The `run_workflow` result is a compact artifact manifest. It includes paths like
47
+ `resultPath` and `transcriptPath`; the completed workflow result is written to
48
+ `resultPath` instead of returned inline. For normal workflow output, the agent
49
+ should read those main files and avoid reading individual sub-agent transcripts.
50
+ Raw and per-agent debug artifacts may exist under the run directory for explicit
51
+ workflow debugging.
52
+ The agent should read those paths first — not re-run the workflow just to recover
53
+ output text.
54
+
46
55
  ## How it works
47
56
 
48
57
  Under the hood, the agent authors a short **Python script** and runs it with a
@@ -69,9 +78,11 @@ return findings
69
78
 
70
79
  <Aside type="note">
71
80
  Workflows are deterministic and **resumable**. Each run is saved under Kolega
72
- Code's state directory (`workflows/<run-id>/`) with its script, a journal, and each
73
- sub-agent's transcript, so an interrupted run can pick up where it left off instead
74
- of redoing finished work.
81
+ Code's state directory (`workflows/<run-id>/`) with its script, full result files,
82
+ a readable Markdown transcript, raw JSONL, a resume journal, and debug sub-agent
83
+ transcripts, so an interrupted run can pick up where it left off instead of redoing
84
+ finished work. Use resume when intentionally iterating on the workflow; use the
85
+ artifact paths when you only need to inspect output.
75
86
  </Aside>
76
87
 
77
88
  ## Behavior and safety
@@ -14,8 +14,9 @@ The screen is split into two columns:
14
14
  - **Conversation panel** (left, larger) — your chat with the agent. Responses
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
- - **Side panel** (right) — a set of tabs for status, logs, the terminal, planning,
18
- and settings. Toggle it with `Ctrl+O` or `/sidebar`.
17
+ - **Side panel** (right) — a set of tabs for status, the terminal, planning,
18
+ and settings. Toggle it with `Ctrl+O` or `/sidebar`. The diagnostic Logs tab is
19
+ opt-in; launch with `--show-logs` when you want it.
19
20
 
20
21
  At the bottom sits the **composer** — the text box where you type prompts. See
21
22
  [Chat Composer](../composer/) for everything it can do.
@@ -25,7 +26,7 @@ At the bottom sits the **composer** — the text box where you type prompts. See
25
26
  | Tab | What it shows |
26
27
  | --- | --- |
27
28
  | **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
- | **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
+ | **Logs** | Optional. Launch with `--show-logs` to show a timestamped, color-coded diagnostic activity log. New entries preserve manual scrollback and an indicator flags unseen entries when you're on another tab. |
29
30
  | **Terminal** | Live output from commands the agent runs. |
30
31
  | **Planning** | The current **Plan** (markdown from the planning agent) and the shared **Task List** that both modes can edit. |
31
32
  | **Settings** | Provider, model, thinking effort, and API-key configuration. See [Settings & API Keys](../../configuration/settings-and-api-keys/). |
@@ -151,4 +151,4 @@ __all__ = [
151
151
  "parse_git_status_output",
152
152
  ]
153
153
 
154
- __version__ = "0.8.1"
154
+ __version__ = "0.8.2"
@@ -44,4 +44,4 @@ __all__ = [
44
44
  "ToolExtension",
45
45
  ]
46
46
 
47
- __version__ = "0.8.1"
47
+ __version__ = "0.8.2"
@@ -134,10 +134,26 @@ After the workflow returns, integrate the results, run the full test suite yours
134
134
  report. If the plan is small or its parts are tightly coupled, skip the workflow and just
135
135
  implement it directly — orchestration is for genuinely independent fan-out.
136
136
 
137
+ ### Artifacts and transcripts
138
+
139
+ `run_workflow` returns a concise manifest, not necessarily the full workflow output.
140
+ Every completed run persists full artifacts under the state directory and returns
141
+ paths including `resultPath` and `transcriptPath`. If the inline tool result says output was omitted, looks incomplete,
142
+ or would require a long transcript to understand, READ `resultPath` or `transcriptPath`
143
+ with the file-reading tools before deciding work is missing. For normal workflow
144
+ output, use only those main files; avoid reading individual sub-agent transcripts
145
+ unless you are explicitly debugging workflow execution.
146
+
147
+ Never re-run a completed workflow solely to recover output from an omitted/truncated
148
+ inline result. The workflow already ran; inspect the persisted result/transcript first.
149
+ Use `resume_from_run_id` only when you intentionally want to iterate on or change the
150
+ workflow, not as a transcript-recovery mechanism.
151
+
137
152
  ### Resume
138
153
 
139
- Each run persists its script and a journal under the state directory and returns a
140
- `runId` and `scriptPath`. To iterate, edit the script and re-run with `script_path`,
141
- or pass `resume_from_run_id` to replay cached `agent()` results for the unchanged
142
- prefix and only re-run new/changed calls.
154
+ Each run persists its script, full results, a readable transcript, raw JSONL, and a
155
+ resume journal under the state directory and returns a `runId` plus artifact paths.
156
+ To iterate, edit the script and re-run with `script_path`, or pass `resume_from_run_id`
157
+ to replay cached `agent()` results for the unchanged prefix and only re-run new/changed
158
+ calls.
143
159
  """
@@ -4,9 +4,13 @@ Everything a run needs lives under::
4
4
 
5
5
  <state-dir>/workflows/<run_id>/
6
6
  script.py the authored source (its path is returned for edit + re-run)
7
- run.json meta, args, status, timing, token totals
7
+ run.json meta, args, status, timing, token totals, artifact paths
8
8
  journal.jsonl one line per completed agent() call (drives resume)
9
- agents/ per sub-agent transcripts (wired via sub_agent_recorder)
9
+ result.json full JSON-rendered workflow return value
10
+ result.md readable workflow return value
11
+ transcript.jsonl raw workflow events/call outcomes
12
+ transcript.md readable workflow transcript/index
13
+ agents/ per sub-agent raw/readable transcripts
10
14
 
11
15
  Resume contract: scripts are deterministic (the runtime blocks ``random``/``time``
12
16
  and ``import``), so the same source + args produce ``agent()`` calls in the same
@@ -18,6 +22,7 @@ new call onward.
18
22
  from __future__ import annotations
19
23
 
20
24
  import json
25
+ import re
21
26
  from pathlib import Path
22
27
  from typing import Any, Dict, Optional, Tuple
23
28
 
@@ -32,6 +37,15 @@ def saved_workflows_dir(state_dir: Path) -> Path:
32
37
  return workflows_root(state_dir) / "_saved"
33
38
 
34
39
 
40
+ def _slugify(value: str, *, fallback: str = "agent", max_length: int = 64) -> str:
41
+ """Return a filesystem-friendly slug for workflow artifact filenames."""
42
+ slug = re.sub(r"[^A-Za-z0-9._-]+", "-", str(value or "").strip().lower())
43
+ slug = re.sub(r"-+", "-", slug).strip("-._")
44
+ if not slug:
45
+ slug = fallback
46
+ return slug[:max_length].rstrip("-._") or fallback
47
+
48
+
35
49
  class RunJournal:
36
50
  """Owns the on-disk artifacts for a single workflow run."""
37
51
 
@@ -40,6 +54,10 @@ class RunJournal:
40
54
  self.run_id = run_id
41
55
  self.agents_dir = self.run_dir / "agents"
42
56
  self._journal_path = self.run_dir / "journal.jsonl"
57
+ self._transcript_jsonl_path = self.run_dir / "transcript.jsonl"
58
+ self._transcript_md_path = self.run_dir / "transcript.md"
59
+ self._result_json_path = self.run_dir / "result.json"
60
+ self._result_md_path = self.run_dir / "result.md"
43
61
  self._script_path = self.run_dir / "script.py"
44
62
  self._meta_path = self.run_dir / "run.json"
45
63
 
@@ -55,6 +73,33 @@ class RunJournal:
55
73
  def script_path(self) -> Path:
56
74
  return self._script_path
57
75
 
76
+ @property
77
+ def journal_path(self) -> Path:
78
+ return self._journal_path
79
+
80
+ @property
81
+ def transcript_jsonl_path(self) -> Path:
82
+ return self._transcript_jsonl_path
83
+
84
+ @property
85
+ def transcript_md_path(self) -> Path:
86
+ return self._transcript_md_path
87
+
88
+ @property
89
+ def result_json_path(self) -> Path:
90
+ return self._result_json_path
91
+
92
+ @property
93
+ def result_md_path(self) -> Path:
94
+ return self._result_md_path
95
+
96
+ def agent_artifact_paths(self, call_index: int, label: Optional[str] = None) -> Dict[str, Path]:
97
+ """Return stable per-agent raw/readable artifact paths for a workflow call."""
98
+ self.ensure_dirs()
99
+ suffix = _slugify(label or f"call-{call_index}")
100
+ stem = f"agent-{call_index:03d}-{suffix}"
101
+ return {"markdown": self.agents_dir / f"{stem}.md", "jsonl": self.agents_dir / f"{stem}.jsonl"}
102
+
58
103
  def write_script(self, source: str) -> Path:
59
104
  self.ensure_dirs()
60
105
  self._script_path.write_text(source, encoding="utf-8")
@@ -86,16 +131,41 @@ class RunJournal:
86
131
  label: Optional[str],
87
132
  value: Any,
88
133
  status: str = "completed",
134
+ **metadata: Any,
89
135
  ) -> None:
90
- """Append one completed ``agent()`` result for resume replay."""
136
+ """Append one completed ``agent()`` result for resume replay.
137
+
138
+ ``journal.jsonl`` is the resume contract. Extra fields are allowed and ignored
139
+ by ``load_cache()`` so newer artifact metadata remains backward-compatible.
140
+ """
91
141
  self.ensure_dirs()
92
- line = json.dumps(
93
- {"index": call_index, "key": key, "label": label, "status": status, "value": value},
94
- default=str,
95
- )
142
+ payload = {"index": call_index, "key": key, "label": label, "status": status, "value": value}
143
+ payload.update({k: v for k, v in metadata.items() if v is not None})
144
+ line = json.dumps(payload, default=str)
96
145
  with self._journal_path.open("a", encoding="utf-8") as handle:
97
146
  handle.write(line + "\n")
98
147
 
148
+ def append_transcript_event(self, event: Dict[str, Any]) -> None:
149
+ """Append one raw workflow transcript event as JSONL."""
150
+ self.ensure_dirs()
151
+ with self._transcript_jsonl_path.open("a", encoding="utf-8") as handle:
152
+ handle.write(json.dumps(event, default=str) + "\n")
153
+
154
+ def write_result_artifacts(self, result: Any, markdown: str) -> None:
155
+ """Persist the full workflow return value in JSON and readable Markdown."""
156
+ self.ensure_dirs()
157
+ try:
158
+ rendered_json = json.dumps(result, indent=2, default=str)
159
+ except (TypeError, ValueError):
160
+ rendered_json = json.dumps(str(result), indent=2)
161
+ self._result_json_path.write_text(rendered_json + "\n", encoding="utf-8")
162
+ self._result_md_path.write_text(markdown, encoding="utf-8")
163
+
164
+ def write_transcript_markdown(self, markdown: str) -> None:
165
+ """Persist the readable workflow transcript."""
166
+ self.ensure_dirs()
167
+ self._transcript_md_path.write_text(markdown, encoding="utf-8")
168
+
99
169
  def load_cache(self) -> Dict[int, Tuple[str, Any]]:
100
170
  """Read a prior run's journal into ``{call_index: (key, value)}``.
101
171
 
@@ -150,8 +150,19 @@ class WorkflowRuntime:
150
150
 
151
151
  cached = self._resume_cache.get(index)
152
152
  if cached is not None and cached[0] == key:
153
- self._emit_soon("workflow_agent_cached", {"label": spec.label or prompt[:60], "phase": spec.phase})
154
- return cached[1]
153
+ cached_value = cached[1]
154
+ label = spec.label or prompt[:60]
155
+ self._journal.append_transcript_event(
156
+ {
157
+ "type": "agent_cached",
158
+ "index": index,
159
+ "label": label,
160
+ "phase": spec.phase,
161
+ "value": cached_value,
162
+ }
163
+ )
164
+ self._emit_soon("workflow_agent_cached", {"label": label, "phase": spec.phase})
165
+ return cached_value
155
166
 
156
167
  self._agent_count += 1
157
168
  if self._agent_count > self._agent_cap:
@@ -169,7 +180,34 @@ class WorkflowRuntime:
169
180
 
170
181
  self.budget.add(result.tokens)
171
182
  value = result.value
172
- self._journal.record(index, key, spec.label, value, status=result.status)
183
+ self._journal.record(
184
+ index,
185
+ key,
186
+ spec.label,
187
+ value,
188
+ status=result.status,
189
+ phase=spec.phase,
190
+ agent_type=spec.agent_type,
191
+ tokens=result.tokens,
192
+ error=result.error,
193
+ transcript_path=result.transcript_path,
194
+ transcript_markdown_path=result.transcript_markdown_path,
195
+ )
196
+ self._journal.append_transcript_event(
197
+ {
198
+ "type": "agent_call",
199
+ "index": index,
200
+ "label": spec.label,
201
+ "phase": spec.phase,
202
+ "agent_type": spec.agent_type,
203
+ "status": result.status,
204
+ "tokens": result.tokens,
205
+ "error": result.error,
206
+ "value": value,
207
+ "transcript_path": result.transcript_path,
208
+ "transcript_markdown_path": result.transcript_markdown_path,
209
+ }
210
+ )
173
211
  return value
174
212
 
175
213
  async def parallel(self, thunks: Iterable[Callable[[], Awaitable[Any]]]) -> List[Any]:
@@ -56,6 +56,8 @@ class AgentRunResult:
56
56
  agent_id: Optional[str] = None
57
57
  status: str = "completed" # completed | failed | skipped
58
58
  error: Optional[str] = None
59
+ transcript_path: Optional[str] = None
60
+ transcript_markdown_path: Optional[str] = None
59
61
 
60
62
  @property
61
63
  def value(self) -> Any:
@@ -46,6 +46,10 @@ Do not run destructive commands automatically. Treat commands that delete files,
46
46
 
47
47
  When running tests or builds, choose the smallest command that gives confidence first, then broaden verification when the change has a wider blast radius.
48
48
 
49
+ ## Git Branches and Pull Requests
50
+
51
+ When creating a branch or opening a pull request, follow repository or user conventions if provided; otherwise use Conventional Commits-style names. Use lowercase kebab-case branch names with a conventional type prefix, such as `feat/add-login-rate-limit` or `fix/navbar-overlap`. Use Conventional Commit PR titles, such as `feat(auth): add session timeout` or `fix: handle empty search results`. Keep names descriptive but not overly long.
52
+
49
53
  ## Development Servers
50
54
 
51
55
  When starting a local development server, use an available port and tell the user the URL. If a server is already running on the default port, use another suitable port. Stop servers you started when they are no longer needed unless the user is actively testing them.
@@ -39,7 +39,8 @@ async def test_compress_history_emits_error_phase_on_failure(tmp_path):
39
39
 
40
40
  def test_app_apply_compaction_status_toggles_indicator():
41
41
  # Exercise the dashboard toggle without constructing the full Textual app.
42
- from kolega_code.cli.app import KolegaCodeApp, StatusDashboardState
42
+ from kolega_code.cli.app import KolegaCodeApp
43
+ from kolega_code.cli.tui.state import StatusDashboardState
43
44
 
44
45
  refreshed = []
45
46
  fake = SimpleNamespace(
@@ -60,7 +61,8 @@ def test_app_apply_compaction_status_toggles_indicator():
60
61
 
61
62
  def test_app_apply_compaction_status_adds_summary_collapsible():
62
63
  # On finish with a summary, a collapsible transcript entry is created.
63
- from kolega_code.cli.app import ConversationEntry, KolegaCodeApp, StatusDashboardState
64
+ from kolega_code.cli.app import KolegaCodeApp
65
+ from kolega_code.cli.tui.state import ConversationEntry, StatusDashboardState
64
66
 
65
67
  added = []
66
68
  fake = SimpleNamespace(
@@ -1,6 +1,7 @@
1
1
  from pathlib import Path
2
2
 
3
3
  from kolega_code.agent import prompts
4
+ from kolega_code.agent.orchestration.guide import GIGACODE_AUTHORING_GUIDE
4
5
 
5
6
 
6
7
  def test_static_prompt_templates_load() -> None:
@@ -45,6 +46,13 @@ def test_implement_plan_prompt_includes_gigacode_nudge_when_enabled() -> None:
45
46
  assert "- [ ] update docs" in rendered
46
47
 
47
48
 
49
+ def test_gigacode_guide_points_agents_to_artifact_transcripts() -> None:
50
+ assert "resultPath" in GIGACODE_AUTHORING_GUIDE
51
+ assert "transcriptPath" in GIGACODE_AUTHORING_GUIDE
52
+ assert "Never re-run a completed workflow solely" in GIGACODE_AUTHORING_GUIDE
53
+ assert "READ `resultPath` or `transcriptPath`" in GIGACODE_AUTHORING_GUIDE
54
+
55
+
48
56
  def test_init_agents_prompt_renders_arguments() -> None:
49
57
  rendered = prompts.build_init_agents_prompt("focus on Python packaging")
50
58
 
@@ -6,7 +6,7 @@ the real run_workflow code path (state-dir resolution, journal, emit, summary).
6
6
 
7
7
  import json
8
8
  from pathlib import Path
9
- from unittest.mock import AsyncMock, Mock
9
+ from unittest.mock import AsyncMock, Mock, patch
10
10
 
11
11
  import pytest
12
12
 
@@ -29,6 +29,9 @@ def caller():
29
29
  c.sub_agent = False
30
30
  c.current_tool_execution_id = "exec-1"
31
31
  c.current_tool_call_id = "exec-1"
32
+ c.sub_agent_recorder = None
33
+ c.prompt_extensions = None
34
+ c.tool_extensions = None
32
35
  c.tool_collection = Mock(read_only=False) # build-mode (writable) caller by default
33
36
  return c
34
37
 
@@ -54,8 +57,20 @@ def _stub_dispatch():
54
57
  """A dispatch_workflow_agent stub returning (recap, tokens, structured)."""
55
58
  calls = []
56
59
 
57
- async def dispatch_workflow_agent(agent_class, task, *, config=None, schema=None, sub_agent_info_extra=None):
58
- calls.append((task, schema, sub_agent_info_extra))
60
+ async def dispatch_workflow_agent(
61
+ agent_class,
62
+ task,
63
+ *,
64
+ config=None,
65
+ schema=None,
66
+ sub_agent_info_extra=None,
67
+ artifact_paths=None,
68
+ artifact_metadata=None,
69
+ ):
70
+ calls.append((task, schema, sub_agent_info_extra, artifact_paths, artifact_metadata))
71
+ if artifact_paths:
72
+ artifact_paths["jsonl"].write_text(json.dumps({"role": "assistant", "content": task}) + "\n")
73
+ artifact_paths["markdown"].write_text(f"# Agent artifact\n\n{task}\n")
59
74
  if schema:
60
75
  return (f"recap:{task}", 7, {"task": task})
61
76
  return (f"recap:{task}", 3, None)
@@ -85,14 +100,21 @@ async def test_run_workflow_writes_artifacts_and_summary(workflow_tool):
85
100
  assert len(calls) == 4
86
101
  assert "Workflow 'demo' completed." in summary
87
102
  assert "runId:" in summary and "scriptPath:" in summary
103
+ assert "resultPath:" in summary
104
+ assert "transcriptPath:" in summary
88
105
 
89
106
  # Artifacts under <state_dir>/workflows/<run_id>/
90
107
  run_id = next(line.split("runId:")[1].strip() for line in summary.splitlines() if "runId:" in line)
91
108
  run_dir = Path(state_dir) / "workflows" / run_id
92
109
  assert (run_dir / "script.py").read_text() == SCRIPT
110
+ assert (run_dir / "result.md").is_file()
111
+ assert (run_dir / "result.json").is_file()
112
+ assert (run_dir / "transcript.md").is_file()
113
+ assert (run_dir / "transcript.jsonl").is_file()
93
114
  meta = json.loads((run_dir / "run.json").read_text())
94
115
  assert meta["status"] == "completed"
95
116
  assert meta["name"] == "demo"
117
+ assert meta["artifacts"]["resultPath"] == str(run_dir / "result.md")
96
118
  # token total = 3*3 (parallel) + 7 (schema) = 16
97
119
  assert meta["total_tokens"] == 16
98
120
  journal_lines = (run_dir / "journal.jsonl").read_text().splitlines()
@@ -122,6 +144,78 @@ async def test_run_workflow_writes_artifacts_and_summary(workflow_tool):
122
144
  assert end["status"] == "completed"
123
145
 
124
146
 
147
+ @pytest.mark.asyncio
148
+ async def test_long_result_is_persisted_not_truncated_inline(workflow_tool):
149
+ tool, state_dir = workflow_tool
150
+ script = 'meta = {"name": "big", "description": "big result"}\nreturn {"blob": "x" * 5001}\n'
151
+
152
+ summary = await tool.run_workflow(script=script)
153
+
154
+ assert "resultPath:" in summary
155
+ assert "transcriptPath:" in summary
156
+ assert "result: written to resultPath" in summary
157
+ assert "IMPORTANT: The workflow already ran" in summary
158
+ assert "resultPreview:" not in summary
159
+ assert "… (truncated)" not in summary
160
+ assert len(summary) < 100_000
161
+
162
+ run_id = next(line.split("runId:")[1].strip() for line in summary.splitlines() if "runId:" in line)
163
+ run_dir = Path(state_dir) / "workflows" / run_id
164
+ result_json = json.loads((run_dir / "result.json").read_text())
165
+ assert result_json["blob"] == "x" * 5001
166
+ assert "x" * 5001 in (run_dir / "result.md").read_text()
167
+
168
+
169
+ @pytest.mark.asyncio
170
+ async def test_readable_transcript_indexes_agent_calls(workflow_tool):
171
+ tool, state_dir = workflow_tool
172
+ stub, calls = _stub_dispatch()
173
+ tool._agent_tool.dispatch_workflow_agent = stub
174
+ script = (
175
+ 'meta = {"name": "transcript", "description": "d", "phases": [{"title": "Find"}]}\n'
176
+ 'phase("Find")\n'
177
+ 'await agent("alpha", label="alpha-label")\n'
178
+ 'await agent("beta", label="beta-label", phase="Check")\n'
179
+ 'return "done"\n'
180
+ )
181
+
182
+ summary = await tool.run_workflow(script=script)
183
+
184
+ assert len(calls) == 2
185
+ run_id = next(line.split("runId:")[1].strip() for line in summary.splitlines() if "runId:" in line)
186
+ run_dir = Path(state_dir) / "workflows" / run_id
187
+ transcript = (run_dir / "transcript.md").read_text()
188
+ assert "# Workflow transcript: transcript" in transcript
189
+ assert "alpha-label" in transcript
190
+ assert "beta-label" in transcript
191
+ assert "Find" in transcript
192
+ assert "Check" in transcript
193
+ # Main workflow transcript should not advertise per-agent transcript paths;
194
+ # agents should use the main result/transcript and avoid individual sub-agent transcripts.
195
+ assert "agent-000-alpha-label.md" not in transcript
196
+ raw_events = [json.loads(line) for line in (run_dir / "transcript.jsonl").read_text().splitlines() if line]
197
+ assert any(event["type"] == "agent_call" for event in raw_events)
198
+
199
+
200
+ @pytest.mark.asyncio
201
+ async def test_failed_agent_call_is_recorded_in_transcript(workflow_tool):
202
+ tool, state_dir = workflow_tool
203
+
204
+ async def failing_dispatch(*args, **kwargs):
205
+ raise RuntimeError("agent exploded")
206
+
207
+ tool._agent_tool.dispatch_workflow_agent = failing_dispatch
208
+ script = 'meta = {"name": "failure", "description": "d"}\nvalue = await agent("boom", label="boom")\nreturn {"value": value}\n'
209
+
210
+ summary = await tool.run_workflow(script=script)
211
+
212
+ assert "transcriptPath:" in summary
213
+ run_id = next(line.split("runId:")[1].strip() for line in summary.splitlines() if "runId:" in line)
214
+ transcript = (Path(state_dir) / "workflows" / run_id / "transcript.md").read_text()
215
+ assert "failed" in transcript
216
+ assert "agent exploded" in transcript
217
+
218
+
125
219
  @pytest.mark.asyncio
126
220
  async def test_run_workflow_carries_phase_and_label_to_dispatch(workflow_tool):
127
221
  tool, _ = workflow_tool
@@ -135,12 +229,52 @@ async def test_run_workflow_carries_phase_and_label_to_dispatch(workflow_tool):
135
229
  "return 1\n"
136
230
  )
137
231
  await tool.run_workflow(script=script)
138
- _task, _schema, extra = calls[0]
232
+ _task, _schema, extra, _artifact_paths, _artifact_metadata = calls[0]
139
233
  assert extra["phase"] == "Build"
140
234
  assert extra["label"] == "my-label"
141
235
  assert "workflow_run_id" in extra
142
236
 
143
237
 
238
+ @pytest.mark.asyncio
239
+ async def test_per_agent_markdown_and_jsonl_are_written(workflow_tool):
240
+ tool, state_dir = workflow_tool
241
+
242
+ class ArtifactAgent:
243
+ agent_name = "artifact-agent"
244
+
245
+ def __init__(self, **kwargs):
246
+ self.total_tokens_used = 11
247
+ self._history = [
248
+ {"role": "user", "content": [{"type": "text", "text": "artifact task"}]},
249
+ {"role": "assistant", "content": [{"type": "text", "text": "artifact answer"}]},
250
+ ]
251
+
252
+ async def process_message_stream(self, task):
253
+ yield {"type": "response", "content": "artifact answer", "complete": True, "uuid": "u1"}
254
+
255
+ def dump_message_history(self):
256
+ return self._history
257
+
258
+ async def recap_agent_outcome(self):
259
+ return "final artifact recap"
260
+
261
+ script = 'meta = {"name": "agent-artifacts", "description": "d"}\nreturn await agent("artifact task", label="artifact")\n'
262
+
263
+ with patch("kolega_code.agent.generalagent.GeneralAgent", ArtifactAgent):
264
+ summary = await tool.run_workflow(script=script)
265
+
266
+ run_id = next(line.split("runId:")[1].strip() for line in summary.splitlines() if "runId:" in line)
267
+ agents_dir = Path(state_dir) / "workflows" / run_id / "agents"
268
+ markdown = agents_dir / "agent-000-artifact.md"
269
+ raw = agents_dir / "agent-000-artifact.jsonl"
270
+ assert markdown.is_file()
271
+ assert raw.is_file()
272
+ markdown_text = markdown.read_text()
273
+ assert "artifact task" in markdown_text
274
+ assert "final artifact recap" in markdown_text
275
+ assert "artifact answer" in raw.read_text()
276
+
277
+
144
278
  @pytest.mark.asyncio
145
279
  async def test_resume_replays_without_redispatch(workflow_tool):
146
280
  tool, state_dir = workflow_tool
@@ -155,6 +289,10 @@ async def test_resume_replays_without_redispatch(workflow_tool):
155
289
  summary2 = await tool.run_workflow(script=SCRIPT, resume_from_run_id=run_id)
156
290
  assert len(calls) == 0 # fully replayed from journal
157
291
  assert "completed" in summary2
292
+ run_id2 = next(line.split("runId:")[1].strip() for line in summary2.splitlines() if "runId:" in line)
293
+ transcript2 = (Path(state_dir) / "workflows" / run_id2 / "transcript.md").read_text()
294
+ assert "Cached resume calls" in transcript2
295
+ assert "served from resume cache" in transcript2
158
296
 
159
297
 
160
298
  @pytest.mark.asyncio
@@ -166,7 +304,7 @@ async def test_read_only_caller_forces_investigation_agents(workflow_tool, calle
166
304
 
167
305
  seen = []
168
306
 
169
- async def stub(agent_class, task, *, config=None, schema=None, sub_agent_info_extra=None):
307
+ async def stub(agent_class, task, *, config=None, schema=None, sub_agent_info_extra=None, **kwargs):
170
308
  seen.append(agent_class.__name__)
171
309
  return (f"recap:{task}", 1, None)
172
310