drydock-cli 1.9.1__tar.gz → 1.9.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (514) hide show
  1. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/PKG-INFO +1 -1
  2. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/agent_loop.py +90 -4
  3. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/pyproject.toml +1 -1
  4. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_drydock_tasks.py +14 -19
  5. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_loop_detection.py +50 -52
  6. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_user_issues.py +35 -31
  7. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.github/CODEOWNERS +0 -0
  8. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  9. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  10. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  11. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.github/workflows/build-and-upload.yml +0 -0
  12. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.github/workflows/ci.yml +0 -0
  13. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.github/workflows/issue-labeler.yml +0 -0
  14. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.github/workflows/release.yml +0 -0
  15. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.gitignore +0 -0
  16. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.pre-commit-config.yaml +0 -0
  17. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.python-version +0 -0
  18. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.typos.toml +0 -0
  19. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.vscode/extensions.json +0 -0
  20. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.vscode/launch.json +0 -0
  21. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/.vscode/settings.json +0 -0
  22. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/AGENTS.md +0 -0
  23. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/CHANGELOG.md +0 -0
  24. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/CLAUDE.md +0 -0
  25. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/CONTRIBUTING.md +0 -0
  26. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/Drydock_rebrand.md +0 -0
  27. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/LICENSE +0 -0
  28. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/NOTICE +0 -0
  29. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/PRD.md +0 -0
  30. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/README.md +0 -0
  31. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/action.yml +0 -0
  32. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/distribution/zed/LICENSE +0 -0
  33. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/distribution/zed/extension.toml +0 -0
  34. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/distribution/zed/icons/mistral_vibe.svg +0 -0
  35. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/docs/README.md +0 -0
  36. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/docs/acp-setup.md +0 -0
  37. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/docs/proxy-setup.md +0 -0
  38. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/__init__.py +0 -0
  39. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/__init__.py +0 -0
  40. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/acp_agent_loop.py +0 -0
  41. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/acp_logger.py +0 -0
  42. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/entrypoint.py +0 -0
  43. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/tools/__init__.py +0 -0
  44. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/tools/base.py +0 -0
  45. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/tools/builtins/bash.py +0 -0
  46. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/tools/builtins/read_file.py +0 -0
  47. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/tools/builtins/search_replace.py +0 -0
  48. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/tools/builtins/todo.py +0 -0
  49. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/tools/builtins/write_file.py +0 -0
  50. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/tools/session_update.py +0 -0
  51. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/acp/utils.py +0 -0
  52. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/__init__.py +0 -0
  53. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/autocompletion/__init__.py +0 -0
  54. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/autocompletion/base.py +0 -0
  55. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/autocompletion/path_completion.py +0 -0
  56. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/autocompletion/slash_command.py +0 -0
  57. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/cli.py +0 -0
  58. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/clipboard.py +0 -0
  59. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/commands.py +0 -0
  60. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/entrypoint.py +0 -0
  61. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/history_manager.py +0 -0
  62. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  63. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  64. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  65. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/terminal_setup.py +0 -0
  66. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/__init__.py +0 -0
  67. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  68. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/app.py +0 -0
  69. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/app.tcss +0 -0
  70. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/external_editor.py +0 -0
  71. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  72. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  73. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  74. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  75. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  76. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  77. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  78. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  79. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  80. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  81. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  82. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  83. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  84. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  85. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  86. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  87. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  88. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  89. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  90. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  91. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  92. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  93. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  94. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  95. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  96. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  97. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  98. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  99. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  100. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  101. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  102. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  103. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  104. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  105. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  106. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  107. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/windowing/history.py +0 -0
  108. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  109. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/textual_ui/windowing/state.py +0 -0
  110. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/update_notifier/__init__.py +0 -0
  111. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  112. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  113. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  114. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  115. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  116. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/update_notifier/update.py +0 -0
  117. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/cli/update_notifier/whats_new.py +0 -0
  118. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/__init__.py +0 -0
  119. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/agents/__init__.py +0 -0
  120. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/agents/manager.py +0 -0
  121. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/agents/models.py +0 -0
  122. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/auth/__init__.py +0 -0
  123. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/auth/crypto.py +0 -0
  124. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/auth/github.py +0 -0
  125. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/__init__.py +0 -0
  126. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/completers.py +0 -0
  127. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  128. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  129. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  130. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  131. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  132. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/fuzzy.py +0 -0
  133. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/path_prompt.py +0 -0
  134. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  135. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/build_orchestrator.py +0 -0
  136. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/config/__init__.py +0 -0
  137. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/config/_settings.py +0 -0
  138. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/config/harness_files/__init__.py +0 -0
  139. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  140. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/config/harness_files/_paths.py +0 -0
  141. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/consultant.py +0 -0
  142. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/drydock_states.py +0 -0
  143. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/hooks.py +0 -0
  144. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/__init__.py +0 -0
  145. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/backend/anthropic.py +0 -0
  146. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/backend/base.py +0 -0
  147. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/backend/factory.py +0 -0
  148. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/backend/generic.py +0 -0
  149. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/backend/mistral.py +0 -0
  150. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  151. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/backend/vertex.py +0 -0
  152. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/exceptions.py +0 -0
  153. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/format.py +0 -0
  154. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/message_utils.py +0 -0
  155. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/llm/types.py +0 -0
  156. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/logger.py +0 -0
  157. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/middleware.py +0 -0
  158. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/output_formatters.py +0 -0
  159. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/paths/__init__.py +0 -0
  160. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/paths/_local_config_walk.py +0 -0
  161. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/paths/_vibe_home.py +0 -0
  162. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/paths/conventions.py +0 -0
  163. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/plan_session.py +0 -0
  164. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/plugins.py +0 -0
  165. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/programmatic.py +0 -0
  166. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/__init__.py +0 -0
  167. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/builder.md +0 -0
  168. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/cli.md +0 -0
  169. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/compact.md +0 -0
  170. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/dangerous_directory.md +0 -0
  171. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/diagnostic.md +0 -0
  172. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/explore.md +0 -0
  173. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/planner.md +0 -0
  174. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/project_context.md +0 -0
  175. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/prompts/tests.md +0 -0
  176. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/proxy_setup.py +0 -0
  177. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/session/agent_memory.py +0 -0
  178. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/session/checkpoints.py +0 -0
  179. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/session/session_loader.py +0 -0
  180. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/session/session_logger.py +0 -0
  181. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/session/session_migration.py +0 -0
  182. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/session/state_file.py +0 -0
  183. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/skills/__init__.py +0 -0
  184. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/skills/manager.py +0 -0
  185. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/skills/models.py +0 -0
  186. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/skills/parser.py +0 -0
  187. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/slug.py +0 -0
  188. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/system_prompt.py +0 -0
  189. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/telemetry/__init__.py +0 -0
  190. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/telemetry/send.py +0 -0
  191. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/teleport/errors.py +0 -0
  192. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/teleport/git.py +0 -0
  193. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/teleport/nuage.py +0 -0
  194. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/teleport/teleport.py +0 -0
  195. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/teleport/types.py +0 -0
  196. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/base.py +0 -0
  197. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  198. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/bash.py +0 -0
  199. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/cron.py +0 -0
  200. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  201. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/glob_tool.py +0 -0
  202. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/grep.py +0 -0
  203. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  204. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/lsp.py +0 -0
  205. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  206. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  207. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/powershell.py +0 -0
  208. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  209. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  210. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  211. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  212. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  213. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  214. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  215. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  216. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  217. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  218. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  219. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  220. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  221. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  222. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/task.md +0 -0
  223. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  224. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  225. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  226. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  227. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  228. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  229. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  230. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/read_file.py +0 -0
  231. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/search_replace.py +0 -0
  232. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/task.py +0 -0
  233. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/task_manager.py +0 -0
  234. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/todo.py +0 -0
  235. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/tool_search.py +0 -0
  236. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/webfetch.py +0 -0
  237. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/websearch.py +0 -0
  238. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/worktree.py +0 -0
  239. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/builtins/write_file.py +0 -0
  240. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/injection_guard.py +0 -0
  241. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/manager.py +0 -0
  242. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/mcp/__init__.py +0 -0
  243. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/mcp/registry.py +0 -0
  244. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/mcp/tools.py +0 -0
  245. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/mcp_sampling.py +0 -0
  246. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/ui.py +0 -0
  247. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/tools/utils.py +0 -0
  248. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/trusted_folders.py +0 -0
  249. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/types.py +0 -0
  250. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/core/utils.py +0 -0
  251. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/setup/onboarding/__init__.py +0 -0
  252. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/setup/onboarding/base.py +0 -0
  253. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/setup/onboarding/onboarding.tcss +0 -0
  254. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/setup/onboarding/screens/__init__.py +0 -0
  255. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/setup/onboarding/screens/api_key.py +0 -0
  256. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/setup/onboarding/screens/welcome.py +0 -0
  257. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  258. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  259. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/skills/__init__.py +0 -0
  260. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/skills/batch/SKILL.md +0 -0
  261. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/skills/create-presentation/SKILL.md +0 -0
  262. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/skills/deep-research/SKILL.md +0 -0
  263. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/skills/investigate/SKILL.md +0 -0
  264. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/skills/review/SKILL.md +0 -0
  265. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/skills/ship/SKILL.md +0 -0
  266. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/skills/simplify/SKILL.md +0 -0
  267. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock/whats_new.md +0 -0
  268. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock-acp.spec +0 -0
  269. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/drydock_terms.md +0 -0
  270. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/flake.lock +0 -0
  271. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/flake.nix +0 -0
  272. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/README.md +0 -0
  273. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/auto_test_loop.sh +0 -0
  274. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/backup.sh +0 -0
  275. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/bump_version.py +0 -0
  276. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/deploy_to_github.sh +0 -0
  277. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/install.sh +0 -0
  278. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/monitor_test_battery.sh +0 -0
  279. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/notify_release.py +0 -0
  280. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/prepare_release.py +0 -0
  281. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/publish_to_pypi.sh +0 -0
  282. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/test_bank.sh +0 -0
  283. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/test_full.sh +0 -0
  284. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/scripts/test_smoke.sh +0 -0
  285. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/__init__.py +0 -0
  286. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/conftest.py +0 -0
  287. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_acp.py +0 -0
  288. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_agent_thought.py +0 -0
  289. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_bash.py +0 -0
  290. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_compact_session_updates.py +0 -0
  291. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_content.py +0 -0
  292. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_initialize.py +0 -0
  293. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_list_sessions.py +0 -0
  294. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_load_session.py +0 -0
  295. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_multi_session.py +0 -0
  296. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_new_session.py +0 -0
  297. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_proxy_setup_acp.py +0 -0
  298. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_read_file.py +0 -0
  299. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_search_replace.py +0 -0
  300. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_set_config_option.py +0 -0
  301. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_set_mode.py +0 -0
  302. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_set_model.py +0 -0
  303. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_tool_call_session_update.py +0 -0
  304. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_utils.py +0 -0
  305. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/acp/test_write_file.py +0 -0
  306. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/autocompletion/test_file_indexer.py +0 -0
  307. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/autocompletion/test_fuzzy.py +0 -0
  308. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  309. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  310. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/autocompletion/test_path_completion_controller.py +0 -0
  311. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  312. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/autocompletion/test_slash_command_controller.py +0 -0
  313. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  314. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/backend/__init__.py +0 -0
  315. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/backend/data/__init__.py +0 -0
  316. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/backend/data/fireworks.py +0 -0
  317. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/backend/data/mistral.py +0 -0
  318. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/backend/test_anthropic_adapter.py +0 -0
  319. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/backend/test_backend.py +0 -0
  320. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/backend/test_reasoning_adapter.py +0 -0
  321. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  322. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  323. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  324. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  325. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_bell_notifications.py +0 -0
  326. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_braille_renderer.py +0 -0
  327. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_clipboard.py +0 -0
  328. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_commands.py +0 -0
  329. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_copy_shortcuts.py +0 -0
  330. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_external_editor.py +0 -0
  331. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_no_markup_static.py +0 -0
  332. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_question_app.py +0 -0
  333. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_spinner.py +0 -0
  334. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_switching_mode.py +0 -0
  335. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  336. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  337. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_ui_session_resume.py +0 -0
  338. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/test_ui_skill_dispatch.py +0 -0
  339. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/textual_ui/__init__.py +0 -0
  340. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/cli/textual_ui/test_session_picker.py +0 -0
  341. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/conftest.py +0 -0
  342. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_agents.py +0 -0
  343. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_auth_crypto.py +0 -0
  344. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_auth_github.py +0 -0
  345. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_config_load_dotenv.py +0 -0
  346. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_config_paths.py +0 -0
  347. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_config_resolution.py +0 -0
  348. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_file_logging.py +0 -0
  349. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_plan_session.py +0 -0
  350. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_proxy_setup.py +0 -0
  351. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_slug.py +0 -0
  352. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_telemetry_send.py +0 -0
  353. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_teleport_git.py +0 -0
  354. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_teleport_nuage.py +0 -0
  355. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_teleport_service.py +0 -0
  356. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_trusted_folders.py +0 -0
  357. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/core/test_utils.py +0 -0
  358. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/e2e/common.py +0 -0
  359. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/e2e/conftest.py +0 -0
  360. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/e2e/mock_server.py +0 -0
  361. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  362. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/e2e/test_cli_tui_streaming.py +0 -0
  363. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  364. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/mock/__init__.py +0 -0
  365. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/mock/mock_backend_factory.py +0 -0
  366. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/mock/mock_entrypoint.py +0 -0
  367. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/mock/utils.py +0 -0
  368. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/onboarding/test_run_onboarding.py +0 -0
  369. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/onboarding/test_ui_onboarding.py +0 -0
  370. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/session/test_session_loader.py +0 -0
  371. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/session/test_session_logger.py +0 -0
  372. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/session/test_session_migration.py +0 -0
  373. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/skills/conftest.py +0 -0
  374. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/skills/test_manager.py +0 -0
  375. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/skills/test_models.py +0 -0
  376. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/skills/test_parser.py +0 -0
  377. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  378. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  379. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  380. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  381. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  382. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  383. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  384. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  385. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  386. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  387. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  388. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  389. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  390. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  391. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  392. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  393. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  394. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  395. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  396. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  397. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  398. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  399. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  400. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  401. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  402. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  403. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  404. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  405. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  406. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  407. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  408. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  409. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  410. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  411. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  412. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  413. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  414. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  415. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  416. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  417. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  418. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  419. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  420. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  421. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  422. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  423. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  424. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  425. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  426. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  427. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  428. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  429. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  430. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  431. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  432. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  433. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  434. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  435. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  436. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  437. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/base_snapshot_test_app.py +0 -0
  438. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/conftest.py +0 -0
  439. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/snap_compare.py +0 -0
  440. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  441. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  442. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  443. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  444. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  445. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  446. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  447. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  448. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  449. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  450. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  451. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  452. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  453. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  454. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/stubs/fake_backend.py +0 -0
  455. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/stubs/fake_client.py +0 -0
  456. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/stubs/fake_tool.py +0 -0
  457. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_agent_auto_compact.py +0 -0
  458. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_agent_backend.py +0 -0
  459. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_agent_observer_streaming.py +0 -0
  460. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_agent_stats.py +0 -0
  461. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_agent_tasks.py +0 -0
  462. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_agent_tool_call.py +0 -0
  463. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_agents.py +0 -0
  464. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_bank_build.py +0 -0
  465. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_bank_debug.py +0 -0
  466. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_bank_multiagent.py +0 -0
  467. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_bank_prd.py +0 -0
  468. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_bank_prd_extended.py +0 -0
  469. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_bank_tools.py +0 -0
  470. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_bank_update.py +0 -0
  471. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_build_projects.py +0 -0
  472. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_cli_programmatic_preload.py +0 -0
  473. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_current_bugs.py +0 -0
  474. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_drydock_regression.py +0 -0
  475. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_full_regression.py +0 -0
  476. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_history_manager.py +0 -0
  477. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_integration.py +0 -0
  478. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_message_id.py +0 -0
  479. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_message_merging.py +0 -0
  480. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_middleware.py +0 -0
  481. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_multi_agent.py +0 -0
  482. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_real_failures.py +0 -0
  483. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_real_issues.py +0 -0
  484. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_real_workflow.py +0 -0
  485. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_reasoning_content.py +0 -0
  486. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_smoke.py +0 -0
  487. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_system_prompt.py +0 -0
  488. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_tagged_text.py +0 -0
  489. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_ui_external_editor.py +0 -0
  490. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_ui_input_history.py +0 -0
  491. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/test_workloads.py +0 -0
  492. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/testbank_helpers.py +0 -0
  493. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_ask_user_question.py +0 -0
  494. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_bash.py +0 -0
  495. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_exit_plan_mode.py +0 -0
  496. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_grep.py +0 -0
  497. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_invoke_context.py +0 -0
  498. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_manager_get_tool_config.py +0 -0
  499. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_mcp.py +0 -0
  500. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_mcp_sampling.py +0 -0
  501. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_task.py +0 -0
  502. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_ui_bash_execution.py +0 -0
  503. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_webfetch.py +0 -0
  504. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/tools/test_websearch.py +0 -0
  505. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  506. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  507. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/update_notifier/test_do_update.py +0 -0
  508. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  509. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/update_notifier/test_github_update_gateway.py +0 -0
  510. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  511. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/update_notifier/test_ui_update_notification.py +0 -0
  512. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/update_notifier/test_update_use_case.py +0 -0
  513. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/tests/update_notifier/test_whats_new.py +0 -0
  514. {drydock_cli-1.9.1 → drydock_cli-1.9.2}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 1.9.1
