drydock-cli 2.1.2__tar.gz → 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (515) hide show
  1. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/PKG-INFO +1 -1
  2. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/PRD.md +42 -5
  3. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/app.py +2 -1
  4. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/agent_loop.py +55 -58
  5. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/pyproject.toml +1 -1
  6. drydock_cli-2.2.0/scripts/overnight_agents_test.sh +219 -0
  7. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_drydock_tasks.py +8 -8
  8. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_loop_detection.py +18 -20
  9. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_user_issues.py +15 -18
  10. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.github/CODEOWNERS +0 -0
  11. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  12. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  13. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  14. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.github/workflows/build-and-upload.yml +0 -0
  15. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.github/workflows/ci.yml +0 -0
  16. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.github/workflows/issue-labeler.yml +0 -0
  17. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.github/workflows/release.yml +0 -0
  18. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.gitignore +0 -0
  19. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.pre-commit-config.yaml +0 -0
  20. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.python-version +0 -0
  21. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.typos.toml +0 -0
  22. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.vscode/extensions.json +0 -0
  23. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.vscode/launch.json +0 -0
  24. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/.vscode/settings.json +0 -0
  25. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/AGENTS.md +0 -0
  26. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/CHANGELOG.md +0 -0
  27. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/CLAUDE.md +0 -0
  28. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/CONTRIBUTING.md +0 -0
  29. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/Drydock_rebrand.md +0 -0
  30. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/LICENSE +0 -0
  31. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/NOTICE +0 -0
  32. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/README.md +0 -0
  33. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/action.yml +0 -0
  34. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/distribution/zed/LICENSE +0 -0
  35. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/distribution/zed/extension.toml +0 -0
  36. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/distribution/zed/icons/mistral_vibe.svg +0 -0
  37. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/docs/README.md +0 -0
  38. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/docs/acp-setup.md +0 -0
  39. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/docs/proxy-setup.md +0 -0
  40. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/__init__.py +0 -0
  41. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/__init__.py +0 -0
  42. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/acp_agent_loop.py +0 -0
  43. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/acp_logger.py +0 -0
  44. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/entrypoint.py +0 -0
  45. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/tools/__init__.py +0 -0
  46. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/tools/base.py +0 -0
  47. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/tools/builtins/bash.py +0 -0
  48. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/tools/builtins/read_file.py +0 -0
  49. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/tools/builtins/search_replace.py +0 -0
  50. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/tools/builtins/todo.py +0 -0
  51. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/tools/builtins/write_file.py +0 -0
  52. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/tools/session_update.py +0 -0
  53. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/acp/utils.py +0 -0
  54. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/__init__.py +0 -0
  55. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/autocompletion/__init__.py +0 -0
  56. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/autocompletion/base.py +0 -0
  57. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/autocompletion/path_completion.py +0 -0
  58. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/autocompletion/slash_command.py +0 -0
  59. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/cli.py +0 -0
  60. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/clipboard.py +0 -0
  61. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/commands.py +0 -0
  62. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/entrypoint.py +0 -0
  63. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/history_manager.py +0 -0
  64. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  65. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  66. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  67. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/terminal_setup.py +0 -0
  68. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/__init__.py +0 -0
  69. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  70. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/app.tcss +0 -0
  71. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/external_editor.py +0 -0
  72. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  73. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  74. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  75. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  76. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  77. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  78. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  79. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  80. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  81. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  82. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  83. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  84. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  85. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  86. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  87. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  88. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  89. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  90. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  91. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  92. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  93. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  94. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  95. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  96. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  97. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  98. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  99. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  100. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  101. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  102. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  103. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  104. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  105. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  106. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  107. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  108. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/windowing/history.py +0 -0
  109. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  110. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/textual_ui/windowing/state.py +0 -0
  111. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/update_notifier/__init__.py +0 -0
  112. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  113. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  114. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  115. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  116. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  117. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/update_notifier/update.py +0 -0
  118. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/cli/update_notifier/whats_new.py +0 -0
  119. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/__init__.py +0 -0
  120. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/agents/__init__.py +0 -0
  121. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/agents/manager.py +0 -0
  122. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/agents/models.py +0 -0
  123. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/auth/__init__.py +0 -0
  124. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/auth/crypto.py +0 -0
  125. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/auth/github.py +0 -0
  126. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/__init__.py +0 -0
  127. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/completers.py +0 -0
  128. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  129. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  130. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  131. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  132. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  133. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/fuzzy.py +0 -0
  134. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/path_prompt.py +0 -0
  135. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  136. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/build_orchestrator.py +0 -0
  137. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/config/__init__.py +0 -0
  138. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/config/_settings.py +0 -0
  139. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/config/harness_files/__init__.py +0 -0
  140. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  141. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/config/harness_files/_paths.py +0 -0
  142. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/consultant.py +0 -0
  143. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/drydock_states.py +0 -0
  144. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/hooks.py +0 -0
  145. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/__init__.py +0 -0
  146. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/backend/anthropic.py +0 -0
  147. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/backend/base.py +0 -0
  148. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/backend/factory.py +0 -0
  149. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/backend/generic.py +0 -0
  150. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/backend/mistral.py +0 -0
  151. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  152. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/backend/vertex.py +0 -0
  153. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/exceptions.py +0 -0
  154. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/format.py +0 -0
  155. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/message_utils.py +0 -0
  156. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/llm/types.py +0 -0
  157. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/logger.py +0 -0
  158. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/middleware.py +0 -0
  159. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/output_formatters.py +0 -0
  160. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/paths/__init__.py +0 -0
  161. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/paths/_local_config_walk.py +0 -0
  162. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/paths/_vibe_home.py +0 -0
  163. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/paths/conventions.py +0 -0
  164. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/plan_session.py +0 -0
  165. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/plugins.py +0 -0
  166. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/programmatic.py +0 -0
  167. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/__init__.py +0 -0
  168. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/builder.md +0 -0
  169. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/cli.md +0 -0
  170. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/compact.md +0 -0
  171. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/dangerous_directory.md +0 -0
  172. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/diagnostic.md +0 -0
  173. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/explore.md +0 -0
  174. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/planner.md +0 -0
  175. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/project_context.md +0 -0
  176. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/prompts/tests.md +0 -0
  177. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/proxy_setup.py +0 -0
  178. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/session/agent_memory.py +0 -0
  179. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/session/checkpoints.py +0 -0
  180. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/session/session_loader.py +0 -0
  181. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/session/session_logger.py +0 -0
  182. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/session/session_migration.py +0 -0
  183. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/session/state_file.py +0 -0
  184. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/skills/__init__.py +0 -0
  185. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/skills/manager.py +0 -0
  186. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/skills/models.py +0 -0
  187. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/skills/parser.py +0 -0
  188. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/slug.py +0 -0
  189. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/system_prompt.py +0 -0
  190. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/telemetry/__init__.py +0 -0
  191. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/telemetry/send.py +0 -0
  192. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/teleport/errors.py +0 -0
  193. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/teleport/git.py +0 -0
  194. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/teleport/nuage.py +0 -0
  195. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/teleport/teleport.py +0 -0
  196. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/teleport/types.py +0 -0
  197. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/base.py +0 -0
  198. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  199. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/bash.py +0 -0
  200. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/cron.py +0 -0
  201. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  202. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/glob_tool.py +0 -0
  203. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/grep.py +0 -0
  204. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  205. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/lsp.py +0 -0
  206. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  207. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  208. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/powershell.py +0 -0
  209. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  210. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  211. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  212. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  213. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  214. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  215. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  216. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  217. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  218. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  219. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  220. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  221. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  222. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  223. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/task.md +0 -0
  224. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  225. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  226. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  227. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  228. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  229. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  230. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  231. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/read_file.py +0 -0
  232. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/search_replace.py +0 -0
  233. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/task.py +0 -0
  234. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/task_manager.py +0 -0
  235. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/todo.py +0 -0
  236. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/tool_search.py +0 -0
  237. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/webfetch.py +0 -0
  238. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/websearch.py +0 -0
  239. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/worktree.py +0 -0
  240. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/builtins/write_file.py +0 -0
  241. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/injection_guard.py +0 -0
  242. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/manager.py +0 -0
  243. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/mcp/__init__.py +0 -0
  244. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/mcp/registry.py +0 -0
  245. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/mcp/tools.py +0 -0
  246. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/mcp_sampling.py +0 -0
  247. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/ui.py +0 -0
  248. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/tools/utils.py +0 -0
  249. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/trusted_folders.py +0 -0
  250. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/types.py +0 -0
  251. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/core/utils.py +0 -0
  252. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/setup/onboarding/__init__.py +0 -0
  253. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/setup/onboarding/base.py +0 -0
  254. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/setup/onboarding/onboarding.tcss +0 -0
  255. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/setup/onboarding/screens/__init__.py +0 -0
  256. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/setup/onboarding/screens/api_key.py +0 -0
  257. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/setup/onboarding/screens/welcome.py +0 -0
  258. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  259. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  260. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/skills/__init__.py +0 -0
  261. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/skills/batch/SKILL.md +0 -0
  262. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/skills/create-presentation/SKILL.md +0 -0
  263. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/skills/deep-research/SKILL.md +0 -0
  264. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/skills/investigate/SKILL.md +0 -0
  265. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/skills/review/SKILL.md +0 -0
  266. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/skills/ship/SKILL.md +0 -0
  267. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/skills/simplify/SKILL.md +0 -0
  268. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock/whats_new.md +0 -0
  269. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock-acp.spec +0 -0
  270. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/drydock_terms.md +0 -0
  271. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/flake.lock +0 -0
  272. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/flake.nix +0 -0
  273. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/README.md +0 -0
  274. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/auto_test_loop.sh +0 -0
  275. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/backup.sh +0 -0
  276. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/bump_version.py +0 -0
  277. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/deploy_to_github.sh +0 -0
  278. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/install.sh +0 -0
  279. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/monitor_test_battery.sh +0 -0
  280. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/notify_release.py +0 -0
  281. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/prepare_release.py +0 -0
  282. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/publish_to_pypi.sh +0 -0
  283. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/test_bank.sh +0 -0
  284. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/test_full.sh +0 -0
  285. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/scripts/test_smoke.sh +0 -0
  286. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/__init__.py +0 -0
  287. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/conftest.py +0 -0
  288. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_acp.py +0 -0
  289. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_agent_thought.py +0 -0
  290. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_bash.py +0 -0
  291. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_compact_session_updates.py +0 -0
  292. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_content.py +0 -0
  293. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_initialize.py +0 -0
  294. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_list_sessions.py +0 -0
  295. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_load_session.py +0 -0
  296. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_multi_session.py +0 -0
  297. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_new_session.py +0 -0
  298. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_proxy_setup_acp.py +0 -0
  299. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_read_file.py +0 -0
  300. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_search_replace.py +0 -0
  301. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_set_config_option.py +0 -0
  302. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_set_mode.py +0 -0
  303. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_set_model.py +0 -0
  304. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_tool_call_session_update.py +0 -0
  305. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_utils.py +0 -0
  306. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/acp/test_write_file.py +0 -0
  307. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/autocompletion/test_file_indexer.py +0 -0
  308. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/autocompletion/test_fuzzy.py +0 -0
  309. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  310. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  311. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/autocompletion/test_path_completion_controller.py +0 -0
  312. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  313. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/autocompletion/test_slash_command_controller.py +0 -0
  314. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  315. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/backend/__init__.py +0 -0
  316. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/backend/data/__init__.py +0 -0
  317. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/backend/data/fireworks.py +0 -0
  318. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/backend/data/mistral.py +0 -0
  319. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/backend/test_anthropic_adapter.py +0 -0
  320. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/backend/test_backend.py +0 -0
  321. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/backend/test_reasoning_adapter.py +0 -0
  322. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  323. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  324. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  325. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  326. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_bell_notifications.py +0 -0
  327. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_braille_renderer.py +0 -0
  328. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_clipboard.py +0 -0
  329. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_commands.py +0 -0
  330. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_copy_shortcuts.py +0 -0
  331. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_external_editor.py +0 -0
  332. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_no_markup_static.py +0 -0
  333. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_question_app.py +0 -0
  334. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_spinner.py +0 -0
  335. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_switching_mode.py +0 -0
  336. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  337. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  338. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_ui_session_resume.py +0 -0
  339. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/test_ui_skill_dispatch.py +0 -0
  340. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/textual_ui/__init__.py +0 -0
  341. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/cli/textual_ui/test_session_picker.py +0 -0
  342. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/conftest.py +0 -0
  343. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_agents.py +0 -0
  344. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_auth_crypto.py +0 -0
  345. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_auth_github.py +0 -0
  346. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_config_load_dotenv.py +0 -0
  347. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_config_paths.py +0 -0
  348. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_config_resolution.py +0 -0
  349. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_file_logging.py +0 -0
  350. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_plan_session.py +0 -0
  351. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_proxy_setup.py +0 -0
  352. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_slug.py +0 -0
  353. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_telemetry_send.py +0 -0
  354. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_teleport_git.py +0 -0
  355. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_teleport_nuage.py +0 -0
  356. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_teleport_service.py +0 -0
  357. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_trusted_folders.py +0 -0
  358. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/core/test_utils.py +0 -0
  359. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/e2e/common.py +0 -0
  360. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/e2e/conftest.py +0 -0
  361. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/e2e/mock_server.py +0 -0
  362. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  363. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/e2e/test_cli_tui_streaming.py +0 -0
  364. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  365. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/mock/__init__.py +0 -0
  366. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/mock/mock_backend_factory.py +0 -0
  367. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/mock/mock_entrypoint.py +0 -0
  368. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/mock/utils.py +0 -0
  369. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/onboarding/test_run_onboarding.py +0 -0
  370. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/onboarding/test_ui_onboarding.py +0 -0
  371. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/session/test_session_loader.py +0 -0
  372. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/session/test_session_logger.py +0 -0
  373. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/session/test_session_migration.py +0 -0
  374. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/skills/conftest.py +0 -0
  375. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/skills/test_manager.py +0 -0
  376. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/skills/test_models.py +0 -0
  377. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/skills/test_parser.py +0 -0
  378. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  379. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  380. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  381. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  382. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  383. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  384. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  385. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  386. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  387. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  388. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  389. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  390. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  391. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  392. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  393. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  394. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  395. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  396. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  397. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  398. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  399. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  400. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  401. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  402. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  403. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  404. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  405. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  406. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  407. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  408. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  409. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  410. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  411. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  412. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  413. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  414. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  415. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  416. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  417. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  418. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  419. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  420. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  421. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  422. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  423. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  424. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  425. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  426. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  427. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  428. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  429. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  430. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  431. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  432. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  433. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  434. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  435. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  436. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  437. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  438. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/base_snapshot_test_app.py +0 -0
  439. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/conftest.py +0 -0
  440. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/snap_compare.py +0 -0
  441. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  442. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  443. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  444. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  445. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  446. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  447. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  448. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  449. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  450. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  451. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  452. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  453. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  454. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  455. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/stubs/fake_backend.py +0 -0
  456. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/stubs/fake_client.py +0 -0
  457. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/stubs/fake_tool.py +0 -0
  458. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_agent_auto_compact.py +0 -0
  459. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_agent_backend.py +0 -0
  460. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_agent_observer_streaming.py +0 -0
  461. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_agent_stats.py +0 -0
  462. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_agent_tasks.py +0 -0
  463. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_agent_tool_call.py +0 -0
  464. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_agents.py +0 -0
  465. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_bank_build.py +0 -0
  466. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_bank_debug.py +0 -0
  467. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_bank_multiagent.py +0 -0
  468. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_bank_prd.py +0 -0
  469. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_bank_prd_extended.py +0 -0
  470. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_bank_tools.py +0 -0
  471. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_bank_update.py +0 -0
  472. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_build_projects.py +0 -0
  473. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_cli_programmatic_preload.py +0 -0
  474. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_current_bugs.py +0 -0
  475. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_drydock_regression.py +0 -0
  476. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_full_regression.py +0 -0
  477. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_history_manager.py +0 -0
  478. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_integration.py +0 -0
  479. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_message_id.py +0 -0
  480. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_message_merging.py +0 -0
  481. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_middleware.py +0 -0
  482. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_multi_agent.py +0 -0
  483. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_real_failures.py +0 -0
  484. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_real_issues.py +0 -0
  485. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_real_workflow.py +0 -0
  486. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_reasoning_content.py +0 -0
  487. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_smoke.py +0 -0
  488. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_system_prompt.py +0 -0
  489. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_tagged_text.py +0 -0
  490. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_ui_external_editor.py +0 -0
  491. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_ui_input_history.py +0 -0
  492. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/test_workloads.py +0 -0
  493. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/testbank_helpers.py +0 -0
  494. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_ask_user_question.py +0 -0
  495. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_bash.py +0 -0
  496. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_exit_plan_mode.py +0 -0
  497. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_grep.py +0 -0
  498. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_invoke_context.py +0 -0
  499. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_manager_get_tool_config.py +0 -0
  500. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_mcp.py +0 -0
  501. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_mcp_sampling.py +0 -0
  502. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_task.py +0 -0
  503. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_ui_bash_execution.py +0 -0
  504. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_webfetch.py +0 -0
  505. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/tools/test_websearch.py +0 -0
  506. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  507. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  508. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/update_notifier/test_do_update.py +0 -0
  509. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  510. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/update_notifier/test_github_update_gateway.py +0 -0
  511. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  512. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/update_notifier/test_ui_update_notification.py +0 -0
  513. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/update_notifier/test_update_use_case.py +0 -0
  514. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/tests/update_notifier/test_whats_new.py +0 -0
  515. {drydock_cli-2.1.2 → drydock_cli-2.2.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 2.1.2
3
+ Version: 2.2.0
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
@@ -547,11 +547,48 @@ Evidence: removing this one line improved `task(agent="explore")` usage from 1/5
547
547
  - Telegram release notifications
548
548
  - `whats_new.md` updated
549
549
 
550
+ ### Phase 15 (Mar 31): Meta-Harness Framework + SWE-bench Push
551
+
552
+ **Paper:** "Meta-Harness: End-to-End Optimization of Model Harnesses" (arXiv:2603.28052)
553
+ **Key insight:** Optimize the harness around the model, not the model itself. A harness change gave +18pp on TerminalBench-2.
554
+
555
+ **What we implemented from Meta-Harness:**
556
+
557
+ 1. **Environment bootstrapping** — Single compound shell command before first LLM call gathers:
558
+ - Repo structure (`find . -name "*.py" | head -30`)
559
+ - Python version, test framework
560
+ - Top-level directories, recent commits
561
+ - Injected as `[Environment Snapshot]` in the prompt
562
+ - Eliminates 2-4 wasted exploratory turns
563
+
564
+ 2. **AGENTS.md per SWE-bench task** — Auto-created in each worktree with bug-fix workflow instructions
565
+
566
+ 3. **Additive-only changes** — Paper proved that modifying control flow regresses. Only ADD context before the agent loop. This validates our decision to disable the orchestrator and circuit breaker.
567
+
568
+ **SWE-bench status:**
569
+ - Baseline (v2.1.3 + AGENTS.md): 4/10 file matches (40%)
570
+ - 50-task eval running with env bootstrapping
571
+ - Previous "39-42% pass rate" was file-match only — actual test pass rate was 0%
572
+ - Target: 68% (devstral-small-2 24B, per Mistral's published results)
573
+ - Mistral achieved 68% with Vibe CLI + Cline harness
574
+
575
+ **Meta-Harness techniques still to implement:**
576
+ - Double-confirmation before completion (verify checklist)
577
+ - Execution trace logging for systematic failure diagnosis
578
+ - Repo-specific routing (different strategies per SWE-bench repo)
579
+ - Draft-then-verify for patches
580
+ - Contrastive examples for decision boundaries
581
+
582
+ **Reference:** https://github.com/stanford-iris-lab/meta-harness-tbench2-artifact
583
+
550
584
  ### Lessons Learned (Updated)
551
585
 
552
586
  1. **One prompt line can block an entire feature.** "Restate the goal" prevented tool calling for months.
553
- 2. **Don't rely on the model to delegate.** Force it structurally (orchestrator) or do it before the model responds.
554
- 3. **Same-process API calls can fail.** httpx from inside DryDock got 404 from vLLM. Use the existing backend connection.
555
- 4. **Test the installed package, not source.** Different Python envs (miniconda3 vs miniforge3) have different behavior.
556
- 5. **Explicit Python paths everywhere.** Cron doesn't inherit PATH. Every script must use the full path.
557
- 6. **The circuit breaker was net negative.** It blocked valid retries more than it prevented loops. Failed-only mode is the right balance.
587
+ 2. **AGENTS.md is essential for devstral.** Without per-project instructions file, model loops on ls/bash. Auto-created on first session.
588
+ 3. **Additive-only harness changes work best.** Every control flow modification (circuit breaker, orchestrator, nudges) caused regressions. Just inject better context.
589
+ 4. **The harness matters as much as the model.** Meta-Harness paper shows 6x performance gap from harness changes alone.
590
+ 5. **Environment bootstrapping saves turns.** Pre-gathering repo structure/versions eliminates 2-4 wasted exploration turns.
591
+ 6. **Plan→Edit workflow is Mistral's design.** Use plan mode first, then switch to accept-edits. Don't try to do everything in one agent shot.
592
+ 7. **Same-process API calls can fail.** httpx from inside DryDock got 404 from vLLM. Use the existing backend connection.
593
+ 8. **Test the installed package, not source.** Different Python envs (miniconda3 vs miniforge3) have different behavior.
594
+ 9. **Explicit Python paths everywhere.** Cron doesn't inherit PATH. Every script must use the full path.
@@ -398,7 +398,8 @@ class VibeApp(App): # noqa: PLR0904
398
398
  if not hasattr(self, "_pending_messages"):
399
399
  self._pending_messages: list[str] = []
400
400
  self._pending_messages.append(value)
401
- self.notify(f"Queued will process after current task ({len(self._pending_messages)} pending)")
401
+ preview = value[:60] + "..." if len(value) > 60 else value
402
+ self.notify(f"Queued: \"{preview}\" ({len(self._pending_messages)} pending)")
402
403
  return
403
404
 
404
405
  if value.startswith("!"):
@@ -299,7 +299,8 @@ class AgentLoop:
299
299
  # Auto-create AGENTS.md if no project instructions exist.
300
300
  # devstral needs per-project AGENTS.md to anchor its behavior —
301
301
  # without it the model loops on ls/bash instead of using subagents.
302
- self._ensure_agents_md()
302
+ if self.stats.steps <= 1:
303
+ self._ensure_agents_md()
303
304
 
304
305
  # Load project state for cross-session context
305
306
  try:
@@ -541,11 +542,14 @@ class AgentLoop:
541
542
  except (RuntimeError, AgentLoopLLMResponseError) as e:
542
543
  api_error_count += 1
543
544
  if api_error_count > MAX_API_ERRORS:
545
+ # Don't stop — reset and let the user know
546
+ import asyncio as _aio
544
547
  yield AssistantEvent(
545
- content=f"\n\n[Too many consecutive API errors ({api_error_count}). Last error: {e}. Stopping.]\n",
546
- stopped_by_middleware=True,
548
+ content=f"\n\n[{api_error_count} consecutive API errors. Waiting 10s then retrying. Last error: {str(e)[:200]}]\n",
547
549
  )
548
- return
550
+ await _aio.sleep(10)
551
+ api_error_count = 0 # Reset — give it another chance
552
+ continue
549
553
  # Check if the error is about invalid function/tool name
550
554
  error_str = str(e)
551
555
  if "Function name" in error_str or "function" in error_str.lower() and "must be" in error_str.lower():
@@ -696,11 +700,14 @@ class AgentLoop:
696
700
  "search_replace to edit one. Do NOT run any more bash commands."
697
701
  )
698
702
  elif bash_count >= 10:
699
- yield AssistantEvent(
700
- content="\n\n[STOPPED: 10+ bash commands without creating any files. Use write_file.]\n",
701
- stopped_by_middleware=True,
703
+ # Redirect, don't stop — prune bash calls and guide
704
+ self._prune_repeated_tool_calls()
705
+ self._inject_system_note(
706
+ "You have run 10+ bash commands without creating files. "
707
+ "Use write_file or search_replace NOW. If you need help, "
708
+ "ask the user what to do."
702
709
  )
703
- return
710
+ bash_count = 6 # Reset partially so it doesn't re-trigger immediately
704
711
 
705
712
  # 3-Strike Rule: search_replace keeps failing
706
713
  if search_replace_failures >= 3:
@@ -817,55 +824,56 @@ class AgentLoop:
817
824
  if nudge_text:
818
825
  self._inject_system_note(nudge_text)
819
826
 
820
- # Check for repeated tool calls (loop detection)
827
+ # Check for repeated tool calls (loop guidance — never stops, only redirects)
821
828
  if not should_break_loop:
822
829
  rep = self._check_tool_call_repetition()
823
830
  if rep == "FORCE_STOP":
824
831
  repeat_warnings += 1
825
- logger.warning("Detected infinite loop: same tool call %d+ times (warning %d)", REPEAT_FORCE_STOP_THRESHOLD, repeat_warnings)
826
- if repeat_warnings >= 5:
827
- # Stop after 5 redirects — model is not recovering
828
- yield AssistantEvent(
829
- content="\n\n[Stopping: exhausted all retry attempts.]\n",
830
- stopped_by_middleware=True,
831
- )
832
- return
833
- # Redirect instead of kill — force an edit attempt
834
- self._inject_system_note(
835
- "CRITICAL: You are in an infinite loop. STOP all searching/reading. "
836
- "Based on what you have already seen, use search_replace RIGHT NOW to make "
837
- "your best fix attempt. If you don't know the exact text, use read_file ONE MORE TIME "
838
- "on the specific function, then search_replace immediately.",
839
- replace_last_tool=True,
840
- )
832
+ logger.warning("Loop detected: same call %d+ times (redirect %d)", REPEAT_FORCE_STOP_THRESHOLD, repeat_warnings)
833
+ # Prune repeated calls and redirect — NEVER stop
841
834
  self._prune_repeated_tool_calls()
835
+ if repeat_warnings <= 3:
836
+ self._inject_system_note(
837
+ "You are repeating the same action. Try a DIFFERENT approach:\n"
838
+ "- If searching: pick a different search term or file\n"
839
+ "- If testing: read the error and fix the code first\n"
840
+ "- If stuck: use task(agent='explore') to get a fresh perspective",
841
+ replace_last_tool=True,
842
+ )
843
+ else:
844
+ # After 3+ redirects, ask the user what to do
845
+ self._inject_system_note(
846
+ "You have been redirected multiple times for repeating actions. "
847
+ "Ask the user for clarification on what to do next.",
848
+ replace_last_tool=True,
849
+ )
842
850
  elif rep and rep.startswith("WARNING"):
843
- # During investigation (no edit yet), soft-count warnings from
844
- # investigation tools — they need room to explore.
845
851
  stuck_tool = ""
846
852
  if "|" in rep:
847
853
  stuck_tool = rep.split("|", 1)[1]
848
- is_investigation_warning = (
849
- not has_made_edit
850
- and stuck_tool in ("grep", "read_file")
851
- )
852
- if is_investigation_warning:
853
- repeat_warnings += 0.3 # Count less — investigation needs room
854
+ is_investigation = not has_made_edit and stuck_tool in ("grep", "read_file")
855
+ if is_investigation:
856
+ repeat_warnings += 0.3
854
857
  else:
855
858
  repeat_warnings += 1
856
- logger.warning("Detected repeated tool calls (warning %.1f, investigation=%s)", repeat_warnings, is_investigation_warning)
857
- if repeat_warnings >= 6:
858
- yield AssistantEvent(
859
- content="\n\n[Stopping: too many repeated actions despite warnings.]\n",
860
- stopped_by_middleware=True,
861
- )
862
- return
859
+ logger.warning("Repeated tool calls (warning %.1f, investigation=%s)", repeat_warnings, is_investigation)
863
860
 
864
- # On 3rd warning: prune duplicate tool calls from history
865
- # This gives the model a "fresh start" with less repetitive context
866
- if repeat_warnings == 3:
861
+ # Prune on 3rd warning
862
+ if repeat_warnings >= 3 and int(repeat_warnings) % 3 == 0:
867
863
  self._prune_repeated_tool_calls()
868
864
 
865
+ # Tool-specific guidance
866
+ nudge = ""
867
+ if stuck_tool in ("read_file",):
868
+ nudge = " You already read this file. Make your edit with search_replace now."
869
+ elif stuck_tool in ("grep",):
870
+ nudge = " Try a different search term, or read the file you found."
871
+ elif stuck_tool in ("bash", "run_command"):
872
+ nudge = " Read the error output and fix the code with search_replace."
873
+ self._inject_system_note(
874
+ f"You are repeating the same tool call.{nudge} Try something different."
875
+ )
876
+
869
877
  # Extract tool-specific nudge
870
878
  nudge = ""
871
879
  if stuck_tool in ("read_file",):
@@ -1007,23 +1015,12 @@ class AgentLoop:
1007
1015
  return ""
1008
1016
 
1009
1017
  def _circuit_breaker_check(self, tool_call: ResolvedToolCall) -> str | None:
1010
- """Block exact-duplicate FAILED tool calls only.
1018
+ """Disabled. Loop detection handles repetition.
1011
1019
 
1012
- Only blocks commands that failed before with the exact same args.
1013
- Successful commands are never blocked — the model legitimately
1014
- retries after fixing code.
1020
+ The circuit breaker consistently caused more harm than good
1021
+ blocking valid retries after the model fixed code.
1022
+ _check_tool_call_repetition() catches actual infinite loops.
1015
1023
  """
1016
- args_str = json.dumps(tool_call.args_dict, sort_keys=True, default=str)
1017
- sig = hashlib.md5(f"{tool_call.tool_name}:{args_str}".encode()).hexdigest()
1018
- count, last_result = self._tool_call_history.get(sig, (0, ""))
1019
-
1020
- # Only block if the SAME command FAILED 3+ times
1021
- is_failed = last_result.startswith("FAILED:") if last_result else False
1022
- if is_failed and count >= 3:
1023
- return (
1024
- f"This command has failed {count} times with the same error. "
1025
- f"Try a DIFFERENT command or approach."
1026
- )
1027
1024
  return None
1028
1025
 
1029
1026
  def _circuit_breaker_check_FULL(self, tool_call: ResolvedToolCall) -> str | None:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "drydock-cli"
3
- version = "2.1.2"
3
+ version = "2.2.0"
4
4
  description = "Drydock — nautical CLI coding agent"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -0,0 +1,219 @@
1
+ #!/bin/bash
2
+ # Overnight test: Try different AGENTS.md versions with plan→build workflow
3
+ # Tests DryDock's ability to build the log analyzer from PRD
4
+ # Runs for up to 20 hours, logs all results
5
+
6
+ set -uo pipefail
7
+ export PATH="/home/bobef/miniconda3/bin:$PATH"
8
+ PYTHON="/home/bobef/miniconda3/bin/python3"
9
+ DRYDOCK="/data3/drydock"
10
+ RESULTS="$DRYDOCK/test_bank_results/agents_md_test"
11
+ PRD="/data3/test_drydock/PRD.md"
12
+ MAX_HOURS=20
13
+ START=$(date +%s)
14
+
15
+ mkdir -p "$RESULTS"
16
+
17
+ log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$RESULTS/run.log"; }
18
+
19
+ check_time() {
20
+ NOW=$(date +%s)
21
+ ELAPSED=$(( (NOW - START) / 3600 ))
22
+ if [ "$ELAPSED" -ge "$MAX_HOURS" ]; then
23
+ log "Time limit reached ($ELAPSED hours). Stopping."
24
+ $PYTHON "$DRYDOCK/scripts/notify_release.py" "test" "Overnight AGENTS.md test complete. $PASS passes, $FAIL fails. Check results."
25
+ exit 0
26
+ fi
27
+ }
28
+
29
+ # Test a single AGENTS.md variant
30
+ run_test() {
31
+ local variant_name="$1"
32
+ local agents_md_content="$2"
33
+ local test_dir="/tmp/drydock_agentsmd_test_$$"
34
+ local result_file="$RESULTS/${variant_name}_$(date +%H%M%S).txt"
35
+
36
+ log "=== Testing variant: $variant_name ==="
37
+
38
+ rm -rf "$test_dir"
39
+ mkdir -p "$test_dir"
40
+ cp "$PRD" "$test_dir/PRD.md"
41
+ echo "$agents_md_content" > "$test_dir/AGENTS.md"
42
+
43
+ cd "$test_dir"
44
+
45
+ # Run DryDock programmatically: simulate plan→build
46
+ timeout 600 $PYTHON -c "
47
+ import asyncio, os, sys, subprocess
48
+ from pathlib import Path
49
+ sys.path.insert(0, '$DRYDOCK')
50
+ sys.path.insert(0, '$DRYDOCK/tests')
51
+ os.chdir('$test_dir')
52
+ from drydock.core.config.harness_files import init_harness_files_manager
53
+ try: init_harness_files_manager('u','p')
54
+ except: pass
55
+ from testbank_helpers import make_agent, run_workload, count_python_files, check_syntax_all
56
+
57
+ async def test():
58
+ agent = make_agent(Path('$test_dir'), max_turns=40)
59
+ r = await run_workload(agent, max_events=400, prompt='review the PRD and build the log analyzer. Test it.')
60
+ n = count_python_files(Path('$test_dir'))
61
+ errs = check_syntax_all(Path('$test_dir'))
62
+ print(f'RESULT: files={n} syntax_errors={len(errs)} tools={r.total_tool_calls} stops={r.force_stops}')
63
+ print(f'TOOLS: {r.summary()}')
64
+ # Check subagent usage
65
+ task_calls = r.tool_counts.get('task', 0)
66
+ print(f'SUBAGENT_CALLS: {task_calls}')
67
+ # Try to run
68
+ for d in Path('$test_dir').iterdir():
69
+ if d.is_dir() and (d / '__init__.py').exists():
70
+ result = subprocess.run(f'python3 -m {d.name} --help', shell=True, capture_output=True, text=True, timeout=10)
71
+ print(f'HELP: rc={result.returncode}')
72
+ if result.returncode == 0:
73
+ print(f'HELP_OUT: {result.stdout[:200]}')
74
+ # Try analyze
75
+ Path('$test_dir/test.log').write_text('2026-03-01 10:01:22 ERROR DBConnection failed: timeout\n2026-03-01 10:01:23 WARN Retrying\n2026-03-01 10:02:00 INFO Recovered\n')
76
+ result2 = subprocess.run(f'python3 -m {d.name} analyze test.log', shell=True, capture_output=True, text=True, timeout=10)
77
+ print(f'ANALYZE: rc={result2.returncode}')
78
+ if result2.returncode == 0:
79
+ print(f'ANALYZE_OUT: {result2.stdout[:300]}')
80
+ break
81
+ else:
82
+ print('HELP: no_package')
83
+
84
+ asyncio.run(test())
85
+ " > "$result_file" 2>&1
86
+
87
+ local rc=$?
88
+
89
+ # Parse results
90
+ local files=$(grep "RESULT:" "$result_file" 2>/dev/null | grep -o "files=[0-9]*" | cut -d= -f2)
91
+ local help_rc=$(grep "HELP:" "$result_file" 2>/dev/null | grep -o "rc=[0-9]*" | cut -d= -f2)
92
+ local analyze_rc=$(grep "ANALYZE:" "$result_file" 2>/dev/null | grep -o "rc=[0-9]*" | cut -d= -f2)
93
+ local subagent=$(grep "SUBAGENT_CALLS:" "$result_file" 2>/dev/null | grep -o "[0-9]*")
94
+
95
+ if [ "${analyze_rc:-1}" = "0" ]; then
96
+ log " FULL PASS: $files files, analyze works, subagents=$subagent"
97
+ echo "FULL_PASS" > "$result_file.status"
98
+ return 0
99
+ elif [ "${help_rc:-1}" = "0" ]; then
100
+ log " HELP PASS: $files files, --help works, subagents=$subagent"
101
+ echo "HELP_PASS" > "$result_file.status"
102
+ return 1
103
+ elif [ "${files:-0}" -gt "3" ]; then
104
+ log " PARTIAL: $files files, subagents=$subagent"
105
+ echo "PARTIAL" > "$result_file.status"
106
+ return 1
107
+ else
108
+ log " FAIL: ${files:-0} files, subagents=${subagent:-0}"
109
+ echo "FAIL" > "$result_file.status"
110
+ return 1
111
+ fi
112
+ }
113
+
114
+ # ============================================================================
115
+ # AGENTS.md Variants
116
+ # ============================================================================
117
+
118
+ VARIANT_A='# Project Instructions
119
+
120
+ ## Workflow
121
+ When building a project:
122
+ 1. Use `task(agent="planner")` to create an implementation plan first
123
+ 2. Use `task(agent="explore")` to understand existing code
124
+ 3. Create files using `write_file` with absolute imports
125
+ 4. Always create `__main__.py` so `python3 -m package_name` works
126
+ 5. Test with `bash` after creating files
127
+
128
+ ## Rules
129
+ - Use absolute imports: `from package.module import X`, NOT `from .module import X`
130
+ - Always create `__init__.py` and `__main__.py` for packages
131
+ - Create sample test data before testing
132
+ - Use `python3 -m package_name` to run, NOT `python3 package/file.py`'
133
+
134
+ VARIANT_B='# Project Instructions
135
+
136
+ ## Build Workflow
137
+ 1. Read the PRD with `read_file`
138
+ 2. Plan: use `task(agent="planner")` to create an implementation plan
139
+ 3. Create each file with `write_file` using absolute imports
140
+ 4. Create `__init__.py` and `__main__.py` for every package
141
+ 5. Create sample data and test with `bash`
142
+
143
+ ## Import Rules
144
+ - ALWAYS: `from package.module import X`
145
+ - NEVER: `from .module import X`
146
+ - Run with: `python3 -m package_name`'
147
+
148
+ VARIANT_C='# Instructions for AI Agent
149
+
150
+ When asked to build a project:
151
+ - Start by reading any PRD or requirements files
152
+ - Use task(agent="planner") to plan the implementation
153
+ - Create files one at a time with write_file
154
+ - Use absolute imports (from pkg.mod import X, not from .mod import X)
155
+ - Create __init__.py and __main__.py for packages
156
+ - Test with python3 -m package_name after building'
157
+
158
+ VARIANT_D='# Build Rules
159
+
160
+ 1. Read requirements (PRD.md)
161
+ 2. Plan with task(agent="planner")
162
+ 3. Explore existing code with task(agent="explore")
163
+ 4. Create files with write_file
164
+ 5. Use absolute imports only
165
+ 6. Always create __init__.py and __main__.py
166
+ 7. Test with python3 -m package_name
167
+ 8. Fix errors with search_replace'
168
+
169
+ VARIANT_E='# Project Configuration
170
+
171
+ ## Agent Workflow
172
+ - For new projects: task(agent="planner") → write_file → bash test
173
+ - For existing projects: task(agent="explore") → read_file → search_replace
174
+ - For reviews: task(agent="explore") → invoke_skill(skill_name="review")
175
+
176
+ ## Package Rules
177
+ - Absolute imports: from package.module import X
178
+ - Always: __init__.py + __main__.py
179
+ - Test: python3 -m package_name
180
+ - Never: from .module import X'
181
+
182
+ # ============================================================================
183
+ # Main Loop
184
+ # ============================================================================
185
+
186
+ log "Starting overnight AGENTS.md test (max $MAX_HOURS hours)"
187
+ log "Variants: A B C D E"
188
+
189
+ PASS=0
190
+ FAIL=0
191
+ ROUND=0
192
+
193
+ while true; do
194
+ check_time
195
+ ROUND=$((ROUND + 1))
196
+ log ""
197
+ log "========== ROUND $ROUND =========="
198
+
199
+ for variant in A B C D E; do
200
+ check_time
201
+ eval "content=\$VARIANT_$variant"
202
+ if run_test "variant_$variant" "$content"; then
203
+ PASS=$((PASS + 1))
204
+ else
205
+ FAIL=$((FAIL + 1))
206
+ fi
207
+ done
208
+
209
+ TOTAL=$((PASS + FAIL))
210
+ PASS_RATE=$((PASS * 100 / TOTAL))
211
+ log "Round $ROUND: $PASS/$TOTAL pass ($PASS_RATE%)"
212
+
213
+ # Send Telegram update every 5 rounds
214
+ if [ $((ROUND % 5)) -eq 0 ]; then
215
+ $PYTHON "$DRYDOCK/scripts/notify_release.py" "test-r$ROUND" "AGENTS.md test round $ROUND: $PASS/$TOTAL pass ($PASS_RATE%). Best variant TBD."
216
+ fi
217
+
218
+ sleep 30
219
+ done
@@ -408,8 +408,8 @@ class TestCircuitBreaker:
408
408
 
409
409
  assert al._circuit_breaker_check(tc) is None
410
410
 
411
- def test_circuit_breaker_blocks_failed_after_3(self):
412
- """Failed tool calls block after 3 repeats."""
411
+ def test_circuit_breaker_disabled_for_failed_commands(self):
412
+ """Circuit breaker is disabled even failed commands are not blocked."""
413
413
  from drydock.core.agent_loop import AgentLoop
414
414
  from drydock.core.types import MessageList
415
415
  from types import SimpleNamespace
@@ -426,12 +426,11 @@ class TestCircuitBreaker:
426
426
  assert al._circuit_breaker_check(tc) is None
427
427
  al._circuit_breaker_record(tc, "FAILED: command not found")
428
428
 
429
- result = al._circuit_breaker_check(tc)
430
- assert result is not None
431
- assert "failed" in result
429
+ # CB is disabled — always returns None
430
+ assert al._circuit_breaker_check(tc) is None
432
431
 
433
- def test_different_args_not_blocked(self):
434
- """Different arguments should not be blocked even if one arg set failed 3x."""
432
+ def test_circuit_breaker_disabled_for_all_args(self):
433
+ """Circuit breaker is disabled no arguments are ever blocked."""
435
434
  from drydock.core.agent_loop import AgentLoop
436
435
  from drydock.core.types import MessageList
437
436
  from types import SimpleNamespace
@@ -445,7 +444,8 @@ class TestCircuitBreaker:
445
444
 
446
445
  for _ in range(3):
447
446
  al._circuit_breaker_record(tc1, "FAILED: command not found")
448
- assert al._circuit_breaker_check(tc1) is not None
447
+ # CB is disabled — both return None
448
+ assert al._circuit_breaker_check(tc1) is None
449
449
  assert al._circuit_breaker_check(tc2) is None
450
450
 
451
451
 
@@ -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: only blocks commands that FAILED 3+ times."""
58
+ """Circuit breaker is fully disabled always returns None."""
59
59
 
60
60
  def test_first_call_allowed(self):
61
61
  al = _make_agent()
@@ -68,18 +68,16 @@ 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_3(self):
72
- """Failed commands blocked after 3 repeats."""
71
+ def test_disabled_for_failed_after_3(self):
72
+ """CB disabled — failed commands are NOT blocked even after 3 repeats."""
73
73
  al = _make_agent()
74
74
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"bad_cmd"})
75
75
  for _ in range(3):
