drydock-cli 2.7.38__tar.gz → 2.7.40__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 (745) hide show
  1. drydock_cli-2.7.40/.auto_release.lock +1 -0
  2. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/PKG-INFO +1 -1
  3. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/messages.py +14 -0
  4. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/agent_loop.py +197 -4
  5. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/_settings.py +12 -0
  6. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/local_detect.py +13 -0
  7. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/gemma4.md +9 -0
  8. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/steering_hook.py +18 -6
  9. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/bash.py +71 -0
  10. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/search_replace.py +11 -0
  11. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/pyproject.toml +1 -1
  12. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/hle_eval.py +8 -3
  13. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/notify_release.py +11 -0
  14. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_issue_fixes.py +101 -1
  15. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_local_detect.py +74 -0
  16. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_wall_of_text_rescue.py +30 -0
  17. drydock_cli-2.7.40/tests/tools/test_bash_exact_cmd_loop_breaker.py +59 -0
  18. drydock_cli-2.7.40/tests/tools/test_bash_python_c_syntaxerr_loop_breaker.py +57 -0
  19. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/trip_log.md +287 -0
  20. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/uv.lock +1 -1
  21. drydock_cli-2.7.38/.auto_release.lock +0 -1
  22. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.claude/scheduled_tasks.lock +0 -0
  23. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/CODEOWNERS +0 -0
  24. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  25. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  26. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  27. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/workflows/build-and-upload.yml +0 -0
  28. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/workflows/ci.yml +0 -0
  29. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/workflows/issue-labeler.yml +0 -0
  30. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.github/workflows/release.yml +0 -0
  31. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.gitignore +0 -0
  32. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.perf_baseline_done +0 -0
  33. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.pre-commit-config.yaml +0 -0
  34. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.python-version +0 -0
  35. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.typos.toml +0 -0
  36. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.vscode/extensions.json +0 -0
  37. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.vscode/launch.json +0 -0
  38. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/.vscode/settings.json +0 -0
  39. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/AGENTS.md +0 -0
  40. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/Admiral.md +0 -0
  41. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/BASELINE_412.md +0 -0
  42. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/CHANGELOG.md +0 -0
  43. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/CLAUDE.md +0 -0
  44. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/CONTRIBUTING.md +0 -0
  45. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/DEPLOYMENT.md +0 -0
  46. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/Drydock_rebrand.md +0 -0
  47. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/HLE_PRD.md +0 -0
  48. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/JETSON_BENCH.md +0 -0
  49. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/LICENSE +0 -0
  50. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/MODEL_SHORTCOMINGS.md +0 -0
  51. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/NOTICE +0 -0
  52. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/OVERNIGHT_PROGRESS.md +0 -0
  53. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
  54. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/PERF_SWEEP_PLAN.md +0 -0
  55. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/PRD.md +0 -0
  56. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/README.md +0 -0
  57. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/SOVEREIGN_PRD.md +0 -0
  58. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/TRIAGE_v1.md +0 -0
  59. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/action.yml +0 -0
  60. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/README.md +0 -0
  61. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results1.tsv +0 -0
  62. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results13.tsv +0 -0
  63. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results14.tsv +0 -0
  64. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results15.tsv +0 -0
  65. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results16.tsv +0 -0
  66. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results17.tsv +0 -0
  67. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results18.tsv +0 -0
  68. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results19.tsv +0 -0
  69. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results2.tsv +0 -0
  70. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results20.tsv +0 -0
  71. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results3.tsv +0 -0
  72. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results4.tsv +0 -0
  73. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results5.tsv +0 -0
  74. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results6.tsv +0 -0
  75. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results7.tsv +0 -0
  76. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results8.tsv +0 -0
  77. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results9.tsv +0 -0
  78. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/baseline_history/results_evolved_v1.tsv +0 -0
  79. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/distribution/zed/LICENSE +0 -0
  80. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/distribution/zed/extension.toml +0 -0
  81. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/distribution/zed/icons/mistral_vibe.svg +0 -0
  82. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/docs/README.md +0 -0
  83. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/docs/acp-setup.md +0 -0
  84. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/docs/proxy-setup.md +0 -0
  85. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/__init__.py +0 -0
  86. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/__init__.py +0 -0
  87. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/acp_agent_loop.py +0 -0
  88. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/acp_logger.py +0 -0
  89. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/entrypoint.py +0 -0
  90. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/__init__.py +0 -0
  91. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/base.py +0 -0
  92. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/bash.py +0 -0
  93. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/read_file.py +0 -0
  94. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/search_replace.py +0 -0
  95. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/todo.py +0 -0
  96. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/builtins/write_file.py +0 -0
  97. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/tools/session_update.py +0 -0
  98. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/acp/utils.py +0 -0
  99. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/__init__.py +0 -0
  100. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/detectors.py +0 -0
  101. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/detectors_proposed.py +0 -0
  102. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/history.py +0 -0
  103. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/interventions.py +0 -0
  104. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/llm_analyzer.py +0 -0
  105. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/metrics.py +0 -0
  106. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/opus_escalator.py +0 -0
  107. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/persistence.py +0 -0
  108. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/policy.py +0 -0
  109. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/proposer.py +0 -0
  110. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/stager.py +0 -0
  111. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/task_classifier.py +0 -0
  112. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/tuning.py +0 -0
  113. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/validator.py +0 -0
  114. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/admiral/worker.py +0 -0
  115. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/__init__.py +0 -0
  116. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/autocompletion/__init__.py +0 -0
  117. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/autocompletion/base.py +0 -0
  118. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/autocompletion/path_completion.py +0 -0
  119. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/autocompletion/slash_command.py +0 -0
  120. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/cli.py +0 -0
  121. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/clipboard.py +0 -0
  122. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/commands.py +0 -0
  123. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/entrypoint.py +0 -0
  124. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/history_manager.py +0 -0
  125. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  126. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  127. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  128. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/terminal_setup.py +0 -0
  129. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/__init__.py +0 -0
  130. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  131. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/app.py +0 -0
  132. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/app.tcss +0 -0
  133. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/external_editor.py +0 -0
  134. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  135. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  136. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  137. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  138. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  139. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  140. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  141. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  142. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  143. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  144. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  145. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  146. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  147. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  148. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  149. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  150. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  151. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  152. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
  153. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  154. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  155. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  156. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  157. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  158. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  159. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  160. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  161. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  162. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  163. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  164. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  165. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  166. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  167. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  168. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  169. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  170. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/windowing/history.py +0 -0
  171. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  172. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/textual_ui/windowing/state.py +0 -0
  173. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/__init__.py +0 -0
  174. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  175. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  176. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  177. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  178. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  179. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/update.py +0 -0
  180. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/cli/update_notifier/whats_new.py +0 -0
  181. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/__init__.py +0 -0
  182. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/agents/__init__.py +0 -0
  183. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/agents/manager.py +0 -0
  184. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/agents/models.py +0 -0
  185. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/auth/__init__.py +0 -0
  186. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/auth/crypto.py +0 -0
  187. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/auth/github.py +0 -0
  188. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/__init__.py +0 -0
  189. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/completers.py +0 -0
  190. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  191. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  192. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  193. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  194. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  195. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/fuzzy.py +0 -0
  196. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/path_prompt.py +0 -0
  197. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  198. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/build_orchestrator.py +0 -0
  199. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/checkpoint.py +0 -0
  200. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/__init__.py +0 -0
  201. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/__main__.py +0 -0
  202. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/classifier.py +0 -0
  203. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/dispatcher.py +0 -0
  204. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/rules.py +0 -0
  205. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/classifier/signal.py +0 -0
  206. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/__init__.py +0 -0
  207. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/doctor.py +0 -0
  208. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/harness_files/__init__.py +0 -0
  209. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  210. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/config/harness_files/_paths.py +0 -0
  211. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/consultant.py +0 -0
  212. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/context_recovery.py +0 -0
  213. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/drydock_states.py +0 -0
  214. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/hooks.py +0 -0
  215. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/__init__.py +0 -0
  216. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/anthropic.py +0 -0
  217. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/base.py +0 -0
  218. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/factory.py +0 -0
  219. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/generic.py +0 -0
  220. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/mistral.py +0 -0
  221. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  222. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/backend/vertex.py +0 -0
  223. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/exceptions.py +0 -0
  224. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/format.py +0 -0
  225. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/message_utils.py +0 -0
  226. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/llm/types.py +0 -0
  227. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/logger.py +0 -0
  228. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/middleware.py +0 -0
  229. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/output_formatters.py +0 -0
  230. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/paths/__init__.py +0 -0
  231. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/paths/_drydock_home.py +0 -0
  232. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/paths/_local_config_walk.py +0 -0
  233. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/paths/conventions.py +0 -0
  234. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/plan_session.py +0 -0
  235. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/plugins.py +0 -0
  236. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/programmatic.py +0 -0
  237. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/__init__.py +0 -0
  238. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/builder.md +0 -0
  239. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/cli.md +0 -0
  240. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/compact.md +0 -0
  241. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/dangerous_directory.md +0 -0
  242. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/diagnostic.md +0 -0
  243. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/explore.md +0 -0
  244. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/planner.md +0 -0
  245. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/project_context.md +0 -0
  246. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/prompts/tests.md +0 -0
  247. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/proxy_setup.py +0 -0
  248. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/agent_memory.py +0 -0
  249. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/checkpoints.py +0 -0
  250. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/session_loader.py +0 -0
  251. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/session_logger.py +0 -0
  252. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/session_migration.py +0 -0
  253. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session/state_file.py +0 -0
  254. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/session_checker.py +0 -0
  255. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/skills/__init__.py +0 -0
  256. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/skills/manager.py +0 -0
  257. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/skills/models.py +0 -0
  258. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/skills/parser.py +0 -0
  259. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/slug.py +0 -0
  260. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/system_prompt.py +0 -0
  261. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/telemetry/__init__.py +0 -0
  262. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/telemetry/send.py +0 -0
  263. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/errors.py +0 -0
  264. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/git.py +0 -0
  265. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/nuage.py +0 -0
  266. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/teleport.py +0 -0
  267. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/teleport/types.py +0 -0
  268. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/base.py +0 -0
  269. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/_task_manager.py +0 -0
  270. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  271. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/cron.py +0 -0
  272. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  273. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/glob_tool.py +0 -0
  274. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/grep.py +0 -0
  275. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  276. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/lsp.py +0 -0
  277. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  278. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  279. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/powershell.py +0 -0
  280. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  281. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  282. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  283. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  284. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  285. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  286. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  287. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  288. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  289. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  290. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  291. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  292. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/retrieve.md +0 -0
  293. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  294. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  295. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/task.md +0 -0
  296. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  297. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  298. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  299. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  300. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  301. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  302. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  303. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/read_file.py +0 -0
  304. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/retrieve.py +0 -0
  305. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/task.py +0 -0
  306. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/todo.py +0 -0
  307. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/tool_search.py +0 -0
  308. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/webfetch.py +0 -0
  309. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/websearch.py +0 -0
  310. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/worktree.py +0 -0
  311. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/builtins/write_file.py +0 -0
  312. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/injection_guard.py +0 -0
  313. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/manager.py +0 -0
  314. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/mcp/__init__.py +0 -0
  315. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/mcp/registry.py +0 -0
  316. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/mcp/tools.py +0 -0
  317. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/mcp_sampling.py +0 -0
  318. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/ui.py +0 -0
  319. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/tools/utils.py +0 -0
  320. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/trusted_folders.py +0 -0
  321. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/types.py +0 -0
  322. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/core/utils.py +0 -0
  323. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/__init__.py +0 -0
  324. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/__main__.py +0 -0
  325. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/code_indexer.py +0 -0
  326. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/retriever.py +0 -0
  327. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/storage.py +0 -0
  328. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/graphrag/text_indexer.py +0 -0
  329. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/__init__.py +0 -0
  330. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/base.py +0 -0
  331. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/onboarding.tcss +0 -0
  332. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/__init__.py +0 -0
  333. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/api_key.py +0 -0
  334. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/choice.py +0 -0
  335. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/local_model.py +0 -0
  336. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/onboarding/screens/welcome.py +0 -0
  337. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  338. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  339. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/__init__.py +0 -0
  340. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/api-design/SKILL.md +0 -0
  341. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/audit-tests/SKILL.md +0 -0
  342. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/batch/SKILL.md +0 -0
  343. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/commit-code/SKILL.md +0 -0
  344. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/context-summary/SKILL.md +0 -0
  345. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/create-presentation/SKILL.md +0 -0
  346. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/deep-research/SKILL.md +0 -0
  347. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/deploy/SKILL.md +0 -0
  348. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/diff-review/SKILL.md +0 -0
  349. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/doc-gen/SKILL.md +0 -0
  350. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/explain-code/SKILL.md +0 -0
  351. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/explore-code/SKILL.md +0 -0
  352. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/fix-issue/SKILL.md +0 -0
  353. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/git-ops/SKILL.md +0 -0
  354. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/init-project/SKILL.md +0 -0
  355. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/investigate/SKILL.md +0 -0
  356. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/loop/SKILL.md +0 -0
  357. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/migrate/SKILL.md +0 -0
  358. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/perf-analyze/SKILL.md +0 -0
  359. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/plan-impl/SKILL.md +0 -0
  360. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/pr-review/SKILL.md +0 -0
  361. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/refactor/SKILL.md +0 -0
  362. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/regex-help/SKILL.md +0 -0
  363. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/review/SKILL.md +0 -0
  364. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/security-review/SKILL.md +0 -0
  365. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/ship/SKILL.md +0 -0
  366. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/simplify/SKILL.md +0 -0
  367. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/strong-tests/SKILL.md +0 -0
  368. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/skills/test-verify/SKILL.md +0 -0
  369. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/__init__.py +0 -0
  370. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/__main__.py +0 -0
  371. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/applier.py +0 -0
  372. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/config.py +0 -0
  373. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/registry.py +0 -0
  374. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/sandbox.py +0 -0
  375. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/steering/vectors.py +0 -0
  376. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock/whats_new.md +0 -0
  377. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock-acp.spec +0 -0
  378. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/drydock_terms.md +0 -0
  379. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/flake.lock +0 -0
  380. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/flake.nix +0 -0
  381. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/nohup.out +0 -0
  382. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777672181.json +0 -0
  383. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777672218.json +0 -0
  384. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777672322.json +0 -0
  385. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777732278.json +0 -0
  386. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777811293.json +0 -0
  387. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/perf_results/baseline_1777811401.json +0 -0
  388. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/README.md +0 -0
  389. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/config_base.toml +0 -0
  390. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/config_best.toml +0 -0
  391. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/domain_spec.md +0 -0
  392. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/experimenter.py +0 -0
  393. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/kernel.py +0 -0
  394. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/mini_prd.md +0 -0
  395. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/mini_prompts.txt +0 -0
  396. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/proposer.py +0 -0
  397. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/research/results.tsv +0 -0
  398. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/resume.md +0 -0
  399. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/README.md +0 -0
  400. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/admiral_probe.py +0 -0
  401. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/audit_sampler.py +0 -0
  402. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/auto_generate_tests.py +0 -0
  403. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/auto_release.sh +0 -0
  404. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/auto_test_loop.sh +0 -0
  405. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/autonomous_review.sh +0 -0
  406. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/autonomous_review_prompt.md +0 -0
  407. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/backup.sh +0 -0
  408. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/bump_version.py +0 -0
  409. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/classify_pulse.sh +0 -0
  410. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/comprehensive_loop.py +0 -0
  411. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/consume_retrieval_queue.py +0 -0
  412. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/deploy_to_github.sh +0 -0
  413. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/discover_cli_tools.sh +0 -0
  414. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/evolve_tests.py +0 -0
  415. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/gen_2000_prompts.py +0 -0
  416. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/hle_eval_seed.jsonl +0 -0
  417. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/install.sh +0 -0
  418. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/llm_balancer.py +0 -0
  419. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/mega_loop.py +0 -0
  420. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/meta_ralph_loop.py +0 -0
  421. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/monitor_swebench.sh +0 -0
  422. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/monitor_test_battery.sh +0 -0
  423. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/oss_task_harness.py +0 -0
  424. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/overnight_agents_test.sh +0 -0
  425. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/perf_baseline_when_idle.sh +0 -0
  426. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/perf_sweep.py +0 -0
  427. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/poll_issues.sh +0 -0
  428. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/port_task.py +0 -0
  429. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/prepare_release.py +0 -0
  430. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/publish_to_pypi.sh +0 -0
  431. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/queue_top.py +0 -0
  432. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/ralph_loop.py +0 -0
  433. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/research_babysitter.sh +0 -0
  434. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/session_loop_audit.py +0 -0
  435. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown.py +0 -0
  436. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown_interactive.py +0 -0
  437. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown_regression.sh +0 -0
  438. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown_suite.sh +0 -0
  439. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/shakedown_variance.sh +0 -0
  440. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_babysitter.sh +0 -0
  441. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_prompts_50.txt +0 -0
  442. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_prompts_realuser.txt +0 -0
  443. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_prompts_tool_agent.txt +0 -0
  444. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
  445. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_shakedown.py +0 -0
  446. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_telegram_status.py +0 -0
  447. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/stress_watcher.py +0 -0
  448. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/telegram_bot.py +0 -0
  449. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/test_bank.sh +0 -0
  450. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/test_full.sh +0 -0
  451. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/test_smoke.sh +0 -0
  452. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/test_tui_path.py +0 -0
  453. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/tui_test.py +0 -0
  454. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/scripts/vllm_failover.sh +0 -0
  455. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/test/project/dummy +0 -0
  456. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/__init__.py +0 -0
  457. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/conftest.py +0 -0
  458. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_acp.py +0 -0
  459. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_agent_thought.py +0 -0
  460. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_bash.py +0 -0
  461. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_compact_session_updates.py +0 -0
  462. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_content.py +0 -0
  463. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_initialize.py +0 -0
  464. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_list_sessions.py +0 -0
  465. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_load_session.py +0 -0
  466. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_multi_session.py +0 -0
  467. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_new_session.py +0 -0
  468. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_proxy_setup_acp.py +0 -0
  469. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_read_file.py +0 -0
  470. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_search_replace.py +0 -0
  471. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_set_config_option.py +0 -0
  472. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_set_mode.py +0 -0
  473. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_set_model.py +0 -0
  474. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_tool_call_session_update.py +0 -0
  475. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_utils.py +0 -0
  476. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/acp/test_write_file.py +0 -0
  477. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_file_indexer.py +0 -0
  478. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_fuzzy.py +0 -0
  479. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  480. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  481. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_path_completion_controller.py +0 -0
  482. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  483. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_slash_command_controller.py +0 -0
  484. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  485. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/__init__.py +0 -0
  486. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/data/__init__.py +0 -0
  487. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/data/fireworks.py +0 -0
  488. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/data/mistral.py +0 -0
  489. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_anthropic_adapter.py +0 -0
  490. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_backend.py +0 -0
  491. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_generic_adapter_sanitize.py +0 -0
  492. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_reasoning_adapter.py +0 -0
  493. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  494. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  495. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  496. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  497. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_bell_notifications.py +0 -0
  498. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_braille_renderer.py +0 -0
  499. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_clipboard.py +0 -0
  500. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_commands.py +0 -0
  501. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_copy_shortcuts.py +0 -0
  502. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_external_editor.py +0 -0
  503. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_no_markup_static.py +0 -0
  504. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_question_app.py +0 -0
  505. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_spinner.py +0 -0
  506. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_switching_mode.py +0 -0
  507. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  508. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  509. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_ui_session_resume.py +0 -0
  510. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/test_ui_skill_dispatch.py +0 -0
  511. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/textual_ui/__init__.py +0 -0
  512. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/cli/textual_ui/test_session_picker.py +0 -0
  513. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/conftest.py +0 -0
  514. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_agents.py +0 -0
  515. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_auth_crypto.py +0 -0
  516. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_auth_github.py +0 -0
  517. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_circuit_breaker_count_escalation.py +0 -0
  518. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_circuit_breaker_readonly_threshold.py +0 -0
  519. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_config_load_dotenv.py +0 -0
  520. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_config_paths.py +0 -0
  521. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_config_resolution.py +0 -0
  522. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_file_logging.py +0 -0
  523. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_plan_session.py +0 -0
  524. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_proxy_setup.py +0 -0
  525. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_slug.py +0 -0
  526. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_telemetry_send.py +0 -0
  527. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_teleport_git.py +0 -0
  528. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_teleport_nuage.py +0 -0
  529. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_teleport_service.py +0 -0
  530. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_trusted_folders.py +0 -0
  531. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/core/test_utils.py +0 -0
  532. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/common.py +0 -0
  533. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/conftest.py +0 -0
  534. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/mock_server.py +0 -0
  535. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  536. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/test_cli_tui_streaming.py +0 -0
  537. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  538. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/fixtures/doc_qa_system_prd.md +0 -0
  539. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/mock/__init__.py +0 -0
  540. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/mock/mock_backend_factory.py +0 -0
  541. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/mock/mock_entrypoint.py +0 -0
  542. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/mock/utils.py +0 -0
  543. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/onboarding/test_run_onboarding.py +0 -0
  544. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/onboarding/test_ui_onboarding.py +0 -0
  545. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/session/test_session_loader.py +0 -0
  546. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/session/test_session_logger.py +0 -0
  547. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/session/test_session_migration.py +0 -0
  548. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/skills/conftest.py +0 -0
  549. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/skills/test_manager.py +0 -0
  550. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/skills/test_models.py +0 -0
  551. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/skills/test_parser.py +0 -0
  552. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  553. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  554. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  555. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  556. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  557. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  558. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  559. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  560. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  561. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  562. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  563. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  564. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  565. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  566. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  567. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  568. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  569. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  570. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  571. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  572. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  573. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  574. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  575. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  576. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  577. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  578. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  579. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  580. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  581. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  582. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  583. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  584. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  585. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  586. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  587. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  588. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  589. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  590. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  591. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  592. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  593. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  594. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  595. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  596. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  597. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  598. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  599. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  600. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  601. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  602. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  603. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  604. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  605. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  606. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  607. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  608. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  609. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  610. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  611. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  612. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/base_snapshot_test_app.py +0 -0
  613. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/conftest.py +0 -0
  614. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/snap_compare.py +0 -0
  615. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  616. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  617. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  618. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  619. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  620. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  621. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  622. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  623. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  624. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  625. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  626. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  627. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  628. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  629. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/stubs/fake_backend.py +0 -0
  630. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/stubs/fake_client.py +0 -0
  631. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/stubs/fake_tool.py +0 -0
  632. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_admiral.py +0 -0
  633. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_admiral_phase3.py +0 -0
  634. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_admiral_proposed.py +0 -0
  635. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_admiral_struggle_dedup.py +0 -0
  636. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_auto_compact.py +0 -0
  637. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_backend.py +0 -0
  638. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_observer_streaming.py +0 -0
  639. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_stats.py +0 -0
  640. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_tasks.py +0 -0
  641. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agent_tool_call.py +0 -0
  642. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_agents.py +0 -0
  643. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_build.py +0 -0
  644. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_debug.py +0 -0
  645. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_multiagent.py +0 -0
  646. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_prd.py +0 -0
  647. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_prd_extended.py +0 -0
  648. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_tools.py +0 -0
  649. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_bank_update.py +0 -0
  650. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_build_projects.py +0 -0
  651. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_checkpoint.py +0 -0
  652. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_classifier.py +0 -0
  653. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_cli_programmatic_preload.py +0 -0
  654. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_context_recovery.py +0 -0
  655. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_current_bugs.py +0 -0
  656. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_dispatcher.py +0 -0
  657. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_drydock_regression.py +0 -0
  658. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_drydock_tasks.py +0 -0
  659. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_fake_tool_call_paren_syntax.py +0 -0
  660. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_full_regression.py +0 -0
  661. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_graphrag.py +0 -0
  662. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_hallucinated_tool_suppression.py +0 -0
  663. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_history_manager.py +0 -0
  664. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_integration.py +0 -0
  665. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_loop_detection.py +0 -0
  666. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_message_id.py +0 -0
  667. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_message_merging.py +0 -0
  668. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_middleware.py +0 -0
  669. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_multi_agent.py +0 -0
  670. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_read_file_not_found_listing.py +0 -0
  671. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_real_failures.py +0 -0
  672. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_real_issues.py +0 -0
  673. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_real_workflow.py +0 -0
  674. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_reasoning_content.py +0 -0
  675. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_retrieval_consumer.py +0 -0
  676. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_retrieve_tool.py +0 -0
  677. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_search_replace_args_not_truncated.py +0 -0
  678. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_smoke.py +0 -0
  679. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_steering.py +0 -0
  680. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_steering_hook.py +0 -0
  681. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_system_prompt.py +0 -0
  682. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_tagged_text.py +0 -0
  683. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_task_complete_nudge.py +0 -0
  684. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_tool_args.py +0 -0
  685. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_truncate_args_valid_json.py +0 -0
  686. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_truncated_arg_path_hint.py +0 -0
  687. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_truncated_search_replace_escalation.py +0 -0
  688. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_truncated_write_escalation.py +0 -0
  689. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_ui_external_editor.py +0 -0
  690. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_ui_input_history.py +0 -0
  691. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_user_issues.py +0 -0
  692. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_workloads.py +0 -0
  693. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/test_write_file_missing_path.py +0 -0
  694. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/testbank_helpers.py +0 -0
  695. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_ask_user_question.py +0 -0
  696. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash.py +0 -0
  697. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_binary_grep_hint.py +0 -0
  698. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_consec_empty_search.py +0 -0
  699. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_echo_escape_loop_breaker.py +0 -0
  700. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_empty_search_loop_breaker.py +0 -0
  701. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_error_loop_breaker.py +0 -0
  702. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_heredoc_confirmation.py +0 -0
  703. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_bash_kill_exit1_annotation.py +0 -0
  704. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_exit_plan_mode.py +0 -0
  705. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_grep.py +0 -0
  706. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_hallucinated_retrieval_redirect.py +0 -0
  707. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_invoke_context.py +0 -0
  708. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_manager_gemma_derived_models.py +0 -0
  709. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_manager_get_tool_config.py +0 -0
  710. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_mcp.py +0 -0
  711. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_mcp_sampling.py +0 -0
  712. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_read_file_dedup_alternating_offset.py +0 -0
  713. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_read_file_dedup_reembed.py +0 -0
  714. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_read_file_directory.py +0 -0
  715. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_read_file_limit_truncation.py +0 -0
  716. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_append_fallback.py +0 -0
  717. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_dir_path.py +0 -0
  718. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_empty_content.py +0 -0
  719. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_file_not_found.py +0 -0
  720. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_first_failure_hint.py +0 -0
  721. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_hard_stop.py +0 -0
  722. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_malformed_block.py +0 -0
  723. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -0
  724. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_placeholder.py +0 -0
  725. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
  726. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_task.py +0 -0
  727. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_ui_bash_execution.py +0 -0
  728. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_webfetch.py +0 -0
  729. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_websearch.py +0 -0
  730. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
  731. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/tools/test_write_file_missing_path_hint.py +0 -0
  732. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  733. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  734. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_do_update.py +0 -0
  735. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  736. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_github_update_gateway.py +0 -0
  737. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  738. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_ui_update_notification.py +0 -0
  739. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_update_use_case.py +0 -0
  740. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/tests/update_notifier/test_whats_new.py +0 -0
  741. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/README.md +0 -0
  742. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/cli_subcommand_dispatch.py +0 -0
  743. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/lookup.json +0 -0
  744. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/sql_parser.py +0 -0
  745. {drydock_cli-2.7.38 → drydock_cli-2.7.40}/worked_examples/tree_walking_interpreter.py +0 -0
