kolega-code 0.35.0__tar.gz → 0.36.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 (488) hide show
  1. {kolega_code-0.35.0 → kolega_code-0.36.0}/CHANGELOG.md +39 -0
  2. {kolega_code-0.35.0 → kolega_code-0.36.0}/PKG-INFO +1 -1
  3. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/__init__.py +1 -1
  4. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/__init__.py +1 -1
  5. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/main.py +19 -1
  6. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/provider_registry.py +1 -0
  7. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/settings_panel.py +128 -2
  8. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/settings_screen.py +20 -0
  9. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/bridge.py +84 -36
  10. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/service.py +40 -3
  11. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/openai.py +15 -0
  12. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/openai_chatgpt.py +17 -0
  13. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/config.py +73 -2
  14. kolega_code-0.36.0/kolega_code/mcp/oauth.py +403 -0
  15. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/service.py +22 -0
  16. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/state.py +12 -1
  17. {kolega_code-0.35.0 → kolega_code-0.36.0}/pyproject.toml +1 -1
  18. kolega_code-0.35.0/kolega_code/mcp/oauth.py +0 -241
  19. {kolega_code-0.35.0 → kolega_code-0.36.0}/.gitignore +0 -0
  20. {kolega_code-0.35.0 → kolega_code-0.36.0}/CONTRIBUTING.md +0 -0
  21. {kolega_code-0.35.0 → kolega_code-0.36.0}/LICENSE +0 -0
  22. {kolega_code-0.35.0 → kolega_code-0.36.0}/MIGRATION.md +0 -0
  23. {kolega_code-0.35.0 → kolega_code-0.36.0}/README.md +0 -0
  24. {kolega_code-0.35.0 → kolega_code-0.36.0}/RELEASING.md +0 -0
  25. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/LICENSE +0 -0
  26. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/manifest.json +0 -0
  27. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/SKILL.md +0 -0
  28. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/references/evidence-and-reporting.md +0 -0
  29. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/references/gigacode-workflow.md +0 -0
  30. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/scripts/deep-research.workflow +0 -0
  31. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/scripts/materialize_report.py +0 -0
  32. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/LICENSE +0 -0
  33. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/SKILL.md +0 -0
  34. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/references/examples.md +0 -0
  35. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/references/limitations.md +0 -0
  36. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/references/operations.md +0 -0
  37. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/references/quality.md +0 -0
  38. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/requirements.txt +0 -0
  39. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/scripts/docx_tool.py +0 -0
  40. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/scripts/smoke_test.py +0 -0
  41. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/humanizer/LICENSE +0 -0
  42. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/humanizer/SKILL.md +0 -0
  43. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/LICENSE +0 -0
  44. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/SKILL.md +0 -0
  45. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/examples.md +0 -0
  46. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/limitations.md +0 -0
  47. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/ocr.md +0 -0
  48. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/operations.md +0 -0
  49. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/quality.md +0 -0
  50. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/redaction.md +0 -0
  51. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-paddle.txt +0 -0
  52. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-surya.txt +0 -0
  53. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/requirements.txt +0 -0
  54. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/scripts/pdf_tool.py +0 -0
  55. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/scripts/smoke_test.py +0 -0
  56. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/LICENSE +0 -0
  57. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/SKILL.md +0 -0
  58. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/references/examples.md +0 -0
  59. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/references/limitations.md +0 -0
  60. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/references/operations.md +0 -0
  61. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/requirements.txt +0 -0
  62. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/scripts/pptx_tool.py +0 -0
  63. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/scripts/smoke_test.py +0 -0
  64. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/review/SKILL.md +0 -0
  65. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/review/references/github-publishing.md +0 -0
  66. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/skill-authoring/SKILL.md +0 -0
  67. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/skill-authoring/references/review-checklist.md +0 -0
  68. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/LICENSE +0 -0
  69. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/SKILL.md +0 -0
  70. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/references/examples.md +0 -0
  71. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/references/limitations.md +0 -0
  72. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/references/operations.md +0 -0
  73. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/references/quality.md +0 -0
  74. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/requirements.txt +0 -0
  75. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/scripts/smoke_test.py +0 -0
  76. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/scripts/xlsx_tool.py +0 -0
  77. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/__init__.py +0 -0
  78. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/agent_factory.py +0 -0
  79. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/bridge.py +0 -0
  80. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/diffs.py +0 -0
  81. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/permissions.py +0 -0
  82. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/plans.py +0 -0
  83. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/questions.py +0 -0
  84. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/server.py +0 -0
  85. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/session.py +0 -0
  86. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/usage.py +0 -0
  87. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/baseagent.py +0 -0
  88. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/browseragent.py +0 -0
  89. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/coder.py +0 -0
  90. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/common.py +0 -0
  91. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/compression.py +0 -0
  92. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/context.py +0 -0
  93. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/conversation.py +0 -0
  94. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/custom_agents.py +0 -0
  95. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/edit_protocols.py +0 -0
  96. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/errors.py +0 -0
  97. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/__init__.py +0 -0
  98. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/bridge.py +0 -0
  99. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/bundle-requirements.in +0 -0
  100. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/bundle-requirements.txt +0 -0
  101. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/env.py +0 -0
  102. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/js_kernel.py +0 -0
  103. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/kernel.py +0 -0
  104. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/prelude.js +0 -0
  105. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/prelude.py +0 -0
  106. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/protocol.py +0 -0
  107. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/py_kernel.py +0 -0
  108. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/runner.js +0 -0
  109. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/runner.py +0 -0
  110. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/generalagent.py +0 -0
  111. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/goal.py +0 -0
  112. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/handoff.py +0 -0
  113. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/investigationagent.py +0 -0
  114. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/model_routing.py +0 -0
  115. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/__init__.py +0 -0
  116. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/accounting.py +0 -0
  117. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/budget.py +0 -0
  118. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/context.py +0 -0
  119. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/errors.py +0 -0
  120. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/executor.py +0 -0
  121. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/guide.py +0 -0
  122. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/journal.py +0 -0
  123. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/runtime.py +0 -0
  124. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/types.py +0 -0
  125. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/planningagent.py +0 -0
  126. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_dump.py +0 -0
  127. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_overrides.py +0 -0
  128. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_provider.py +0 -0
  129. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_exhausted.user.md +0 -0
  130. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_nudge.user.md.j2 +0 -0
  131. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/truncated_turn_nudge.user.md.j2 +0 -0
  132. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
  133. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
  134. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/handoff/document.system.md +0 -0
  135. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/handoff/document.user.md.j2 +0 -0
  136. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
  137. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
  138. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/build_questions.md +0 -0
  139. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/current_plan_artifact.md.j2 +0 -0
  140. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/mode_switch_notice.md.j2 +0 -0
  141. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
  142. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/scratchpad.md.j2 +0 -0
  143. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
  144. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list_readonly.md +0 -0
  145. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/worktree_control.md.j2 +0 -0
  146. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
  147. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
  148. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/coder_ask.md.j2 +0 -0
  149. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/coder_base.md.j2 +0 -0
  150. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +0 -0
  151. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
  152. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
  153. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
  154. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
  155. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/context_updates.md +0 -0
  156. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
  157. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
  158. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
  159. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
  160. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
  161. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
  162. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/terminal_tools.md +0 -0
  163. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/apply_patch.md +0 -0
  164. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/ask_user_choice.md +0 -0
  165. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_click.md +0 -0
  166. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_close.md +0 -0
  167. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_console_messages.md +0 -0
  168. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_drag.md +0 -0
  169. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_drop.md +0 -0
  170. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_evaluate.md +0 -0
  171. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_file_upload.md +0 -0
  172. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_fill_form.md +0 -0
  173. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_find.md +0 -0
  174. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_handle_dialog.md +0 -0
  175. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_hover.md +0 -0
  176. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_navigate.md +0 -0
  177. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_navigate_back.md +0 -0
  178. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_network_request.md +0 -0
  179. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_network_requests.md +0 -0
  180. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_press_key.md +0 -0
  181. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_resize.md +0 -0
  182. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_scroll.md +0 -0
  183. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_select_option.md +0 -0
  184. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_snapshot.md +0 -0
  185. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_tabs.md +0 -0
  186. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_take_screenshot.md +0 -0
  187. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_type.md +0 -0
  188. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_wait_for.md +0 -0
  189. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/build_backend.md +0 -0
  190. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/build_frontend.md +0 -0
  191. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/claude_edit.md +0 -0
  192. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/claude_write.md +0 -0
  193. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/dispatch_agent.md +0 -0
  194. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/edit.md +0 -0
  195. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/eval.md +0 -0
  196. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/exec_command.md +0 -0
  197. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/get_host.md +0 -0
  198. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/get_task_list.md +0 -0
  199. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/get_task_list_readonly.md +0 -0
  200. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/hashline_edit.md +0 -0
  201. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/hashline_write.md +0 -0
  202. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/kill_command.md +0 -0
  203. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/list_agents.md +0 -0
  204. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/list_sessions.md +0 -0
  205. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/list_subagent_models.md +0 -0
  206. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/list_workflow_runs.md +0 -0
  207. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/lsp.md +0 -0
  208. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/lsp_edit.md +0 -0
  209. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/multi_edit.md +0 -0
  210. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/read.md +0 -0
  211. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/read_image.md +0 -0
  212. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/resolve.md +0 -0
  213. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/run_workflow.md +0 -0
  214. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/send_message.md +0 -0
  215. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/set_goal.md +0 -0
  216. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/skill.md +0 -0
  217. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/snapshot.md +0 -0
  218. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/switch_worktree.md +0 -0
  219. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/update_task_list.md +0 -0
  220. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/web_fetch.md +0 -0
  221. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/web_search.md +0 -0
  222. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/write.md +0 -0
  223. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/write_plan.md +0 -0
  224. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/write_stdin.md +0 -0
  225. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
  226. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
  227. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompts.py +0 -0
  228. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/session_metadata.py +0 -0
  229. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/agent_tool.py +0 -0
  230. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/base_tool.py +0 -0
  231. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
  232. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/build_tool.py +0 -0
  233. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/codex_patch.py +0 -0
  234. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
  235. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/edit_tool.py +0 -0
  236. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/eval_tool.py +0 -0
  237. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/hashline_v2.py +0 -0
  238. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/lsp_tool.py +0 -0
  239. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
  240. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/network_status.py +0 -0
  241. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
  242. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
  243. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
  244. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
  245. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
  246. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
  247. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
  248. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
  249. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
  250. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
  251. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/snapshot_tool.py +0 -0
  252. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
  253. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
  254. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/__init__.py +0 -0
  255. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/answering.py +0 -0
  256. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/documents.py +0 -0
  257. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/extractors.py +0 -0
  258. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/pipeline.py +0 -0
  259. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/retrieval.py +0 -0
  260. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
  261. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
  262. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/workflow_tool.py +0 -0
  263. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_definitions.py +0 -0
  264. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tools.py +0 -0
  265. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/utils/commands.py +0 -0
  266. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/volatile_context.py +0 -0
  267. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/__init__.py +0 -0
  268. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/_jwt.py +0 -0
  269. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/chatgpt_oauth.py +0 -0
  270. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/constants.py +0 -0
  271. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/tokens.py +0 -0
  272. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/__init__.py +0 -0
  273. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/framing.py +0 -0
  274. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/installer.py +0 -0
  275. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/manager.py +0 -0
  276. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/multiplex.py +0 -0
  277. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/native_host.py +0 -0
  278. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/protocol.py +0 -0
  279. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/registry.py +0 -0
  280. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/runtime.py +0 -0
  281. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/__init__.py +0 -0
  282. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/acp.py +0 -0
  283. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/app.py +0 -0
  284. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/ask_output.py +0 -0
  285. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/atif_export.py +0 -0
  286. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/browser_backend.py +0 -0
  287. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/clipboard_image.py +0 -0
  288. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/config.py +0 -0
  289. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/connection.py +0 -0
  290. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/cron.py +0 -0
  291. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/diagnostics.py +0 -0
  292. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/file_index.py +0 -0
  293. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/gateway.py +0 -0
  294. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/goal.py +0 -0
  295. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/loop.py +0 -0
  296. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/mentions.py +0 -0
  297. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/messages.py +0 -0
  298. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/model_catalog.py +0 -0
  299. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/model_connection.py +0 -0
  300. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/peer_messaging.py +0 -0
  301. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/plan_artifacts.py +0 -0
  302. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/prompt_history.py +0 -0
  303. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_event_protocol.py +0 -0
  304. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_event_store.py +0 -0
  305. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_journal.py +0 -0
  306. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_store.py +0 -0
  307. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_usage.py +0 -0
  308. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/settings.py +0 -0
  309. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/skills.py +0 -0
  310. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/slash_commands.py +0 -0
  311. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/theme.py +0 -0
  312. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/__init__.py +0 -0
  313. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/agent_runtime.py +0 -0
  314. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/app_base.py +0 -0
  315. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/changes_screen.py +0 -0
  316. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/command_handlers.py +0 -0
  317. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/constants.py +0 -0
  318. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/custom_model.py +0 -0
  319. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/loop_runtime.py +0 -0
  320. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/memory_screen.py +0 -0
  321. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/onboarding_screen.py +0 -0
  322. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/pacing.py +0 -0
  323. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/prompt_flows.py +0 -0
  324. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/session_diff.py +0 -0
  325. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/state.py +0 -0
  326. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/status_dashboard.py +0 -0
  327. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/styles.tcss +0 -0
  328. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/sub_agent_screen.py +0 -0
  329. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/terminal_display.py +0 -0
  330. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/transcript.py +0 -0
  331. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/widgets.py +0 -0
  332. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/updater.py +0 -0
  333. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/config.py +0 -0
  334. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/events.py +0 -0
  335. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/extensions.py +0 -0
  336. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/__init__.py +0 -0
  337. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/access.py +0 -0
  338. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/__init__.py +0 -0
  339. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/base.py +0 -0
  340. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/echo.py +0 -0
  341. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/telegram/__init__.py +0 -0
  342. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/telegram/adapter.py +0 -0
  343. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/telegram/formatting.py +0 -0
  344. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/commands.py +0 -0
  345. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/config.py +0 -0
  346. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/control_relay.py +0 -0
  347. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/daemon.py +0 -0
  348. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/event_router.py +0 -0
  349. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/questions.py +0 -0
  350. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/redaction.py +0 -0
  351. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/router.py +0 -0
  352. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/sessions.py +0 -0
  353. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/stt.py +0 -0
  354. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/git_env.py +0 -0
  355. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/__init__.py +0 -0
  356. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/backends.py +0 -0
  357. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/config.py +0 -0
  358. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/dispatcher.py +0 -0
  359. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/events.py +0 -0
  360. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/matcher.py +0 -0
  361. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/outcome.py +0 -0
  362. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/client.py +0 -0
  363. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/exceptions.py +0 -0
  364. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/instrumented_client.py +0 -0
  365. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/ledger.py +0 -0
  366. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/models.py +0 -0
  367. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/__init__.py +0 -0
  368. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/_token_encoding.py +0 -0
  369. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/anthropic.py +0 -0
  370. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/base.py +0 -0
  371. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
  372. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/deepseek_responses.py +0 -0
  373. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/google.py +0 -0
  374. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/models.py +0 -0
  375. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/openai.py +0 -0
  376. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/openai_responses.py +0 -0
  377. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/perplexity_responses.py +0 -0
  378. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/responses_common.py +0 -0
  379. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/tinker.py +0 -0
  380. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/tinker_trace.py +0 -0
  381. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/ratelimit.py +0 -0
  382. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/__init__.py +0 -0
  383. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/accessors.py +0 -0
  384. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/__init__.py +0 -0
  385. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/anthropic.py +0 -0
  386. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/dashscope.py +0 -0
  387. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/deepseek.py +0 -0
  388. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/fireworks.py +0 -0
  389. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/google.py +0 -0
  390. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/groq.py +0 -0
  391. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/kimi_coding.py +0 -0
  392. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/moonshot.py +0 -0
  393. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/ollama_cloud.py +0 -0
  394. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/openrouter.py +0 -0
  395. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/perplexity_agent.py +0 -0
  396. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/thinking_machines.py +0 -0
  397. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/tinker.py +0 -0
  398. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/together.py +0 -0
  399. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/xai.py +0 -0
  400. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/zai.py +0 -0
  401. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/custom_endpoints.py +0 -0
  402. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/ollama_cloud_catalog.py +0 -0
  403. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/openrouter_catalog.py +0 -0
  404. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/perplexity_catalog.py +0 -0
  405. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/thinking.py +0 -0
  406. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/tinker_catalog.py +0 -0
  407. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/types.py +0 -0
  408. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/validation.py +0 -0
  409. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/timeouts.py +0 -0
  410. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/tool_execution_ids.py +0 -0
  411. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/usage.py +0 -0
  412. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/local_state.py +0 -0
  413. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/__init__.py +0 -0
  414. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/tools.py +0 -0
  415. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/transport.py +0 -0
  416. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/__init__.py +0 -0
  417. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/identity.py +0 -0
  418. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/manager.py +0 -0
  419. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/manifest.py +0 -0
  420. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/markdown.py +0 -0
  421. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/models.py +0 -0
  422. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/protocol.py +0 -0
  423. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/registry.py +0 -0
  424. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/models/__init__.py +0 -0
  425. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/models/sandbox_terminal_state.py +0 -0
  426. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/permissions.py +0 -0
  427. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/runtime.py +0 -0
  428. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/README.md +0 -0
  429. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/__init__.py +0 -0
  430. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/async_filesystem.py +0 -0
  431. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/base.py +0 -0
  432. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/browser.py +0 -0
  433. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/event_loop.py +0 -0
  434. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/filesystem.py +0 -0
  435. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/local.py +0 -0
  436. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/serializer.py +0 -0
  437. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/terminal.py +0 -0
  438. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/utils.py +0 -0
  439. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/scratchpad.py +0 -0
  440. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/security/__init__.py +0 -0
  441. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/security/secrets.py +0 -0
  442. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/base.py +0 -0
  443. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/browser.py +0 -0
  444. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/file_system.py +0 -0
  445. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/html.py +0 -0
  446. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/__init__.py +0 -0
  447. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/client.py +0 -0
  448. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/config.py +0 -0
  449. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/detector.py +0 -0
  450. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/diagnostics.py +0 -0
  451. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/edits.py +0 -0
  452. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/manager.py +0 -0
  453. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/registry.py +0 -0
  454. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/registry.yaml +0 -0
  455. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/snapshots.py +0 -0
  456. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/terminal.py +0 -0
  457. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/terminal_buffer.py +0 -0
  458. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/workspace_scan.py +0 -0
  459. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/__init__.py +0 -0
  460. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/control.py +0 -0
  461. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/inbox.py +0 -0
  462. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/inmemory.py +0 -0
  463. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/projection.py +0 -0
  464. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/recording.py +0 -0
  465. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/runtime.py +0 -0
  466. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/store.py +0 -0
  467. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/testing/__init__.py +0 -0
  468. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/testing/store_conformance.py +0 -0
  469. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/__init__.py +0 -0
  470. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/ask_user.py +0 -0
  471. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/core.py +0 -0
  472. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/definitions.py +0 -0
  473. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/param_aliases.py +0 -0
  474. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/registry.py +0 -0
  475. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/utils/__init__.py +0 -0
  476. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/utils/images.py +0 -0
  477. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/__init__.py +0 -0
  478. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/assets/fold.js +0 -0
  479. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/assets/player.css +0 -0
  480. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/assets/player.html +0 -0
  481. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/assets/player.js +0 -0
  482. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/bundle.py +0 -0
  483. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/hosting.py +0 -0
  484. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/redaction.py +0 -0
  485. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/server.py +0 -0
  486. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/singlefile.py +0 -0
  487. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/theme_css.py +0 -0
  488. {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/worktrees.py +0 -0
@@ -6,6 +6,45 @@ This project uses GitHub Releases for detailed generated release notes. This fil
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.36.0 - 2026-09-07
10
+
11
+ ### Added
12
+
13
+ - **GPT-6 Astra.** OpenAI's new flagship model is available on both the API
14
+ and ChatGPT-subscription providers: 1M-token context with 128K output,
15
+ vision, hosted web search, `codex_apply_patch` editing, and
16
+ `low`–`max` reasoning effort levels (default `medium`). The
17
+ ChatGPT-subscription route keeps the conservative 400K input budget until
18
+ Astra's larger window is verified on the Codex backend.
19
+ - **Pre-registered OAuth credentials for remote MCP servers.** Servers that
20
+ don't implement Dynamic Client Registration (HubSpot, Slack, GitHub
21
+ Copilot, enterprise IdPs) can now be connected with a pre-registered
22
+ client: new `--oauth-client-id`, `--oauth-client-secret`,
23
+ `--oauth-client-secret-env`, and `--oauth-auth-method` flags on
24
+ `kolega-code mcp add`, matching OAuth controls on the MCP page in TUI
25
+ settings, preserved explicit redirect ports/hosts, actionable diagnostics
26
+ when registration fails, and PBKDF2-salted OAuth cache fingerprints with
27
+ refresh tokens preserved across reconnects.
28
+
29
+ ### Fixed
30
+
31
+ - **Gateway (Telegram):** the typing indicator now stays alive for the whole
32
+ turn. Telegram expires typing actions after ~5 seconds, so it previously
33
+ vanished during exactly the stretches where feedback matters — model
34
+ thinking before the first chunk and long-running tool calls.
35
+
36
+ ## 0.35.1 - 2026-09-03
37
+
38
+ ### Fixed
39
+
40
+ - **Gateway (Telegram):** the tool-activity status now re-appears below the
41
+ newest reply bubble. Previously it stayed stranded in an older message once
42
+ a reply opened, so later tool calls looked detached from the conversation.
43
+ Adapters without message-delete support keep the edit-in-place behavior.
44
+ - **Gateway service:** the background daemon now launches through the user's
45
+ login shell, so gateway-driven agent sessions see user-installed tools such
46
+ as Homebrew instead of the minimal `PATH` that launchd and systemd provide.
47
+
9
48
  ## 0.35.0 - 2026-09-03