76
76
  al._circuit_breaker_record(tc, "FAILED: command not found")
77
- result = al._circuit_breaker_check(tc)
78
- assert result is not None
79
- assert "failed" in result
77
+ assert al._circuit_breaker_check(tc) is None
80
78
 
81
79
  def test_failed_2_not_blocked(self):
82
- """Failed commands with only 2 repeats are not blocked yet."""
80
+ """Failed commands with only 2 repeats are not blocked."""
83
81
  al = _make_agent()
84
82
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"bad_cmd"})
85
83
  al._circuit_breaker_record(tc, "FAILED: command not found")
@@ -102,39 +100,40 @@ class TestCircuitBreaker:
102
100
  al._circuit_breaker_record(tc, "match.py:10:foo")
103
101
  assert al._circuit_breaker_check(tc) is None
104
102
 
105
- def test_blocked_message_suggests_different_approach(self):
103
+ def test_disabled_returns_none_even_for_failed(self):
104
+ """CB disabled — returns None even for commands that would have been blocked."""
106
105
  al = _make_agent()
107
106
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"python3 run.py"})
108
107
  for _ in range(3):
109
108
  al._circuit_breaker_record(tc, "FAILED: module not found")
110
- result = al._circuit_breaker_check(tc)
111
- assert result is not None
112
- assert "DIFFERENT" in result or "different" in result
109
+ assert al._circuit_breaker_check(tc) is None
113
110
 