3
+ Version: 1.9.2
4
4
  Summary: Drydock — nautical CLI coding agent
5
5
  Project-URL: Homepage, https://github.com/fbobe321/drydock
6
6
  Project-URL: Repository, https://github.com/fbobe321/drydock
@@ -531,10 +531,8 @@ class AgentLoop:
531
531
  if auto_context:
532
532
  self._inject_system_note(auto_context)
533
533
  else:
534
- # Normal flow: inject context for non-build tasks
535
- auto_context = self._build_auto_context(user_msg)
536
- if auto_context:
537
- self._inject_system_note(auto_context)
534
+ # Smart task routing: auto-explore + skill injection
535
+ await self._auto_route_task(user_msg)
538
536
 
539
537
  try:
540
538
  should_break_loop = False
@@ -1737,6 +1735,94 @@ class AgentLoop:
1737
1735
 
1738
1736
  return None
1739
1737
 
1738
+ async def _auto_route_task(self, user_msg: str) -> None:
1739
+ """Auto-explore the project and inject skill instructions.
1740
+
1741
+ Instead of hoping the model calls task(agent='explore'), we do
1742
+ the exploration ourselves and inject the results + relevant skill.
1743
+ """
1744
+ msg_lower = user_msg.lower()
1745
+ parts = []
1746
+
1747
+ # 1. Auto-explore: if project has files, read key ones
1748
+ try:
1749
+ cwd = Path.cwd()
1750
+ py_files = sorted(
1751
+ f for f in cwd.rglob("*.py")
1752
+ if ".logs" not in str(f) and ".venv" not in str(f)
1753
+ and "__pycache__" not in str(f)
1754
+ )
1755
+
1756
+ if len(py_files) >= 3:
1757
+ # List all files
1758
+ listing = "\n".join(f" {f.relative_to(cwd)}" for f in py_files[:30])
1759
+ parts.append(f"PROJECT FILES ({len(py_files)} Python files):\n{listing}")
1760
+
1761
+ # Auto-read key files (entry points, __init__, small files)
1762
+ files_read = 0
1763
+ for f in py_files[:15]:
1764
+ if files_read >= 5:
1765
+ break
1766
+ if f.stat().st_size > 10000:
1767
+ continue # Skip large files
1768
+ if f.name in ("__init__.py", "__main__.py"):
1769
+ continue # Skip boilerplate
1770
+ try:
1771
+ content = f.read_text()[:2000]
1772
+ rel = f.relative_to(cwd)
1773
+ # Extract just function/class signatures
1774
+ import ast
1775
+ tree = ast.parse(content)
1776
+ sigs = []
1777
+ for node in ast.walk(tree):
1778
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
1779
+ args = ", ".join(a.arg for a in node.args.args)
1780
+ sigs.append(f" def {node.name}({args}) [line {node.lineno}]")
1781
+ elif isinstance(node, ast.ClassDef):
1782
+ sigs.append(f" class {node.name} [line {node.lineno}]")
1783
+ if sigs:
1784
+ parts.append(f"{rel}:\n" + "\n".join(sigs[:10]))
1785
+ files_read += 1
1786
+ except Exception:
1787
+ pass
1788
+ except Exception:
1789
+ pass
1790
+
1791
+ # 2. Detect task type and inject skill content
1792
+ skill_name = None
1793
+ if any(kw in msg_lower for kw in ("review", "audit", "check the code", "code quality")):
1794
+ skill_name = "review"
1795
+ elif any(kw in msg_lower for kw in ("investigate", "debug", "why does", "why is", "broken", "failing")):
1796
+ skill_name = "investigate"
1797
+ elif any(kw in msg_lower for kw in ("ship", "commit and push", "create a pr", "open pr", "deploy")):
1798
+ skill_name = "ship"
1799
+ elif any(kw in msg_lower for kw in ("simplify", "clean up", "refactor", "reduce complexity")):
1800
+ skill_name = "simplify"
1801
+
1802
+ if skill_name:
1803
+ skill_info = self.skill_manager.get_skill(skill_name)
1804
+ if skill_info and skill_info.skill_path:
1805
+ try:
1806
+ content = skill_info.skill_path.read_text(encoding="utf-8")
1807
+ if content.startswith("---"):
1808
+ end = content.find("---", 3)
1809
+ if end > 0:
1810
+ content = content[end + 3:].strip()
1811
+ parts.append(f"FOLLOW THIS WORKFLOW ({skill_name} skill):\n{content[:2000]}")
1812
+ except Exception:
1813
+ pass
1814
+
1815
+ # 3. Also list non-Python files of interest
1816
+ try:
1817
+ for pattern in ("*.md", "*.txt", "*.json", "*.yaml", "*.yml", "*.toml", "*.csv"):
1818
+ for f in sorted(Path.cwd().glob(pattern))[:3]:
1819
+ parts.append(f" {f.name} ({f.stat().st_size} bytes)")
1820
+ except Exception:
1821
+ pass
1822
+
1823
+ if parts:
1824
+ self._inject_system_note("\n\n".join(parts))
1825
+
1740
1826
  def _is_build_task(self, user_msg: str) -> bool:
1741
1827
  """Detect if a user message is a complex build task that needs orchestration."""
1742
1828
  msg_lower = user_msg.lower()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "drydock-cli"
3
- version = "1.9.1"
3
+ version = "1.9.2"
4
4
  description = "Drydock — nautical CLI coding agent"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -388,11 +388,10 @@ class TestDeviationHandling:
388
388
  # ============================================================================
389
389
 
390
390
  class TestCircuitBreaker:
391
- """Prevents exact duplicate tool calls."""
391
+ """Circuit breaker only blocks commands that FAILED 3+ times."""
392
392
 
393
- def test_circuit_breaker_blocks_after_threshold(self):
394
- """Non-readonly successful bash calls block after 4 repeats."""
395
- import asyncio
393
+ def test_successful_commands_never_blocked(self):
394
+ """Successful commands are never blocked, no matter how many repeats."""
396
395
  from drydock.core.agent_loop import AgentLoop
397
396
  from drydock.core.types import MessageList
398
397
  from types import SimpleNamespace
@@ -403,18 +402,14 @@ class TestCircuitBreaker:
403
402
 
404
403
  tc = SimpleNamespace(tool_name="bash", args_dict={"command": "ls -ltr"})
405
404
 
406
- # Non-readonly bash: success threshold is 4
407
- for _ in range(4):
405
+ for _ in range(10):
408
406
  assert al._circuit_breaker_check(tc) is None
