drydock-cli 2.7.17__tar.gz → 2.7.18__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 (671) hide show
  1. drydock_cli-2.7.18/.auto_release.lock +1 -0
  2. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/PKG-INFO +1 -1
  3. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/format.py +50 -5
  4. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/read_file.py +15 -1
  5. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/search_replace.py +40 -0
  6. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/write_file.py +13 -0
  7. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/pyproject.toml +1 -1
  8. drydock_cli-2.7.18/tests/test_write_file_missing_path.py +75 -0
  9. drydock_cli-2.7.18/tests/tools/test_read_file_limit_truncation.py +76 -0
  10. drydock_cli-2.7.18/tests/tools/test_search_replace_empty_content.py +90 -0
  11. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/trip_log.md +76 -0
  12. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/uv.lock +1 -1
  13. drydock_cli-2.7.17/.auto_release.lock +0 -1
  14. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.claude/scheduled_tasks.lock +0 -0
  15. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/CODEOWNERS +0 -0
  16. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  17. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  18. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  19. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/workflows/build-and-upload.yml +0 -0
  20. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/workflows/ci.yml +0 -0
  21. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/workflows/issue-labeler.yml +0 -0
  22. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/workflows/release.yml +0 -0
  23. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.gitignore +0 -0
  24. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.pre-commit-config.yaml +0 -0
  25. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.python-version +0 -0
  26. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.typos.toml +0 -0
  27. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.vscode/extensions.json +0 -0
  28. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.vscode/launch.json +0 -0
  29. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.vscode/settings.json +0 -0
  30. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/AGENTS.md +0 -0
  31. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/Admiral.md +0 -0
  32. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/BASELINE_412.md +0 -0
  33. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/CHANGELOG.md +0 -0
  34. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/CLAUDE.md +0 -0
  35. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/CONTRIBUTING.md +0 -0
  36. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/DEPLOYMENT.md +0 -0
  37. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/Drydock_rebrand.md +0 -0
  38. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/LICENSE +0 -0
  39. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/MODEL_SHORTCOMINGS.md +0 -0
  40. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/NOTICE +0 -0
  41. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/OVERNIGHT_PROGRESS.md +0 -0
  42. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
  43. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/PRD.md +0 -0
  44. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/README.md +0 -0
  45. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/action.yml +0 -0
  46. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/README.md +0 -0
  47. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results1.tsv +0 -0
  48. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results13.tsv +0 -0
  49. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results14.tsv +0 -0
  50. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results15.tsv +0 -0
  51. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results16.tsv +0 -0
  52. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results17.tsv +0 -0
  53. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results18.tsv +0 -0
  54. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results19.tsv +0 -0
  55. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results2.tsv +0 -0
  56. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results20.tsv +0 -0
  57. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results3.tsv +0 -0
  58. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results4.tsv +0 -0
  59. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results5.tsv +0 -0
  60. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results6.tsv +0 -0
  61. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results7.tsv +0 -0
  62. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results8.tsv +0 -0
  63. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results9.tsv +0 -0
  64. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results_evolved_v1.tsv +0 -0
  65. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/distribution/zed/LICENSE +0 -0
  66. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/distribution/zed/extension.toml +0 -0
  67. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/distribution/zed/icons/mistral_vibe.svg +0 -0
  68. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/docs/README.md +0 -0
  69. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/docs/acp-setup.md +0 -0
  70. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/docs/proxy-setup.md +0 -0
  71. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/__init__.py +0 -0
  72. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/__init__.py +0 -0
  73. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/acp_agent_loop.py +0 -0
  74. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/acp_logger.py +0 -0
  75. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/entrypoint.py +0 -0
  76. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/__init__.py +0 -0
  77. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/base.py +0 -0
  78. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/bash.py +0 -0
  79. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/read_file.py +0 -0
  80. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/search_replace.py +0 -0
  81. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/todo.py +0 -0
  82. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/write_file.py +0 -0
  83. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/session_update.py +0 -0
  84. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/utils.py +0 -0
  85. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/__init__.py +0 -0
  86. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/detectors.py +0 -0
  87. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/detectors_proposed.py +0 -0
  88. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/history.py +0 -0
  89. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/interventions.py +0 -0
  90. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/llm_analyzer.py +0 -0
  91. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/metrics.py +0 -0
  92. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/opus_escalator.py +0 -0
  93. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/persistence.py +0 -0
  94. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/policy.py +0 -0
  95. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/proposer.py +0 -0
  96. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/stager.py +0 -0
  97. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/task_classifier.py +0 -0
  98. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/tuning.py +0 -0
  99. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/validator.py +0 -0
  100. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/worker.py +0 -0
  101. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/__init__.py +0 -0
  102. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/autocompletion/__init__.py +0 -0
  103. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/autocompletion/base.py +0 -0
  104. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/autocompletion/path_completion.py +0 -0
  105. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/autocompletion/slash_command.py +0 -0
  106. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/cli.py +0 -0
  107. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/clipboard.py +0 -0
  108. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/commands.py +0 -0
  109. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/entrypoint.py +0 -0
  110. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/history_manager.py +0 -0
  111. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  112. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  113. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  114. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/terminal_setup.py +0 -0
  115. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/__init__.py +0 -0
  116. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  117. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/app.py +0 -0
  118. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/app.tcss +0 -0
  119. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/external_editor.py +0 -0
  120. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  121. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  122. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  123. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  124. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  125. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  126. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  127. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  128. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  129. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  130. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  131. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  132. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  133. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  134. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  135. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  136. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  137. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  138. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
  139. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  140. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  141. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  142. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  143. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  144. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  145. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  146. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  147. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  148. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  149. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  150. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  151. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  152. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  153. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  154. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  155. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  156. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  157. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/windowing/history.py +0 -0
  158. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  159. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/windowing/state.py +0 -0
  160. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/__init__.py +0 -0
  161. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  162. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  163. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  164. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  165. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  166. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/update.py +0 -0
  167. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/whats_new.py +0 -0
  168. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/__init__.py +0 -0
  169. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/agent_loop.py +0 -0
  170. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/agents/__init__.py +0 -0
  171. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/agents/manager.py +0 -0
  172. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/agents/models.py +0 -0
  173. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/auth/__init__.py +0 -0
  174. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/auth/crypto.py +0 -0
  175. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/auth/github.py +0 -0
  176. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/__init__.py +0 -0
  177. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/completers.py +0 -0
  178. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  179. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  180. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  181. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  182. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  183. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/fuzzy.py +0 -0
  184. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/path_prompt.py +0 -0
  185. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  186. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/build_orchestrator.py +0 -0
  187. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/checkpoint.py +0 -0
  188. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/__init__.py +0 -0
  189. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/_settings.py +0 -0
  190. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/doctor.py +0 -0
  191. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/harness_files/__init__.py +0 -0
  192. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  193. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/harness_files/_paths.py +0 -0
  194. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/consultant.py +0 -0
  195. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/drydock_states.py +0 -0
  196. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/hooks.py +0 -0
  197. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/__init__.py +0 -0
  198. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/anthropic.py +0 -0
  199. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/base.py +0 -0
  200. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/factory.py +0 -0
  201. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/generic.py +0 -0
  202. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/mistral.py +0 -0
  203. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  204. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/vertex.py +0 -0
  205. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/exceptions.py +0 -0
  206. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/message_utils.py +0 -0
  207. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/types.py +0 -0
  208. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/logger.py +0 -0
  209. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/middleware.py +0 -0
  210. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/output_formatters.py +0 -0
  211. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/paths/__init__.py +0 -0
  212. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/paths/_drydock_home.py +0 -0
  213. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/paths/_local_config_walk.py +0 -0
  214. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/paths/conventions.py +0 -0
  215. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/plan_session.py +0 -0
  216. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/plugins.py +0 -0
  217. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/programmatic.py +0 -0
  218. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/__init__.py +0 -0
  219. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/builder.md +0 -0
  220. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/cli.md +0 -0
  221. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/compact.md +0 -0
  222. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/dangerous_directory.md +0 -0
  223. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/diagnostic.md +0 -0
  224. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/explore.md +0 -0
  225. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/gemma4.md +0 -0
  226. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/planner.md +0 -0
  227. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/project_context.md +0 -0
  228. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/tests.md +0 -0
  229. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/proxy_setup.py +0 -0
  230. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/agent_memory.py +0 -0
  231. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/checkpoints.py +0 -0
  232. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/session_loader.py +0 -0
  233. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/session_logger.py +0 -0
  234. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/session_migration.py +0 -0
  235. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/state_file.py +0 -0
  236. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session_checker.py +0 -0
  237. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/skills/__init__.py +0 -0
  238. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/skills/manager.py +0 -0
  239. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/skills/models.py +0 -0
  240. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/skills/parser.py +0 -0
  241. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/slug.py +0 -0
  242. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/system_prompt.py +0 -0
  243. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/telemetry/__init__.py +0 -0
  244. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/telemetry/send.py +0 -0
  245. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/errors.py +0 -0
  246. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/git.py +0 -0
  247. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/nuage.py +0 -0
  248. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/teleport.py +0 -0
  249. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/types.py +0 -0
  250. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/base.py +0 -0
  251. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/_task_manager.py +0 -0
  252. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  253. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/bash.py +0 -0
  254. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/cron.py +0 -0
  255. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  256. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/glob_tool.py +0 -0
  257. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/grep.py +0 -0
  258. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  259. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/lsp.py +0 -0
  260. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  261. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  262. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/powershell.py +0 -0
  263. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  264. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  265. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  266. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  267. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  268. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  269. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  270. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  271. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  272. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  273. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  274. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  275. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  276. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  277. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/task.md +0 -0
  278. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  279. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  280. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  281. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  282. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  283. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  284. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  285. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/task.py +0 -0
  286. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/todo.py +0 -0
  287. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/tool_search.py +0 -0
  288. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/webfetch.py +0 -0
  289. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/websearch.py +0 -0
  290. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/worktree.py +0 -0
  291. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/injection_guard.py +0 -0
  292. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/manager.py +0 -0
  293. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/mcp/__init__.py +0 -0
  294. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/mcp/registry.py +0 -0
  295. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/mcp/tools.py +0 -0
  296. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/mcp_sampling.py +0 -0
  297. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/ui.py +0 -0
  298. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/utils.py +0 -0
  299. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/trusted_folders.py +0 -0
  300. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/types.py +0 -0
  301. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/utils.py +0 -0
  302. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/__init__.py +0 -0
  303. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/base.py +0 -0
  304. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/onboarding.tcss +0 -0
  305. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/__init__.py +0 -0
  306. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/api_key.py +0 -0
  307. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/choice.py +0 -0
  308. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/local_model.py +0 -0
  309. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/welcome.py +0 -0
  310. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  311. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  312. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/__init__.py +0 -0
  313. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/api-design/SKILL.md +0 -0
  314. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/audit-tests/SKILL.md +0 -0
  315. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/batch/SKILL.md +0 -0
  316. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/commit-code/SKILL.md +0 -0
  317. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/context-summary/SKILL.md +0 -0
  318. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/create-presentation/SKILL.md +0 -0
  319. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/deep-research/SKILL.md +0 -0
  320. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/deploy/SKILL.md +0 -0
  321. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/diff-review/SKILL.md +0 -0
  322. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/doc-gen/SKILL.md +0 -0
  323. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/explain-code/SKILL.md +0 -0
  324. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/explore-code/SKILL.md +0 -0
  325. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/fix-issue/SKILL.md +0 -0
  326. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/git-ops/SKILL.md +0 -0
  327. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/init-project/SKILL.md +0 -0
  328. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/investigate/SKILL.md +0 -0
  329. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/loop/SKILL.md +0 -0
  330. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/migrate/SKILL.md +0 -0
  331. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/perf-analyze/SKILL.md +0 -0
  332. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/plan-impl/SKILL.md +0 -0
  333. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/pr-review/SKILL.md +0 -0
  334. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/refactor/SKILL.md +0 -0
  335. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/regex-help/SKILL.md +0 -0
  336. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/review/SKILL.md +0 -0
  337. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/security-review/SKILL.md +0 -0
  338. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/ship/SKILL.md +0 -0
  339. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/simplify/SKILL.md +0 -0
  340. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/strong-tests/SKILL.md +0 -0
  341. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/test-verify/SKILL.md +0 -0
  342. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/whats_new.md +0 -0
  343. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock-acp.spec +0 -0
  344. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock_terms.md +0 -0
  345. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/flake.lock +0 -0
  346. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/flake.nix +0 -0
  347. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/nohup.out +0 -0
  348. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/README.md +0 -0
  349. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/config_base.toml +0 -0
  350. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/config_best.toml +0 -0
  351. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/domain_spec.md +0 -0
  352. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/experimenter.py +0 -0
  353. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/kernel.py +0 -0
  354. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/mini_prd.md +0 -0
  355. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/mini_prompts.txt +0 -0
  356. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/proposer.py +0 -0
  357. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/results.tsv +0 -0
  358. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/resume.md +0 -0
  359. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/README.md +0 -0
  360. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/admiral_probe.py +0 -0
  361. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/audit_sampler.py +0 -0
  362. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/auto_generate_tests.py +0 -0
  363. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/auto_release.sh +0 -0
  364. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/auto_test_loop.sh +0 -0
  365. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/autonomous_review.sh +0 -0
  366. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/autonomous_review_prompt.md +0 -0
  367. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/backup.sh +0 -0
  368. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/bump_version.py +0 -0
  369. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/comprehensive_loop.py +0 -0
  370. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/deploy_to_github.sh +0 -0
  371. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/discover_cli_tools.sh +0 -0
  372. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/evolve_tests.py +0 -0
  373. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/gen_2000_prompts.py +0 -0
  374. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/install.sh +0 -0
  375. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/llm_balancer.py +0 -0
  376. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/mega_loop.py +0 -0
  377. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/meta_ralph_loop.py +0 -0
  378. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/monitor_swebench.sh +0 -0
  379. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/monitor_test_battery.sh +0 -0
  380. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/notify_release.py +0 -0
  381. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/oss_task_harness.py +0 -0
  382. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/overnight_agents_test.sh +0 -0
  383. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/poll_issues.sh +0 -0
  384. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/port_task.py +0 -0
  385. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/prepare_release.py +0 -0
  386. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/publish_to_pypi.sh +0 -0
  387. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/ralph_loop.py +0 -0
  388. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/research_babysitter.sh +0 -0
  389. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/session_loop_audit.py +0 -0
  390. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown.py +0 -0
  391. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown_interactive.py +0 -0
  392. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown_regression.sh +0 -0
  393. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown_suite.sh +0 -0
  394. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown_variance.sh +0 -0
  395. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_babysitter.sh +0 -0
  396. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_prompts_50.txt +0 -0
  397. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_prompts_realuser.txt +0 -0
  398. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_prompts_tool_agent.txt +0 -0
  399. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
  400. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_shakedown.py +0 -0
  401. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_telegram_status.py +0 -0
  402. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_watcher.py +0 -0
  403. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/telegram_bot.py +0 -0
  404. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/test_bank.sh +0 -0
  405. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/test_full.sh +0 -0
  406. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/test_smoke.sh +0 -0
  407. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/test_tui_path.py +0 -0
  408. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/tui_test.py +0 -0
  409. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/vllm_failover.sh +0 -0
  410. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/test/project/dummy +0 -0
  411. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/__init__.py +0 -0
  412. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/conftest.py +0 -0
  413. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_acp.py +0 -0
  414. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_agent_thought.py +0 -0
  415. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_bash.py +0 -0
  416. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_compact_session_updates.py +0 -0
  417. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_content.py +0 -0
  418. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_initialize.py +0 -0
  419. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_list_sessions.py +0 -0
  420. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_load_session.py +0 -0
  421. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_multi_session.py +0 -0
  422. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_new_session.py +0 -0
  423. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_proxy_setup_acp.py +0 -0
  424. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_read_file.py +0 -0
  425. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_search_replace.py +0 -0
  426. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_set_config_option.py +0 -0
  427. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_set_mode.py +0 -0
  428. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_set_model.py +0 -0
  429. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_tool_call_session_update.py +0 -0
  430. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_utils.py +0 -0
  431. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_write_file.py +0 -0
  432. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_file_indexer.py +0 -0
  433. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_fuzzy.py +0 -0
  434. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  435. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  436. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_path_completion_controller.py +0 -0
  437. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  438. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_slash_command_controller.py +0 -0
  439. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  440. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/__init__.py +0 -0
  441. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/data/__init__.py +0 -0
  442. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/data/fireworks.py +0 -0
  443. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/data/mistral.py +0 -0
  444. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_anthropic_adapter.py +0 -0
  445. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_backend.py +0 -0
  446. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_generic_adapter_sanitize.py +0 -0
  447. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_reasoning_adapter.py +0 -0
  448. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  449. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  450. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  451. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  452. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_bell_notifications.py +0 -0
  453. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_braille_renderer.py +0 -0
  454. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_clipboard.py +0 -0
  455. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_commands.py +0 -0
  456. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_copy_shortcuts.py +0 -0
  457. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_external_editor.py +0 -0
  458. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_no_markup_static.py +0 -0
  459. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_question_app.py +0 -0
  460. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_spinner.py +0 -0
  461. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_switching_mode.py +0 -0
  462. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  463. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  464. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_ui_session_resume.py +0 -0
  465. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_ui_skill_dispatch.py +0 -0
  466. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/textual_ui/__init__.py +0 -0
  467. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/textual_ui/test_session_picker.py +0 -0
  468. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/conftest.py +0 -0
  469. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_agents.py +0 -0
  470. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_auth_crypto.py +0 -0
  471. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_auth_github.py +0 -0
  472. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_circuit_breaker_readonly_threshold.py +0 -0
  473. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_config_load_dotenv.py +0 -0
  474. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_config_paths.py +0 -0
  475. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_config_resolution.py +0 -0
  476. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_file_logging.py +0 -0
  477. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_plan_session.py +0 -0
  478. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_proxy_setup.py +0 -0
  479. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_slug.py +0 -0
  480. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_telemetry_send.py +0 -0
  481. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_teleport_git.py +0 -0
  482. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_teleport_nuage.py +0 -0
  483. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_teleport_service.py +0 -0
  484. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_trusted_folders.py +0 -0
  485. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_utils.py +0 -0
  486. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/common.py +0 -0
  487. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/conftest.py +0 -0
  488. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/mock_server.py +0 -0
  489. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  490. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/test_cli_tui_streaming.py +0 -0
  491. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  492. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/fixtures/doc_qa_system_prd.md +0 -0
  493. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/mock/__init__.py +0 -0
  494. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/mock/mock_backend_factory.py +0 -0
  495. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/mock/mock_entrypoint.py +0 -0
  496. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/mock/utils.py +0 -0
  497. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/onboarding/test_run_onboarding.py +0 -0
  498. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/onboarding/test_ui_onboarding.py +0 -0
  499. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/session/test_session_loader.py +0 -0
  500. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/session/test_session_logger.py +0 -0
  501. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/session/test_session_migration.py +0 -0
  502. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/skills/conftest.py +0 -0
  503. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/skills/test_manager.py +0 -0
  504. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/skills/test_models.py +0 -0
  505. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/skills/test_parser.py +0 -0
  506. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  507. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  508. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  509. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  510. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  511. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  512. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  513. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  514. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  515. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  516. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  517. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  518. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  519. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  520. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  521. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  522. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  523. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  524. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  525. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  526. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  527. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  528. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  529. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  530. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  531. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  532. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  533. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  534. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  535. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  536. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  537. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  538. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  539. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  540. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  541. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  542. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  543. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  544. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  545. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  546. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  547. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  548. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  549. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  550. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  551. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  552. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  553. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  554. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  555. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  556. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  557. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  558. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  559. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  560. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  561. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  562. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  563. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  564. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  565. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  566. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/base_snapshot_test_app.py +0 -0
  567. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/conftest.py +0 -0
  568. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/snap_compare.py +0 -0
  569. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  570. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  571. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  572. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  573. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  574. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  575. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  576. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  577. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  578. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  579. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  580. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  581. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  582. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  583. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/stubs/fake_backend.py +0 -0
  584. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/stubs/fake_client.py +0 -0
  585. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/stubs/fake_tool.py +0 -0
  586. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_admiral.py +0 -0
  587. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_admiral_phase3.py +0 -0
  588. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_admiral_proposed.py +0 -0
  589. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_admiral_struggle_dedup.py +0 -0
  590. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_auto_compact.py +0 -0
  591. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_backend.py +0 -0
  592. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_observer_streaming.py +0 -0
  593. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_stats.py +0 -0
  594. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_tasks.py +0 -0
  595. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_tool_call.py +0 -0
  596. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agents.py +0 -0
  597. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_build.py +0 -0
  598. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_debug.py +0 -0
  599. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_multiagent.py +0 -0
  600. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_prd.py +0 -0
  601. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_prd_extended.py +0 -0
  602. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_tools.py +0 -0
  603. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_update.py +0 -0
  604. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_build_projects.py +0 -0
  605. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_checkpoint.py +0 -0
  606. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_cli_programmatic_preload.py +0 -0
  607. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_current_bugs.py +0 -0
  608. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_drydock_regression.py +0 -0
  609. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_drydock_tasks.py +0 -0
  610. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_fake_tool_call_paren_syntax.py +0 -0
  611. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_full_regression.py +0 -0
  612. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_history_manager.py +0 -0
  613. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_integration.py +0 -0
  614. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_issue_fixes.py +0 -0
  615. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_loop_detection.py +0 -0
  616. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_message_id.py +0 -0
  617. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_message_merging.py +0 -0
  618. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_middleware.py +0 -0
  619. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_multi_agent.py +0 -0
  620. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_read_file_not_found_listing.py +0 -0
  621. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_real_failures.py +0 -0
  622. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_real_issues.py +0 -0
  623. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_real_workflow.py +0 -0
  624. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_reasoning_content.py +0 -0
  625. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_smoke.py +0 -0
  626. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_system_prompt.py +0 -0
  627. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_tagged_text.py +0 -0
  628. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_tool_args.py +0 -0
  629. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_truncate_args_valid_json.py +0 -0
  630. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_truncated_arg_path_hint.py +0 -0
  631. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_ui_external_editor.py +0 -0
  632. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_ui_input_history.py +0 -0
  633. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_user_issues.py +0 -0
  634. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_wall_of_text_rescue.py +0 -0
  635. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_workloads.py +0 -0
  636. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/testbank_helpers.py +0 -0
  637. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_ask_user_question.py +0 -0
  638. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_bash.py +0 -0
  639. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_exit_plan_mode.py +0 -0
  640. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_grep.py +0 -0
  641. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_invoke_context.py +0 -0
  642. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_manager_gemma_derived_models.py +0 -0
  643. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_manager_get_tool_config.py +0 -0
  644. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_mcp.py +0 -0
  645. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_mcp_sampling.py +0 -0
  646. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_read_file_directory.py +0 -0
  647. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_append_fallback.py +0 -0
  648. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_dir_path.py +0 -0
  649. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_hard_stop.py +0 -0
  650. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -0
  651. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
  652. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_task.py +0 -0
  653. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_ui_bash_execution.py +0 -0
  654. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_webfetch.py +0 -0
  655. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_websearch.py +0 -0
  656. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
  657. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_write_file_missing_path_hint.py +0 -0
  658. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  659. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  660. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_do_update.py +0 -0
  661. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  662. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_github_update_gateway.py +0 -0
  663. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  664. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_ui_update_notification.py +0 -0
  665. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_update_use_case.py +0 -0
  666. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_whats_new.py +0 -0
  667. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/README.md +0 -0
  668. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/cli_subcommand_dispatch.py +0 -0
  669. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/lookup.json +0 -0
  670. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/sql_parser.py +0 -0
  671. {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/tree_walking_interpreter.py +0 -0
@@ -0,0 +1 @@
1
+ 341821
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 2.7.17
3
+ Version: 2.7.18
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
@@ -412,7 +412,7 @@ class APIToolFormatHandler:
412
412
  tool_name=parsed_call.tool_name,
413
413
  call_id=parsed_call.call_id,
414
414
  error=(
415
- f"{parsed_call.tool_name}: your call used a "
415
+ f"your call used a "
416
416
  f"truncated history entry as a template (it contained "
417
417
  f"'_truncated'/'_original_bytes' instead of real "
418
418
  f"arguments).{file_embed} Provide the full required arguments."
@@ -438,11 +438,56 @@ class APIToolFormatHandler:
438
438
  and "path" in error_str
439
439
  and "Field required" in error_str
440
440
  ):
441
+ # Try to infer path from the first comment line of content.
442
+ # Gemma 4 frequently calls write_file(content="...") without path.
443
+ content_val = parsed_call.raw_args.get("content", "")
444
+ inferred_path: str | None = None
445
+ if content_val:
446
+ for _line in content_val.splitlines()[:5]:
447
+ _line = _line.strip()
448
+ _m = _re.match(
449
+ r'^#\s+([\w./+-]+\.(?:py|js|ts|json|yaml|yml|toml|md|txt|sh|cfg|ini))\s*$',
450
+ _line,
451
+ )
452
+ if _m:
453
+ inferred_path = _m.group(1)
454
+ break
455
+ if inferred_path:
456
+ try:
457
+ _new_args = dict(parsed_call.raw_args)
458
+ _new_args["path"] = inferred_path
459
+ validated_args = args_model.model_validate(_new_args)
460
+ resolved_calls.append(
461
+ ResolvedToolCall(
462
+ tool_name=parsed_call.tool_name,
463
+ tool_class=tool_class,
464
+ validated_args=validated_args,
465
+ call_id=parsed_call.call_id,
466
+ )
467
+ )
468
+ continue
469
+ except ValidationError:
470
+ pass
471
+ # List project .py files as hints so the model can pick the right one
472
+ _candidates: list[str] = []
473
+ try:
474
+ _candidates = [
475
+ str(p.relative_to(Path.cwd()))
476
+ for p in sorted(Path.cwd().rglob("*.py"))
477
+ if "__pycache__" not in str(p) and ".git" not in str(p)
478
+ ][:12]
479
+ except Exception:
480
+ pass
481
+ _hint = (
482
+ f"Project .py files: {', '.join(_candidates)}"
483
+ if _candidates
484
+ else "Use read_file or glob to list available files."
485
+ )
441
486
  error_msg = (
442
- "write_file: missing required `path` parameter. "
443
- "You must pass BOTH `path` AND `content` as separate arguments. "
444
- 'Fix: write_file(path="your/file.py", content="..."). '
445
- "Do NOT omit `path`."
487
+ "missing required `path` parameter. "
488
+ "You must pass BOTH `path` AND `content` as separate arguments: "
489
+ 'write_file(path="pkg/file.py", content="..."). '
490
+ f"Do NOT omit `path`. {_hint}"
446
491
  )
447
492
  else:
448
493
  error_msg = f"Invalid arguments: {e}"
@@ -45,7 +45,7 @@ class ReadFileResult(BaseModel):
45
45
  content: str
46
46
  lines_read: int
47
47
  was_truncated: bool = Field(
48
- description="True if the reading was stopped due to the max_read_bytes limit."
48
+ description="True if the reading was stopped due to the line limit or max_read_bytes limit."
49
49
  )
50
50
 
51
51
 
@@ -130,6 +130,19 @@ class ReadFile(
130
130
  read_result = await self._read_file(args, file_path)
131
131
  content = "".join(read_result.lines)
132
132
 
133
+ # When stopped by the line limit (not byte limit), append a hint so
134
+ # the model knows to paginate with offset= instead of re-reading.
135
+ if (
136
+ read_result.was_truncated
137
+ and args.limit is not None
138
+ and len(read_result.lines) == args.limit
139
+ ):
140
+ next_offset = args.offset + args.limit
141
+ content += (
142
+ f"\n[lines {args.offset + 1}–{next_offset} shown; "
143
+ f"use offset={next_offset} to read more]"
144
+ )
145
+
133
146
  # Record read state so Write/Edit can enforce Read-before-Write
134
147
  # and so future re-reads can dedup against this one.
135
148
  if read_state is not None:
@@ -195,6 +208,7 @@ class ReadFile(
195
208
  continue
196
209
 
197
210
  if args.limit is not None and len(lines_to_return) >= args.limit:
211
+ was_truncated = True
198
212
  break
199
213
 
200
214
  line_bytes = len(line.encode("utf-8"))
@@ -131,6 +131,46 @@ class SearchReplace(
131
131
  file_path, search_replace_blocks = self._prepare_and_validate_args(args)
132
132
  except ToolError as e:
133
133
  err_msg = str(e)
134
+ if err_msg.startswith("Empty content provided.") or err_msg.startswith("File path is required."):
135
+ # Model sent search_replace with missing content or file_path.
136
+ # Convert to a soft result so the model corrects — a ToolError
137
+ # causes panic-retry loops (feedback: never raise ToolError for
138
+ # loop detection). Track count to escalate on repeat offenses.
139
+ empty_state = self.state.__dict__.setdefault("_sr_empty_history", {})
140
+ key = args.file_path.strip() or "<no-path>"
141
+ entry = empty_state.get(key, {"count": 0})
142
+ entry["count"] += 1
143
+ empty_state[key] = entry
144
+ count = entry["count"]
145
+ escalate = count >= 2
146
+ extra = ""
147
+ if escalate:
148
+ # Show project files so model can recover context
149
+ try:
150
+ py_files = sorted(
151
+ str(p.relative_to(Path.cwd()))
152
+ for p in Path.cwd().rglob("*.py")
153
+ if "__pycache__" not in str(p) and ".git" not in str(p)
154
+ )[:20]
155
+ extra = (
156
+ f"\n[This is the #{count} empty search_replace on '{key}'. "
157
+ f"Stop retrying. Current .py files in project:\n"
158
+ + "\n".join(f" {f}" for f in py_files)
159
+ + "\nUse write_file to create a file, or read_file to "
160
+ f"see file contents before editing.]"
161
+ )
162
+ except Exception:
163
+ extra = (
164
+ f"\n[This is the #{count} empty search_replace on '{key}'. "
165
+ "Stop retrying. Use write_file or read the file first.]"
166
+ )
167
+ yield SearchReplaceResult(
168
+ file=key,
169
+ blocks_applied=0,
170
+ lines_changed=0,
171
+ content=err_msg + extra,
172
+ )
173
+ return
134
174
  if err_msg.startswith("Path is not a file:"):
135
175
  # Model passed a directory instead of a file path.
136
176
  # Return a result (not raise) so the model corrects the call
@@ -735,6 +735,19 @@ class WriteFile(
735
735
  file_path = Path.cwd() / file_path
736
736
  file_path = file_path.resolve()
737
737
 
738
+ if file_path.is_dir():
739
+ try:
740
+ children = sorted(p.name for p in file_path.iterdir())[:20]
741
+ listing = ", ".join(children) if children else "(empty)"
742
+ except OSError:
743
+ listing = "(unreadable)"
744
+ raise ToolError(
745
+ f"'{file_path}' is a directory, not a file. "
746
+ f"Specify the exact file path inside it.\n"
747
+ f"Files in that directory: {listing}\n"
748
+ f"Example: {file_path}/{children[0] if children else 'yourfile.py'}"
749
+ )
750
+
738
751
  file_existed = file_path.exists()
739
752
 
740
753
  if file_existed and not args.overwrite:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "drydock-cli"
3
- version = "2.7.17"
3
+ version = "2.7.18"
4
4
  description = "Local-first CLI coding agent — tested with Gemma 4 26B via vLLM"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -0,0 +1,75 @@
1
+ """Regression test: write_file missing-path loop fix.
2
+
3
+ Stress run 2026-04-28 showed Gemma 4 calling write_file(content="...")
4
+ without a path. format.py returned "write_file: missing required `path`..."
5
+ and agent_loop.py wrapped it as "<tool_error>write_file: write_file: ..."
6
+ producing a confusing double-prefix. Also, the error message placeholder
7
+ "your/file.py" gave the model no real hint.
8
+
9
+ Fixes in format.py:
10
+ 1. Remove tool-name prefix from error msg (agent_loop adds it already).
11
+ 2. When content first line is "# filename.py", infer path and succeed.
12
+ 3. When path can't be inferred, include project .py file listing in error.
13
+ """
14
+ from __future__ import annotations
15
+
16
+ from unittest.mock import MagicMock
17
+
18
+ import pytest
19
+
20
+ from drydock.core.llm.format import APIToolFormatHandler, ParsedMessage, ParsedToolCall
21
+
22
+
23
+ def _make_tool_manager():
24
+ tm = MagicMock()
25
+ from drydock.core.tools.builtins.write_file import WriteFile
26
+ tm.available_tools = {"write_file": WriteFile}
27
+ return tm
28
+
29
+
30
+ class TestWriteFileMissingPath:
31
+ def _resolve(self, raw_args: dict) -> object:
32
+ handler = APIToolFormatHandler()
33
+ parsed = ParsedMessage(
34
+ tool_calls=[
35
+ ParsedToolCall(
36
+ tool_name="write_file",
37
+ call_id="tc1",
38
+ raw_args=raw_args,
39
+ )
40
+ ],
41
+ text_content="",
42
+ )
43
+ return handler.resolve_tool_calls(parsed, _make_tool_manager())
44
+
45
+ def test_missing_path_no_double_prefix(self):
46
+ """Error for missing path must NOT start with 'write_file:'."""
47
+ result = self._resolve({"content": "import os\nprint('hello')\n"})
48
+ assert result.failed_calls
49
+ err = result.failed_calls[0].error
50
+ # agent_loop.py will add "write_file: " prefix — the error itself must not
51
+ assert not err.startswith("write_file:"), f"Double prefix found: {err!r}"
52
+
53
+ def test_missing_path_error_has_useful_hint(self):
54
+ """Error should mention path parameter and how to fix it."""
55
+ result = self._resolve({"content": "import os\nprint('hello')\n"})
56
+ err = result.failed_calls[0].error
57
+ assert "path" in err.lower()
58
+ # Must not contain the useless placeholder "your/file.py"
59
+ assert "your/file.py" not in err
60
+
61
+ def test_path_inferred_from_comment(self, tmp_path, monkeypatch):
62
+ """When first line is '# mymodule.py', path is inferred and write succeeds."""
63
+ monkeypatch.chdir(tmp_path)
64
+ content = "# mymodule.py\nimport os\n\ndef hello():\n pass\n"
65
+ result = self._resolve({"content": content})
66
+ # Should resolve (no failed call), path inferred as mymodule.py
67
+ assert not result.failed_calls, f"Expected no failure, got: {result.failed_calls[0].error!r}"
68
+ assert result.tool_calls
69
+ assert result.tool_calls[0].validated_args.path == "mymodule.py"
70
+
71
+ def test_path_not_inferred_from_plain_import(self):
72
+ """Content starting with bare import (no comment) must produce a failed call."""
73
+ result = self._resolve({"content": "import abc\nimport os\nimport datetime\n"})
74
+ assert result.failed_calls
75
+ assert not result.tool_calls
@@ -0,0 +1,76 @@
1
+ """Regression test: read_file with limit= sets was_truncated and appends pagination hint.
2
+
3
+ The model (Gemma 4) called read_file with limit=100 on large files, received
4
+ was_truncated=False and no hint, and then re-read the same file 10+ times
5
+ confused about why it was seeing partial content. Fix: set was_truncated=True
6
+ when the line limit stops reading, and append an "offset=N to read more" hint
7
+ so the model knows to paginate rather than re-read.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import pytest
12
+ from pathlib import Path
13
+ from unittest.mock import MagicMock
14
+
15
+ from drydock.core.tools.base import BaseToolState
16
+ from drydock.core.tools.builtins.read_file import ReadFile, ReadFileArgs, ReadFileResult, ReadFileToolConfig
17
+
18
+
19
+ async def _run_result(tool, args, ctx) -> ReadFileResult:
20
+ async for event in tool.run(args, ctx):
21
+ if isinstance(event, ReadFileResult):
22
+ return event
23
+ raise AssertionError("no ReadFileResult yielded")
24
+
25
+
26
+ @pytest.mark.asyncio
27
+ async def test_limit_sets_was_truncated_and_adds_hint(tmp_path):
28
+ """was_truncated=True and pagination hint appended when limit stops the read."""
29
+ f = tmp_path / "big.py"
30
+ f.write_text("\n".join(f"line{i}" for i in range(1, 201))) # 200 lines
31
+
32
+ tool = ReadFile(ReadFileToolConfig(), BaseToolState())
33
+ args = ReadFileArgs(path=str(f), offset=0, limit=100)
34
+ ctx = MagicMock()
35
+ ctx.read_file_state = {}
36
+
37
+ result = await _run_result(tool, args, ctx)
38
+
39
+ assert result.was_truncated is True
40
+ assert result.lines_read == 100
41
+ assert "offset=100" in result.content
42
+ assert "read more" in result.content
43
+
44
+
45
+ @pytest.mark.asyncio
46
+ async def test_no_truncation_when_file_fits_in_limit(tmp_path):
47
+ """was_truncated=False when file has fewer lines than the limit."""
48
+ f = tmp_path / "small.py"
49
+ f.write_text("\n".join(f"line{i}" for i in range(1, 11))) # 10 lines
50
+
51
+ tool = ReadFile(ReadFileToolConfig(), BaseToolState())
52
+ args = ReadFileArgs(path=str(f), offset=0, limit=100)
53
+ ctx = MagicMock()
54
+ ctx.read_file_state = {}
55
+
56
+ result = await _run_result(tool, args, ctx)
57
+
58
+ assert result.was_truncated is False
59
+ assert "offset=" not in result.content
60
+
61
+
62
+ @pytest.mark.asyncio
63
+ async def test_offset_pagination_hint_uses_correct_next_offset(tmp_path):
64
+ """Hint shows the correct next offset when reading a middle chunk."""
65
+ f = tmp_path / "file.py"
66
+ f.write_text("\n".join(f"line{i}" for i in range(1, 301))) # 300 lines
67
+
68
+ tool = ReadFile(ReadFileToolConfig(), BaseToolState())
69
+ args = ReadFileArgs(path=str(f), offset=50, limit=100)
70
+ ctx = MagicMock()
71
+ ctx.read_file_state = {}
72
+
73
+ result = await _run_result(tool, args, ctx)
74
+
75
+ assert result.was_truncated is True
76
+ assert "offset=150" in result.content # 50 + 100
@@ -0,0 +1,90 @@
1
+ """Regression test: search_replace empty-content raises ToolError → retry loop.
2
+
3
+ Stress run 2026-04-28 showed Gemma 4 calling search_replace with empty
4
+ content (content="") 20+ times consecutively. The ToolError path caused
5
+ panic-retry loops (feedback: never raise ToolError for loop detection).
6
+
7
+ Fix: detect empty content/file_path in the ToolError handler in run()
8
+ and yield a soft SearchReplaceResult instead of re-raising. Track count
9
+ per call-target so the 2nd+ offense escalates with project file listing.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import asyncio
14
+ from pathlib import Path
15
+
16
+ import pytest
17
+
18
+ from drydock.core.tools.base import BaseToolState, InvokeContext
19
+ from drydock.core.tools.builtins.search_replace import (
20
+ SearchReplace,
21
+ SearchReplaceArgs,
22
+ SearchReplaceConfig,
23
+ SearchReplaceResult,
24
+ )
25
+
26
+
27
+ def _make_tool() -> SearchReplace:
28
+ config = SearchReplaceConfig()
29
+ state = BaseToolState()
30
+ return SearchReplace(config=config, state=state)
31
+
32
+
33
+ async def _run(tool: SearchReplace, args: SearchReplaceArgs, tmp_path: Path) -> SearchReplaceResult:
34
+ ctx = InvokeContext(tool_call_id="test-1", read_file_state={})
35
+ results = []
36
+ async for item in tool.run(args, ctx):
37
+ if isinstance(item, SearchReplaceResult):
38
+ results.append(item)
39
+ assert results, "Expected at least one SearchReplaceResult"
40
+ return results[-1]
41
+
42
+
43
+ @pytest.mark.asyncio
44
+ async def test_empty_content_returns_result_not_raises(tmp_path: Path) -> None:
45
+ """Empty content must yield a result, never raise ToolError."""
46
+ tool = _make_tool()
47
+ result = await _run(
48
+ tool,
49
+ SearchReplaceArgs(file_path="foo.py", content=""),
50
+ tmp_path,
51
+ )
52
+ assert isinstance(result, SearchReplaceResult)
53
+ assert result.blocks_applied == 0
54
+ assert "Empty content" in result.content
55
+
56
+
57
+ @pytest.mark.asyncio
58
+ async def test_empty_content_escalates_on_repeat(tmp_path: Path) -> None:
59
+ """2nd consecutive empty-content call adds project file listing."""
60
+ tool = _make_tool()
61
+ # First call
62
+ result1 = await _run(
63
+ tool,
64
+ SearchReplaceArgs(file_path="foo.py", content=""),
65
+ tmp_path,
66
+ )
67
+ assert "Empty content" in result1.content
68
+ assert "#2" not in result1.content # no escalation yet
69
+
70
+ # Second call — same key, should escalate
71
+ result2 = await _run(
72
+ tool,
73
+ SearchReplaceArgs(file_path="foo.py", content=""),
74
+ tmp_path,
75
+ )
76
+ assert "#2" in result2.content
77
+ assert "Stop retrying" in result2.content
78
+
79
+
80
+ @pytest.mark.asyncio
81
+ async def test_missing_file_path_returns_result_not_raises(tmp_path: Path) -> None:
82
+ """Missing file_path (can't infer) must also yield a result, not raise."""
83
+ tool = _make_tool()
84
+ result = await _run(
85
+ tool,
86
+ SearchReplaceArgs(file_path="", content=""),
87
+ tmp_path,
88
+ )
89
+ assert isinstance(result, SearchReplaceResult)
90
+ assert result.blocks_applied == 0
@@ -390,3 +390,79 @@ restarted, cron self-match bug fixed in this same session).
390
390
  - vLLM 400s: 0
391
391
  - GH issues: 0 open
392
392
  - Action this tick: committed fix(circuit-breaker): read_file/grep threshold 12→5; the 12-call threshold never fired within 45-prompt session windows — model looped 5-8x on the same read_file before moving on; threshold=5 will now actually engage and return cached result + directive (4f61c5d)
393
+
394
+ ## 2026-04-28 23:10 UTC tick
395
+ - Stress: 68/1658 (new run, PID 270529 alive; previous run completed at 1310/1658 done, babysitter restarted fresh run)
396
+ - Write rate: 37% last 48 prompts (early utility-function prompts: parse_int, parse_float, parse_bool, is_valid_email — expected lower write rate)
397
+ - Admiral last 30 min: 1 fire (loop:read_file:cli.py at 23:02 UTC — isolated, circuit-breaker threshold=5 now in place from 4f61c5d)
398
+ - vLLM 400s: 0
399
+ - GH issues: 0 open
400
+ - Services: llm_balancer PID 24354 on :8001 healthy, vLLM gemma4 container up, stress harness PID 270529 alive
401
+ - Action this tick: no action — system healthy; previous tick's circuit-breaker fix (4f61c5d, threshold 12→5) is active; admiral activity minimal; no new drydock bugs found
402
+
403
+ ## 2026-04-28 23:35 UTC tick
404
+ - Stress: 74/1658 (new run — previous run completed 1310/1658 before harness died ~20:00 UTC; babysitter restarted fresh run at ~20:30 UTC)
405
+ - Write rate: 38% (first 74 prompts; early in run, likely to improve)
406
+ - Admiral last few hours: 36 interventions — all known patterns (loop:read_file, retry_after_error:search_replace, retry_after_error:write_file missing-path, loop:write_file)
407
+ - vLLM 400s: 0
408
+ - GH issues: 0 open
409
+ - Services: llm_balancer PID 24354 on :8001 healthy, vLLM gemma4 container up, stress harness PID 270527 alive (~2h58m elapsed)
410
+ - Action this tick: investigated write_file missing-path loop (admiral shows 3+ retries on same broken call); found format.py already has specific error message for this case ("You must pass BOTH `path` AND `content` as separate arguments"); this is Gemma 4 behavior, no drydock fix available. No new bugs found.
411
+
412
+ ## 2026-04-29 00:30 UTC tick
413
+ - Stress: 89/1658 (harness PID 270529 alive, TUI PID 270531 active)
414
+ - Write rate: 21/58 = 36% (lower than 74% baseline; current prompts are string-util one-liners, 0 writes expected from many)
415
+ - Skip rate: 17/89 = 19% (above 8% baseline; context spiral on step 83 "pluralize" generated 120 msgs)
416
+ - Admiral last 30 min: 36 struggle, 29 loop, 22 retry_after_error, 9 empty_after_tool
417
+ - vLLM 400s: 0
418
+ - GH issues: 0 open
419
+ - Balancer: up on :8001, forwarding to gemma4
420
+ - Pending release: 95fbd1a (write_file double-prefix fix) unreleased; v2.7.18 auto-ships at 05:00 UTC
421
+ - Action this tick: no action — model stuck in search_replace retry loop at step 89 (wrap_text_at_width), harness 300s timeout will advance it; HARD-STOP advisory already fires; no new drydock bug identified
422
+
423
+ ## 2026-04-29 01:32 UTC tick
424
+ - Stress: 100/1658 (PID 270529 alive, 4h58m elapsed on new run)
425
+ - Write rate: 23/61 = 37% (consistent with previous tick; early string-util prompts have low write signal)
426
+ - Skip rate: elevated — multiple "TUI did not accept after 3 retries" in log, FORCE-RESET triggers seen; harness self-recovers via ESC+/clear
427
+ - Admiral last 30 min: struggle:write_file, loop:read_file, loop:bash, retry_after_error:search_replace (all known patterns)
428
+ - vLLM 400s: 0
429
+ - GH issues: 0 open
430
+ - Services: llm_balancer PID 24354 on :8001 healthy (curl verified), vLLM gemma4 container up
431
+ - Pending release: 2 write_file commits (95fbd1a + f4394c9) ahead of v2.7.17 tag; will auto-ship as v2.7.18 at 06:00 UTC
432
+ - Action this tick: no action — all services healthy, no new bugs found; search_replace directory-path handler already present in source
433
+
434
+ ## 2026-04-29 02:02 UTC tick
435
+ - Stress: 104/1658 (new run restarted by babysitter after previous run completed 1658/1658 at 20:00 UTC on 04-28; new run PID 270527, ~5.5h elapsed)
436
+ - Write rate: 37% (23/61 prompts with writes; early string-util prompts expected to have lower write rate)
437
+ - Skip rate: 24/104 = 23% (elevated vs 8% baseline; concentrated in first 20 prompts as TUI settled; prompts 85+ progressing normally)
438
+ - Admiral last 30 min: struggle:write_file (40-47 tool calls without writing), loop:read_file:plugins.py — all known model behavior patterns
439
+ - vLLM 400s: 0
440
+ - GH issues: 0 open
441
+ - Services: llm_balancer PID 24354 on :8001 healthy, vLLM gemma4 container up, stress harness PID 270527 alive
442
+ - Pending release: 2 write_file commits (f4394c9 + 95fbd1a + 4f61c5d circuit-breaker) ahead of v2.7.17 tag; auto-ships as v2.7.18 at 06:00 UTC
443
+ - Action this tick: no action — system healthy; previous run completed full 1658/1658; new run progressing; no new drydock bugs found
444
+
445
+ ## 2026-04-29 02:33 UTC tick
446
+ - Stress: 109/1658 (fresh restart by babysitter; old run had reached 680/1658)
447
+ - Write rate: 38% (last 62 prompts on new log — low due to SKIP storm early in run; FORCE-RESETs unsticking TUI as expected)
448
+ - Admiral last 30 min: ~20+ fires; struggle:25:search_replace repeating every 60s (DEDUP_WINDOW_SEC expiry) — known Gemma 4 advisory-ignore behavior, not a new bug
449
+ - vLLM 400s: 0
450
+ - GH issues: 0 open
451
+ - Action this tick: no action — system healthy, no new drydock bugs; high SKIP rate is harness timing (not drydock source), write rate expected to recover as session warms up
452
+
453
+ ## 2026-04-29 03:15 UTC tick
454
+ - Stress: 113/1658 (new run, PID 270529, restarted since last tick; old PID 3713698 gone)
455
+ - Write rate: 38% (62 prompts evaluated) — down from 74% sustained in prior run
456
+ - Admiral last 30 min: struggle:search_replace firing up to struggle:52 — model looping on search_replace calls (40-52 per session) without any file writes; admiral fires every 2 calls but model ignores it
457
+ - vLLM 400s: 0
458
+ - GH issues: 0 open
459
+ - Action this tick: no action — stress harness alive and progressing (35% SKIP rate = TUI stuck in search_replace loops, harness FORCE-RESETs unsticking); this is Gemma 4 model behavior on mismatching SEARCH text, not a drydock source bug; balancer and vLLM healthy
460
+
461
+ ## 2026-04-29 03:34 UTC tick
462
+ - Stress: 118/1658 (new run PID 270529, restarted by babysitter; old run 3713698 dead)
463
+ - Write rate: 25/63 = 39% (elevated SKIP rate — 44/118 = 37% SKIPs due to search_replace loops)
464
+ - Admiral last 30 min: not measured; TUI log showed 20+ consecutive "Empty content provided" ToolErrors from Gemma 4 calling search_replace with empty content= — this was the root failure causing retry loops
465
+ - vLLM 400s: 0
466
+ - GH issues: 0 open
467
+ - Services: llm_balancer PID 24354 on :8001 healthy, vLLM gemma4 up, balancer curl verified
468
+ - Action this tick: committed fix (11f1752) — search_replace empty-content ToolError converted to soft advisory SearchReplaceResult; tracks consecutive empty-content calls per file and escalates with project file listing on 2nd+ offense; 3 regression tests added; auto-ships as v2.7.18 at next 06:00 UTC cron tick
@@ -326,7 +326,7 @@ wheels = [
326
326
 
327
327
  [[package]]
328
328
  name = "drydock-cli"
329
- version = "2.7.16"
329
+ version = "2.7.17"
330
330
  source = { editable = "." }
331
331
  dependencies = [
332
332
  { name = "agent-client-protocol" },
@@ -1 +0,0 @@
1
- 291967
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes