drydock-cli 2.7.16__tar.gz → 2.7.17__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 (668) hide show
  1. drydock_cli-2.7.17/.auto_release.lock +1 -0
  2. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/PKG-INFO +1 -1
  3. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/detectors.py +20 -10
  4. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/agent_loop.py +30 -4
  5. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/format.py +30 -2
  6. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/search_replace.py +59 -11
  7. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/pyproject.toml +1 -1
  8. drydock_cli-2.7.17/tests/core/test_circuit_breaker_readonly_threshold.py +93 -0
  9. drydock_cli-2.7.17/tests/test_admiral_struggle_dedup.py +68 -0
  10. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_truncated_arg_path_hint.py +30 -0
  11. drydock_cli-2.7.17/tests/tools/test_search_replace_dir_path.py +91 -0
  12. drydock_cli-2.7.17/tests/tools/test_search_replace_hard_stop.py +136 -0
  13. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/trip_log.md +69 -0
  14. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/uv.lock +1 -1
  15. drydock_cli-2.7.16/.auto_release.lock +0 -1
  16. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.claude/scheduled_tasks.lock +0 -0
  17. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.github/CODEOWNERS +0 -0
  18. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  19. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  20. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  21. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.github/workflows/build-and-upload.yml +0 -0
  22. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.github/workflows/ci.yml +0 -0
  23. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.github/workflows/issue-labeler.yml +0 -0
  24. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.github/workflows/release.yml +0 -0
  25. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.gitignore +0 -0
  26. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.pre-commit-config.yaml +0 -0
  27. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.python-version +0 -0
  28. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.typos.toml +0 -0
  29. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.vscode/extensions.json +0 -0
  30. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.vscode/launch.json +0 -0
  31. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/.vscode/settings.json +0 -0
  32. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/AGENTS.md +0 -0
  33. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/Admiral.md +0 -0
  34. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/BASELINE_412.md +0 -0
  35. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/CHANGELOG.md +0 -0
  36. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/CLAUDE.md +0 -0
  37. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/CONTRIBUTING.md +0 -0
  38. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/DEPLOYMENT.md +0 -0
  39. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/Drydock_rebrand.md +0 -0
  40. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/LICENSE +0 -0
  41. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/MODEL_SHORTCOMINGS.md +0 -0
  42. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/NOTICE +0 -0
  43. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/OVERNIGHT_PROGRESS.md +0 -0
  44. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
  45. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/PRD.md +0 -0
  46. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/README.md +0 -0
  47. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/action.yml +0 -0
  48. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/README.md +0 -0
  49. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results1.tsv +0 -0
  50. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results13.tsv +0 -0
  51. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results14.tsv +0 -0
  52. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results15.tsv +0 -0
  53. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results16.tsv +0 -0
  54. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results17.tsv +0 -0
  55. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results18.tsv +0 -0
  56. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results19.tsv +0 -0
  57. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results2.tsv +0 -0
  58. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results20.tsv +0 -0
  59. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results3.tsv +0 -0
  60. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results4.tsv +0 -0
  61. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results5.tsv +0 -0
  62. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results6.tsv +0 -0
  63. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results7.tsv +0 -0
  64. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results8.tsv +0 -0
  65. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results9.tsv +0 -0
  66. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/baseline_history/results_evolved_v1.tsv +0 -0
  67. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/distribution/zed/LICENSE +0 -0
  68. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/distribution/zed/extension.toml +0 -0
  69. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/distribution/zed/icons/mistral_vibe.svg +0 -0
  70. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/docs/README.md +0 -0
  71. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/docs/acp-setup.md +0 -0
  72. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/docs/proxy-setup.md +0 -0
  73. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/__init__.py +0 -0
  74. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/__init__.py +0 -0
  75. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/acp_agent_loop.py +0 -0
  76. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/acp_logger.py +0 -0
  77. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/entrypoint.py +0 -0
  78. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/tools/__init__.py +0 -0
  79. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/tools/base.py +0 -0
  80. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/tools/builtins/bash.py +0 -0
  81. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/tools/builtins/read_file.py +0 -0
  82. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/tools/builtins/search_replace.py +0 -0
  83. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/tools/builtins/todo.py +0 -0
  84. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/tools/builtins/write_file.py +0 -0
  85. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/tools/session_update.py +0 -0
  86. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/acp/utils.py +0 -0
  87. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/__init__.py +0 -0
  88. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/detectors_proposed.py +0 -0
  89. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/history.py +0 -0
  90. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/interventions.py +0 -0
  91. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/llm_analyzer.py +0 -0
  92. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/metrics.py +0 -0
  93. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/opus_escalator.py +0 -0
  94. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/persistence.py +0 -0
  95. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/policy.py +0 -0
  96. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/proposer.py +0 -0
  97. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/stager.py +0 -0
  98. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/task_classifier.py +0 -0
  99. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/tuning.py +0 -0
  100. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/validator.py +0 -0
  101. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/admiral/worker.py +0 -0
  102. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/__init__.py +0 -0
  103. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/autocompletion/__init__.py +0 -0
  104. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/autocompletion/base.py +0 -0
  105. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/autocompletion/path_completion.py +0 -0
  106. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/autocompletion/slash_command.py +0 -0
  107. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/cli.py +0 -0
  108. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/clipboard.py +0 -0
  109. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/commands.py +0 -0
  110. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/entrypoint.py +0 -0
  111. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/history_manager.py +0 -0
  112. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  113. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  114. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  115. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/terminal_setup.py +0 -0
  116. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/__init__.py +0 -0
  117. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  118. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/app.py +0 -0
  119. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/app.tcss +0 -0
  120. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/external_editor.py +0 -0
  121. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  122. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  123. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  124. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  125. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  126. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  127. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  128. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  129. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  130. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  131. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  132. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  133. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  134. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  135. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  136. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  137. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  138. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  139. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
  140. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  141. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  142. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  143. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  144. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  145. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  146. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  147. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  148. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  149. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  150. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  151. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  152. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  153. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  154. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  155. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  156. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  157. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  158. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/windowing/history.py +0 -0
  159. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  160. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/textual_ui/windowing/state.py +0 -0
  161. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/update_notifier/__init__.py +0 -0
  162. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  163. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  164. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  165. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  166. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  167. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/update_notifier/update.py +0 -0
  168. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/cli/update_notifier/whats_new.py +0 -0
  169. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/__init__.py +0 -0
  170. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/agents/__init__.py +0 -0
  171. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/agents/manager.py +0 -0
  172. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/agents/models.py +0 -0
  173. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/auth/__init__.py +0 -0
  174. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/auth/crypto.py +0 -0
  175. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/auth/github.py +0 -0
  176. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/__init__.py +0 -0
  177. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/completers.py +0 -0
  178. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  179. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  180. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  181. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  182. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  183. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/fuzzy.py +0 -0
  184. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/path_prompt.py +0 -0
  185. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  186. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/build_orchestrator.py +0 -0
  187. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/checkpoint.py +0 -0
  188. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/config/__init__.py +0 -0
  189. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/config/_settings.py +0 -0
  190. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/config/doctor.py +0 -0
  191. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/config/harness_files/__init__.py +0 -0
  192. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  193. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/config/harness_files/_paths.py +0 -0
  194. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/consultant.py +0 -0
  195. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/drydock_states.py +0 -0
  196. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/hooks.py +0 -0
  197. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/__init__.py +0 -0
  198. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/backend/anthropic.py +0 -0
  199. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/backend/base.py +0 -0
  200. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/backend/factory.py +0 -0
  201. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/backend/generic.py +0 -0
  202. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/backend/mistral.py +0 -0
  203. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  204. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/backend/vertex.py +0 -0
  205. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/exceptions.py +0 -0
  206. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/message_utils.py +0 -0
  207. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/llm/types.py +0 -0
  208. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/logger.py +0 -0
  209. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/middleware.py +0 -0
  210. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/output_formatters.py +0 -0
  211. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/paths/__init__.py +0 -0
  212. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/paths/_drydock_home.py +0 -0
  213. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/paths/_local_config_walk.py +0 -0
  214. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/paths/conventions.py +0 -0
  215. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/plan_session.py +0 -0
  216. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/plugins.py +0 -0
  217. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/programmatic.py +0 -0
  218. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/__init__.py +0 -0
  219. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/builder.md +0 -0
  220. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/cli.md +0 -0
  221. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/compact.md +0 -0
  222. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/dangerous_directory.md +0 -0
  223. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/diagnostic.md +0 -0
  224. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/explore.md +0 -0
  225. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/gemma4.md +0 -0
  226. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/planner.md +0 -0
  227. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/project_context.md +0 -0
  228. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/prompts/tests.md +0 -0
  229. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/proxy_setup.py +0 -0
  230. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/session/agent_memory.py +0 -0
  231. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/session/checkpoints.py +0 -0
  232. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/session/session_loader.py +0 -0
  233. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/session/session_logger.py +0 -0
  234. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/session/session_migration.py +0 -0
  235. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/session/state_file.py +0 -0
  236. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/session_checker.py +0 -0
  237. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/skills/__init__.py +0 -0
  238. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/skills/manager.py +0 -0
  239. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/skills/models.py +0 -0
  240. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/skills/parser.py +0 -0
  241. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/slug.py +0 -0
  242. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/system_prompt.py +0 -0
  243. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/telemetry/__init__.py +0 -0
  244. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/telemetry/send.py +0 -0
  245. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/teleport/errors.py +0 -0
  246. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/teleport/git.py +0 -0
  247. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/teleport/nuage.py +0 -0
  248. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/teleport/teleport.py +0 -0
  249. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/teleport/types.py +0 -0
  250. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/base.py +0 -0
  251. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/_task_manager.py +0 -0
  252. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  253. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/bash.py +0 -0
  254. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/cron.py +0 -0
  255. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  256. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/glob_tool.py +0 -0
  257. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/grep.py +0 -0
  258. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  259. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/lsp.py +0 -0
  260. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  261. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  262. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/powershell.py +0 -0
  263. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  264. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  265. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  266. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  267. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  268. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  269. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  270. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  271. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  272. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  273. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  274. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  275. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  276. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  277. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/task.md +0 -0
  278. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  279. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  280. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  281. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  282. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  283. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  284. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  285. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/read_file.py +0 -0
  286. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/task.py +0 -0
  287. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/todo.py +0 -0
  288. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/tool_search.py +0 -0
  289. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/webfetch.py +0 -0
  290. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/websearch.py +0 -0
  291. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/worktree.py +0 -0
  292. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/builtins/write_file.py +0 -0
  293. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/injection_guard.py +0 -0
  294. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/manager.py +0 -0
  295. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/mcp/__init__.py +0 -0
  296. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/mcp/registry.py +0 -0
  297. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/mcp/tools.py +0 -0
  298. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/mcp_sampling.py +0 -0
  299. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/ui.py +0 -0
  300. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/tools/utils.py +0 -0
  301. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/trusted_folders.py +0 -0
  302. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/types.py +0 -0
  303. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/core/utils.py +0 -0
  304. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/onboarding/__init__.py +0 -0
  305. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/onboarding/base.py +0 -0
  306. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/onboarding/onboarding.tcss +0 -0
  307. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/onboarding/screens/__init__.py +0 -0
  308. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/onboarding/screens/api_key.py +0 -0
  309. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/onboarding/screens/choice.py +0 -0
  310. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/onboarding/screens/local_model.py +0 -0
  311. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/onboarding/screens/welcome.py +0 -0
  312. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  313. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  314. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/__init__.py +0 -0
  315. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/api-design/SKILL.md +0 -0
  316. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/audit-tests/SKILL.md +0 -0
  317. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/batch/SKILL.md +0 -0
  318. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/commit-code/SKILL.md +0 -0
  319. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/context-summary/SKILL.md +0 -0
  320. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/create-presentation/SKILL.md +0 -0
  321. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/deep-research/SKILL.md +0 -0
  322. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/deploy/SKILL.md +0 -0
  323. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/diff-review/SKILL.md +0 -0
  324. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/doc-gen/SKILL.md +0 -0
  325. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/explain-code/SKILL.md +0 -0
  326. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/explore-code/SKILL.md +0 -0
  327. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/fix-issue/SKILL.md +0 -0
  328. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/git-ops/SKILL.md +0 -0
  329. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/init-project/SKILL.md +0 -0
  330. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/investigate/SKILL.md +0 -0
  331. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/loop/SKILL.md +0 -0
  332. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/migrate/SKILL.md +0 -0
  333. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/perf-analyze/SKILL.md +0 -0
  334. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/plan-impl/SKILL.md +0 -0
  335. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/pr-review/SKILL.md +0 -0
  336. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/refactor/SKILL.md +0 -0
  337. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/regex-help/SKILL.md +0 -0
  338. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/review/SKILL.md +0 -0
  339. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/security-review/SKILL.md +0 -0
  340. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/ship/SKILL.md +0 -0
  341. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/simplify/SKILL.md +0 -0
  342. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/strong-tests/SKILL.md +0 -0
  343. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/skills/test-verify/SKILL.md +0 -0
  344. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock/whats_new.md +0 -0
  345. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock-acp.spec +0 -0
  346. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/drydock_terms.md +0 -0
  347. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/flake.lock +0 -0
  348. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/flake.nix +0 -0
  349. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/nohup.out +0 -0
  350. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/README.md +0 -0
  351. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/config_base.toml +0 -0
  352. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/config_best.toml +0 -0
  353. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/domain_spec.md +0 -0
  354. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/experimenter.py +0 -0
  355. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/kernel.py +0 -0
  356. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/mini_prd.md +0 -0
  357. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/mini_prompts.txt +0 -0
  358. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/proposer.py +0 -0
  359. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/research/results.tsv +0 -0
  360. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/resume.md +0 -0
  361. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/README.md +0 -0
  362. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/admiral_probe.py +0 -0
  363. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/audit_sampler.py +0 -0
  364. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/auto_generate_tests.py +0 -0
  365. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/auto_release.sh +0 -0
  366. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/auto_test_loop.sh +0 -0
  367. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/autonomous_review.sh +0 -0
  368. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/autonomous_review_prompt.md +0 -0
  369. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/backup.sh +0 -0
  370. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/bump_version.py +0 -0
  371. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/comprehensive_loop.py +0 -0
  372. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/deploy_to_github.sh +0 -0
  373. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/discover_cli_tools.sh +0 -0
  374. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/evolve_tests.py +0 -0
  375. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/gen_2000_prompts.py +0 -0
  376. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/install.sh +0 -0
  377. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/llm_balancer.py +0 -0
  378. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/mega_loop.py +0 -0
  379. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/meta_ralph_loop.py +0 -0
  380. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/monitor_swebench.sh +0 -0
  381. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/monitor_test_battery.sh +0 -0
  382. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/notify_release.py +0 -0
  383. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/oss_task_harness.py +0 -0
  384. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/overnight_agents_test.sh +0 -0
  385. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/poll_issues.sh +0 -0
  386. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/port_task.py +0 -0
  387. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/prepare_release.py +0 -0
  388. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/publish_to_pypi.sh +0 -0
  389. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/ralph_loop.py +0 -0
  390. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/research_babysitter.sh +0 -0
  391. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/session_loop_audit.py +0 -0
  392. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/shakedown.py +0 -0
  393. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/shakedown_interactive.py +0 -0
  394. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/shakedown_regression.sh +0 -0
  395. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/shakedown_suite.sh +0 -0
  396. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/shakedown_variance.sh +0 -0
  397. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/stress_babysitter.sh +0 -0
  398. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/stress_prompts_50.txt +0 -0
  399. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/stress_prompts_realuser.txt +0 -0
  400. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/stress_prompts_tool_agent.txt +0 -0
  401. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
  402. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/stress_shakedown.py +0 -0
  403. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/stress_telegram_status.py +0 -0
  404. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/stress_watcher.py +0 -0
  405. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/telegram_bot.py +0 -0
  406. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/test_bank.sh +0 -0
  407. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/test_full.sh +0 -0
  408. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/test_smoke.sh +0 -0
  409. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/test_tui_path.py +0 -0
  410. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/tui_test.py +0 -0
  411. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/scripts/vllm_failover.sh +0 -0
  412. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/test/project/dummy +0 -0
  413. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/__init__.py +0 -0
  414. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/conftest.py +0 -0
  415. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_acp.py +0 -0
  416. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_agent_thought.py +0 -0
  417. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_bash.py +0 -0
  418. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_compact_session_updates.py +0 -0
  419. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_content.py +0 -0
  420. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_initialize.py +0 -0
  421. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_list_sessions.py +0 -0
  422. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_load_session.py +0 -0
  423. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_multi_session.py +0 -0
  424. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_new_session.py +0 -0
  425. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_proxy_setup_acp.py +0 -0
  426. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_read_file.py +0 -0
  427. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_search_replace.py +0 -0
  428. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_set_config_option.py +0 -0
  429. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_set_mode.py +0 -0
  430. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_set_model.py +0 -0
  431. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_tool_call_session_update.py +0 -0
  432. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_utils.py +0 -0
  433. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/acp/test_write_file.py +0 -0
  434. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/autocompletion/test_file_indexer.py +0 -0
  435. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/autocompletion/test_fuzzy.py +0 -0
  436. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  437. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  438. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/autocompletion/test_path_completion_controller.py +0 -0
  439. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  440. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/autocompletion/test_slash_command_controller.py +0 -0
  441. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  442. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/backend/__init__.py +0 -0
  443. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/backend/data/__init__.py +0 -0
  444. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/backend/data/fireworks.py +0 -0
  445. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/backend/data/mistral.py +0 -0
  446. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/backend/test_anthropic_adapter.py +0 -0
  447. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/backend/test_backend.py +0 -0
  448. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/backend/test_generic_adapter_sanitize.py +0 -0
  449. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/backend/test_reasoning_adapter.py +0 -0
  450. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  451. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  452. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  453. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  454. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_bell_notifications.py +0 -0
  455. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_braille_renderer.py +0 -0
  456. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_clipboard.py +0 -0
  457. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_commands.py +0 -0
  458. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_copy_shortcuts.py +0 -0
  459. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_external_editor.py +0 -0
  460. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_no_markup_static.py +0 -0
  461. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_question_app.py +0 -0
  462. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_spinner.py +0 -0
  463. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_switching_mode.py +0 -0
  464. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  465. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  466. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_ui_session_resume.py +0 -0
  467. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/test_ui_skill_dispatch.py +0 -0
  468. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/textual_ui/__init__.py +0 -0
  469. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/cli/textual_ui/test_session_picker.py +0 -0
  470. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/conftest.py +0 -0
  471. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_agents.py +0 -0
  472. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_auth_crypto.py +0 -0
  473. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_auth_github.py +0 -0
  474. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_config_load_dotenv.py +0 -0
  475. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_config_paths.py +0 -0
  476. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_config_resolution.py +0 -0
  477. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_file_logging.py +0 -0
  478. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_plan_session.py +0 -0
  479. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_proxy_setup.py +0 -0
  480. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_slug.py +0 -0
  481. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_telemetry_send.py +0 -0
  482. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_teleport_git.py +0 -0
  483. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_teleport_nuage.py +0 -0
  484. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_teleport_service.py +0 -0
  485. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_trusted_folders.py +0 -0
  486. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/core/test_utils.py +0 -0
  487. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/e2e/common.py +0 -0
  488. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/e2e/conftest.py +0 -0
  489. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/e2e/mock_server.py +0 -0
  490. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  491. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/e2e/test_cli_tui_streaming.py +0 -0
  492. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  493. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/fixtures/doc_qa_system_prd.md +0 -0
  494. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/mock/__init__.py +0 -0
  495. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/mock/mock_backend_factory.py +0 -0
  496. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/mock/mock_entrypoint.py +0 -0
  497. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/mock/utils.py +0 -0
  498. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/onboarding/test_run_onboarding.py +0 -0
  499. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/onboarding/test_ui_onboarding.py +0 -0
  500. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/session/test_session_loader.py +0 -0
  501. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/session/test_session_logger.py +0 -0
  502. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/session/test_session_migration.py +0 -0
  503. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/skills/conftest.py +0 -0
  504. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/skills/test_manager.py +0 -0
  505. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/skills/test_models.py +0 -0
  506. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/skills/test_parser.py +0 -0
  507. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  508. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  509. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  510. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  511. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  512. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  513. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  514. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  515. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  516. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  517. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  518. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  519. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  520. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  521. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  522. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  523. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  524. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  525. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  526. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  527. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  528. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  529. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  530. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  531. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  532. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  533. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  534. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  535. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  536. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  537. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  538. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  539. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  540. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  541. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  542. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  543. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  544. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  545. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  546. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  547. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  548. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  549. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  550. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  551. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  552. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  553. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  554. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  555. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  556. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  557. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  558. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  559. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  560. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  561. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  562. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  563. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  564. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  565. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  566. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  567. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/base_snapshot_test_app.py +0 -0
  568. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/conftest.py +0 -0
  569. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/snap_compare.py +0 -0
  570. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  571. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  572. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  573. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  574. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  575. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  576. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  577. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  578. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  579. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  580. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  581. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  582. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  583. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  584. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/stubs/fake_backend.py +0 -0
  585. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/stubs/fake_client.py +0 -0
  586. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/stubs/fake_tool.py +0 -0
  587. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_admiral.py +0 -0
  588. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_admiral_phase3.py +0 -0
  589. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_admiral_proposed.py +0 -0
  590. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_agent_auto_compact.py +0 -0
  591. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_agent_backend.py +0 -0
  592. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_agent_observer_streaming.py +0 -0
  593. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_agent_stats.py +0 -0
  594. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_agent_tasks.py +0 -0
  595. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_agent_tool_call.py +0 -0
  596. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_agents.py +0 -0
  597. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_bank_build.py +0 -0
  598. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_bank_debug.py +0 -0
  599. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_bank_multiagent.py +0 -0
  600. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_bank_prd.py +0 -0
  601. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_bank_prd_extended.py +0 -0
  602. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_bank_tools.py +0 -0
  603. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_bank_update.py +0 -0
  604. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_build_projects.py +0 -0
  605. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_checkpoint.py +0 -0
  606. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_cli_programmatic_preload.py +0 -0
  607. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_current_bugs.py +0 -0
  608. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_drydock_regression.py +0 -0
  609. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_drydock_tasks.py +0 -0
  610. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_fake_tool_call_paren_syntax.py +0 -0
  611. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_full_regression.py +0 -0
  612. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_history_manager.py +0 -0
  613. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_integration.py +0 -0
  614. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_issue_fixes.py +0 -0
  615. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_loop_detection.py +0 -0
  616. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_message_id.py +0 -0
  617. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_message_merging.py +0 -0
  618. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_middleware.py +0 -0
  619. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_multi_agent.py +0 -0
  620. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_read_file_not_found_listing.py +0 -0
  621. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_real_failures.py +0 -0
  622. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_real_issues.py +0 -0
  623. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_real_workflow.py +0 -0
  624. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_reasoning_content.py +0 -0
  625. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_smoke.py +0 -0
  626. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_system_prompt.py +0 -0
  627. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_tagged_text.py +0 -0
  628. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_tool_args.py +0 -0
  629. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_truncate_args_valid_json.py +0 -0
  630. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_ui_external_editor.py +0 -0
  631. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_ui_input_history.py +0 -0
  632. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_user_issues.py +0 -0
  633. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_wall_of_text_rescue.py +0 -0
  634. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/test_workloads.py +0 -0
  635. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/testbank_helpers.py +0 -0
  636. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_ask_user_question.py +0 -0
  637. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_bash.py +0 -0
  638. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_exit_plan_mode.py +0 -0
  639. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_grep.py +0 -0
  640. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_invoke_context.py +0 -0
  641. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_manager_gemma_derived_models.py +0 -0
  642. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_manager_get_tool_config.py +0 -0
  643. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_mcp.py +0 -0
  644. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_mcp_sampling.py +0 -0
  645. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_read_file_directory.py +0 -0
  646. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_search_replace_append_fallback.py +0 -0
  647. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -0
  648. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
  649. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_task.py +0 -0
  650. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_ui_bash_execution.py +0 -0
  651. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_webfetch.py +0 -0
  652. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_websearch.py +0 -0
  653. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
  654. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/tools/test_write_file_missing_path_hint.py +0 -0
  655. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  656. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  657. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/update_notifier/test_do_update.py +0 -0
  658. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  659. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/update_notifier/test_github_update_gateway.py +0 -0
  660. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  661. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/update_notifier/test_ui_update_notification.py +0 -0
  662. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/update_notifier/test_update_use_case.py +0 -0
  663. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/tests/update_notifier/test_whats_new.py +0 -0
  664. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/worked_examples/README.md +0 -0
  665. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/worked_examples/cli_subcommand_dispatch.py +0 -0
  666. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/worked_examples/lookup.json +0 -0
  667. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/worked_examples/sql_parser.py +0 -0
  668. {drydock_cli-2.7.16 → drydock_cli-2.7.17}/worked_examples/tree_walking_interpreter.py +0 -0