409
407
  al._circuit_breaker_record(tc, "file1.py\nfile2.py")
410
408
 
411
- result = al._circuit_breaker_check(tc)
412
- assert result is not None
413
- assert "CIRCUIT BREAKER" in result
409
+ assert al._circuit_breaker_check(tc) is None
414
410
 
415
- def test_circuit_breaker_blocks_failed_after_2(self):
416
- """Failed tool calls still block after 2 repeats."""
417
- import asyncio
411
+ def test_circuit_breaker_blocks_failed_after_3(self):
412
+ """Failed tool calls block after 3 repeats."""
418
413
  from drydock.core.agent_loop import AgentLoop
419
414
  from drydock.core.types import MessageList
420
415
  from types import SimpleNamespace
@@ -425,17 +420,18 @@ class TestCircuitBreaker:
425
420
 
426
421
  tc = SimpleNamespace(tool_name="bash", args_dict={"command": "bad_cmd"})
427
422
 
423
+ al._circuit_breaker_record(tc, "FAILED: command not found")
424
+ assert al._circuit_breaker_check(tc) is None
428
425
  al._circuit_breaker_record(tc, "FAILED: command not found")
429
426
  assert al._circuit_breaker_check(tc) is None
430
427
  al._circuit_breaker_record(tc, "FAILED: command not found")
431
428
 
432
429
  result = al._circuit_breaker_check(tc)
433
430
  assert result is not None
434
- assert "CIRCUIT BREAKER" in result
431
+ assert "failed" in result
435
432
 
436
433
  def test_different_args_not_blocked(self):
437
- """Different arguments should not be blocked even if one arg set is."""
438
- import asyncio
434
+ """Different arguments should not be blocked even if one arg set failed 3x."""
439
435
  from drydock.core.agent_loop import AgentLoop
440
436
  from drydock.core.types import MessageList
441
437
  from types import SimpleNamespace
@@ -444,12 +440,11 @@ class TestCircuitBreaker:
444
440
  al.messages = MessageList()
445
441
  al._tool_call_history = {}
446
442
 
447
- tc1 = SimpleNamespace(tool_name="bash", args_dict={"command": "ls -ltr"})
443
+ tc1 = SimpleNamespace(tool_name="bash", args_dict={"command": "bad_cmd"})
448
444
  tc2 = SimpleNamespace(tool_name="bash", args_dict={"command": "ls -la"})
449
445
 
450
- # Non-readonly bash needs 4 repeats to block
451
- for _ in range(4):
452
- al._circuit_breaker_record(tc1, "result1")
446
+ for _ in range(3):
447
+ al._circuit_breaker_record(tc1, "FAILED: command not found")
453
448
  assert al._circuit_breaker_check(tc1) is not None