114
- def test_blocked_message_mentions_failure_count(self):
111
+ def test_disabled_returns_none_for_repeated_failures(self):
112
+ """CB disabled — returns None regardless of failure count."""
115
113
  al = _make_agent()
116
114
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"python3 run.py"})
117
115
  for _ in range(3):
118
116
  al._circuit_breaker_record(tc, "FAILED: error")
119
- result = al._circuit_breaker_check(tc)
120
- assert "3" in result
117
+ assert al._circuit_breaker_check(tc) is None
121
118
 
122
- def test_different_args_not_blocked(self):
119
+ def test_disabled_for_all_args(self):
120
+ """CB disabled — no args are blocked, even after repeated failures."""
123
121
  al = _make_agent()
124
122
  tc1 = SimpleNamespace(tool_name="bash", args_dict={"command":"bad_cmd"})
125
123
  tc2 = SimpleNamespace(tool_name="bash", args_dict={"command":"ls -la"})
126
124
  for _ in range(3):
127
125
  al._circuit_breaker_record(tc1, "FAILED: not found")
128
- assert al._circuit_breaker_check(tc1) is not None # Blocked (failed 3x)
129
- assert al._circuit_breaker_check(tc2) is None # Not blocked
126
+ assert al._circuit_breaker_check(tc1) is None
127
+ assert al._circuit_breaker_check(tc2) is None
130
128
 