10
49
 
11
50
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kolega-code
3
- Version: 0.35.0
3
+ Version: 0.36.0
4
4
  Summary: Multi-agent coding in the terminal
5
5
  Project-URL: Homepage, https://kolega-ai.github.io/kolega-code/
6
6
  Project-URL: Documentation, https://kolega-ai.github.io/kolega-code/
@@ -174,4 +174,4 @@ __all__ = [
174
174
  "parse_git_status_output",
175
175
  ]
176
176
 
177
- __version__ = "0.35.0"
177
+ __version__ = "0.36.0"
@@ -51,4 +51,4 @@ __all__ = [
51
51
  "ToolExtension",
52
52
  ]
53
53
 
54
- __version__ = "0.35.0"
54
+ __version__ = "0.36.0"
@@ -796,6 +796,14 @@ def _build_subcommand_parser() -> argparse.ArgumentParser:
796
796
  add.add_argument("--env", action="append", default=[], help="Environment variable as NAME=VALUE (repeatable).")
797
797
  add.add_argument("--cwd", help="Working directory for stdio command; relative paths resolve under project.")
798
798
  add.add_argument("--oauth", action="store_true", help="Enable OAuth for this HTTP MCP server.")
799
+ add.add_argument("--oauth-client-id", help="Pre-registered OAuth client ID.")
800
+ add.add_argument("--oauth-client-secret", help="Pre-registered OAuth client secret.")
801
+ add.add_argument("--oauth-client-secret-env", help="Environment variable name holding the OAuth client secret.")
802
+ add.add_argument(
803
+ "--oauth-auth-method",
804
+ choices=["client_secret_post", "client_secret_basic", "none"],
805
+ help="Token endpoint authentication method.",
806
+ )
799
807
  add.add_argument("--oauth-scope", help="OAuth scopes to request.")
800
808
  add.add_argument("--redirect-uri", help="OAuth redirect URI; defaults to an ephemeral localhost callback.")
801
809
  add.add_argument("--disabled", action="store_true", help="Add the server disabled.")
@@ -2697,6 +2705,12 @@ def _mcp_mutation_target(args: argparse.Namespace, project_path: Path, state_dir
2697
2705
  def _server_config_from_add_args(args: argparse.Namespace) -> MCPServerConfig:
2698
2706
  headers = _parse_key_value_options(getattr(args, "header", []) or [], "--header")
2699
2707
  env = _parse_key_value_options(getattr(args, "env", []) or [], "--env")
2708
+ oauth_client_id = getattr(args, "oauth_client_id", None)
2709
+ oauth_client_secret = getattr(args, "oauth_client_secret", None)
2710
+ oauth_client_secret_env = getattr(args, "oauth_client_secret_env", None)
2711
+ oauth_auth_method = getattr(args, "oauth_auth_method", None)
2712
+ oauth_enabled = bool(args.oauth) or bool(oauth_client_id or oauth_client_secret or oauth_client_secret_env)
2713
+
2700
2714
  payload: dict[str, Any] = {
2701
2715
  "id": args.server_id,
2702
2716
  "name": args.name,
@@ -2709,9 +2723,13 @@ def _server_config_from_add_args(args: argparse.Namespace) -> MCPServerConfig:
2709
2723
  "env": env,
2710
2724
  "cwd": args.cwd,
2711
2725
  "oauth": {
2712
- "enabled": bool(args.oauth),
2726
+ "enabled": oauth_enabled,
2713
2727
  "scope": args.oauth_scope,
2714
2728
  "redirect_uri": args.redirect_uri,
2729
+ "client_id": oauth_client_id,
2730
+ "client_secret": oauth_client_secret,
2731
+ "client_secret_env": oauth_client_secret_env,
2732
+ "token_endpoint_auth_method": oauth_auth_method,
2715
2733
  },
2716
2734
  }
2717
2735
  return MCPServerConfig.model_validate(payload)
@@ -90,6 +90,7 @@ MODEL_LABELS: dict[str, str] = {
90
90
  "claude-opus-4-5-20251101": "Claude Opus 4.5",
91
91
  "claude-haiku-4-5-20251001": "Claude Haiku 4.5",
92
92
  # OpenAI (shared labels across the API and ChatGPT-subscription providers)
93
+ "gpt-6-astra": "GPT-6 Astra",
93
94
  "gpt-5.6-sol": "GPT-5.6 Sol",
94
95
  "gpt-5.6-terra": "GPT-5.6 Terra",
95
96
  "gpt-5.6-luna": "GPT-5.6 Luna",
@@ -104,6 +104,12 @@ MCP_TRANSPORT_OPTIONS = [
104
104
  ("stdio command", "stdio"),
105
105
  ]
106
106
  MCP_ENABLED_OPTIONS = [("Enabled", "true"), ("Disabled", "false")]
107
+ MCP_OAUTH_AUTH_METHOD_OPTIONS = [
108
+ ("Auto (POST if secret, none if public)", "auto"),
109
+ ("client_secret_post", "client_secret_post"),
110
+ ("client_secret_basic", "client_secret_basic"),
111
+ ("none (public client / PKCE)", "none"),
112
+ ]
107
113
  MCP_STATUS_MESSAGE_MAX = 96
108
114
  MCP_STATUS_NAME_MAX = 34
109
115
  # Compression threshold select: "default" maps to None (the agent's built-in 95%).
@@ -417,6 +423,16 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
417
423
  self._update_mcp_transport_fields(str(event.value))
418
424
  return
419
425
 
426
+ if select_id == "mcp_oauth_select":
427
+ transport = "streamable_http"
428
+ try:
429
+ transport = str(self._settings_query_one("#mcp_transport_select", Select).value)
430
+ except NoMatches:
431
+ pass
432
+ http = transport in {"streamable_http", "sse"}
433
+ self._update_mcp_oauth_fields(http and str(event.value) == "true")
434
+ return
435
+
420
436
  row = _row_for_widget(select_id)
421
437
  if row is not None and select_id == row.provider_id:
422
438
  provider = str(event.value)
@@ -1477,6 +1493,12 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
1477
1493
  set_input("mcp_url_input", "")
1478
1494
  set_input("mcp_headers_input", "")
1479
1495
  set_select("mcp_oauth_select", "false")
1496
+ set_input("mcp_oauth_client_id_input", "")
1497
+ set_input("mcp_oauth_client_secret_input", "")
1498
+ set_input("mcp_oauth_client_secret_env_input", "")
1499
+ set_input("mcp_oauth_redirect_uri_input", "")
1500
+ set_input("mcp_oauth_scope_input", "")
1501
+ set_select("mcp_oauth_auth_method_select", "auto")
1480
1502
  set_input("mcp_command_input", "")
1481
1503
  set_input("mcp_args_input", "")
1482
1504
  set_input("mcp_env_input", "")
@@ -1491,6 +1513,12 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
1491
1513
  set_input("mcp_url_input", server.url or "")
1492
1514
  set_input("mcp_headers_input", json.dumps(server.headers, sort_keys=True) if server.headers else "")
1493
1515
  set_select("mcp_oauth_select", "true" if server.oauth.enabled else "false")
1516
+ set_input("mcp_oauth_client_id_input", server.oauth.client_id or "")
1517
+ set_input("mcp_oauth_client_secret_input", server.oauth.client_secret or "")
1518
+ set_input("mcp_oauth_client_secret_env_input", server.oauth.client_secret_env or "")
1519
+ set_input("mcp_oauth_redirect_uri_input", server.oauth.redirect_uri or "")
1520
+ set_input("mcp_oauth_scope_input", server.oauth.scope or "")
1521
+ set_select("mcp_oauth_auth_method_select", server.oauth.token_endpoint_auth_method or "auto")
1494
1522
  set_input("mcp_command_input", server.command or "")
1495
1523
  set_input("mcp_args_input", " ".join(shlex.quote(arg) for arg in server.args))
1496
1524
  set_input("mcp_env_input", json.dumps(server.env, sort_keys=True) if server.env else "")
@@ -1503,6 +1531,26 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
1503
1531
  self._set_mcp_source_hint("This server is stored in your global MCP config.")
1504
1532
  self._update_mcp_transport_fields(server.transport)
1505
1533
 
1534
+ def _update_mcp_oauth_fields(self, visible: bool) -> None:
1535
+ for widget_id in (
1536
+ "mcp_oauth_client_id_label",
1537
+ "mcp_oauth_client_id_input",
1538
+ "mcp_oauth_client_secret_label",
1539
+ "mcp_oauth_client_secret_input",
1540
+ "mcp_oauth_client_secret_env_label",
1541
+ "mcp_oauth_client_secret_env_input",
1542
+ "mcp_oauth_redirect_uri_label",
1543
+ "mcp_oauth_redirect_uri_input",
1544
+ "mcp_oauth_scope_label",
1545
+ "mcp_oauth_scope_input",
1546
+ "mcp_oauth_auth_method_label",
1547
+ "mcp_oauth_auth_method_select",
1548
+ ):
1549
+ try:
1550
+ self._settings_query_one(f"#{widget_id}").display = visible
1551
+ except NoMatches:
1552
+ pass
1553
+
1506
1554
  def _update_mcp_transport_fields(self, transport: str) -> None:
1507
1555
  http = transport in {"streamable_http", "sse"}
1508
1556
  for widget_id, visible in (
@@ -1525,6 +1573,12 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
1525
1573
  self._settings_query_one(f"#{widget_id}").display = visible
1526
1574
  except NoMatches:
1527
1575
  pass
1576
+ oauth_enabled = False
1577
+ try:
1578
+ oauth_enabled = http and str(self._settings_query_one("#mcp_oauth_select", Select).value) == "true"
1579
+ except NoMatches:
1580
+ pass
1581
+ self._update_mcp_oauth_fields(oauth_enabled)
1528
1582
  try:
1529
1583
  url_input = self._settings_query_one("#mcp_url_input", Input)
1530
1584
  if transport == "streamable_http":
@@ -1621,7 +1675,8 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
1621
1675
  enabled = str(self._settings_query_one("#mcp_enabled_select", Select).value) == "true"
1622
1676
  url = self._settings_query_one("#mcp_url_input", Input).value.strip() or None
1623
1677
  headers_text = self._settings_query_one("#mcp_headers_input", Input).value.strip()
1624
- oauth_enabled = str(self._settings_query_one("#mcp_oauth_select", Select).value) == "true"
1678
+ http = transport in {"streamable_http", "sse"}
1679
+ oauth_enabled = http and str(self._settings_query_one("#mcp_oauth_select", Select).value) == "true"
1625
1680
  command = self._settings_query_one("#mcp_command_input", Input).value.strip() or None
1626
1681
  args_text = self._settings_query_one("#mcp_args_input", Input).value.strip()
1627
1682
  env_text = self._settings_query_one("#mcp_env_input", Input).value.strip()
@@ -1640,6 +1695,77 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
1640
1695
  else selected
1641
1696
  )
1642
1697
 
1698
+ oauth_client_id = None
1699
+ oauth_client_secret = None
1700
+ oauth_client_secret_env = None
1701
+ oauth_redirect_uri = None
1702
+ oauth_scope = None
1703
+ oauth_auth_method: Optional[Literal["client_secret_post", "client_secret_basic", "none"]] = None
1704
+
1705
+ if http:
1706
+ try:
1707
+ oauth_client_id = self._settings_query_one("#mcp_oauth_client_id_input", Input).value.strip() or None
1708
+ except NoMatches:
1709
+ pass
1710
+ try:
1711
+ oauth_client_secret = (
1712
+ self._settings_query_one("#mcp_oauth_client_secret_input", Input).value.strip() or None
1713
+ )
1714
+ except NoMatches:
1715
+ pass
1716
+ try:
1717
+ oauth_client_secret_env = (
1718
+ self._settings_query_one("#mcp_oauth_client_secret_env_input", Input).value.strip() or None
1719
+ )
1720
+ except NoMatches:
1721
+ pass
1722
+ try:
1723
+ oauth_redirect_uri = (
1724
+ self._settings_query_one("#mcp_oauth_redirect_uri_input", Input).value.strip() or None
1725
+ )
1726
+ except NoMatches:
1727
+ pass
1728
+ try:
1729
+ oauth_scope = self._settings_query_one("#mcp_oauth_scope_input", Input).value.strip() or None
1730
+ except NoMatches:
1731
+ pass
1732
+ try:
1733
+ method_val = str(self._settings_query_one("#mcp_oauth_auth_method_select", Select).value)
1734
+ if method_val in {"client_secret_post", "client_secret_basic", "none"}:
1735
+ oauth_auth_method = cast(Literal["client_secret_post", "client_secret_basic", "none"], method_val)
1736
+ except NoMatches:
1737
+ pass
1738
+
1739
+ client_name = "Kolega Code"
1740
+ client_uri = None
1741
+ client_metadata_url = None
1742
+ timeout_seconds = 300.0
1743
+ if selected != MCP_NEW_SERVER_VALUE:
1744
+ try:
1745
+ config = self._load_mcp_config_for_ui()
1746
+ existing = config.servers.get(selected)
1747
+ if existing:
1748
+ client_name = existing.oauth.client_name
1749
+ client_uri = existing.oauth.client_uri
1750
+ client_metadata_url = existing.oauth.client_metadata_url
1751
+ timeout_seconds = existing.oauth.timeout_seconds
1752
+ except Exception:
1753
+ pass
1754
+
1755
+ oauth = MCPOAuthConfig(
1756
+ enabled=oauth_enabled,
1757
+ client_id=oauth_client_id,
1758
+ client_secret=oauth_client_secret,
1759
+ client_secret_env=oauth_client_secret_env,
1760
+ redirect_uri=oauth_redirect_uri,
1761
+ scope=oauth_scope,
1762
+ token_endpoint_auth_method=oauth_auth_method,
1763
+ client_name=client_name,
1764
+ client_uri=client_uri,
1765
+ client_metadata_url=client_metadata_url,
1766
+ timeout_seconds=timeout_seconds,
1767
+ )
1768
+
1643
1769
  return MCPServerConfig(
1644
1770
  id=server_id,
1645
1771
  name=name,
@@ -1647,7 +1773,7 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
1647
1773
  enabled=enabled,
1648
1774
  url=url,
1649
1775
  headers=headers,
1650
- oauth=MCPOAuthConfig(enabled=oauth_enabled),
1776
+ oauth=oauth,
1651
1777
  command=command,
1652
1778
  args=args,
1653
1779
  env=env,
@@ -588,6 +588,26 @@ class SettingsScreen(ModalScreen[None]):
588
588
  allow_blank=False,
589
589
  value="false",
590
590
  )
591
+ yield Label("OAuth Client ID", id="mcp_oauth_client_id_label")
592
+ yield Input(id="mcp_oauth_client_id_input", placeholder="e.g. client_abc123")
593
+ yield Label("OAuth Client Secret", id="mcp_oauth_client_secret_label")
594
+ yield Input(id="mcp_oauth_client_secret_input", placeholder="optional direct secret", password=True)
595
+ yield Label("OAuth Client Secret Env Var", id="mcp_oauth_client_secret_env_label")
596
+ yield Input(id="mcp_oauth_client_secret_env_input", placeholder="e.g. HUBSPOT_MCP_CLIENT_SECRET")
597
+ yield Label("OAuth Redirect URI", id="mcp_oauth_redirect_uri_label")
598
+ yield Input(
599
+ id="mcp_oauth_redirect_uri_input",
600
+ placeholder="e.g. http://127.0.0.1:33418/callback (default: ephemeral port)",
601
+ )
602
+ yield Label("OAuth Scopes", id="mcp_oauth_scope_label")
603
+ yield Input(id="mcp_oauth_scope_input", placeholder="e.g. read write")
604
+ yield Label("OAuth Token Auth Method", id="mcp_oauth_auth_method_label")
605
+ yield Select(
606
+ settings_panel.MCP_OAUTH_AUTH_METHOD_OPTIONS,
607
+ id="mcp_oauth_auth_method_select",
608
+ allow_blank=False,
609
+ value="auto",
610
+ )
591
611
  yield Label("Command", id="mcp_command_label")
592
612
  yield Input(id="mcp_command_input", placeholder="npx")
593
613
  yield Label("Arguments", id="mcp_args_label")
@@ -12,10 +12,16 @@ turns:
12
12
  - a placeholder reply is created on first content and edited in place on a
13
13
  throttle until the turn ends (final-only transports get one message at the
14
14
  end);
15
- - tool activity lands in a separate "working…" status message, edited as
16
- events arrive and deleted when the turn finishes;
15
+ - each round of tool activity lands in its own "working…" message below the
16
+ newest reply bubble: a round that starts after text was streamed opens a
17
+ fresh message (Telegram cannot move messages, so appending to an older one
18
+ would surface above the latest text), and the messages persist as a trail
19
+ of what the agent did during the turn;
17
20
  - text is chunked at the adapter's limit; the first chunk is the edited
18
- message and overflow chunks are sent as continuations on finalize.
21
+ message and overflow chunks are sent as continuations on finalize;
22
+ - a typing action is re-sent every few seconds for the whole turn (chat
23
+ platforms expire it after ~5s), so thinking and long tool runs keep
24
+ showing "typing…" until the reply lands.
19
25
 
20
26
  Chunk content is *incremental*, so the renderer appends and re-renders the
21
27
  accumulated text — it never replaces with the last segment.
@@ -34,10 +40,14 @@ from kolega_code.gateway.adapters.telegram.formatting import chunk_text
34
40
 
35
41
  logger = logging.getLogger(__name__)
36
42
 
37
- #: Cap on status-message lines so a chatty turn cannot spam an unbounded edit.
43
+ #: Cap on a round message's lines so a chatty turn cannot spam an unbounded edit.
38
44
  MAX_STATUS_LINES = 8
39
- #: Events the status pump renders; everything else on the stream is ignored.
40
- STATUS_MESSAGE_TYPES = {"tool_call", "tool_result", "tool_error"}
45
+ #: Chat platforms expire a typing action after ~5 seconds (Telegram: "status
46
+ #: is set for 5 seconds or less"); refresh slightly faster so the indicator
47
+ #: never lapses while a turn is in progress.
48
+ TYPING_REFRESH_SECONDS = 4.0
49
+ #: Rendered status line: (icon, tool description, tool call id).
50
+ StatusLine = tuple[str, str, str]
41
51
 
42
52
 
43
53
  class TurnRenderer:
@@ -51,6 +61,7 @@ class TurnRenderer:
51
61
  event_queue: asyncio.Queue[AgentEvent],
52
62
  chunk_limit: Optional[int] = None,
53
63
  edit_throttle_seconds: float = 1.0,
64
+ typing_refresh_seconds: float = TYPING_REFRESH_SECONDS,
54
65
  monotonic: Any = time.monotonic,
55
66
  ) -> None:
56
67
  self._adapter = adapter
@@ -58,6 +69,7 @@ class TurnRenderer:
58
69
  self._events = event_queue
59
70
  self._chunk_limit = chunk_limit or adapter.capabilities.text_chunk_limit
60
71
  self._edit_throttle = edit_throttle_seconds
72
+ self._typing_refresh = typing_refresh_seconds
61
73
  self._monotonic = monotonic
62
74
  # Per-segment state, mirroring the TUI's stream fold: a segment is one
63
75
  # contiguous assistant response identified by its chunk uuid (the
@@ -69,10 +81,17 @@ class TurnRenderer:
69
81
  self._reply_id: Optional[str] = None
70
82
  self._edited_text = ""
71
83
  self._last_flush = 0.0
84
+ #: The current tool round's message, one per burst of tool activity.
85
+ #: Older rounds' messages stay in the chat as a trail of the turn.
72
86
  self._status_id: Optional[str] = None
73
- self._status_lines: list[str] = []
87
+ self._status_lines: list[StatusLine] = []
74
88
  self._status_sent_text = ""
75
89
  self._last_status_flush = 0.0
90
+ #: Set when a reply message was sent after the current round message:
91
+ #: the next tool event then opens a fresh round message below the
92
+ #: newest bubble (Telegram cannot move messages) instead of appending
93
+ #: to the stale one higher up the chat.
94
+ self._status_stale = False
76
95
 
77
96
  async def run(self, chunks: AsyncIterator[dict[str, Any]]) -> str:
78
97
  """Consume the turn generator and mirror it into the chat.
@@ -82,10 +101,12 @@ class TurnRenderer:
82
101
  reply stays visible.
83
102
  """
84
103
  pump: Optional[asyncio.Task[None]] = None
104
+ typing: Optional[asyncio.Task[None]] = None
85
105
  if self._events is not None:
86
106
  pump = asyncio.create_task(self._event_pump(), name="gateway-turn-event-pump")
87
107
  try:
88
108
  await self._adapter.set_typing(self._chat_id, True)
109
+ typing = asyncio.create_task(self._typing_keepalive(), name="gateway-turn-typing")
89
110
  async for chunk in chunks:
90
111
  if chunk.get("type") != "response":
91
112
  # Thinking chunks stay off the wire; they are reasoning, not output.
@@ -111,14 +132,30 @@ class TurnRenderer:
111
132
  await self._finalize_segment()
112
133
  return self._total_text
113
134
  finally:
114
- if pump is not None:
115
- pump.cancel()
116
- try:
117
- await pump
118
- except asyncio.CancelledError:
119
- pass
135
+ for task in (pump, typing):
136
+ if task is not None:
137
+ task.cancel()
138
+ try:
139
+ await task
140
+ except asyncio.CancelledError:
141
+ pass
120
142
  await self._adapter.set_typing(self._chat_id, False)
121
- await self._finalize_status()
143
+
144
+ async def _typing_keepalive(self) -> None:
145
+ """Re-send the typing action so the indicator outlives its ~5s expiry.
146
+
147
+ Covers the silent stretches of a turn — model thinking before the
148
+ first chunk and long-running tool calls, where no message is sent or
149
+ edited. Refresh only (never hides: the ``False`` call is the
150
+ adapter's business); a failing adapter must not end the loop, since
151
+ typing is cosmetic.
152
+ """
153
+ while True:
154
+ await asyncio.sleep(self._typing_refresh)
155
+ try:
156
+ await self._adapter.set_typing(self._chat_id, True)
157
+ except Exception: # noqa: BLE001 — typing indicators are cosmetic
158
+ logger.debug("gateway: typing refresh failed", exc_info=True)
122
159
 
123
160
  # -- Reply messages (one per response segment) -------------------------
124
161
 
@@ -144,6 +181,7 @@ class TurnRenderer:
144
181
  return # final-only transports send once, at the end
145
182
  self._reply_id = await self._adapter.send_text(self._chat_id, chunks[0])
146
183
  self._edited_text = chunks[0]
184
+ self._status_stale = True
147
185
  return
148
186
  if not final:
149
187
  if len(chunks) > 1:
@@ -155,6 +193,7 @@ class TurnRenderer:
155
193
  await self._edit_reply(chunks[0])
156
194
  for extra in chunks[1:]:
157
195
  await self._adapter.send_text(self._chat_id, extra)
196
+ self._status_stale = True
158
197
 
159
198
  async def _edit_reply(self, text: str) -> None:
160
199
  if text == self._edited_text:
@@ -163,39 +202,58 @@ class TurnRenderer:
163
202
  await self._adapter.edit_text(self._chat_id, self._reply_id or "", text)
164
203
  self._edited_text = text
165
204
 
166
- # -- Tool status message ----------------------------------------------
205
+ # -- Tool round messages ----------------------------------------------
167
206
 
168
207
  async def _event_pump(self) -> None:
169
208
  try:
170
209
  while True:
171
210
  event = await self._events.get()
172
- line = self._status_line_for(event)
173
- if line is None:
211
+ record = self._line_record_for(event)
212
+ if record is None:
174
213
  continue
175
- self._status_lines.append(line)
176
- self._status_lines = self._status_lines[-MAX_STATUS_LINES:]
214
+ if self._status_stale:
215
+ # The newest reply bubble was sent after the current round
216
+ # message: open a fresh round message below it instead of
217
+ # appending to the stale one higher up the chat.
218
+ self._status_stale = False
219
+ self._status_id = None
220
+ self._status_lines = []
221
+ self._record_line(record)
177
222
  await self._flush_status()
178
223
  except asyncio.CancelledError:
179
224
  raise
180
225
 
181
226
  @staticmethod
182
- def _status_line_for(event: AgentEvent) -> Optional[str]:
227
+ def _line_record_for(event: AgentEvent) -> Optional[StatusLine]:
183
228
  if event.event_type != "chat_message":
184
229
  return None
185
230
  message_type = event.content.get("message_type")
231
+ description = str(event.content.get("tool_description") or "tool")
232
+ call_id = str(event.content.get("tool_call_id") or "")
186
233
  if message_type == "tool_call":
187
- description = event.content.get("tool_description") or "tool"
188
- return f"⏳ {description}"
234
+ return ("⏳", description, call_id)
189
235
  if message_type == "tool_result":
190
- return "✅ tool finished"
236
+ return ("✅", description, call_id)
191
237
  if message_type == "tool_error":
192
- return "❌ tool failed"
238
+ return ("❌", description, call_id)
193
239
  return None
194
240
 
241
+ def _record_line(self, record: StatusLine) -> None:
242
+ icon, _, call_id = record
243
+ if icon != "⏳" and call_id:
244
+ # A finished call replaces its pending line so the round message
245
+ # reads as a settled trail (⏳ bash -> ✅ bash), not an append log.
246
+ for index, (pending_icon, _, pending_id) in enumerate(self._status_lines):
247
+ if pending_icon == "⏳" and pending_id == call_id:
248
+ self._status_lines[index] = record
249
+ return
250
+ self._status_lines.append(record)
251
+ self._status_lines = self._status_lines[-MAX_STATUS_LINES:]
252
+
195
253
  async def _flush_status(self) -> None:
196
254
  if not self._status_lines:
197
255
  return
198
- text = "\n".join(self._status_lines)
256
+ text = "\n".join(f"{icon} {description}" for icon, description, _ in self._status_lines)
199
257
  if text == self._status_sent_text:
200
258
  # Line-cap truncation can make a new event's rendered text
201
259
  # identical to the previous one; re-sending the same content is a
@@ -206,20 +264,10 @@ class TurnRenderer:
206
264
  return
207
265
  self._last_status_flush = now
208
266
  if self._status_id is None:
209
- # No status message on transports that cannot edit it away.
267
+ # No round message on transports that cannot edit it away.
210
268
  if not self._adapter.capabilities.supports_edits:
211
269
  return
212
270
  self._status_id = await self._adapter.send_text(self._chat_id, text)
213
271
  else:
214
272
  await self._adapter.edit_text(self._chat_id, self._status_id, text)
215
273
  self._status_sent_text = text
216
-
217
- async def _finalize_status(self) -> None:
218
- if self._status_id is None:
219
- return
220
- message_id, self._status_id = self._status_id, None
221
- if self._adapter.capabilities.supports_delete:
222
- try:
223
- await self._adapter.delete_message(self._chat_id, message_id)
224
- except Exception: # noqa: BLE001 — a stuck status message is cosmetic
225
- logger.debug("gateway: status delete failed for chat %s", self._chat_id)
@@ -50,6 +50,34 @@ class ServiceInstallResult:
50
50
  unit_path: Optional[Path] = None
51
51
 
52
52
 
53
+ def login_shell(platform: Optional[str] = None) -> str:
54
+ """The user's login shell: ``$SHELL`` when set, else the platform default.
55
+
56
+ launchd and systemd start service programs directly, so the daemon would
57
+ inherit the service manager's minimal environment (launchd gives agents
58
+ ``PATH=/usr/bin:/bin:/usr/sbin:/sbin``), which starves gateway-driven
59
+ agent sessions of Homebrew and other user-installed tools. The service
60
+ therefore launches through the user's login shell: ``-l`` runs the shell
61
+ profile files, so the daemon's environment matches what an interactive
62
+ terminal sees, and nothing is captured at install time.
63
+ """
64
+ platform = platform if platform is not None else sys.platform
65
+ from_env = os.environ.get("SHELL")
66
+ if from_env:
67
+ return from_env
68
+ return "/bin/zsh" if platform == "darwin" else "/bin/bash"
69
+
70
+
71
+ def service_launch_command(config: GatewayConfig, executable: str, *, shell: str) -> list[str]:
72
+ """The service-level argv: the login shell exec-ing the daemon.
73
+
74
+ ``exec`` replaces the shell process, so termination signals reach the
75
+ daemon directly and launchd/KeepAlive track the real process.
76
+ """
77
+ inner = " ".join(shlex.quote(part) for part in service_command(config, executable))
78
+ return [shell, "-l", "-c", f"exec {inner}"]
79
+
80
+
53
81
  def service_command(config: GatewayConfig, executable: str) -> list[str]:
54
82
  """The exact argv the service runs."""
55
83
  return [
@@ -69,6 +97,7 @@ def install_service(
69
97
  config: GatewayConfig,
70
98
  *,
71
99
  executable: Optional[str] = None,
100
+ shell: Optional[str] = None,
72
101
  systemd_dir: Optional[Path] = None,
73
102
  launchd_dir: Optional[Path] = None,
74
103
  platform: Optional[str] = None,
@@ -76,12 +105,16 @@ def install_service(
76
105
  """Write the service definition.
77
106
 
78
107
  ``systemd_dir``/``launchd_dir`` are the unit destination directories;
79
- callers resolve the platform defaults (tests pass temp dirs).
108
+ callers resolve the platform defaults (tests pass temp dirs). ``shell``
109
+ overrides the login shell the service launches through (tests pass one
110
+ for determinism); by default the user's ``$SHELL`` or the platform
111
+ default is used.
80
112
  """
81
113
  platform = platform if platform is not None else sys.platform
82
114
  executable = executable or shutil.which("kolega-code") or ""
83
115
  if not executable:
84
116
  raise RuntimeError("kolega-code executable not found; is it on PATH?")
117
+ launch_shell = shell or login_shell(platform)
85
118
  config.state_dir.mkdir(parents=True, exist_ok=True)
86
119
  result = ServiceInstallResult()
87
120
  if platform == "darwin":
@@ -90,7 +123,7 @@ def install_service(
90
123
  plist_path = launchd_dir / LAUNCHD_PLIST_NAME
91
124
  plist: dict[str, object] = {
92
125
  "Label": LAUNCHD_LABEL,
93
- "ProgramArguments": service_command(config, executable),
126
+ "ProgramArguments": service_launch_command(config, executable, shell=launch_shell),
94
127
  "RunAtLoad": True,
95
128
  "KeepAlive": True,
96
129
  "StandardOutPath": str(config.state_dir / "gateway.log"),
@@ -103,10 +136,14 @@ def install_service(
103
136
  systemd_dir = systemd_dir or (Path.home() / ".config" / "systemd" / "user")
104
137
  systemd_dir.mkdir(parents=True, exist_ok=True)
105
138
  unit_path = systemd_dir / SYSTEMD_UNIT_NAME
106
- command = " ".join(shlex.quote(part) for part in service_command(config, executable))
139
+ command = " ".join(shlex.quote(part) for part in service_launch_command(config, executable, shell=launch_shell))
107
140
  unit_path.write_text(_SYSTEMD_UNIT_TEMPLATE.format(command=command), encoding="utf-8")
108
141
  result.unit_path = unit_path
109
142
  result.notes.append(f"systemd user unit written to {unit_path}")
143
+ result.notes.append(
144
+ f"the service launches via your login shell ({launch_shell}), so it inherits your "
145
+ "normal terminal environment; restart it after changing your shell profile"
146
+ )
110
147
  result.notes.append(
111
148
  "the service reads settings.json from the same state dir — make sure your provider "
112
149
  "API keys are saved in Settings (they apply to the gateway too)"