454
449
  assert al._circuit_breaker_check(tc2) is None
455
450
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  Simulates real message histories that trigger each loop detection mechanism.
4
4
  These test the exact scenarios users report:
5
- - Running same command 4+ times (circuit breaker for bash, 6 for readonly)
6
- - Exact same tool call repeated 4+ times (Check 1: REPEAT_WARNING)
5
+ - Same command FAILING 3+ times (circuit breaker only blocks failed commands)
6
+ - Exact same tool call repeated N+ times (Check 1: REPEAT_WARNING)
7
7
  - 5 consecutive bash calls with different args (Check 2: same-tool)
8
8
  - Reading the same file 5+ times with different offsets (Check 3: same-file)
9
9
  - Alternating grep->read_file->grep->read_file (Check 4: alternating)
@@ -55,7 +55,7 @@ def _add_tool_call(al: AgentLoop, tool_name: str, arguments: str = "{}") -> None
55
55
  # ============================================================================
56
56
 
57
57
  class TestCircuitBreaker:
58
- """Circuit breaker: blocks failed commands after 2, successful after 4 (6 for readonly)."""
58
+ """Circuit breaker: only blocks commands that FAILED 3+ times."""
59
59
 
60
60
  def test_first_call_allowed(self):
61
61
  al = _make_agent()
@@ -68,86 +68,84 @@ class TestCircuitBreaker:
68
68
  al._circuit_breaker_record(tc, "file1.py\nfile2.py")
69
69
  assert al._circuit_breaker_check(tc) is None
70
70
 
71
- def test_failed_blocked_after_2(self):
72
- """Failed commands blocked after 2 repeats."""
71
+ def test_failed_blocked_after_3(self):
72
+ """Failed commands blocked after 3 repeats."""
73
73
  al = _make_agent()
74
74
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"bad_cmd"})
75
- al._circuit_breaker_record(tc, "FAILED: command not found")
76
- al._circuit_breaker_record(tc, "FAILED: command not found")
75
+ for _ in range(3):
76
+ al._circuit_breaker_record(tc, "FAILED: command not found")
77
77
  result = al._circuit_breaker_check(tc)
78
78
  assert result is not None
79
- assert "CIRCUIT BREAKER" in result
79
+ assert "failed" in result
80
80
 
81
- def test_successful_blocked_after_4(self):
82
- """Successful non-readonly commands blocked after 4 repeats."""
81
+ def test_failed_2_not_blocked(self):
82
+ """Failed commands with only 2 repeats are not blocked yet."""
83
83
  al = _make_agent()
84
- tc = SimpleNamespace(tool_name="bash", args_dict={"command":"python3 app.py"})
85
- for _ in range(4):
86
- al._circuit_breaker_record(tc, "output ok")
87
- result = al._circuit_breaker_check(tc)
88
- assert result is not None
89
- assert "CIRCUIT BREAKER" in result
84
+ tc = SimpleNamespace(tool_name="bash", args_dict={"command":"bad_cmd"})
85
+ al._circuit_breaker_record(tc, "FAILED: command not found")
86
+ al._circuit_breaker_record(tc, "FAILED: command not found")
87
+ assert al._circuit_breaker_check(tc) is None
90
88
 
91
- def test_successful_3_not_blocked(self):
92
- """3 successful non-readonly calls still allowed."""
89
+ def test_successful_never_blocked(self):
90
+ """Successful commands are never blocked regardless of repeat count."""
93
91
  al = _make_agent()
94
92
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"python3 app.py"})
95
- for _ in range(3):
93
+ for _ in range(10):
96
94
  al._circuit_breaker_record(tc, "output ok")
97
95
  assert al._circuit_breaker_check(tc) is None
98
96
 
99
- def test_readonly_higher_threshold(self):
100
- """Read-only tools (grep) get higher threshold (6)."""
97
+ def test_successful_readonly_never_blocked(self):
98
+ """Read-only successful tools are never blocked."""
101
99
  al = _make_agent()
102
100
  tc = SimpleNamespace(tool_name="grep", args_dict={"pattern":"foo"})
103
- for _ in range(5):
101
+ for _ in range(10):
104
102
  al._circuit_breaker_record(tc, "match.py:10:foo")
105
- assert al._circuit_breaker_check(tc) is None # 5 is OK for readonly
106
- al._circuit_breaker_record(tc, "match.py:10:foo")
107
- result = al._circuit_breaker_check(tc)
108
- assert result is not None # 6 triggers block
103
+ assert al._circuit_breaker_check(tc) is None
109
104
 
110
- def test_blocked_message_contains_previous_result(self):
105
+ def test_blocked_message_suggests_different_approach(self):
111
106
  al = _make_agent()
112
107
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"python3 run.py"})
113
- for _ in range(4):
114
- al._circuit_breaker_record(tc, "important_file.py")
108
+ for _ in range(3):
109
+ al._circuit_breaker_record(tc, "FAILED: module not found")
115
110
  result = al._circuit_breaker_check(tc)