@@ -0,0 +1 @@
1
+ 2806441
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 2.7.38
3
+ Version: 2.7.40
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
@@ -118,6 +118,16 @@ _SENTENCE_BOUNDARY_RE = re.compile(r"(?<=[.!?]) (?=[A-Z])")
118
118
  _INLINE_CAPWORD_HEADING_RE = re.compile(
119
119
  r"(?<=[.!?]) (?=[A-Z][A-Za-z]{1,15}:\s)"
120
120
  )
121
+ # Issue #16: quantized Gemma 4 (Q3_K_M) strips whitespace tokens, jamming
122
+ # `### Header text body` and `* item * item * item` runs onto one line.
123
+ # These patterns insert paragraph breaks before inline markdown headers
124
+ # and asterisk bullets that weren't preceded by a real newline.
125
+ _INLINE_ATX_HEADING_RE = re.compile(r"(?<=[.!?\)]) (?=#{1,4} [A-Z])")
126
+ # Asterisk-bullet rescue. Accepts either case for the first bullet word
127
+ # (file names start lowercase, sentences start uppercase). Requires the
128
+ # bullet word to be ≥3 alpha chars + dot/space — guards against math
129
+ # (`2 * 3`) and inline emphasis (`a * b`).
130
+ _INLINE_ASTERISK_BULLET_RE = re.compile(r"(?<=[a-zA-Z.!?\)]) (?=\* [A-Za-z][A-Za-z0-9_]{2,})")
121
131
 