@@ -0,0 +1 @@
1
+ 291967
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 2.7.16
3
+ Version: 2.7.17
4
4
  Summary: Local-first CLI coding agent — tested with Gemma 4 26B via vLLM
5
5
  Project-URL: Homepage, https://github.com/fbobe321/drydock
6
6
  Project-URL: Repository, https://github.com/fbobe321/drydock
@@ -80,18 +80,28 @@ def detect_struggle(messages: Sequence[LLMMessage], threshold: int = 20) -> Find
80
80
  calls_since_write += 1
81
81
  if calls_since_write < threshold:
82
82
  return None
83
- hint = (
84
- "Either (a) you already have enough context commit to a plan and "
85
- "start writing code now, or (b) you're genuinely stuck stop and "
86
- "report what's blocking you to the user."
87
- )
88
- return Finding(
89
- code=f"struggle:{calls_since_write}:{last_write_tool or 'none'}",
90
- directive=(
83
+ # Stable code (no count) so DEDUP_WINDOW_SEC suppresses repeated firings.
84
+ # Previously included the count, which caused 33 identical interventions
85
+ # in a single session (each with a unique key that bypassed dedup).
86
+ code = f"struggle:{last_write_tool or 'none'}"
87
+ if calls_since_write >= 30:
88
+ directive = (
89
+ f"Admiral: you have made {calls_since_write} tool calls without "
90
+ f"writing any file — search_replace is clearly not finding the text. "
91
+ f"STOP retrying. Call `write_file` with `overwrite=True` to rewrite "
92
+ f"the target file from scratch right now."
93
+ )
94
+ else:
95
+ hint = (
96
+ "Either (a) you already have enough context — commit to a plan and "
97
+ "start writing code now, or (b) you're genuinely stuck — stop and "
98
+ "report what's blocking you to the user."
99
+ )
100
+ directive = (
91
101
  f"Admiral: you have made {calls_since_write} tool calls without "
92
102
  f"writing or editing any file. {hint}"
93
- ),
94
- )
103
+ )
104
+ return Finding(code=code, directive=directive)
95
105
 