116
- assert "important_file.py" in result
111
+ assert result is not None
112
+ assert "DIFFERENT" in result or "different" in result
117
113
 
118
- def test_blocked_message_contains_alternatives(self):
114
+ def test_blocked_message_mentions_failure_count(self):
119
115
  al = _make_agent()
120
116
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"python3 run.py"})
121
- for _ in range(4):
122
- al._circuit_breaker_record(tc, "output")
117
+ for _ in range(3):
118
+ al._circuit_breaker_record(tc, "FAILED: error")
123
119
  result = al._circuit_breaker_check(tc)
124
- assert "DIFFERENT" in result or "different" in result
120
+ assert "3" in result
125
121
 
126
122
  def test_different_args_not_blocked(self):
127
123
  al = _make_agent()
128
- tc1 = SimpleNamespace(tool_name="bash", args_dict={"command":"ls -ltr"})
124
+ tc1 = SimpleNamespace(tool_name="bash", args_dict={"command":"bad_cmd"})
129
125
  tc2 = SimpleNamespace(tool_name="bash", args_dict={"command":"ls -la"})
130
- for _ in range(4):
131
- al._circuit_breaker_record(tc1, "r1")
132
- assert al._circuit_breaker_check(tc1) is not None # Blocked
126
+ for _ in range(3):
127
+ al._circuit_breaker_record(tc1, "FAILED: not found")
128
+ assert al._circuit_breaker_check(tc1) is not None # Blocked (failed 3x)
133
129
  assert al._circuit_breaker_check(tc2) is None # Not blocked
134
130
 
135
131
  def test_different_tools_not_blocked(self):
136
132
  al = _make_agent()
137
- tc1 = SimpleNamespace(tool_name="bash", args_dict={"command":"ls"})
133
+ tc1 = SimpleNamespace(tool_name="bash", args_dict={"command":"bad_cmd"})
138
134
  tc2 = SimpleNamespace(tool_name="grep", args_dict={"pattern":"foo"})
139
- for _ in range(4):
140
- al._circuit_breaker_record(tc1, "r1")
135
+ for _ in range(3):
136
+ al._circuit_breaker_record(tc1, "FAILED: not found")
141
137
  assert al._circuit_breaker_check(tc1) is not None
142
138
  assert al._circuit_breaker_check(tc2) is None
143
139
 
144
- def test_already_attempted_summary(self):
140
+ def test_failed_then_success_not_blocked(self):
141
+ """If a command fails then succeeds, it should not be blocked."""
145
142
  al = _make_agent()
146
- tc = SimpleNamespace(tool_name="bash", args_dict={"command":"ls"})
147
- for _ in range(4):
148
- al._circuit_breaker_record(tc, "output1")
149
- result = al._circuit_breaker_check(tc)
150
- assert "ALREADY ATTEMPTED" in result
143
+ tc = SimpleNamespace(tool_name="bash", args_dict={"command":"python3 run.py"})
144
+ al._circuit_breaker_record(tc, "FAILED: error")
145
+ al._circuit_breaker_record(tc, "FAILED: error")
146
+ # Now it succeeds — last_result no longer starts with FAILED:
147
+ al._circuit_breaker_record(tc, "output ok")
148
+ assert al._circuit_breaker_check(tc) is None
151
149
 
152
150
 
153
151
  # ============================================================================
@@ -355,16 +353,16 @@ class TestRealWorldLoops:
355
353
  """Simulate actual user-reported looping scenarios."""
356
354
 
357
355
  def test_ls_ltr_loop(self):
358
- """User reports: `ls -ltr` runs 5+ times. Circuit breaker stops at 4."""
356
+ """Successful `ls -ltr` is never blocked by circuit breaker.
357
+ Loop detection (_check_tool_call_repetition) handles this instead."""
359
358
  al = _make_agent()
360
359
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"ls -ltr"})
361
360
 
362
- # First 3 calls go through (bash threshold is 4 for success)
363
- for _ in range(4):
361
+ # Successful commands are never blocked by the circuit breaker
362
+ for _ in range(10):
364
363
  al._circuit_breaker_record(tc, "total 48\n-rw-r--r-- 1 user user 1234 auth.py")
365
364
 
366
- # 5th call is blocked
367
- assert al._circuit_breaker_check(tc) is not None
365
+ assert al._circuit_breaker_check(tc) is None
368
366
 
369
367
  def test_grep_same_pattern_loop(self):
370
368
  """Model greps for the same pattern 10 times."""
@@ -62,8 +62,8 @@ class TestCondaEnv:
62
62
  # ============================================================================
63
63
 
64
64
  class TestCircuitBreakerEnforcement:
65
- def test_circuit_breaker_blocks_not_just_warns(self):
66
- """After threshold identical calls, the next must return an ERROR, not execute."""
65
+ def test_circuit_breaker_blocks_failed_commands(self):
66
+ """After 3 identical failed calls, the next must be blocked."""
67
67
  from drydock.core.agent_loop import AgentLoop
68
68
  from drydock.core.types import MessageList
69
69
 
@@ -71,16 +71,14 @@ class TestCircuitBreakerEnforcement:
71
71
  al.messages = MessageList()
72
72
  al._tool_call_history = {}
73
73
 