122
132
 
123
133
  def _sentence_chunks(text: str, group: int = 2) -> str:
@@ -164,6 +174,10 @@ def _break_walls_of_text(text: str) -> str:
164
174
  out = _INLINE_ENUM_RE.sub("\n", out)
165
175
  out = _INLINE_DASH_BULLET_RE.sub("\n", out)
166
176
  out = _INLINE_CAPWORD_HEADING_RE.sub("\n\n", out)
177
+ # Issue #16: rescue inline ATX headers (`### Foo`) and asterisk bullets
178
+ # (`* item`) that quantized Gemma 4 emits without surrounding newlines.
179
+ out = _INLINE_ATX_HEADING_RE.sub("\n\n", out)
180
+ out = _INLINE_ASTERISK_BULLET_RE.sub("\n", out)
167
181
  # If inline markers didn't produce any breaks AND the text is long
168
182
  # enough that one paragraph hurts readability, split at sentence
169
183
  # boundaries. group=1 = each sentence on its own paragraph (most
@@ -693,6 +693,25 @@ class AgentLoop:
693
693
  _ar_t1 = time.perf_counter()
694
694
  logger.warning("[TIMING] _auto_route_task: %.2fs", _ar_t1 - _ar_t0)
695
695
 
696
+ # === AUTO-PREFETCH RETRIEVE ===
697
+ # HLE Phase 1 finding (memory: project_graphrag_underused.md): Gemma 4
698
+ # almost never calls retrieve() on its own for general-knowledge
699
+ # questions — it defaults to web_search instead. So a curated
700
+ # GraphRAG corpus is invisible to the model unless we surface it
701
+ # automatically. This hook runs retrieve(query=user_msg[:300]) and,
702
+ # if there are real hits (above a quality threshold), prepends them
703
+ # as a system note BEFORE the first LLM call. Zero behavior change
704
+ # when the index has nothing relevant; pure lift when it does.
705
+ #
706
+ # Env-gated via DRYDOCK_AUTO_RETRIEVE so existing workflows are
707
+ # unaffected. Set to "1" or "true" to enable.
708
+ if os.environ.get("DRYDOCK_AUTO_RETRIEVE", "").strip().lower() in ("1", "true", "yes"):
709
+ logger.warning("[AUTO-RETRIEVE] hook entry, query=%r", (user_msg or "")[:80])
710
+ try:
711
+ self._auto_prefetch_retrieve(user_msg)
712
+ except Exception as _e:
713
+ logger.warning("auto-prefetch retrieve failed (skipped): %s", _e, exc_info=True)
714
+
696
715
  try:
697
716
  should_break_loop = False
698
717
  tool_turns = 0
@@ -1885,7 +1904,39 @@ class AgentLoop:
1885
1904
  if len(cleaned) != len(self.messages):
1886
1905
  self.messages.reset(cleaned)
1887
1906
 
1888
- # Fix 2: If last message is assistant, add a user "Continue." prompt.
1907
+ # Fix 2: Drop empty assistant messages (no content AND no tool_calls).
1908
+ # These violate the OpenAI schema and cause 400 errors on the next LLM
1909
+ # call. They arise when the model returns only thinking/reasoning tokens
1910
+ # (which get stripped) and stall-retry exhaustion leaves the empty msg
1911
+ # in history. An assistant message that follows a tool result must have
1912
+ # either content or tool_calls; if neither, drop it along with any
1913
+ # orphaned tool result messages that precede it (to keep role ordering
1914
+ # valid).
1915
+ cleaned2: list[LLMMessage] = []
1916
+ for msg in self.messages:
1917
+ if (msg.role == Role.assistant
1918
+ and not (msg.content or "").strip()
1919
+ and not msg.tool_calls):
1920
+ # Skip empty assistant — also drop any immediately preceding
1921
+ # tool result that would be truly orphaned (no matching
1922
+ # assistant.tool_calls entry in the preceding messages).
1923
+ while cleaned2 and cleaned2[-1].role == Role.tool:
1924
+ preceding_tool = cleaned2[-1]
1925
+ tcid = getattr(preceding_tool, "tool_call_id", None)
1926
+ if tcid and any(
1927
+ m.role == Role.assistant
1928
+ and m.tool_calls
1929
+ and any(tc.id == tcid for tc in m.tool_calls)
1930
+ for m in cleaned2[:-1]
1931
+ ):
1932
+ break # tool result has a valid match; keep it
1933
+ cleaned2.pop()
1934
+ else:
1935
+ cleaned2.append(msg)
1936
+ if len(cleaned2) != len(self.messages):
1937
+ self.messages.reset(cleaned2)
1938
+
1939
+ # Fix 3: If last message is assistant, add a user "Continue." prompt.
1889
1940
  # The auto-Continue exists so Gemma 4 keeps executing multi-step plans
1890
1941
  # without stopping prematurely at an intermediate text response. For
1891
1942
  # stress runs against prompts that don't need tool calls (pure
@@ -2032,22 +2083,37 @@ class AgentLoop:
2032
2083
  temp = active_model.temperature
2033
2084
  extra_sampling: dict | None = None
2034
2085
 
2086
+ # Per-model `extra_params` (top_k, top_p, frequency_penalty,
2087
+ # max_tokens, etc.) declared in config.toml flow through
2088
+ # extra_sampling. This is the seam llama.cpp users need to
2089
+ # pass top_k=40, top_p=0.95, frequency_penalty=1.1 per the
2090
+ # Gemma 4 loop-fix recipe.
2091
+ cfg_extra = getattr(active_model, "extra_params", None) or {}
2092
+ if cfg_extra:
2093
+ extra_sampling = dict(cfg_extra)
2094
+
2035
2095
  # Token-level loop-breaker: when repetition is detected, bump
2036
2096
  # temperature and add frequency_penalty + a fresh seed so the
2037
2097
  # model's next completion is mechanically likely to diverge.
2038
2098
  # Mistral/OpenAI-compat backends pass these straight through
2039
- # to vLLM's SamplingParams.
2099
+ # to vLLM's SamplingParams. These OVERRIDE config.extra_params
2100
+ # for the duration of the loop-break.
2040
2101
  if getattr(self, "_loop_detected", False):
2041
2102
  signal = getattr(self, "_loop_signal", "") or ""
2042
2103
  # Heavier bump if we've already hit the FORCE_STOP signal
2043
2104
  # (=8 repeats) vs a WARNING (=3-5 repeats).
2044
2105
  heavy = signal == "FORCE_STOP"
2045
2106
  temp = min(1.0, temp + (0.5 if heavy else 0.3))