96
106
 
97
107
  def run_all(messages: Sequence[LLMMessage]) -> list[Finding]:
@@ -1131,10 +1131,12 @@ class AgentLoop:
1131
1131
  token-level sampling bumps don't help when the model picks
1132
1132
  the SAME serialized args every time.
1133
1133
 
1134
- Conservative thresholds only fires on truly pathological
1135
- repeat counts that would never be a "valid retry":
1134
+ Thresholds tuned for 45-prompt session windows (stress sessions
1135
+ reset every 45 prompts — a threshold of 12 never fires in practice
1136
+ because the model loops 4-8 times then moves on; admiral advisories
1137
+ fire at 3 but the model ignores them):
1136
1138
  search_replace, write_file, bash: after 8 identical calls
1137
- read_file, grep, glob, ls: after 12 identical calls
1139
+ read_file, grep, glob, ls: after 5 identical calls
1138
1140
  """
1139
1141
  args_str = json.dumps(tool_call.args_dict, sort_keys=True, default=str)
1140
1142
  sig = hashlib.sha256(
@@ -1143,7 +1145,7 @@ class AgentLoop:
1143
1145
  count, last_result = self._tool_call_history.get(sig, (0, ""))
1144
1146
  tool_name = tool_call.tool_name
1145
1147
  is_readonly = tool_name in ("grep", "read_file", "glob", "ls")
1146
- threshold = 12 if is_readonly else 8
1148
+ threshold = 5 if is_readonly else 8
1147
1149
  if count < threshold:
1148
1150
  return None
1149
1151
  return (
@@ -2379,6 +2381,30 @@ class AgentLoop:
2379
2381
  if len(recent_sr) >= 2 and recent_sr[0] == recent_sr[1]:
2380
2382
  return "WARNING|search_replace"
2381
2383
 
2384
+ # Early check: write_file with _truncated args twice in a row for the
2385
+ # same path. format.py already embeds the file content in the error,
2386
+ # but Gemma 4 ignores the advisory and retries identically. Mute
2387
+ # write_file for 1 turn so the model must use read_file or
2388
+ # search_replace instead — same pattern as the search_replace check.
2389
+ recent_wf_truncated: list[str] = []
2390
+ for msg in reversed(self.messages[-20:]):
2391
+ if msg.role == Role.assistant and msg.tool_calls:
2392
+ for tc in msg.tool_calls:
2393
+ if tc.function and tc.function.name == "write_file":
2394
+ try:
2395
+ args = json.loads(tc.function.arguments or "{}")
2396
+ if args.get("_truncated"):
2397
+ p = (args.get("file_path") or args.get("path") or "")
2398
+ recent_wf_truncated.append(p)
2399
+ except (json.JSONDecodeError, AttributeError):
2400
+ pass
2401
+ if len(recent_wf_truncated) >= 2:
2402
+ break
2403
+ if (len(recent_wf_truncated) >= 2
2404
+ and recent_wf_truncated[0] == recent_wf_truncated[1]):
2405
+ self._hot_tool_path = ("write_file", recent_wf_truncated[0])
2406
+ return "FORCE_STOP"
2407
+
2382
2408
  sigs: list[str] = []
2383
2409
  tool_names: list[str] = []
2384
2410
  lookback = 0
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import json
4
4
  import logging
5
5
  import re as _re
6
+ from pathlib import Path
6
7
  from typing import TYPE_CHECKING, Any
7
8
 
8
9
  from pydantic import BaseModel, ConfigDict, Field, ValidationError
@@ -378,7 +379,34 @@ class APIToolFormatHandler:
378
379
  path_hint = (parsed_call.raw_args.get("path")
379
380
  or parsed_call.raw_args.get("file_path")
380
381
  or "")
381
- hint = f" Re-read `{path_hint}` with read_file first." if path_hint else ""
382
+ # Auto-embed the current file content so the model can
383
+ # rewrite immediately without an extra read_file round-trip.
384
+ file_embed = ""
385
+ if path_hint:
386
+ try:
387
+ p = Path(path_hint)
388
+ if p.exists() and p.is_file():
389
+ raw = p.read_text(errors="replace")
390
+ lines = raw.splitlines()
391
+ max_lines = 120
392
+ if len(lines) <= max_lines:
393
+ file_embed = (
394
+ f"\n\nCurrent file content of `{path_hint}`:\n"
395
+ f"```\n{raw}\n```\n"
396
+ f"Rewrite it now using write_file with the correct content."
397
+ )
398
+ else:
399
+ snippet = "\n".join(lines[:max_lines])
400
+ file_embed = (
401
+ f"\n\nCurrent file content of `{path_hint}` "
402
+ f"(first {max_lines} of {len(lines)} lines):\n"
403
+ f"```\n{snippet}\n```\n"
404
+ f"Use read_file to see the rest, then rewrite with write_file."
405
+ )
406
+ except Exception:
407
+ pass
408
+ if not file_embed and path_hint:
409
+ file_embed = f" Re-read `{path_hint}` with read_file first."
382
410
  failed_calls.append(
383
411
  FailedToolCall(
384
412
  tool_name=parsed_call.tool_name,
@@ -387,7 +415,7 @@ class APIToolFormatHandler:
387
415
  f"{parsed_call.tool_name}: your call used a "
388
416
  f"truncated history entry as a template (it contained "
389
417
  f"'_truncated'/'_original_bytes' instead of real "
390
- f"arguments).{hint} Provide the full required arguments."
418
+ f"arguments).{file_embed} Provide the full required arguments."
391
419
  ),
392
420
  )
393
421
  )
@@ -131,6 +131,34 @@ class SearchReplace(
131
131
  file_path, search_replace_blocks = self._prepare_and_validate_args(args)
132
132
  except ToolError as e:
133
133
  err_msg = str(e)
134
+ if err_msg.startswith("Path is not a file:"):
135
+ # Model passed a directory instead of a file path.
136
+ # Return a result (not raise) so the model corrects the call
137
+ # rather than retrying the same directory path in a loop.
138
+ dir_path_str = args.file_path.strip()
139
+ dir_path = Path(dir_path_str).expanduser()
140
+ if not dir_path.is_absolute():
141
+ dir_path = Path.cwd() / dir_path
142
+ dir_path = dir_path.resolve()
143
+ if dir_path.is_dir():
144
+ try:
145
+ files = sorted(p.name for p in dir_path.iterdir() if p.is_file())
146
+ except OSError:
147
+ files = []
148
+ files_list = "\n".join(f" {f}" for f in files[:20]) or " (empty directory)"
149
+ yield SearchReplaceResult(
150
+ file=str(dir_path),
151
+ blocks_applied=0,
152
+ lines_changed=0,
153
+ content=(
154
+ f"PATH ERROR: '{dir_path}' is a directory, not a file. "
155
+ f"search_replace requires a path to a specific file.\n"
156
+ f"Files in that directory:\n{files_list}\n"
157
+ f"Specify the full path including the filename, e.g. "
158
+ f"'{dir_path}/<filename.py>'"
159
+ ),
160
+ )
161
+ return
134
162
  if err_msg.startswith("NO_BLOCKS:"):
135
163
  # Gemma 4 sent raw code without SEARCH/REPLACE markers.
136
164
  # CAREFULLY fall back to full file overwrite — but refuse if
@@ -383,18 +411,38 @@ class SearchReplace(
383
411
  state[fail_key] = entry
384
412
  if entry["count"] >= 2:
385
413
  try:
386
- head = original_content[:2000]
387
414
  line_count = original_content.count("\n")
388
- error_message += (
389
- f"\n\n[LOOP-BREAKER: this is the #{entry['count']} "
390
- f"consecutive search_replace failure on "
391
- f"{file_path.name}. Stop retrying the same search. "
392
- f"Actual file content (first 2000 chars of "
393
- f"{line_count} lines):\n"
394
- f"-----FILE START-----\n{head}\n-----FILE END-----\n"
395
- f"Use THIS exact text as your search target, OR "
396
- f"abandon this edit and try write_file.]"
397
- )
415
+ count = entry["count"]
416
+ if count >= 3:
417
+ # Show full file (up to 4000 chars) and prohibit retry.
418
+ body = original_content[:4000]
419
+ tail = (
420
+ f"\n...[truncated, {line_count} lines total]"
421
+ if len(original_content) > 4000 else ""
422
+ )
423
+ error_message += (
424
+ f"\n\n[HARD-STOP: this is the #{count} consecutive "
425
+ f"search_replace failure on {file_path.name}. "
426
+ f"Your search text was NOT found in the file. "
427
+ f"DO NOT retry search_replace with the same or similar text. "
428
+ f"REQUIRED action: call write_file with overwrite=True "
429
+ f"and provide the complete new file content. "
430
+ f"Full file content below — use this as the basis "
431
+ f"for your write_file call:\n"
432
+ f"-----FILE START-----\n{body}{tail}\n-----FILE END-----]"
433
+ )
434
+ else:
435
+ head = original_content[:2000]
436
+ error_message += (
437
+ f"\n\n[LOOP-BREAKER: this is the #{count} "
438
+ f"consecutive search_replace failure on "
439
+ f"{file_path.name}. Stop retrying the same search. "
440
+ f"Actual file content (first 2000 chars of "
441
+ f"{line_count} lines):\n"
442
+ f"-----FILE START-----\n{head}\n-----FILE END-----\n"
443
+ f"Use THIS exact text as your search target, OR "
444
+ f"abandon this edit and try write_file.]"
445
+ )
398
446
  except Exception:
399
447
  pass
400
448
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "drydock-cli"
3
- version = "2.7.16"
3
+ version = "2.7.17"
4
4
  description = "Local-first CLI coding agent — tested with Gemma 4 26B via vLLM"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -0,0 +1,93 @@
1
+ """Regression test: read_file circuit breaker fires at threshold 5, not 12.
2
+
3
+ Stress sessions reset every 45 prompts. With threshold=12, the model could
4
+ loop 11× on the same read_file call before being blocked — admiral advisories
5
+ fire at 3× but are ignored. Threshold=5 actually engages the block before
6
+ the session's budget is exhausted.
7
+ """
8
+ import hashlib
9
+ import json
10
+ import unittest
11
+ from unittest.mock import MagicMock
12
+
13
+
14
+ def _make_circuit_breaker_check():
15
+ """Import and bind just the circuit breaker logic for unit testing."""
16
+ from drydock.core.agent_loop import AgentLoop
17
+
18
+ loop = AgentLoop.__new__(AgentLoop)
19
+ loop._tool_call_history = {}
20
+ loop._get_attempted_summary = lambda: ""
21
+ return loop
22
+
23
+
24
+ class TestCircuitBreakerReadonlyThreshold(unittest.TestCase):
25
+ def _make_tool_call(self, name, args):
26
+ tc = MagicMock()
27
+ tc.tool_name = name
28
+ tc.args_dict = args
29
+ tc.call_id = "test-id"
30
+ return tc
31
+
32
+ def _record(self, loop, tool_call, result="some content"):
33
+ from drydock.core.agent_loop import AgentLoop
34
+ AgentLoop._circuit_breaker_record(loop, tool_call, result)
35
+
36
+ def test_read_file_blocks_at_5(self):
37
+ """Circuit breaker fires on the 6th identical call (threshold=5 means count>=5 blocks)."""
38
+ loop = _make_circuit_breaker_check()
39
+ tc = self._make_tool_call("read_file", {"path": "foo.py", "offset": 150, "limit": 100})
40
+
41
+ # First 5 calls: should not block
42
+ for i in range(5):
43
+ result = loop._circuit_breaker_check(tc)
44
+ self.assertIsNone(result, f"Expected no block on call {i+1}, got: {result}")
45
+ self._record(loop, tc)
46
+
47
+ # 6th call: should block (count=5 >= threshold=5)
48
+ result = loop._circuit_breaker_check(tc)
49
+ self.assertIsNotNone(result, "Expected circuit breaker to fire on 6th identical read_file")
50
+ self.assertIn("read_file", result)
51
+
52
+ def test_bash_still_blocks_at_8(self):
53
+ """bash threshold=8, so blocks on 9th call (count=8 >= threshold=8)."""
54
+ loop = _make_circuit_breaker_check()
55
+ tc = self._make_tool_call("bash", {"command": "ls -la"})
56
+
57
+ for i in range(8):
58
+ result = loop._circuit_breaker_check(tc)
59
+ self.assertIsNone(result, f"Expected no block on bash call {i+1}")
60
+ self._record(loop, tc)
61
+
62
+ result = loop._circuit_breaker_check(tc)
63
+ self.assertIsNotNone(result, "Expected circuit breaker to fire on 9th identical bash")
64
+
65
+ def test_grep_blocks_at_5(self):
66
+ loop = _make_circuit_breaker_check()
67
+ tc = self._make_tool_call("grep", {"pattern": "def foo", "path": "bar.py"})
68
+
69
+ for i in range(5):
70
+ result = loop._circuit_breaker_check(tc)
71
+ self.assertIsNone(result)
72
+ self._record(loop, tc)
73
+
74
+ # 6th call blocks (count=5 >= threshold=5)
75
+ result = loop._circuit_breaker_check(tc)
76
+ self.assertIsNotNone(result, "Expected circuit breaker to fire on 6th identical grep")
77
+
78
+ def test_different_args_not_blocked(self):
79
+ loop = _make_circuit_breaker_check()
80
+
81
+ # 5 reads of foo.py at offset 150
82
+ tc1 = self._make_tool_call("read_file", {"path": "foo.py", "offset": 150})
83
+ for _ in range(5):
84
+ self._record(loop, tc1)
85
+
86
+ # Different offset should not be blocked
87
+ tc2 = self._make_tool_call("read_file", {"path": "foo.py", "offset": 200})
88
+ result = loop._circuit_breaker_check(tc2)
89
+ self.assertIsNone(result, "Different args should not be blocked")
90
+
91
+
92
+ if __name__ == "__main__":
93
+ unittest.main()
@@ -0,0 +1,68 @@
1
+ """Regression tests for struggle detector dedup fix.
2
+
3
+ Before the fix, the finding code was f"struggle:{count}:{tool}" — each count
4
+ was a unique key, bypassing DEDUP_WINDOW_SEC and producing 33 identical
5
+ interventions in one session that the model ignored.
6
+
7
+ After the fix, the code is stable (f"struggle:{tool}") so a single entry
8
+ in recent_findings suppresses repeat firings within the 60-second window.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ from drydock.admiral.detectors import detect_struggle
13
+ from drydock.core.types import FunctionCall, LLMMessage, Role, ToolCall
14
+
15
+
16
+ def _assistant(tool: str, args: str = "{}") -> LLMMessage:
17
+ return LLMMessage(
18
+ role=Role.assistant,
19
+ content="",
20
+ tool_calls=[ToolCall(function=FunctionCall(name=tool, arguments=args))],
21
+ )
22
+
23
+
24
+ def _make_msgs(write_tool: str, non_write_count: int) -> list[LLMMessage]:
25
+ msgs: list[LLMMessage] = [LLMMessage(role=Role.user, content="build it")]
26
+ msgs.append(_assistant(write_tool, '{"path":"x.py","content":"x"}'))
27
+ msgs.append(LLMMessage(role=Role.tool, content="ok"))
28
+ for i in range(non_write_count):
29
+ msgs.append(_assistant("read_file", f'{{"path":"f{i}.py"}}'))
30
+ msgs.append(LLMMessage(role=Role.tool, content="content"))
31
+ return msgs
32
+
33
+
34
+ def test_struggle_code_is_stable_no_count() -> None:
35
+ """Finding code must NOT include the count so dedup works across counts."""
36
+ msgs20 = _make_msgs("search_replace", 20)
37
+ msgs33 = _make_msgs("search_replace", 33)
38
+ f20 = detect_struggle(msgs20)
39
+ f33 = detect_struggle(msgs33)
40
+ assert f20 is not None
41
+ assert f33 is not None
42
+ # Same stable code regardless of count
43
+ assert f20.code == f33.code
44
+ assert "20" not in f20.code
45
+ assert "33" not in f33.code
46
+
47
+
48
+ def test_struggle_escalated_directive_at_30() -> None:
49
+ """At 30+ non-write calls, directive must mention write_file overwrite."""
50
+ msgs = _make_msgs("search_replace", 30)
51
+ f = detect_struggle(msgs)
52
+ assert f is not None
53
+ assert "write_file" in f.directive
54
+ assert "overwrite" in f.directive
55
+
56
+
57
+ def test_struggle_gentle_directive_below_30() -> None:
58
+ """Below 30, directive is the gentle nudge (no overwrite mention)."""
59
+ msgs = _make_msgs("search_replace", 22)
60
+ f = detect_struggle(msgs)
61
+ assert f is not None
62
+ assert "overwrite" not in f.directive
63
+ assert "commit to a plan" in f.directive
64
+
65
+
66
+ def test_struggle_no_fire_below_threshold() -> None:
67
+ msgs = _make_msgs("write_file", 5)
68
+ assert detect_struggle(msgs) is None
@@ -92,3 +92,33 @@ class TestTruncatedArgPathHint:
92
92
  assert len(result.failed_calls) == 1