74
- # Non-readonly bash: success threshold is 4
75
- tc = SimpleNamespace(tool_name="bash", args_dict={"command": "ls -ltr"})
76
- for _ in range(4):
77
- al._circuit_breaker_record(tc, "file1.py")
74
+ tc = SimpleNamespace(tool_name="bash", args_dict={"command": "bad_cmd"})
75
+ for _ in range(3):
76
+ al._circuit_breaker_record(tc, "FAILED: command not found")
78
77
 
79
78
  result = al._circuit_breaker_check(tc)
80
- assert result is not None, "Circuit breaker should block"
81
- assert "CIRCUIT BREAKER" in result
82
- # The blocked message should tell the model to STOP, not just warn
83
- assert "STOP" in result or "Do NOT" in result or "MUST" in result
79
+ assert result is not None, "Circuit breaker should block failed commands after 3 repeats"
80
+ assert "failed" in result
81
+ assert "DIFFERENT" in result or "different" in result
84
82
 
85
83
  def test_circuit_breaker_resets_for_new_conversation(self):
86
84
  """Circuit breaker should reset between conversations, not cache forever."""
@@ -91,10 +89,9 @@ class TestCircuitBreakerEnforcement:
91
89
  al.messages = MessageList()
92
90
  al._tool_call_history = {}
93
91
 
94
- # Non-readonly bash: success threshold is 4
95
- tc = SimpleNamespace(tool_name="bash", args_dict={"command": "ls"})
96
- for _ in range(4):
97
- al._circuit_breaker_record(tc, "r1")
92
+ tc = SimpleNamespace(tool_name="bash", args_dict={"command": "bad_cmd"})
93
+ for _ in range(3):
94
+ al._circuit_breaker_record(tc, "FAILED: command not found")
98
95
  assert al._circuit_breaker_check(tc) is not None # Blocked
99
96
 
100
97
  # Simulate new conversation — history should be clearable
@@ -121,8 +118,8 @@ class TestUnderstoodBug:
121
118
  # ============================================================================
122
119
 
123
120
  class TestCircuitBreakerSensitivity:
124
- def test_circuit_breaker_should_have_decay(self):
125
- """The circuit breaker should eventually allow re-running a command."""
121
+ def test_successful_commands_never_blocked(self):
122
+ """Successful commands are never blocked only failed commands are."""
126
123
  from drydock.core.agent_loop import AgentLoop
127
124
  from drydock.core.types import MessageList
128
125
 
@@ -130,15 +127,24 @@ class TestCircuitBreakerSensitivity:
130
127
  al.messages = MessageList()
131
128
  al._tool_call_history = {}
132
129
 
133
- # Non-readonly bash: success threshold is 4
134
130
  tc = SimpleNamespace(tool_name="bash", args_dict={"command": "git status"})
135
- for _ in range(4):
131
+ for _ in range(10):
136
132
  al._circuit_breaker_record(tc, "clean")
137
- assert al._circuit_breaker_check(tc) is not None # Blocked
133
+ assert al._circuit_breaker_check(tc) is None # Never blocked
138
134
 
139
- # After clearing (simulating passage of time / new task), should work again
140
- al._tool_call_history.clear()
141
- assert al._circuit_breaker_check(tc) is None
135
+ def test_failed_commands_blocked_after_3(self):
136
+ """Failed commands are blocked after 3 repeats."""
137
+ from drydock.core.agent_loop import AgentLoop
138
+ from drydock.core.types import MessageList
139
+
140
+ al = object.__new__(AgentLoop)
141
+ al.messages = MessageList()
142
+ al._tool_call_history = {}
143
+
144
+ tc = SimpleNamespace(tool_name="bash", args_dict={"command": "git status"})
145
+ for _ in range(3):
146
+ al._circuit_breaker_record(tc, "FAILED: not a git repo")
147
+ assert al._circuit_breaker_check(tc) is not None # Blocked
142
148
 
143
149
 
144
150
  # ============================================================================
@@ -201,8 +207,8 @@ class TestConsultantConfig:
201
207
  # ============================================================================
202
208
 
203
209
  class TestAutoConsult:
204
- def test_circuit_breaker_suggests_consult(self):
205
- """When circuit breaker fires, it should mention /consult or different approach."""
210
+ def test_circuit_breaker_suggests_different_approach(self):
211
+ """When circuit breaker fires on failed commands, it should suggest a different approach."""
206
212
  from drydock.core.agent_loop import AgentLoop
207
213
  from drydock.core.types import MessageList
208
214
 
@@ -210,14 +216,12 @@ class TestAutoConsult:
210
216
  al.messages = MessageList()
211
217
  al._tool_call_history = {}
212
218
 
213
- # Non-readonly bash: success threshold is 4
214
- tc = SimpleNamespace(tool_name="bash", args_dict={"command": "ls"})
215
- for _ in range(4):
216
- al._circuit_breaker_record(tc, "output")
219
+ tc = SimpleNamespace(tool_name="bash", args_dict={"command": "bad_cmd"})
220
+ for _ in range(3):
221
+ al._circuit_breaker_record(tc, "FAILED: command not found")
217
222
  result = al._circuit_breaker_check(tc)
218
- assert result is not None, "Circuit breaker should have fired"
219
- # Should suggest using /consult or mention consultant or different approach
220
- assert "/consult" in result or "consultant" in result.lower() or "different" in result.lower()
223
+ assert result is not None, "Circuit breaker should have fired for failed command"
224
+ assert "different" in result.lower()
221
225
 
222
226
 
223
227
  # ============================================================================
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes