kon-coding-agent 0.3.10__tar.gz → 0.3.11__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 (180) hide show
  1. {kon_coding_agent-0.3.10/.kon → kon_coding_agent-0.3.11/.agents}/skills/kon-tmux-test/SKILL.md +1 -1
  2. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/CHANGELOG.md +32 -0
  3. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/PKG-INFO +1 -1
  4. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/pyproject.toml +1 -1
  5. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/scripts/show_themes.py +1 -1
  6. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/__init__.py +8 -0
  7. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/builtin_skills/init/SKILL.md +1 -1
  8. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/config.py +66 -3
  9. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/agent_mds.py +15 -13
  10. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/skills.py +42 -12
  11. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/defaults/config.toml +12 -4
  12. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/__init__.py +2 -0
  13. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/base.py +20 -0
  14. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/models.py +10 -0
  15. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/oauth/__init__.py +2 -0
  16. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/oauth/copilot.py +3 -1
  17. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/oauth/openai.py +10 -5
  18. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/anthropic.py +65 -37
  19. kon_coding_agent-0.3.11/src/kon/llm/providers/anthropic_capabilities.py +121 -0
  20. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/azure_ai_foundry.py +4 -2
  21. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/copilot_anthropic.py +24 -20
  22. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/openai_codex_responses.py +366 -32
  23. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/openai_completions.py +9 -1
  24. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/openai_responses.py +2 -1
  25. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/runtime.py +20 -18
  26. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/session.py +2 -3
  27. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/themes.py +240 -6
  28. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools_manager.py +5 -9
  29. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/turn.py +21 -0
  30. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/app.py +80 -33
  31. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/blocks.py +4 -1
  32. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/chat.py +41 -37
  33. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/commands.py +112 -59
  34. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/export.py +2 -2
  35. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/floating_list.py +21 -27
  36. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/formatting.py +82 -0
  37. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/prompt_history.py +2 -2
  38. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/styles.py +5 -0
  39. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/conftest.py +7 -0
  40. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/context/test_skills.py +10 -9
  41. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/test_anthropic_provider.py +75 -2
  42. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/test_openai_codex_provider_errors.py +334 -3
  43. kon_coding_agent-0.3.11/tests/llm/test_openai_oauth.py +86 -0
  44. kon_coding_agent-0.3.11/tests/llm/test_tls_verify.py +44 -0
  45. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_cli_auth_flags.py +9 -0
  46. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_cli_provider_resolution.py +1 -8
  47. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_compaction.py +10 -0
  48. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_config_error_fallback.py +6 -5
  49. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_config_migration.py +7 -9
  50. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_local_auth_config.py +1 -1
  51. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_notifications_config.py +1 -1
  52. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_openai_compat.py +1 -1
  53. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_runtime_switch_model.py +44 -1
  54. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_system_prompt.py +1 -1
  55. kon_coding_agent-0.3.11/tests/test_tools_manager.py +42 -0
  56. kon_coding_agent-0.3.11/tests/ui/test_completion_chrome.py +486 -0
  57. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_floating_list.py +17 -0
  58. kon_coding_agent-0.3.11/tests/ui/test_login_command.py +189 -0
  59. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_permission_selection_status.py +3 -2
  60. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_permissions_command.py +18 -1
  61. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_styles.py +9 -0
  62. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_thinking_notifications_commands.py +18 -1
  63. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/uv.lock +1 -1
  64. kon_coding_agent-0.3.10/tests/llm/test_openai_oauth.py +0 -14
  65. kon_coding_agent-0.3.10/tests/test_tools_manager.py +0 -18
  66. {kon_coding_agent-0.3.10/.kon → kon_coding_agent-0.3.11/.agents}/skills/kon-release-publish/SKILL.md +0 -0
  67. {kon_coding_agent-0.3.10/.kon → kon_coding_agent-0.3.11/.agents}/skills/kon-tmux-test/run-e2e-tests.sh +0 -0
  68. {kon_coding_agent-0.3.10/.kon → kon_coding_agent-0.3.11/.agents}/skills/kon-tmux-test/setup-test-project.sh +0 -0
  69. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/.github/workflows/test.yml +0 -0
  70. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/.gitignore +0 -0
  71. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/.python-version +0 -0
  72. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/AGENTS.md +0 -0
  73. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/LICENSE +0 -0
  74. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/README.md +0 -0
  75. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/docs/e2e-test-coverage-review.md +0 -0
  76. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/docs/images/kon-screenshot.png +0 -0
  77. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/docs/local-models.md +0 -0
  78. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/async_utils.py +0 -0
  79. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/__init__.py +0 -0
  80. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/_xml.py +0 -0
  81. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/git.py +0 -0
  82. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/loader.py +0 -0
  83. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/core/__init__.py +0 -0
  84. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/core/compaction.py +0 -0
  85. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/core/handoff.py +0 -0
  86. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/core/types.py +0 -0
  87. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/defaults/__init__.py +0 -0
  88. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/events.py +0 -0
  89. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/git_branch.py +0 -0
  90. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/__init__.py +0 -0
  91. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/copilot.py +0 -0
  92. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/github_copilot_headers.py +0 -0
  93. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/mock.py +0 -0
  94. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/openai_compat.py +0 -0
  95. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/sanitize.py +0 -0
  96. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/loop.py +0 -0
  97. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/notify.py +0 -0
  98. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/permissions.py +0 -0
  99. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/py.typed +0 -0
  100. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/sounds/completion.wav +0 -0
  101. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/sounds/error.wav +0 -0
  102. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/sounds/permission.wav +0 -0
  103. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/__init__.py +0 -0
  104. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/_read_image.py +0 -0
  105. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/_tool_utils.py +0 -0
  106. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/base.py +0 -0
  107. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/bash.py +0 -0
  108. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/edit.py +0 -0
  109. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/find.py +0 -0
  110. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/grep.py +0 -0
  111. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/read.py +0 -0
  112. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/web_fetch.py +0 -0
  113. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/web_search.py +0 -0
  114. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/write.py +0 -0
  115. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/__init__.py +0 -0
  116. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/app_protocol.py +0 -0
  117. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/autocomplete.py +0 -0
  118. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/clipboard.py +0 -0
  119. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/input.py +0 -0
  120. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/latex.py +0 -0
  121. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/path_complete.py +0 -0
  122. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/selection_mode.py +0 -0
  123. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/session_ui.py +0 -0
  124. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/tool_output.py +0 -0
  125. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/tree.py +0 -0
  126. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/welcome.py +0 -0
  127. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/widgets.py +0 -0
  128. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/update_check.py +0 -0
  129. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/context/test_agents.py +0 -0
  130. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/__init__.py +0 -0
  131. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/test_azure_ai_foundry_provider.py +0 -0
  132. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/test_mock_provider.py +0 -0
  133. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_agentic_loop.py +0 -0
  134. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_config_binaries.py +0 -0
  135. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_config_injection.py +0 -0
  136. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_git_branch.py +0 -0
  137. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_handoff.py +0 -0
  138. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_handoff_link_interrupt.py +0 -0
  139. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_launch_warnings.py +0 -0
  140. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_llm_lazy_imports.py +0 -0
  141. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_model_provider_resolution.py +0 -0
  142. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_notify.py +0 -0
  143. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_permissions.py +0 -0
  144. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_session_persistence.py +0 -0
  145. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_session_queries.py +0 -0
  146. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_session_resume.py +0 -0
  147. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_session_tree.py +0 -0
  148. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_system_prompt_git_context.py +0 -0
  149. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_themes.py +0 -0
  150. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_ui_notifications.py +0 -0
  151. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_update_check.py +0 -0
  152. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_update_notice_behavior.py +0 -0
  153. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_bash_truncation.py +0 -0
  154. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_diff.py +0 -0
  155. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_edit.py +0 -0
  156. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_edit_display.py +0 -0
  157. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_read.py +0 -0
  158. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_read_image.py +0 -0
  159. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_read_image_integration.py +0 -0
  160. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_read_image_resize.py +0 -0
  161. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_subprocess_cancellation.py +0 -0
  162. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_web_fetch.py +0 -0
  163. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_write.py +0 -0
  164. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_app_approval_keys.py +0 -0
  165. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_autocomplete.py +0 -0
  166. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_info_bar_clicks.py +0 -0
  167. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_info_bar_permissions.py +0 -0
  168. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_approval_submit.py +0 -0
  169. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_cursor_theme.py +0 -0
  170. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_handoff.py +0 -0
  171. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_paste.py +0 -0
  172. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_shell_style.py +0 -0
  173. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_keybindings.py +0 -0
  174. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_latex.py +0 -0
  175. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_prompt_history.py +0 -0
  176. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_queue_editing.py +0 -0
  177. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_shell_command_detection.py +0 -0
  178. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_status_line.py +0 -0
  179. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_streaming_blocks.py +0 -0
  180. {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_tool_output_expansion.py +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: kon-tmux-test
3
- description: E2E testing of kon using tmux sessions; IMPORTANT: only trigger this skill when user asks for e2e testing of kon
3
+ description: "E2E testing of kon using tmux sessions; IMPORTANT: only trigger this skill when user asks for e2e testing of kon"
4
4
  ---
5
5
 
6
6
  # Kon Tmux E2E Testing
@@ -6,6 +6,38 @@ All notable changes to this project will be documented in this file.
6
6
 
7
7
  - No changes yet.
8
8
 
9
+ ## 0.3.11 - 2026-05-29
10
+
11
+ ### Added
12
+
13
+ - Added `insecure_skip_verify` for local providers using self-signed certificates - @s3rj1k.
14
+ - Added per-model Anthropic capability registry and thinking config improvements.
15
+ - Added Claude Opus 4.7 Azure model entry.
16
+ - Added migration of user data from `~/.kon` to `~/.config/kon` and `~/.agents`.
17
+ - Added bash command header highlighting.
18
+ - Added persisted UI settings toggles.
19
+
20
+ ### Changed
21
+
22
+ - Migrated context system paths for skills and `AGENTS.md` to `.agents`.
23
+ - Centralized internal path handling and removed legacy Kon path migration.
24
+ - Updated default Codex model and authentication guidance.
25
+ - Refined `/init`, `/resume`, thinking UI, and theme styling.
26
+
27
+ ### Fixed
28
+
29
+ - Honored `request_timeout_seconds` in insecure-skip-verify HTTP clients - @s3rj1k.
30
+ - Fixed loaded resource display before agent initialization.
31
+ - Fixed OpenAI Codex transport, websocket interrupt handling, and SSE fallback behavior.
32
+ - Fixed UI completion path handling.
33
+ - Fixed empty thinking block handling and empty-compaction error display.
34
+ - Fixed duplicate home skill loading and skill frontmatter parsing.
35
+ - Fixed stale OAuth login state and completion popup info bar behavior - @Meltedd.
36
+
37
+ ### Tests
38
+
39
+ - Updated config, login, migration, and compaction test coverage.
40
+
9
41
  ## 0.3.10 - 2026-05-21
10
42
 
11
43
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kon-coding-agent
3
- Version: 0.3.10
3
+ Version: 0.3.11
4
4
  Summary: Minimal coding agent
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -14,7 +14,7 @@ default = true
14
14
 
15
15
  [project]
16
16
  name = "kon-coding-agent"
17
- version = "0.3.10"
17
+ version = "0.3.11"
18
18
  description = "Minimal coding agent"
19
19
  readme = "README.md"
20
20
  requires-python = ">=3.12"
@@ -51,7 +51,7 @@ def parse_args() -> argparse.Namespace:
51
51
  parser.add_argument(
52
52
  "--kon-config",
53
53
  type=Path,
54
- default=Path.home() / ".kon/config.toml",
54
+ default=Path.home() / ".config" / "kon" / "config.toml",
55
55
  help="Kon config file to rewrite during previews.",
56
56
  )
57
57
  parser.add_argument(
@@ -3,11 +3,15 @@ from kon.config import (
3
3
  CONFIG_DIR_NAME,
4
4
  Config,
5
5
  consume_config_warnings,
6
+ get_agents_dir,
6
7
  get_config,
7
8
  get_config_dir,
8
9
  reload_config,
9
10
  reset_config,
10
11
  set_config,
12
+ set_notifications_enabled,
13
+ set_permissions_mode,
14
+ set_show_welcome_shortcuts,
11
15
  set_theme,
12
16
  update_available_binaries,
13
17
  )
@@ -30,11 +34,15 @@ __all__ = [
30
34
  "config",
31
35
  "consume_config_warnings",
32
36
  "escape_xml",
37
+ "get_agents_dir",
33
38
  "get_config",
34
39
  "get_config_dir",
35
40
  "reload_config",
36
41
  "reset_config",
37
42
  "set_config",
43
+ "set_notifications_enabled",
44
+ "set_permissions_mode",
45
+ "set_show_welcome_shortcuts",
38
46
  "set_theme",
39
47
  "update_available_binaries",
40
48
  ]
@@ -2,7 +2,7 @@
2
2
  name: init
3
3
  description: Create or update AGENTS.md for this repository
4
4
  register_cmd: true
5
- cmd_info: Guided AGENTS.md setup
5
+ cmd_info: guided AGENTS.md setup
6
6
  ---
7
7
 
8
8
  Create or update `AGENTS.md` for this repository.
@@ -15,7 +15,7 @@ from pydantic import BaseModel, Field, ValidationError, field_validator
15
15
 
16
16
  from .themes import ColorsConfig, get_theme, get_theme_ids
17
17
 
18
- CONFIG_DIR_NAME: str = ".kon"
18
+ CONFIG_DIR_NAME: str = "kon"
19
19
 
20
20
  OnOverflowMode = Literal["continue", "pause"]
21
21
  AuthMode = Literal["auto", "required", "none"]
@@ -50,6 +50,9 @@ class UIConfig(BaseModel):
50
50
  # When true, finalized thinking blocks are collapsed to a single line summary.
51
51
  # Set to false to always show the full thinking content.
52
52
  collapse_thinking: bool = True
53
+ # Show the list of keyboard shortcuts in the welcome section on launch.
54
+ # Set to false to hide the shortcuts panel.
55
+ show_welcome_shortcuts: bool = True
53
56
 
54
57
  @field_validator("theme")
55
58
  @classmethod
@@ -73,6 +76,10 @@ class AuthConfig(BaseModel):
73
76
  anthropic_compat: AuthMode = "auto"
74
77
 
75
78
 
79
+ class TLSConfig(BaseModel):
80
+ insecure_skip_verify: bool = False
81
+
82
+
76
83
  class LLMConfig(BaseModel):
77
84
  default_provider: str
78
85
  default_model: str
@@ -82,6 +89,7 @@ class LLMConfig(BaseModel):
82
89
  tool_call_idle_timeout_seconds: float = 180
83
90
  request_timeout_seconds: float = 600
84
91
  auth: AuthConfig = AuthConfig()
92
+ tls: TLSConfig = TLSConfig()
85
93
 
86
94
 
87
95
  class CompactionConfig(BaseModel):
@@ -219,7 +227,14 @@ class Config:
219
227
 
220
228
 
221
229
  def get_config_dir() -> Path:
222
- return Path.home() / CONFIG_DIR_NAME
230
+ base = os.environ.get("XDG_CONFIG_HOME")
231
+ if base:
232
+ return Path(base) / CONFIG_DIR_NAME
233
+ return Path.home() / ".config" / CONFIG_DIR_NAME
234
+
235
+
236
+ def get_agents_dir() -> Path:
237
+ return Path.home() / ".agents"
223
238
 
224
239
 
225
240
  def _ensure_config_file() -> Path:
@@ -247,7 +262,7 @@ def consume_config_warnings() -> list[str]:
247
262
  def _detect_available_binaries() -> set[str]:
248
263
  binaries = {"rg", "fd"}
249
264
  available = set()
250
- bin_dir = Path.home() / CONFIG_DIR_NAME / "bin"
265
+ bin_dir = get_config_dir() / "bin"
251
266
 
252
267
  for binary in binaries:
253
268
  if shutil.which(binary) or (bin_dir / binary).exists():
@@ -584,6 +599,54 @@ def set_theme(theme: str) -> Config:
584
599
  return reload_config()
585
600
 
586
601
 
602
+ def set_show_welcome_shortcuts(enabled: bool) -> Config:
603
+ config_file = _ensure_config_file()
604
+ data = _read_config_data(config_file)
605
+
606
+ ui = data.get("ui")
607
+ if not isinstance(ui, dict):
608
+ ui = {}
609
+ data["ui"] = ui
610
+
611
+ ui["show_welcome_shortcuts"] = enabled
612
+ _set_config_version(data)
613
+
614
+ _atomic_write_text(config_file, _serialize_config_toml(data))
615
+ return reload_config()
616
+
617
+
618
+ def set_permissions_mode(mode: PermissionMode) -> Config:
619
+ config_file = _ensure_config_file()
620
+ data = _read_config_data(config_file)
621
+
622
+ perms = data.get("permissions")
623
+ if not isinstance(perms, dict):
624
+ perms = {}
625
+ data["permissions"] = perms
626
+
627
+ perms["mode"] = mode
628
+ _set_config_version(data)
629
+
630
+ _atomic_write_text(config_file, _serialize_config_toml(data))
631
+ return reload_config()
632
+
633
+
634
+ def set_notifications_enabled(enabled: bool) -> Config:
635
+ config_file = _ensure_config_file()
636
+ data = _read_config_data(config_file)
637
+
638
+ notifications = data.get("notifications")
639
+ if not isinstance(notifications, dict):
640
+ notifications = {}
641
+ data["notifications"] = notifications
642
+
643
+ notifications["enabled"] = enabled
644
+ _set_config_version(data)
645
+
646
+ _atomic_write_text(config_file, _serialize_config_toml(data))
647
+ return reload_config()
648
+
649
+
587
650
  def reset_config() -> None:
588
651
  """Reset config to uninitialized state (next get_config() will reload from file)."""
589
652
  _config_var.set(None)
@@ -2,14 +2,15 @@
2
2
  AGENTS.md discovery and loading.
3
3
 
4
4
  Discovers AGENTS.md (or CLAUDE.md) files from:
5
- 1. Global config dir (~/.kon/)
6
- 2. Ancestor directories from cwd up to git root or home directory (closest last)
5
+ 1. Global agents dir (~/.agents/)
6
+ 2. Ancestor .agents directories from cwd up to git root or home directory (closest last)
7
+ 3. Root-level AGENTS.md/CLAUDE.md files for compatibility
7
8
  """
8
9
 
9
10
  from dataclasses import dataclass
10
11
  from pathlib import Path
11
12
 
12
- from .. import get_config_dir
13
+ from .. import get_agents_dir as get_config_dir
13
14
  from ._xml import escape_xml
14
15
 
15
16
  CONTEXT_FILE_CANDIDATES = ["AGENTS.md", "CLAUDE.md"]
@@ -62,8 +63,8 @@ def load_agent_mds(cwd: str | None = None) -> list[ContextFile]:
62
63
  Load all AGENTS.md files from config dir and ancestor directories.
63
64
 
64
65
  Discovery order:
65
- 1. Global config dir (~/.kon/) - loaded first
66
- 2. Ancestor directories from stop dir down to cwd - closest to cwd loaded last
66
+ 1. Global agents dir (~/.agents/) - loaded first
67
+ 2. Ancestor .agents/root directories from stop dir down to cwd - closest to cwd loaded last
67
68
 
68
69
  Stop directory is determined by:
69
70
  - Git root (if cwd is inside a git repository)
@@ -77,10 +78,10 @@ def load_agent_mds(cwd: str | None = None) -> list[ContextFile]:
77
78
  context_files: list[ContextFile] = []
78
79
  seen_paths: set[str] = set()
79
80
 
80
- # 1. Load from global config dir
81
- config_dir = get_config_dir()
82
- if config_dir.exists():
83
- global_context = _load_context_from_dir(config_dir)
81
+ # 1. Load from global agents dir
82
+ agents_dir = get_config_dir()
83
+ if agents_dir.exists():
84
+ global_context = _load_context_from_dir(agents_dir)
84
85
  if global_context:
85
86
  context_files.append(global_context)
86
87
  seen_paths.add(global_context.path)
@@ -93,10 +94,11 @@ def load_agent_mds(cwd: str | None = None) -> list[ContextFile]:
93
94
  current = resolved_cwd
94
95
 
95
96
  while True:
96
- context_file = _load_context_from_dir(current)
97
- if context_file and context_file.path not in seen_paths:
98
- ancestor_files.insert(0, context_file)
99
- seen_paths.add(context_file.path)
97
+ for candidate_dir in (current / ".agents", current):
98
+ context_file = _load_context_from_dir(candidate_dir)
99
+ if context_file and context_file.path not in seen_paths:
100
+ ancestor_files.insert(0, context_file)
101
+ seen_paths.add(context_file.path)
100
102
  if current == stop_dir:
101
103
  break
102
104
  current = current.parent
@@ -5,8 +5,8 @@ Skills are directories containing a SKILL.md file with frontmatter.
5
5
  They provide specialized instructions that the model can read on-demand.
6
6
 
7
7
  Discovery locations:
8
- 1. Global: ~/.kon/skills/
9
- 2. Project: <cwd>/.kon/skills/
8
+ 1. User: ~/.agents/skills/
9
+ 2. Project: <cwd-or-ancestor>/.agents/skills/
10
10
  """
11
11
 
12
12
  import os
@@ -16,7 +16,7 @@ from importlib import resources
16
16
  from pathlib import Path
17
17
  from typing import Any
18
18
 
19
- from .. import CONFIG_DIR_NAME, get_config_dir
19
+ from .. import get_agents_dir as get_config_dir
20
20
  from ._xml import escape_xml
21
21
 
22
22
  MAX_NAME_LENGTH = 64
@@ -165,13 +165,18 @@ def _load_skill_from_dir(skill_dir: Path) -> tuple[Skill | None, list[SkillWarni
165
165
  return None, [SkillWarning(file_path, str(e))]
166
166
 
167
167
 
168
- def _load_skills_from_dir(directory: Path) -> LoadSkillsResult:
168
+ def _load_skills_from_dir(
169
+ directory: Path, *, legacy_warning: str | None = None
170
+ ) -> LoadSkillsResult:
169
171
  skills: list[Skill] = []
170
172
  warnings: list[SkillWarning] = []
171
173
 
172
174
  if not directory.exists():
173
175
  return LoadSkillsResult(skills=skills, warnings=warnings)
174
176
 
177
+ if legacy_warning:
178
+ warnings.append(SkillWarning(str(directory), legacy_warning))
179
+
175
180
  try:
176
181
  for entry in directory.iterdir():
177
182
  if entry.name.startswith("."):
@@ -190,13 +195,37 @@ def _load_skills_from_dir(directory: Path) -> LoadSkillsResult:
190
195
  return LoadSkillsResult(skills=skills, warnings=warnings)
191
196
 
192
197
 
198
+ def _find_git_root(start: Path) -> Path | None:
199
+ current = start
200
+ while True:
201
+ if (current / ".git").is_dir():
202
+ return current
203
+ parent = current.parent
204
+ if parent == current:
205
+ return None
206
+ current = parent
207
+
208
+
209
+ def _project_skill_dirs(cwd: Path) -> list[Path]:
210
+ git_root = _find_git_root(cwd)
211
+ stop_dir = git_root or cwd
212
+ dirs: list[Path] = []
213
+ current = cwd
214
+ while True:
215
+ dirs.append((current / ".agents" / "skills").resolve(strict=False))
216
+ if current == stop_dir:
217
+ break
218
+ current = current.parent
219
+ return dirs
220
+
221
+
193
222
  def load_skills(cwd: str | None = None) -> LoadSkillsResult:
194
223
  """
195
- Load skills from global and project locations.
224
+ Load skills from ~/.agents and project .agents locations.
196
225
 
197
226
  Discovery:
198
- 1. <cwd>/.kon/skills/ - each subdirectory with SKILL.md is a skill
199
- 2. ~/.kon/skills/ - each subdirectory with SKILL.md is a skill
227
+ 1. <cwd-or-ancestor>/.agents/skills/ - each subdirectory with SKILL.md is a skill
228
+ 2. ~/.agents/skills/ - each subdirectory with SKILL.md is a skill
200
229
 
201
230
  Local skills take precedence over global skills with the same name.
202
231
  """
@@ -220,12 +249,13 @@ def load_skills(cwd: str | None = None) -> LoadSkillsResult:
220
249
  else:
221
250
  skill_map[skill.name] = skill
222
251
 
223
- local_skills_dir = (resolved_cwd / CONFIG_DIR_NAME / "skills").resolve(strict=False)
224
- global_skills_dir = (get_config_dir() / "skills").resolve(strict=False)
252
+ project_skills_dirs = _project_skill_dirs(resolved_cwd)
253
+ for skills_dir in project_skills_dirs:
254
+ add_skills(_load_skills_from_dir(skills_dir))
225
255
 
226
- add_skills(_load_skills_from_dir(local_skills_dir))
227
- if global_skills_dir != local_skills_dir:
228
- add_skills(_load_skills_from_dir(global_skills_dir))
256
+ user_skills_dir = (get_config_dir() / "skills").resolve(strict=False)
257
+ if user_skills_dir not in project_skills_dirs:
258
+ add_skills(_load_skills_from_dir(user_skills_dir))
229
259
 
230
260
  return LoadSkillsResult(skills=list(skill_map.values()), warnings=all_warnings)
231
261
 
@@ -3,11 +3,11 @@ config_version = 6
3
3
 
4
4
  [llm]
5
5
  default_provider = "openai-codex" # "zhipu", "github-copilot", "openai-codex"
6
- default_model = "gpt-5.4"
6
+ default_model = "gpt-5.5"
7
7
  # Optional API base URL override for the selected provider or local/self-hosted endpoint.
8
8
  # Leave empty to use the provider's default URL.
9
9
  default_base_url = ""
10
- default_thinking_level = "high"
10
+ default_thinking_level = "low"
11
11
  # Abort a tool call if it stays idle for this long during a turn.
12
12
  # Helps prevent stalled tool executions from hanging the agent loop.
13
13
  tool_call_idle_timeout_seconds = 180
@@ -23,6 +23,11 @@ request_timeout_seconds = 600
23
23
  openai_compat = "auto" # "auto", "required", or "none"
24
24
  anthropic_compat = "auto" # "auto", "required", or "none"
25
25
 
26
+ [llm.tls]
27
+ # Skip TLS verification for LLM HTTP requests. Enables self-signed certs
28
+ # on local providers.
29
+ insecure_skip_verify = false
30
+
26
31
  [llm.system_prompt]
27
32
  git_context = true
28
33
  content = """You are an expert coding assistant called Kon. You help users by reading, searching, executing commands, editing code, and writing new files.
@@ -32,8 +37,8 @@ content = """You are an expert coding assistant called Kon. You help users by re
32
37
  - Be concise in your responses
33
38
  - Show file paths clearly when working with files
34
39
  - When summarizing your actions, output plain text directly DO NOT use cat or bash to display
35
- - Kon session logs are JSONL files in ~/.kon/sessions; If the user references recent sessions or a particular session, look there
36
- - If the user mentions adding a new skill then look at https://github.com/0xku/kon/blob/main/README.md#skills"""
40
+ - Kon session logs are JSONL files in ~/.config/kon/sessions; If the user references recent sessions or a particular session, look there
41
+ - If the user mentions adding a new skill, use ~/.agents/skills for user skills and .agents/skills for project skills"""
37
42
 
38
43
  [compaction]
39
44
  # What kon should do after compacting history on context overflow.
@@ -58,6 +63,9 @@ theme = "gruvbox-dark"
58
63
  # When true, finalized thinking blocks are collapsed to a single line summary.
59
64
  # Set to false to always show the full thinking content.
60
65
  collapse_thinking = true
66
+ # Show the list of keyboard shortcuts in the welcome section on launch.
67
+ # Set to false to hide the shortcuts panel.
68
+ show_welcome_shortcuts = true
61
69
 
62
70
  [permissions]
63
71
  # Approval behavior for mutating tools.
@@ -10,6 +10,7 @@ from .models import (
10
10
  from .oauth import clear_credentials as clear_copilot_credentials
11
11
  from .oauth import (
12
12
  clear_openai_credentials,
13
+ get_valid_openai_credentials,
13
14
  is_copilot_logged_in,
14
15
  is_openai_logged_in,
15
16
  load_openai_credentials,
@@ -39,6 +40,7 @@ __all__ = [
39
40
  "get_models_by_provider",
40
41
  "get_openai_token",
41
42
  "get_provider_class",
43
+ "get_valid_openai_credentials",
42
44
  "is_copilot_logged_in",
43
45
  "is_openai_logged_in",
44
46
  "load_copilot_credentials",
@@ -6,6 +6,10 @@ from ipaddress import ip_address
6
6
  from typing import Literal
7
7
  from urllib.parse import urlparse
8
8
 
9
+ import httpx
10
+
11
+ from kon import config as kon_config
12
+
9
13
  from ..core.types import Message, StreamPart, ToolDefinition, Usage
10
14
 
11
15
  DEFAULT_THINKING_LEVELS: list[str] = ["none", "minimal", "low", "medium", "high", "xhigh"]
@@ -48,6 +52,15 @@ def is_local_base_url(base_url: str | None) -> bool:
48
52
  return addr.is_loopback or addr.is_private or addr.is_link_local
49
53
 
50
54
 
55
+ def make_http_client() -> httpx.AsyncClient | None:
56
+ # Returns None when verify is required so the SDK uses its own default client.
57
+ if not kon_config.llm.tls.insecure_skip_verify:
58
+ return None
59
+ return httpx.AsyncClient(
60
+ verify=False, timeout=httpx.Timeout(kon_config.llm.request_timeout_seconds)
61
+ )
62
+
63
+
51
64
  def resolve_api_key(
52
65
  explicit_api_key: str | None,
53
66
  *,
@@ -121,6 +134,13 @@ class LLMStream(AsyncIterator["StreamPart"]):
121
134
  raise StopAsyncIteration
122
135
  return await self._iterator.__anext__()
123
136
 
137
+ async def aclose(self) -> None:
138
+ if self._iterator is None:
139
+ return
140
+ close = getattr(self._iterator, "aclose", None)
141
+ if close is not None:
142
+ await close()
143
+
124
144
  @property
125
145
  def usage(self) -> Usage | None:
126
146
  return self._usage
@@ -169,6 +169,16 @@ MODELS: dict[str, Model] = {
169
169
  supports_images=True,
170
170
  supports_thinking=True,
171
171
  ),
172
+ # Azure AI Foundry - Opus 4.7
173
+ "claude-opus-4.7-azure": Model(
174
+ id="claude-opus-4.7",
175
+ provider="azure-ai-foundry",
176
+ api=ApiType.AZURE_AI_FOUNDRY,
177
+ base_url="", # resolved from AZURE_AI_FOUNDRY_BASE_URL env var
178
+ max_tokens=8192 * 2,
179
+ supports_images=True,
180
+ supports_thinking=True,
181
+ ),
172
182
  }
173
183
 
174
184
 
@@ -13,6 +13,7 @@ from .openai import (
13
13
  OpenAICredentials,
14
14
  clear_openai_credentials,
15
15
  get_openai_auth_path,
16
+ get_valid_openai_credentials,
16
17
  get_valid_openai_token,
17
18
  is_openai_logged_in,
18
19
  load_openai_credentials,
@@ -28,6 +29,7 @@ __all__ = [
28
29
  "get_base_url_from_token",
29
30
  "get_copilot_auth_path",
30
31
  "get_openai_auth_path",
32
+ "get_valid_openai_credentials",
31
33
  "get_valid_openai_token",
32
34
  "get_valid_token",
33
35
  "is_copilot_logged_in",
@@ -14,6 +14,8 @@ from typing import Any
14
14
 
15
15
  import aiohttp
16
16
 
17
+ from kon import get_config_dir
18
+
17
19
  # GitHub OAuth client ID (same as VS Code Copilot extension)
18
20
  _CLIENT_ID = b64decode("SXYxLmI1MDdhMDhjODdlY2ZlOTg=").decode()
19
21
 
@@ -44,7 +46,7 @@ class DeviceCodeResponse:
44
46
 
45
47
 
46
48
  def get_copilot_auth_path() -> Path:
47
- return Path.home() / ".kon" / "copilot_auth.json"
49
+ return get_config_dir() / "copilot_auth.json"
48
50
 
49
51
 
50
52
  def load_credentials() -> CopilotCredentials | None:
@@ -18,6 +18,8 @@ from urllib.parse import parse_qs, urlencode, urlparse
18
18
 
19
19
  import aiohttp
20
20
 
21
+ from kon import get_config_dir
22
+
21
23
  _CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann"
22
24
  _AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize"
23
25
  _TOKEN_URL = "https://auth.openai.com/oauth/token"
@@ -40,7 +42,7 @@ class OpenAICredentials:
40
42
 
41
43
 
42
44
  def get_openai_auth_path() -> Path:
43
- return Path.home() / ".kon" / "openai_auth.json"
45
+ return get_config_dir() / "openai_auth.json"
44
46
 
45
47
 
46
48
  def load_openai_credentials() -> OpenAICredentials | None:
@@ -379,9 +381,7 @@ async def login(
379
381
  await server.wait_closed()
380
382
 
381
383
 
382
- async def get_valid_openai_token() -> str | None:
383
- import time
384
-
384
+ async def get_valid_openai_credentials() -> OpenAICredentials | None:
385
385
  creds = load_openai_credentials()
386
386
  if not creds:
387
387
  return None
@@ -392,4 +392,9 @@ async def get_valid_openai_token() -> str | None:
392
392
  except Exception:
393
393
  return None
394
394
 
395
- return creds.access
395
+ return creds
396
+
397
+
398
+ async def get_valid_openai_token() -> str | None:
399
+ creds = await get_valid_openai_credentials()
400
+ return creds.access if creds else None