93
93
  assert "Re-read" not in result.failed_calls[0].error
94
94
  assert "_truncated" in result.failed_calls[0].error or "truncated" in result.failed_calls[0].error
95
+
96
+ def test_existing_file_content_embedded(self, tmp_path):
97
+ """When the target file exists, its content is embedded in the error
98
+ so the model can rewrite without an extra read_file round-trip."""
99
+ target = tmp_path / "utils.py"
100
+ target.write_text("def hello():\n return 42\n")
101
+
102
+ handler = APIToolFormatHandler()
103
+ parsed = ParsedMessage(
104
+ tool_calls=[
105
+ ParsedToolCall(
106
+ tool_name="write_file",
107
+ call_id="tc4",
108
+ raw_args={
109
+ "_truncated": True,
110
+ "_original_bytes": 4096,
111
+ "file_path": str(target),
112
+ },
113
+ )
114
+ ]
115
+ )
116
+ tm = _make_tool_manager_with("write_file", _make_write_file_class())
117
+ result = handler.resolve_tool_calls(parsed, tm)
118
+ assert len(result.failed_calls) == 1
119
+ err = result.failed_calls[0].error
120
+ # Content should be embedded, not just a Re-read directive
121
+ assert "def hello():" in err
122
+ assert "return 42" in err
123
+ # Re-read advisory should NOT appear when content is embedded
124
+ assert "Re-read" not in err
@@ -0,0 +1,91 @@
1
+ """Regression test: search_replace returns actionable result when passed a directory.
2
+
3
+ Admiral logs (2026-04-28) showed 38 instances of retry_after_error:search_replace
4
+ with error head 'file: /data3/.../tool_agent' — the model was passing the package
5
+ directory path instead of a specific file path. The old code raised ToolError
6
+ ("Path is not a file") which the framework turned into a tool error, and the model
7
+ retried the same bad path in a loop.
8
+
9
+ Fix: catch the directory-path case in run() and yield a SearchReplaceResult listing
10
+ the files in the directory. The model can then correct the path instead of looping.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import os
15
+ from pathlib import Path
16
+
17
+ import pytest
18
+
19
+ from drydock.core.tools.base import BaseToolState, InvokeContext
20
+ from drydock.core.tools.builtins.search_replace import (
21
+ SearchReplace,
22
+ SearchReplaceArgs,
23
+ SearchReplaceConfig,
24
+ SearchReplaceResult,
25
+ )
26
+
27
+
28
+ async def _collect(gen):
29
+ results = []
30
+ async for item in gen:
31
+ results.append(item)
32
+ return results
33
+
34
+
35
+ @pytest.fixture
36
+ def tool():
37
+ return SearchReplace(SearchReplaceConfig(), BaseToolState())
38
+
39
+
40
+ @pytest.fixture
41
+ def ctx() -> InvokeContext:
42
+ return InvokeContext(tool_call_id="tc_1", read_file_state={})
43
+
44
+
45
+ @pytest.mark.asyncio
46
+ async def test_directory_path_returns_result_not_error(tool, ctx, tmp_path):
47
+ """Passing a directory path should yield a SearchReplaceResult with the file list."""
48
+ # Create some files in the temp dir
49
+ (tmp_path / "cli.py").write_text("print('cli')\n")
50
+ (tmp_path / "tools.py").write_text("def run(): pass\n")
51
+
52
+ args = SearchReplaceArgs(
53
+ file_path=str(tmp_path),
54
+ content="<<<<<<< SEARCH\nold\n=======\nnew\n>>>>>>> REPLACE",
55
+ )
56
+ results = await _collect(tool.run(args, ctx))
57
+ assert results, "expected at least one result"
58
+ result = results[-1]
59
+ assert isinstance(result, SearchReplaceResult)
60
+ assert result.blocks_applied == 0
61
+ assert "PATH ERROR" in result.content
62
+ assert "cli.py" in result.content
63
+ assert "tools.py" in result.content
64
+
65
+
66
+ @pytest.mark.asyncio
67
+ async def test_directory_path_does_not_raise(tool, ctx, tmp_path):
68
+ """Verify no exception propagates when a directory path is given."""
69
+ args = SearchReplaceArgs(
70
+ file_path=str(tmp_path),
71
+ content="<<<<<<< SEARCH\nold\n=======\nnew\n>>>>>>> REPLACE",
72
+ )
73
+ # Should not raise
74
+ results = await _collect(tool.run(args, ctx))
75
+ assert any(isinstance(r, SearchReplaceResult) for r in results)
76
+
77
+
78
+ @pytest.mark.asyncio
79
+ async def test_directory_path_repeated_call_still_returns_result(tool, ctx, tmp_path):
80
+ """Second call with the same directory path still returns a result (not an error)."""
81
+ (tmp_path / "main.py").write_text("x = 1\n")
82
+ args = SearchReplaceArgs(
83
+ file_path=str(tmp_path),
84
+ content="<<<<<<< SEARCH\nold\n=======\nnew\n>>>>>>> REPLACE",
85
+ )
86
+ for _ in range(3):
87
+ results = await _collect(tool.run(args, ctx))
88
+ result = results[-1]
89
+ assert isinstance(result, SearchReplaceResult)
90
+ assert result.blocks_applied == 0
91
+ assert "PATH ERROR" in result.content