131
- def test_different_tools_not_blocked(self):
129
+ def test_disabled_for_all_tools(self):
130
+ """CB disabled — no tools are blocked, even after repeated failures."""
132
131
  al = _make_agent()
133
132
  tc1 = SimpleNamespace(tool_name="bash", args_dict={"command":"bad_cmd"})
134
133
  tc2 = SimpleNamespace(tool_name="grep", args_dict={"pattern":"foo"})
135
134
  for _ in range(3):
136
135
  al._circuit_breaker_record(tc1, "FAILED: not found")
137
- assert al._circuit_breaker_check(tc1) is not None
136
+ assert al._circuit_breaker_check(tc1) is None
138
137
  assert al._circuit_breaker_check(tc2) is None
139
138
 
140
139
  def test_failed_then_success_not_blocked(self):
@@ -143,7 +142,6 @@ class TestCircuitBreaker:
143
142
  tc = SimpleNamespace(tool_name="bash", args_dict={"command":"python3 run.py"})
144
143
  al._circuit_breaker_record(tc, "FAILED: error")
145
144
  al._circuit_breaker_record(tc, "FAILED: error")
146
- # Now it succeeds — last_result no longer starts with FAILED:
147
145
  al._circuit_breaker_record(tc, "output ok")
148
146
  assert al._circuit_breaker_check(tc) is None
149
147