2046
- extra_sampling = {
2107
+ # Merge loop-breaker overrides on top of any cfg_extra so
2108
+ # config-declared sampling params survive when a loop is
2109
+ # NOT detected, and get overridden when one IS detected.
2110
+ if extra_sampling is None:
2111
+ extra_sampling = {}
2112
+ extra_sampling.update({
2047
2113
  "frequency_penalty": 0.7 if heavy else 0.4,
2048
2114
  "presence_penalty": 0.3,
2049
2115
  "seed": int(time.time() * 1000) & 0x7FFFFFFF,
2050
- }
2116
+ })
2051
2117
  logger.info(
2052
2118
  "[LOOP-BREAK] %s → temp %.2f, freq_pen %.2f, seed %d",
2053
2119
  signal, temp, extra_sampling["frequency_penalty"],
@@ -2776,6 +2842,133 @@ class AgentLoop:
2776
2842
 
2777
2843
  return None
2778
2844
 
2845
+ def _auto_prefetch_retrieve(self, user_msg: str) -> None:
2846
+ """Auto-fetch relevant chunks from GraphRAG and inject as system note.
2847
+
2848
+ Runs synchronously (the GraphRAG retriever is a fast SQLite query).
2849
+ Caps the query length at 300 chars and the injected context at 2000
2850
+ chars to avoid blowing context budget on long user prompts.
2851
+
2852
+ Quality gate: only inject if at least one text-chunk hit has score
2853
+ >= 8.0 (the indexer's score is roughly TF-IDF magnitude). Below
2854
+ that, the retrieval is probably noise and would just bloat the
2855
+ prompt.
2856
+
2857
+ See memory/project_graphrag_underused.md for why this exists:
2858
+ Gemma 4 doesn't call retrieve() on its own for general-knowledge
2859
+ questions, so a curated index is invisible without a hook like
2860
+ this one.
2861
+ """
2862
+ try:
2863
+ from drydock.graphrag import Index
2864
+ db = os.environ.get("DRYDOCK_GRAPHRAG_DB") or str(
2865
+ Path.home() / ".drydock" / "graphrag.sqlite"
2866
+ )
2867
+ if not Path(db).is_file():
2868
+ logger.warning("[AUTO-RETRIEVE] db missing: %s", db)
2869
+ return
2870
+ idx = Index(db)
2871
+ except Exception as e:
2872
+ logger.warning("[AUTO-RETRIEVE] setup failed: %s", e, exc_info=True)
2873
+ return
2874
+
2875
+ # Extract the actual question from boilerplate. HLE-style prompts
2876
+ # are wrapped: "Answer this question. End your response with...
2877
+ # QUESTION: <real text>". Without this strip the retrieve query
2878
+ # matches scaffolding (CLAUDE.md learnings, etc.) instead of the
2879
+ # actual content. Also strip "FINAL ANSWER:" trailing instructions.
2880
+ raw = (user_msg or "")
2881
+ q_marker = raw.find("QUESTION:")
2882
+ if q_marker >= 0:
2883
+ raw = raw[q_marker + len("QUESTION:"):]
2884
+ # Drop trailing answer-format instructions
2885
+ for stopper in ("FINAL ANSWER:", "Your answer", "Format your", "End your response"):
2886
+ idx_ = raw.find(stopper)
2887
+ if idx_ > 50: # only strip if there's still meaningful content
2888
+ raw = raw[:idx_]
2889
+ query = raw.strip()[:400]
2890
+ if len(query) < 10:
2891
+ logger.warning("[AUTO-RETRIEVE] query too short (%d chars)", len(query))
2892
+ return
2893
+ logger.warning("[AUTO-RETRIEVE] extracted query: %r", query[:120])
2894
+
2895
+ try:
2896
+ result = idx.retrieve(query, symbol_limit=0, text_limit=4)
2897
+ except Exception as e:
2898
+ logger.warning("[AUTO-RETRIEVE] query failed: %s", e, exc_info=True)
2899
+ return
2900
+
2901
+ text_hits = getattr(result, "text", None) or getattr(result, "text_hits", []) or []
2902
+ QUALITY_THRESHOLD = 8.0
2903
+ good_hits = [h for h in text_hits if getattr(h, "score", 0) >= QUALITY_THRESHOLD]
2904
+ logger.warning("[AUTO-RETRIEVE] %d total hits, %d above threshold %.1f",
2905
+ len(text_hits), len(good_hits), QUALITY_THRESHOLD)
2906
+ if not good_hits:
2907
+ return
2908
+
2909
+ # Build the system note. Cap at ~2000 chars total.
2910
+ chunks = []
2911
+ budget = 2000
2912
+ for h in good_hits[:3]:
2913
+ text = (getattr(h, "content", "") or "").strip()
2914
+ score = float(getattr(h, "score", 0))
2915
+ file_ = getattr(h, "file", "") or "?"
2916
+ s, e = getattr(h, "start_line", 0), getattr(h, "end_line", 0)
2917
+ piece = f"--- {file_}:{s}-{e} (score={score:.1f}) ---\n{text}"
2918
+ if len(piece) > budget:
2919
+ piece = piece[:budget] + "..."
2920
+ chunks.append(piece)
2921
+ budget -= len(piece) + 4
2922
+ if budget <= 0:
2923
+ break
2924
+
2925
+ # SYNTHETIC TOOL CALL: instead of mutating the user message
2926
+ # (which iter6-9 proved is treated as scaffolding by Gemma 4 — it
2927
+ # ignores inline references and trusts its training prior), spawn
2928
+ # a fake assistant->tool message pair that LOOKS like the model
2929
+ # called retrieve() and got results. Models trust tool outputs
2930
+ # as authoritative input.
2931
+ #
2932
+ # Sequence:
2933
+ # user -> [our synthetic assistant with tool_call retrieve]
2934
+ # -> [our synthetic tool result with the chunks]
2935
+ # -> real LLM turn begins from there
2936
+ from drydock.core.types import ToolCall, FunctionCall as _FC
2937
+ import uuid
2938
+
2939
+ tool_call_id = f"auto-retrieve-{uuid.uuid4().hex[:16]}"
2940
+ tool_args = json.dumps({"query": (user_msg or "")[:200]})
2941
+ synth_assistant = LLMMessage(
2942
+ role=Role.assistant,
2943
+ content="",
2944
+ tool_calls=[
2945
+ ToolCall(
2946
+ id=tool_call_id,
2947
+ function=_FC(name="retrieve", arguments=tool_args),
2948
+ type="function",
2949
+ )
2950
+ ],
2951
+ )
2952
+ # Format chunks as the retrieve tool's actual output shape.
2953
+ formatted = "=== TEXT ===\n\n" + "\n\n".join(chunks)
2954
+ synth_tool = LLMMessage(
2955
+ role=Role.tool,
2956
+ content=formatted,
2957
+ name="retrieve",
2958
+ tool_call_id=tool_call_id,
2959
+ )
2960
+ self.messages.append(synth_assistant)
2961
+ self.messages.append(synth_tool)
2962
+
2963
+ logger.warning(
2964
+ "[AUTO-RETRIEVE] synthesized retrieve tool result: %d chunks "
2965
+ "(top score %.1f, content %d chars), msgs now %d",
2966
+ len(chunks),
2967
+ max(float(getattr(h, "score", 0)) for h in good_hits),
2968
+ len(formatted),
2969
+ len(self.messages),
2970
+ )
2971
+
2779
2972
  async def _auto_route_task(self, user_msg: str) -> None:
2780
2973
  """Lightweight auto-context: list project files and key docs.
2781
2974
 
@@ -238,6 +238,18 @@ class ModelConfig(BaseModel):
238
238
  output_price: float = 0.0 # Price per million output tokens
239
239
  thinking: Literal["off", "low", "medium", "high"] = "off"
240
240
  auto_compact_threshold: int = 200_000
241
+ # Free-form sampling overrides forwarded to the LLM backend's
242
+ # extra_sampling (top_k, top_p, frequency_penalty, repeat_penalty,
243
+ # min_p, max_tokens, etc). Anything supported by the OpenAI-compat
244
+ # server. For llama.cpp + Gemma 4 the article-recommended config is:
245
+ # [models.extra_params]
246
+ # top_k = 40
247
+ # top_p = 0.95
248
+ # frequency_penalty = 1.1
249
+ # max_tokens = 2048
250
+ # Set temperature via the top-level `temperature` field; do not
251
+ # duplicate it here.
252
+ extra_params: dict[str, Any] = Field(default_factory=dict)
241
253
 
242
254
  @model_validator(mode="before")
243
255
  @classmethod
@@ -117,4 +117,17 @@ def patch_config_for_local(
117
117
  for model in models:
118
118
  if isinstance(model, dict) and model.get("alias") == "local":
119
119
  model["name"] = info.model_name
120
+ # When the detected backend is llama.cpp, bake in the
121
+ # Gemma 4 anti-loop sampling recipe (article: i-built-a-
122
+ # gemma-4-ai-agent-it-kept-looping). Temperature must be
123
+ # 1.0; lower values reinforce loops on quantized GGUF.
124
+ # Don't clobber user-defined values if config was already
125
+ # touched.
126
+ if info.label == "llama.cpp":
127
+ model.setdefault("temperature", 1.0)
128
+ extra = model.setdefault("extra_params", {})
129
+ extra.setdefault("top_k", 40)
130
+ extra.setdefault("top_p", 0.95)
131
+ extra.setdefault("frequency_penalty", 1.1)
132
+ extra.setdefault("max_tokens", 2048)
120
133
  break
@@ -140,3 +140,12 @@ When you're asked to BUILD a package: always also write a
140
140
  `strong_tests.sh` that exercises the PRD's specific examples and
141
141
  roundtrip/state properties. A package with only `functional_tests.sh`
142
142
  is not finished.
143
+
144
+ FORMATTING — when answering with prose (not tool calls):
145
+ - Always put a BLANK LINE before any `###`/`##`/`#` header.
146
+ - Always put a BLANK LINE between paragraphs.
147
+ - Always put a BLANK LINE before the FIRST item of a bullet list and a
148
+ newline between items. Do NOT pack `* a * b * c` onto one line.
149
+ - Use `\n\n` between sections. Quantized models drop whitespace tokens
150
+ to save length; the renderer cannot always recover the original
151
+ structure if you do.
@@ -52,7 +52,9 @@ def _initialize() -> _CachedSteering | None:
52
52
 
53
53
  try:
54
54
  from drydock.steering import (
55
+ LogitBiasSteeringApplier,
55
56
  LogOnlySteeringApplier,
57
+ NullSteeringApplier,
56
58
  SteeringConfig,
57
59
  load_registry,
58
60
  )
@@ -63,13 +65,23 @@ def _initialize() -> _CachedSteering | None:
63
65
  root = os.environ.get("DRYDOCK_STEERING_ROOT") or None
64
66
  registry = load_registry(root)
65
67
  config = SteeringConfig.from_mode_names(mode_names)
66
- # Default applier is log-only — a real applier (vLLM sidecar etc.)
67
- # is the next-phase deliverable. The seam is the same either way.
68
- applier = LogOnlySteeringApplier()
68
+ # Applier selection via DRYDOCK_STEERING_APPLIER:
69
+ # "log_only" (default) : log-only, no inference change
70
+ # "logit_bias" : token-level steering via vLLM logit_bias
71
+ # (manifest must carry tags.tokens_boost
72
+ # and/or tags.tokens_suppress)
73
+ # "null" : no-op (same as not setting MODES at all)
74
+ # Real activation steering (VllmSidecarSteeringApplier) lands later.
75
+ kind = os.environ.get("DRYDOCK_STEERING_APPLIER", "log_only").strip().lower()
76
+ if kind == "logit_bias":
77
+ applier = LogitBiasSteeringApplier()
78
+ elif kind == "null":
79
+ applier = NullSteeringApplier()
80
+ else:
81
+ applier = LogOnlySteeringApplier()
69
82
  logger.info(
70
- "steering: enabled, modes=%s, registry=%s",
71
- mode_names,
72
- registry.root,
83
+ "steering: enabled, modes=%s, applier=%s, registry=%s",
84
+ mode_names, applier.kind, registry.root,
73
85
  )
74
86
  return _CachedSteering(config=config, registry=registry, applier=applier)
75
87
 
@@ -586,6 +586,10 @@ class Bash(
586
586
  state = self.state.__dict__.setdefault("_bash_history", {})
587
587
  # Track total error-exit calls per command (regardless of output).
588
588
  err_state = self.state.__dict__.setdefault("_bash_err_count", {})
589
+ # Track total run count per exact command regardless of output or
590
+ # exit code. Catches benchmark/timeit loops where output varies
591
+ # each run (timings differ) so the hash check never fires.
592
+ run_count_state = self.state.__dict__.setdefault("_bash_run_count", {})
589
593
  # Track consecutive empty-stdout search commands (any command, not
590
594
  # just identical ones). The model semantic-loops by trying different
591
595
  # search terms for a non-existent target:
@@ -595,6 +599,73 @@ class Bash(
595
599
  _consec_empty_search_state = self.state.__dict__.setdefault(
596
600
  "_consec_empty_searches", {"count": 0}
597
601
  )
602
+ # python -c / python3 -c SyntaxError loop-breaker.
603
+ # The model truncates multi-line inline scripts; each re-run
604
+ # produces a SyntaxError but with slightly different stderr
605
+ # (different column/line), so the hash check never fires.
606
+ # Track cross-command: any python3 -c that hits SyntaxError.
607
+ _python_c_err_state = self.state.__dict__.setdefault(
608
+ "_python_c_syntaxerr_count", 0
609
+ )
610
+ _is_python_c_syntaxerr = (
611
+ returncode != 0
612
+ and "SyntaxError" in stderr_raw
613
+ and bool(__import__("re").search(r"\bpython3?\s+-c\b", args.command))
614
+ )
615
+ if _is_python_c_syntaxerr:
616
+ self.state.__dict__["_python_c_syntaxerr_count"] = _python_c_err_state + 1
617
+ if _python_c_err_state >= 1:
618
+ _cnt = _python_c_err_state + 1
619
+ yield self._build_result(
620
+ command=args.command,
621
+ stdout=(
622
+ f"[LOOP-BREAKER: `python3 -c '...'` has hit SyntaxError "
623
+ f"{_cnt} times. Inline -c scripts get truncated by the "
624
+ f"shell when they contain newlines or quotes. "
625
+ f"Write the script to a file first, then run it:\n"
626
+ f" write_file path='/tmp/script.py' content='...'\n"
627
+ f" bash command='python3 /tmp/script.py'\n"
628
+ f"Do NOT retry the inline -c form again.]"
629
+ ),
630
+ stderr="",
631
+ returncode=returncode,
632
+ )
633
+ return
634
+
635
+ # Exact-command repetition loop-breaker: fires when the same
636
+ # command text is run 5+ times regardless of output or exit code.
637
+ # Catches benchmark/timeit/import-check loops where each run has
638
+ # varying output (timings, object ids) that defeats the hash check.
639
+ # Excludes commands that write files (heredoc, redirect, sed -i)
640
+ # since those legitimately run the same form multiple times.
641
+ _is_write_cmd = bool(
642
+ __import__("re").search(
643
+ r"(>|>>|\bsed\s+-i\b|\btee\b|\bcat\s+<<|\bprintf\b.*>)",
644
+ args.command,
645
+ )
646
+ )
647
+ if not _is_write_cmd:
648
+ _run_cnt = run_count_state.get(args.command, 0) + 1
649
+ run_count_state[args.command] = _run_cnt
650
+ if _run_cnt >= 5:
651
+ cmd_preview = args.command[:80]
652
+ yield self._build_result(
653
+ command=args.command,
654
+ stdout=(
655
+ f"[LOOP-BREAKER: `{cmd_preview}` has been run "
656
+ f"{_run_cnt} times this session with the same "
657
+ f"command text. The output is stable — re-running "
658
+ f"it will not produce new information. "
659
+ f"Stop repeating this command and move on to the "
660
+ f"next task step. If you are benchmarking, one "
661
+ f"run is enough. If you are checking an import, "
662
+ f"the result is already known.]\n{stdout}"
663
+ ),
664
+ stderr=stderr,
665
+ returncode=returncode,
666
+ )
667
+ return
668
+
598
669
  if returncode != 0:
599
670
  err_count = err_state.get(args.command, 0) + 1
600
671
  err_state[args.command] = err_count
@@ -1069,6 +1069,17 @@ class SearchReplace(
1069
1069
 
1070
1070
  if fuzzy_context:
1071
1071
  error_msg += f"\n{fuzzy_context}"
1072
+ elif "not found anywhere" in context:
1073
+ # First search line not found at all — embed file head so the
1074
+ # model can craft a correct SEARCH block without calling read_file.
1075
+ head_lines = current_content.split("\n")[:30]
1076
+ head = "\n".join(head_lines)
1077
+ error_msg += (
1078
+ f"\nFile head (first {len(head_lines)} lines of actual content):\n"
1079
+ f"```\n{head}\n```\n"
1080
+ "Read the file head above and craft your SEARCH block using "
1081
+ "text that actually appears in the file."
1082
+ )
1072
1083
 
1073
1084
  error_msg += (
1074
1085
  "\nDebugging tips:\n"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "drydock-cli"
3
- version = "2.7.38"
3
+ version = "2.7.40"
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"
@@ -210,10 +210,15 @@ def score_answer(q: dict, pred: str) -> dict:
210
210
  def notify_telegram(tag: str, message: str) -> None:
211
211
  """Fire-and-forget Telegram ping via the existing notify_release.py.
212
212
 
213
- All HLE runs notify on start, every MILESTONE_EVERY completions, and
214
- on final completion (or crash). Failures are silent a missed
215
- Telegram is never worth crashing the eval.
213
+ Default OFF: HLE eval is too noisy for routine notifications and the
214
+ user explicitly asked to stop. Opt in via HLE_TELEGRAM=1 if you want
215
+ start/milestone/final/crash pings for a specific run.
216
+
217
+ Failures are silent — a missed Telegram is never worth crashing
218
+ the eval.
216
219
  """
220
+ if os.environ.get("HLE_TELEGRAM", "").strip().lower() not in ("1", "true", "yes"):
221
+ return
217
222
  if not NOTIFY.exists():
218
223
  return
219
224
  import subprocess
@@ -51,6 +51,17 @@ if __name__ == "__main__":
51
51
  version = sys.argv[1] if len(sys.argv) > 1 else "unknown"
52
52
  summary = "New release"
53
53
 
54
+ # User explicitly asked to stop HLE telegram spam (2026-05-04).
55
+ # Drop HLE-prefixed tags by default; override with HLE_TELEGRAM=1.
56
+ # This silences the in-flight overnight HLE process too — it shells
57
+ # out to this script per ping, so the filter applies retroactively.
58
+ import os as _os
59
+ if (version.startswith("hle-")
60
+ and _os.environ.get("HLE_TELEGRAM", "").strip().lower()
61
+ not in ("1", "true", "yes")):
62
+ print(f"[notify_release] dropped HLE-tagged ping: {version}")
63
+ sys.exit(0)
64
+
54
65
  if version == "status":
55
66
  # Hourly status — plain text, no Markdown parsing issues
56
67
  msg = f"⚓ {summary}"
@@ -1,4 +1,4 @@
1
- """Regression tests for GitHub issues #4, #5, #6."""
1
+ """Regression tests for GitHub issues #4, #5, #6, #14."""
2
2
  from __future__ import annotations
3
3
 
4
4
  import os
@@ -116,3 +116,103 @@ class TestIssue6BashAllowlistBasename:
116
116
  # Returns None (caller prompts for approval) — not ALWAYS.
117
117
  from drydock.core.tools.base import ToolPermission
118
118
  assert res != ToolPermission.ALWAYS
119
+
120
+
121
+ # Issue #14: empty assistant messages (no content, no tool_calls) persist in
122
+ # history after stall-retry exhaustion and cause 400 errors on the next turn.
123
+ # _sanitize_message_ordering must drop them before the next LLM call.
124
+
125
+ class TestIssue14EmptyAssistantDropped:
126
+ def _make_minimal_agent(self):
127
+ from drydock.core.agent_loop import AgentLoop
128
+ from drydock.core.types import MessageList
129
+ al = object.__new__(AgentLoop)
130
+ al.messages = MessageList()
131
+ # stubs for methods called by _sanitize_message_ordering
132
+ al._truncate_old_tool_results = lambda: None
133
+ al._proactive_prune_write_oscillation = lambda: None
134
+ import os as _os
135
+ al._os = _os
136
+ return al
137
+
138
+ def test_empty_assistant_dropped(self):
139
+ """Empty assistant message (no content, no tool_calls) is dropped."""
140
+ from drydock.core.agent_loop import AgentLoop
141
+ from drydock.core.types import LLMMessage, Role, MessageList
142
+ import os
143
+ al = object.__new__(AgentLoop)
144
+ al.messages = MessageList()
145
+ al._truncate_old_tool_results = lambda: None
146
+ al._proactive_prune_write_oscillation = lambda: None
147
+
148
+ al.messages.append(LLMMessage(role=Role.user, content="hello"))
149
+ al.messages.append(LLMMessage(role=Role.assistant, content=None)) # empty — bug
150
+
151
+ original_env = os.environ.get("DRYDOCK_AUTO_CONTINUE_DISABLE")
152
+ os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = "1"
153
+ try:
154
+ al._sanitize_message_ordering()
155
+ finally:
156
+ if original_env is None:
157
+ os.environ.pop("DRYDOCK_AUTO_CONTINUE_DISABLE", None)
158
+ else:
159
+ os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = original_env
160
+
161
+ roles = [m.role for m in al.messages]
162
+ assert Role.assistant not in roles, f"Empty assistant must be dropped; got {roles}"
163
+
164
+ def test_empty_assistant_with_preceding_tool_result_both_dropped(self):
165
+ """Tool result immediately before an empty assistant is also dropped
166
+ to avoid a dangling tool message with no matching assistant turn."""
167
+ from drydock.core.agent_loop import AgentLoop
168
+ from drydock.core.types import LLMMessage, Role, MessageList, ToolCall, FunctionCall
169
+ import os
170
+ al = object.__new__(AgentLoop)
171
+ al.messages = MessageList()
172
+ al._truncate_old_tool_results = lambda: None
173
+ al._proactive_prune_write_oscillation = lambda: None
174
+
175
+ al.messages.append(LLMMessage(role=Role.user, content="do it"))
176
+ al.messages.append(LLMMessage(
177
+ role=Role.assistant,
178
+ content=None,
179
+ tool_calls=[ToolCall(id="c1", function=FunctionCall(name="bash", arguments="{}"))],
180
+ ))
181
+ al.messages.append(LLMMessage(role=Role.tool, content="ok", tool_call_id="c1"))
182
+ al.messages.append(LLMMessage(role=Role.assistant, content=None)) # empty — bug
183
+
184
+ os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = "1"
185
+ try:
186
+ al._sanitize_message_ordering()
187
+ finally:
188
+ os.environ.pop("DRYDOCK_AUTO_CONTINUE_DISABLE", None)
189
+
190
+ roles = [m.role for m in al.messages]
191
+ # The empty assistant AND its preceding orphan tool result should be gone
192
+ assert roles == [Role.user, Role.assistant, Role.tool] or roles == [Role.user], \
193
+ f"Unexpected roles after sanitize: {roles}"
194
+ # The productive assistant (with tool_calls) must survive
195
+ productive = [m for m in al.messages if m.role == Role.assistant]
196
+ assert all(m.tool_calls for m in productive), "Non-empty assistant must keep tool_calls"
197
+
198
+ def test_non_empty_assistant_preserved(self):
199
+ """Assistant messages with content are never dropped."""
200
+ from drydock.core.agent_loop import AgentLoop
201
+ from drydock.core.types import LLMMessage, Role, MessageList
202
+ import os
203
+ al = object.__new__(AgentLoop)
204
+ al.messages = MessageList()
205
+ al._truncate_old_tool_results = lambda: None
206
+ al._proactive_prune_write_oscillation = lambda: None
207
+
208
+ al.messages.append(LLMMessage(role=Role.user, content="hi"))
209
+ al.messages.append(LLMMessage(role=Role.assistant, content="I'm here"))
210
+
211
+ os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = "1"
212
+ try:
213
+ al._sanitize_message_ordering()
214
+ finally:
215
+ os.environ.pop("DRYDOCK_AUTO_CONTINUE_DISABLE", None)
216
+
217
+ roles = [m.role for m in al.messages]
218
+ assert Role.assistant in roles, "Non-empty assistant must not be dropped"