drydock-cli 2.7.6__tar.gz → 2.7.22__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 (677) hide show
  1. drydock_cli-2.7.22/.auto_release.lock +1 -0
  2. drydock_cli-2.7.22/.claude/scheduled_tasks.lock +1 -0
  3. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/PKG-INFO +1 -1
  4. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/PRD.md +59 -2
  5. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/detectors.py +28 -10
  6. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/detectors_proposed.py +9 -2
  7. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/agent_loop.py +62 -9
  8. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/format.py +185 -4
  9. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/bash.py +65 -8
  10. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/read_file.py +74 -15
  11. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/search_replace.py +246 -27
  12. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/write_file.py +30 -0
  13. drydock_cli-2.7.22/nohup.out +38138 -0
  14. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/pyproject.toml +1 -1
  15. drydock_cli-2.7.22/resume.md +183 -0
  16. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/auto_release.sh +26 -6
  17. drydock_cli-2.7.22/scripts/autonomous_review.sh +97 -0
  18. drydock_cli-2.7.22/scripts/autonomous_review_prompt.md +101 -0
  19. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/llm_balancer.py +5 -1
  20. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/stress_babysitter.sh +6 -2
  21. drydock_cli-2.7.22/test/project/dummy +32 -0
  22. drydock_cli-2.7.22/tests/core/test_circuit_breaker_count_escalation.py +93 -0
  23. drydock_cli-2.7.22/tests/core/test_circuit_breaker_readonly_threshold.py +93 -0
  24. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_admiral_proposed.py +19 -0
  25. drydock_cli-2.7.22/tests/test_admiral_struggle_dedup.py +99 -0
  26. drydock_cli-2.7.22/tests/test_hallucinated_tool_suppression.py +87 -0
  27. drydock_cli-2.7.22/tests/test_read_file_not_found_listing.py +70 -0
  28. drydock_cli-2.7.22/tests/test_truncated_arg_path_hint.py +124 -0
  29. drydock_cli-2.7.22/tests/test_truncated_search_replace_escalation.py +76 -0
  30. drydock_cli-2.7.22/tests/test_truncated_write_escalation.py +104 -0
  31. drydock_cli-2.7.22/tests/test_write_file_missing_path.py +75 -0
  32. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_bash.py +42 -10
  33. drydock_cli-2.7.22/tests/tools/test_read_file_dedup_reembed.py +136 -0
  34. drydock_cli-2.7.22/tests/tools/test_read_file_directory.py +65 -0
  35. drydock_cli-2.7.22/tests/tools/test_read_file_limit_truncation.py +76 -0
  36. drydock_cli-2.7.22/tests/tools/test_search_replace_dir_path.py +114 -0
  37. drydock_cli-2.7.22/tests/tools/test_search_replace_empty_content.py +90 -0
  38. drydock_cli-2.7.22/tests/tools/test_search_replace_hard_stop.py +136 -0
  39. drydock_cli-2.7.22/tests/tools/test_search_replace_no_op_loop_breaker.py +139 -0
  40. drydock_cli-2.7.22/tests/tools/test_search_replace_refused_loop_breaker.py +144 -0
  41. drydock_cli-2.7.22/tests/tools/test_write_file_dedup_missing_imports.py +103 -0
  42. drydock_cli-2.7.22/tests/tools/test_write_file_missing_path_hint.py +78 -0
  43. drydock_cli-2.7.22/trip_log.md +772 -0
  44. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/uv.lock +1 -1
  45. drydock_cli-2.7.6/.auto_release.lock +0 -1
  46. drydock_cli-2.7.6/.claude/scheduled_tasks.lock +0 -1
  47. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.github/CODEOWNERS +0 -0
  48. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  49. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  50. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  51. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.github/workflows/build-and-upload.yml +0 -0
  52. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.github/workflows/ci.yml +0 -0
  53. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.github/workflows/issue-labeler.yml +0 -0
  54. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.github/workflows/release.yml +0 -0
  55. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.gitignore +0 -0
  56. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.pre-commit-config.yaml +0 -0
  57. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.python-version +0 -0
  58. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.typos.toml +0 -0
  59. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.vscode/extensions.json +0 -0
  60. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.vscode/launch.json +0 -0
  61. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/.vscode/settings.json +0 -0
  62. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/AGENTS.md +0 -0
  63. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/Admiral.md +0 -0
  64. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/BASELINE_412.md +0 -0
  65. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/CHANGELOG.md +0 -0
  66. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/CLAUDE.md +0 -0
  67. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/CONTRIBUTING.md +0 -0
  68. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/DEPLOYMENT.md +0 -0
  69. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/Drydock_rebrand.md +0 -0
  70. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/LICENSE +0 -0
  71. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/MODEL_SHORTCOMINGS.md +0 -0
  72. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/NOTICE +0 -0
  73. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/OVERNIGHT_PROGRESS.md +0 -0
  74. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
  75. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/README.md +0 -0
  76. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/action.yml +0 -0
  77. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/README.md +0 -0
  78. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results1.tsv +0 -0
  79. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results13.tsv +0 -0
  80. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results14.tsv +0 -0
  81. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results15.tsv +0 -0
  82. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results16.tsv +0 -0
  83. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results17.tsv +0 -0
  84. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results18.tsv +0 -0
  85. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results19.tsv +0 -0
  86. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results2.tsv +0 -0
  87. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results20.tsv +0 -0
  88. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results3.tsv +0 -0
  89. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results4.tsv +0 -0
  90. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results5.tsv +0 -0
  91. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results6.tsv +0 -0
  92. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results7.tsv +0 -0
  93. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results8.tsv +0 -0
  94. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results9.tsv +0 -0
  95. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/baseline_history/results_evolved_v1.tsv +0 -0
  96. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/distribution/zed/LICENSE +0 -0
  97. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/distribution/zed/extension.toml +0 -0
  98. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/distribution/zed/icons/mistral_vibe.svg +0 -0
  99. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/docs/README.md +0 -0
  100. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/docs/acp-setup.md +0 -0
  101. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/docs/proxy-setup.md +0 -0
  102. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/__init__.py +0 -0
  103. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/__init__.py +0 -0
  104. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/acp_agent_loop.py +0 -0
  105. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/acp_logger.py +0 -0
  106. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/entrypoint.py +0 -0
  107. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/tools/__init__.py +0 -0
  108. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/tools/base.py +0 -0
  109. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/tools/builtins/bash.py +0 -0
  110. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/tools/builtins/read_file.py +0 -0
  111. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/tools/builtins/search_replace.py +0 -0
  112. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/tools/builtins/todo.py +0 -0
  113. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/tools/builtins/write_file.py +0 -0
  114. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/tools/session_update.py +0 -0
  115. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/acp/utils.py +0 -0
  116. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/__init__.py +0 -0
  117. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/history.py +0 -0
  118. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/interventions.py +0 -0
  119. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/llm_analyzer.py +0 -0
  120. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/metrics.py +0 -0
  121. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/opus_escalator.py +0 -0
  122. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/persistence.py +0 -0
  123. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/policy.py +0 -0
  124. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/proposer.py +0 -0
  125. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/stager.py +0 -0
  126. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/task_classifier.py +0 -0
  127. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/tuning.py +0 -0
  128. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/validator.py +0 -0
  129. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/admiral/worker.py +0 -0
  130. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/__init__.py +0 -0
  131. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/autocompletion/__init__.py +0 -0
  132. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/autocompletion/base.py +0 -0
  133. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/autocompletion/path_completion.py +0 -0
  134. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/autocompletion/slash_command.py +0 -0
  135. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/cli.py +0 -0
  136. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/clipboard.py +0 -0
  137. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/commands.py +0 -0
  138. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/entrypoint.py +0 -0
  139. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/history_manager.py +0 -0
  140. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  141. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  142. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  143. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/terminal_setup.py +0 -0
  144. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/__init__.py +0 -0
  145. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  146. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/app.py +0 -0
  147. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/app.tcss +0 -0
  148. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/external_editor.py +0 -0
  149. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  150. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  151. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  152. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  153. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  154. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  155. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  156. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  157. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  158. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  159. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  160. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  161. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  162. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  163. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  164. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  165. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  166. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  167. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
  168. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  169. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  170. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  171. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  172. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  173. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  174. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  175. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  176. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  177. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  178. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  179. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  180. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  181. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  182. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  183. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  184. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  185. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  186. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/windowing/history.py +0 -0
  187. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  188. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/textual_ui/windowing/state.py +0 -0
  189. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/update_notifier/__init__.py +0 -0
  190. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  191. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  192. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  193. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  194. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  195. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/update_notifier/update.py +0 -0
  196. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/cli/update_notifier/whats_new.py +0 -0
  197. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/__init__.py +0 -0
  198. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/agents/__init__.py +0 -0
  199. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/agents/manager.py +0 -0
  200. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/agents/models.py +0 -0
  201. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/auth/__init__.py +0 -0
  202. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/auth/crypto.py +0 -0
  203. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/auth/github.py +0 -0
  204. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/__init__.py +0 -0
  205. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/completers.py +0 -0
  206. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  207. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  208. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  209. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  210. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  211. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/fuzzy.py +0 -0
  212. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/path_prompt.py +0 -0
  213. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  214. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/build_orchestrator.py +0 -0
  215. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/checkpoint.py +0 -0
  216. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/config/__init__.py +0 -0
  217. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/config/_settings.py +0 -0
  218. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/config/doctor.py +0 -0
  219. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/config/harness_files/__init__.py +0 -0
  220. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  221. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/config/harness_files/_paths.py +0 -0
  222. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/consultant.py +0 -0
  223. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/drydock_states.py +0 -0
  224. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/hooks.py +0 -0
  225. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/__init__.py +0 -0
  226. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/backend/anthropic.py +0 -0
  227. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/backend/base.py +0 -0
  228. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/backend/factory.py +0 -0
  229. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/backend/generic.py +0 -0
  230. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/backend/mistral.py +0 -0
  231. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  232. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/backend/vertex.py +0 -0
  233. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/exceptions.py +0 -0
  234. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/message_utils.py +0 -0
  235. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/llm/types.py +0 -0
  236. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/logger.py +0 -0
  237. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/middleware.py +0 -0
  238. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/output_formatters.py +0 -0
  239. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/paths/__init__.py +0 -0
  240. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/paths/_drydock_home.py +0 -0
  241. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/paths/_local_config_walk.py +0 -0
  242. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/paths/conventions.py +0 -0
  243. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/plan_session.py +0 -0
  244. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/plugins.py +0 -0
  245. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/programmatic.py +0 -0
  246. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/__init__.py +0 -0
  247. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/builder.md +0 -0
  248. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/cli.md +0 -0
  249. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/compact.md +0 -0
  250. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/dangerous_directory.md +0 -0
  251. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/diagnostic.md +0 -0
  252. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/explore.md +0 -0
  253. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/gemma4.md +0 -0
  254. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/planner.md +0 -0
  255. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/project_context.md +0 -0
  256. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/prompts/tests.md +0 -0
  257. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/proxy_setup.py +0 -0
  258. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/session/agent_memory.py +0 -0
  259. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/session/checkpoints.py +0 -0
  260. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/session/session_loader.py +0 -0
  261. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/session/session_logger.py +0 -0
  262. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/session/session_migration.py +0 -0
  263. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/session/state_file.py +0 -0
  264. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/session_checker.py +0 -0
  265. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/skills/__init__.py +0 -0
  266. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/skills/manager.py +0 -0
  267. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/skills/models.py +0 -0
  268. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/skills/parser.py +0 -0
  269. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/slug.py +0 -0
  270. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/system_prompt.py +0 -0
  271. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/telemetry/__init__.py +0 -0
  272. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/telemetry/send.py +0 -0
  273. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/teleport/errors.py +0 -0
  274. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/teleport/git.py +0 -0
  275. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/teleport/nuage.py +0 -0
  276. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/teleport/teleport.py +0 -0
  277. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/teleport/types.py +0 -0
  278. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/base.py +0 -0
  279. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/_task_manager.py +0 -0
  280. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  281. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/cron.py +0 -0
  282. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  283. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/glob_tool.py +0 -0
  284. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/grep.py +0 -0
  285. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  286. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/lsp.py +0 -0
  287. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  288. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  289. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/powershell.py +0 -0
  290. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  291. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  292. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  293. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  294. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  295. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  296. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  297. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  298. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  299. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  300. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  301. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  302. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  303. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  304. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/task.md +0 -0
  305. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  306. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  307. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  308. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  309. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  310. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  311. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  312. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/task.py +0 -0
  313. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/todo.py +0 -0
  314. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/tool_search.py +0 -0
  315. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/webfetch.py +0 -0
  316. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/websearch.py +0 -0
  317. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/builtins/worktree.py +0 -0
  318. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/injection_guard.py +0 -0
  319. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/manager.py +0 -0
  320. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/mcp/__init__.py +0 -0
  321. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/mcp/registry.py +0 -0
  322. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/mcp/tools.py +0 -0
  323. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/mcp_sampling.py +0 -0
  324. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/ui.py +0 -0
  325. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/tools/utils.py +0 -0
  326. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/trusted_folders.py +0 -0
  327. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/types.py +0 -0
  328. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/core/utils.py +0 -0
  329. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/onboarding/__init__.py +0 -0
  330. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/onboarding/base.py +0 -0
  331. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/onboarding/onboarding.tcss +0 -0
  332. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/onboarding/screens/__init__.py +0 -0
  333. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/onboarding/screens/api_key.py +0 -0
  334. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/onboarding/screens/choice.py +0 -0
  335. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/onboarding/screens/local_model.py +0 -0
  336. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/onboarding/screens/welcome.py +0 -0
  337. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  338. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  339. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/__init__.py +0 -0
  340. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/api-design/SKILL.md +0 -0
  341. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/audit-tests/SKILL.md +0 -0
  342. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/batch/SKILL.md +0 -0
  343. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/commit-code/SKILL.md +0 -0
  344. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/context-summary/SKILL.md +0 -0
  345. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/create-presentation/SKILL.md +0 -0
  346. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/deep-research/SKILL.md +0 -0
  347. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/deploy/SKILL.md +0 -0
  348. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/diff-review/SKILL.md +0 -0
  349. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/doc-gen/SKILL.md +0 -0
  350. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/explain-code/SKILL.md +0 -0
  351. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/explore-code/SKILL.md +0 -0
  352. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/fix-issue/SKILL.md +0 -0
  353. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/git-ops/SKILL.md +0 -0
  354. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/init-project/SKILL.md +0 -0
  355. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/investigate/SKILL.md +0 -0
  356. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/loop/SKILL.md +0 -0
  357. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/migrate/SKILL.md +0 -0
  358. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/perf-analyze/SKILL.md +0 -0
  359. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/plan-impl/SKILL.md +0 -0
  360. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/pr-review/SKILL.md +0 -0
  361. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/refactor/SKILL.md +0 -0
  362. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/regex-help/SKILL.md +0 -0
  363. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/review/SKILL.md +0 -0
  364. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/security-review/SKILL.md +0 -0
  365. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/ship/SKILL.md +0 -0
  366. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/simplify/SKILL.md +0 -0
  367. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/strong-tests/SKILL.md +0 -0
  368. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/skills/test-verify/SKILL.md +0 -0
  369. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock/whats_new.md +0 -0
  370. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock-acp.spec +0 -0
  371. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/drydock_terms.md +0 -0
  372. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/flake.lock +0 -0
  373. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/flake.nix +0 -0
  374. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/README.md +0 -0
  375. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/config_base.toml +0 -0
  376. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/config_best.toml +0 -0
  377. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/domain_spec.md +0 -0
  378. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/experimenter.py +0 -0
  379. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/kernel.py +0 -0
  380. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/mini_prd.md +0 -0
  381. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/mini_prompts.txt +0 -0
  382. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/proposer.py +0 -0
  383. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/research/results.tsv +0 -0
  384. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/README.md +0 -0
  385. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/admiral_probe.py +0 -0
  386. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/audit_sampler.py +0 -0
  387. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/auto_generate_tests.py +0 -0
  388. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/auto_test_loop.sh +0 -0
  389. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/backup.sh +0 -0
  390. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/bump_version.py +0 -0
  391. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/comprehensive_loop.py +0 -0
  392. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/deploy_to_github.sh +0 -0
  393. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/discover_cli_tools.sh +0 -0
  394. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/evolve_tests.py +0 -0
  395. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/gen_2000_prompts.py +0 -0
  396. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/install.sh +0 -0
  397. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/mega_loop.py +0 -0
  398. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/meta_ralph_loop.py +0 -0
  399. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/monitor_swebench.sh +0 -0
  400. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/monitor_test_battery.sh +0 -0
  401. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/notify_release.py +0 -0
  402. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/oss_task_harness.py +0 -0
  403. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/overnight_agents_test.sh +0 -0
  404. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/poll_issues.sh +0 -0
  405. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/port_task.py +0 -0
  406. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/prepare_release.py +0 -0
  407. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/publish_to_pypi.sh +0 -0
  408. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/ralph_loop.py +0 -0
  409. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/research_babysitter.sh +0 -0
  410. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/session_loop_audit.py +0 -0
  411. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/shakedown.py +0 -0
  412. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/shakedown_interactive.py +0 -0
  413. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/shakedown_regression.sh +0 -0
  414. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/shakedown_suite.sh +0 -0
  415. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/shakedown_variance.sh +0 -0
  416. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/stress_prompts_50.txt +0 -0
  417. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/stress_prompts_realuser.txt +0 -0
  418. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/stress_prompts_tool_agent.txt +0 -0
  419. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
  420. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/stress_shakedown.py +0 -0
  421. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/stress_telegram_status.py +0 -0
  422. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/stress_watcher.py +0 -0
  423. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/telegram_bot.py +0 -0
  424. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/test_bank.sh +0 -0
  425. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/test_full.sh +0 -0
  426. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/test_smoke.sh +0 -0
  427. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/test_tui_path.py +0 -0
  428. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/tui_test.py +0 -0
  429. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/scripts/vllm_failover.sh +0 -0
  430. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/__init__.py +0 -0
  431. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/conftest.py +0 -0
  432. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_acp.py +0 -0
  433. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_agent_thought.py +0 -0
  434. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_bash.py +0 -0
  435. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_compact_session_updates.py +0 -0
  436. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_content.py +0 -0
  437. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_initialize.py +0 -0
  438. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_list_sessions.py +0 -0
  439. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_load_session.py +0 -0
  440. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_multi_session.py +0 -0
  441. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_new_session.py +0 -0
  442. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_proxy_setup_acp.py +0 -0
  443. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_read_file.py +0 -0
  444. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_search_replace.py +0 -0
  445. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_set_config_option.py +0 -0
  446. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_set_mode.py +0 -0
  447. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_set_model.py +0 -0
  448. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_tool_call_session_update.py +0 -0
  449. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_utils.py +0 -0
  450. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/acp/test_write_file.py +0 -0
  451. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/autocompletion/test_file_indexer.py +0 -0
  452. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/autocompletion/test_fuzzy.py +0 -0
  453. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  454. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  455. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/autocompletion/test_path_completion_controller.py +0 -0
  456. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  457. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/autocompletion/test_slash_command_controller.py +0 -0
  458. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  459. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/backend/__init__.py +0 -0
  460. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/backend/data/__init__.py +0 -0
  461. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/backend/data/fireworks.py +0 -0
  462. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/backend/data/mistral.py +0 -0
  463. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/backend/test_anthropic_adapter.py +0 -0
  464. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/backend/test_backend.py +0 -0
  465. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/backend/test_generic_adapter_sanitize.py +0 -0
  466. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/backend/test_reasoning_adapter.py +0 -0
  467. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  468. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  469. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  470. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  471. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_bell_notifications.py +0 -0
  472. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_braille_renderer.py +0 -0
  473. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_clipboard.py +0 -0
  474. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_commands.py +0 -0
  475. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_copy_shortcuts.py +0 -0
  476. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_external_editor.py +0 -0
  477. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_no_markup_static.py +0 -0
  478. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_question_app.py +0 -0
  479. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_spinner.py +0 -0
  480. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_switching_mode.py +0 -0
  481. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  482. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  483. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_ui_session_resume.py +0 -0
  484. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/test_ui_skill_dispatch.py +0 -0
  485. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/textual_ui/__init__.py +0 -0
  486. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/cli/textual_ui/test_session_picker.py +0 -0
  487. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/conftest.py +0 -0
  488. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_agents.py +0 -0
  489. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_auth_crypto.py +0 -0
  490. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_auth_github.py +0 -0
  491. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_config_load_dotenv.py +0 -0
  492. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_config_paths.py +0 -0
  493. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_config_resolution.py +0 -0
  494. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_file_logging.py +0 -0
  495. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_plan_session.py +0 -0
  496. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_proxy_setup.py +0 -0
  497. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_slug.py +0 -0
  498. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_telemetry_send.py +0 -0
  499. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_teleport_git.py +0 -0
  500. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_teleport_nuage.py +0 -0
  501. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_teleport_service.py +0 -0
  502. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_trusted_folders.py +0 -0
  503. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/core/test_utils.py +0 -0
  504. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/e2e/common.py +0 -0
  505. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/e2e/conftest.py +0 -0
  506. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/e2e/mock_server.py +0 -0
  507. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  508. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/e2e/test_cli_tui_streaming.py +0 -0
  509. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  510. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/fixtures/doc_qa_system_prd.md +0 -0
  511. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/mock/__init__.py +0 -0
  512. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/mock/mock_backend_factory.py +0 -0
  513. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/mock/mock_entrypoint.py +0 -0
  514. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/mock/utils.py +0 -0
  515. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/onboarding/test_run_onboarding.py +0 -0
  516. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/onboarding/test_ui_onboarding.py +0 -0
  517. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/session/test_session_loader.py +0 -0
  518. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/session/test_session_logger.py +0 -0
  519. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/session/test_session_migration.py +0 -0
  520. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/skills/conftest.py +0 -0
  521. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/skills/test_manager.py +0 -0
  522. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/skills/test_models.py +0 -0
  523. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/skills/test_parser.py +0 -0
  524. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  525. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  526. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  527. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  528. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  529. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  530. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  531. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  532. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  533. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  534. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  535. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  536. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  537. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  538. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  539. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  540. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  541. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  542. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  543. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  544. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  545. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  546. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  547. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  548. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  549. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  550. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  551. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  552. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  553. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  554. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  555. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  556. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  557. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  558. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  559. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  560. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  561. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  562. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  563. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  564. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  565. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  566. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  567. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  568. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  569. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  570. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  571. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  572. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  573. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  574. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  575. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  576. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  577. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  578. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  579. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  580. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  581. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  582. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  583. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  584. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/base_snapshot_test_app.py +0 -0
  585. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/conftest.py +0 -0
  586. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/snap_compare.py +0 -0
  587. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  588. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  589. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  590. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  591. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  592. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  593. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  594. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  595. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  596. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  597. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  598. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  599. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  600. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  601. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/stubs/fake_backend.py +0 -0
  602. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/stubs/fake_client.py +0 -0
  603. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/stubs/fake_tool.py +0 -0
  604. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_admiral.py +0 -0
  605. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_admiral_phase3.py +0 -0
  606. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_agent_auto_compact.py +0 -0
  607. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_agent_backend.py +0 -0
  608. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_agent_observer_streaming.py +0 -0
  609. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_agent_stats.py +0 -0
  610. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_agent_tasks.py +0 -0
  611. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_agent_tool_call.py +0 -0
  612. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_agents.py +0 -0
  613. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_bank_build.py +0 -0
  614. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_bank_debug.py +0 -0
  615. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_bank_multiagent.py +0 -0
  616. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_bank_prd.py +0 -0
  617. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_bank_prd_extended.py +0 -0
  618. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_bank_tools.py +0 -0
  619. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_bank_update.py +0 -0
  620. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_build_projects.py +0 -0
  621. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_checkpoint.py +0 -0
  622. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_cli_programmatic_preload.py +0 -0
  623. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_current_bugs.py +0 -0
  624. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_drydock_regression.py +0 -0
  625. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_drydock_tasks.py +0 -0
  626. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_fake_tool_call_paren_syntax.py +0 -0
  627. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_full_regression.py +0 -0
  628. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_history_manager.py +0 -0
  629. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_integration.py +0 -0
  630. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_issue_fixes.py +0 -0
  631. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_loop_detection.py +0 -0
  632. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_message_id.py +0 -0
  633. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_message_merging.py +0 -0
  634. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_middleware.py +0 -0
  635. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_multi_agent.py +0 -0
  636. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_real_failures.py +0 -0
  637. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_real_issues.py +0 -0
  638. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_real_workflow.py +0 -0
  639. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_reasoning_content.py +0 -0
  640. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_smoke.py +0 -0
  641. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_system_prompt.py +0 -0
  642. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_tagged_text.py +0 -0
  643. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_tool_args.py +0 -0
  644. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_truncate_args_valid_json.py +0 -0
  645. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_ui_external_editor.py +0 -0
  646. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_ui_input_history.py +0 -0
  647. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_user_issues.py +0 -0
  648. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_wall_of_text_rescue.py +0 -0
  649. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/test_workloads.py +0 -0
  650. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/testbank_helpers.py +0 -0
  651. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_ask_user_question.py +0 -0
  652. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_exit_plan_mode.py +0 -0
  653. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_grep.py +0 -0
  654. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_invoke_context.py +0 -0
  655. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_manager_gemma_derived_models.py +0 -0
  656. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_manager_get_tool_config.py +0 -0
  657. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_mcp.py +0 -0
  658. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_mcp_sampling.py +0 -0
  659. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_search_replace_append_fallback.py +0 -0
  660. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_task.py +0 -0
  661. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_ui_bash_execution.py +0 -0
  662. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_webfetch.py +0 -0
  663. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/tools/test_websearch.py +0 -0
  664. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  665. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  666. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/update_notifier/test_do_update.py +0 -0
  667. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  668. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/update_notifier/test_github_update_gateway.py +0 -0
  669. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  670. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/update_notifier/test_ui_update_notification.py +0 -0
  671. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/update_notifier/test_update_use_case.py +0 -0
  672. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/tests/update_notifier/test_whats_new.py +0 -0
  673. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/worked_examples/README.md +0 -0
  674. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/worked_examples/cli_subcommand_dispatch.py +0 -0
  675. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/worked_examples/lookup.json +0 -0
  676. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/worked_examples/sql_parser.py +0 -0
  677. {drydock_cli-2.7.6 → drydock_cli-2.7.22}/worked_examples/tree_walking_interpreter.py +0 -0
@@ -0,0 +1 @@
1
+ 522842
@@ -0,0 +1 @@
1
+ {"sessionId":"facd51cc-fa47-4911-afc8-14485ae9caf3","pid":711220,"acquiredAt":1775966390914}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 2.7.6
3
+ Version: 2.7.22
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
@@ -1,7 +1,7 @@
1
1
  # DryDock — Local CLI Coding Agent
2
2
 
3
3
  **Repository:** https://github.com/fbobe321/drydock
4
- **PyPI:** https://pypi.org/project/drydock-cli/ (v2.7.4)
4
+ **PyPI:** https://pypi.org/project/drydock-cli/ (v2.7.6)
5
5
  **License:** Apache 2.0 (fork of [mistralai/mistral-vibe](https://github.com/mistralai/mistral-vibe))
6
6
 
7
7
  ## Vision
@@ -398,6 +398,54 @@ order:
398
398
  Auto-created if none exist. AGENTS.md is essential for devstral
399
399
  (it loops without one) but Gemma 4 works without it.
400
400
 
401
+ ## Recent fixes (April 25, 2026)
402
+
403
+ ### v2.7.6 (April 25, 09:18 CDT) — truncation JSON-validity fix
404
+ **Root cause of the recurring vLLM 400 spiral.** Live capture from a
405
+ 2000-prompt stress run pinpointed it: `_truncate_old_tool_results` was
406
+ shrinking old assistant `tool_calls.function.arguments` by appending
407
+ `"\n[…truncated N bytes…]"` directly into the JSON-string field. vLLM's
408
+ tool-call parser re-parses arguments as JSON; raw `\n` (0x0A) inside a
409
+ JSON string is invalid → `JSONDecodeError: Invalid control character
410
+ at: line 1 column 401` → HTTP 400 → drydock's "6 consecutive errors"
411
+ banner → harness `/clear` → prompt lost. The pattern repeated every
412
+ ~30 prompts as truncation kicked in, costing dozens of prompts per
413
+ batch.
414
+
415
+ Fix in `agent_loop.py::_truncate_old_tool_results`: rebuild the
416
+ truncated arguments as a small VALID JSON stub (`{"_truncated": true,
417
+ "_original_bytes": N, "<id_field>": ...}`) preserving the most-useful
418
+ identifying field (path / file_path / command / cmd / url / file)
419
+ from the parsed original. 5 regression tests in
420
+ `tests/test_truncate_args_valid_json.py`; 2 of them fail with the
421
+ exact "char 400" error without the fix.
422
+
423
+ **Stress measurement:** before fix, write rate 10% / vLLM 400s
424
+ 315 per 30 min. After fix, write rate sustained at ~44% / vLLM 400s
425
+ 0 per hour. **4.4× correctness improvement** on the same workload.
426
+
427
+ ### v2.7.6 (April 25) — search_replace APPEND fallback
428
+ The 2026-04-25 stress run also exposed a search_replace REFUSED loop:
429
+ Gemma 4 sent a single new function with no SEARCH/REPLACE markers,
430
+ the safety check refused as "would shrink the file by 90%", model
431
+ retried the same broken call, prompts dropped. Model intent in this
432
+ shape is APPEND, not rewrite.
433
+
434
+ Fix in `search_replace.py`: try appending the raw content first; for
435
+ .py files only commit if the combined text still parses cleanly; if
436
+ syntax breaks, return a directive REFUSED that explains the
437
+ EOF-anchored SEARCH/REPLACE pattern. Tests in
438
+ `tests/tools/test_search_replace_append_fallback.py`.
439
+
440
+ ### v2.7.5 (April 25, 07:25 CDT) — yesterday's GitHub issue batch
441
+ Auto-release shipped the four fixes from 2026-04-24 plus the PRD
442
+ refresh:
443
+ - #13 control-char JSON sanitization in OpenAIAdapter
444
+ - #11 fake `task(...)` text nuker in format.py
445
+ - #12 wall-rescue at stream end in messages.py
446
+ - #10 navygpt auto-disable in tool manager
447
+ - PRD.md refresh for v2.7.4 (Admiral, Meta-Harness sections)
448
+
401
449
  ## Recent fixes (April 16–24, 2026)
402
450
 
403
451
  ### v2.7.4 + unreleased (April 24) — GitHub issue triage batch
@@ -749,7 +797,16 @@ Second claude-code pass produced two more wins:
749
797
 
750
798
  ## Roadmap
751
799
 
752
- ### Currently in flight (April 24, 2026)
800
+ ### Currently in flight (April 25, 2026)
801
+ - **2000-prompt stress test** running against v2.7.6 on
802
+ `/data3/drydock_test_projects/403_tool_agent` (PID 3713698, log
803
+ `/tmp/stress_2000_1777119799.log`). At 5+ hours in: 189/1658 prompts
804
+ done, write rate ~44% sustained, vLLM 400s eliminated, SKIPs 8%.
805
+ Babysitter cron will auto-restart on death.
806
+ - **Resume sentinel** at `/data3/drydock/resume.md` — point a fresh
807
+ Claude session at it via `review the resume.md file and continue`.
808
+
809
+ ### Carried over from April 24, 2026
753
810
  - **GitHub issue triage** — 4 user-reported bugs (#10–#13) fixed this
754
811
  week, all with regression tests. Remaining open issues should be
755
812
  picked up on sight; `feedback_proactive_github_issues.md` codifies
@@ -80,18 +80,36 @@ def detect_struggle(messages: Sequence[LLMMessage], threshold: int = 20) -> Find
80
80
  calls_since_write += 1
81
81
  if calls_since_write < threshold:
82
82
  return None
83
- hint = (
84
- "Either (a) you already have enough context commit to a plan and "
85
- "start writing code now, or (b) you're genuinely stuck stop and "
86
- "report what's blocking you to the user."
87
- )
88
- return Finding(
89
- code=f"struggle:{calls_since_write}:{last_write_tool or 'none'}",
90
- directive=(
83
+ # Stable code (no count) so DEDUP_WINDOW_SEC suppresses repeated firings.
84
+ # Previously included the count, which caused 33 identical interventions
85
+ # in a single session (each with a unique key that bypassed dedup).
86
+ code = f"struggle:{last_write_tool or 'none'}"
87
+ if calls_since_write >= 30:
88
+ if last_write_tool is None:
89
+ directive = (
90
+ f"Admiral: you have made {calls_since_write} tool calls without "
91
+ f"writing a single file. You have enough context. STOP exploring "
92
+ f"and start writing code NOW. Call `write_file` to create your "
93
+ f"first file immediately."
94
+ )
95
+ else:
96
+ directive = (
97
+ f"Admiral: you have made {calls_since_write} tool calls without "
98
+ f"writing any file — search_replace is clearly not finding the text. "
99
+ f"STOP retrying. Call `write_file` with `overwrite=True` to rewrite "
100
+ f"the target file from scratch right now."
101
+ )
102
+ else:
103
+ hint = (
104
+ "Either (a) you already have enough context — commit to a plan and "
105
+ "start writing code now, or (b) you're genuinely stuck — stop and "
106
+ "report what's blocking you to the user."
107
+ )
108
+ directive = (
91
109
  f"Admiral: you have made {calls_since_write} tool calls without "
92
110
  f"writing or editing any file. {hint}"
93
- ),
94
- )
111
+ )
112
+ return Finding(code=code, directive=directive)
95
113
 
96
114
 
97
115
  def run_all(messages: Sequence[LLMMessage]) -> list[Finding]:
@@ -43,11 +43,18 @@ def _tool_result_errored(m: LLMMessage) -> bool:
43
43
  """Heuristic: does this tool-role message look like a failure?
44
44
 
45
45
  Conservative — we only want high-precision firing on actual errors.
46
- Scanned the first 800 chars of the result content.
46
+ Scanned the first 200 chars of the result content (tightened from 800
47
+ to avoid false positives when matched file content contains words like
48
+ "error" or "failed" — grep results starting with "matches:" are always
49
+ successful).
47
50
  """
48
51
  if m.role is not Role.tool:
49
52
  return False
50
- content = str(getattr(m, "content", "") or "")[:800].lower()
53
+ raw = str(getattr(m, "content", "") or "")
54
+ # Successful grep results start with "matches:" — never treat as error.
55
+ if raw.lstrip().startswith("matches:"):
56
+ return False
57
+ content = raw[:200].lower()
51
58
  return any(marker in content for marker in _TOOL_ERROR_MARKERS)
52
59
 
53
60
 
@@ -1131,10 +1131,12 @@ class AgentLoop:
1131
1131
  token-level sampling bumps don't help when the model picks
1132
1132
  the SAME serialized args every time.
1133
1133
 
1134
- Conservative thresholds only fires on truly pathological
1135
- repeat counts that would never be a "valid retry":
1134
+ Thresholds tuned for 45-prompt session windows (stress sessions
1135
+ reset every 45 prompts — a threshold of 12 never fires in practice
1136
+ because the model loops 4-8 times then moves on; admiral advisories
1137
+ fire at 3 but the model ignores them):
1136
1138
  search_replace, write_file, bash: after 8 identical calls
1137
- read_file, grep, glob, ls: after 12 identical calls
1139
+ read_file, grep, glob, ls: after 5 identical calls
1138
1140
  """
1139
1141
  args_str = json.dumps(tool_call.args_dict, sort_keys=True, default=str)
1140
1142
  sig = hashlib.sha256(
@@ -1143,9 +1145,13 @@ class AgentLoop:
1143
1145
  count, last_result = self._tool_call_history.get(sig, (0, ""))
1144
1146
  tool_name = tool_call.tool_name
1145
1147
  is_readonly = tool_name in ("grep", "read_file", "glob", "ls")
1146
- threshold = 12 if is_readonly else 8
1148
+ threshold = 5 if is_readonly else 8
1147
1149
  if count < threshold:
1148
1150
  return None
1151
+ # Increment so the count escalates on every repeated fire, giving the
1152
+ # model a growing signal that nothing has changed. Preserve last_result
1153
+ # so the message always shows the real bash/tool output, not a prior NOTE.
1154
+ self._tool_call_history[sig] = (count + 1, last_result)
1149
1155
  return (
1150
1156
  f"NOTE: this exact call to `{tool_name}` has been made "
1151
1157
  f"{count} times this session with identical arguments. "
@@ -1505,9 +1511,23 @@ class AgentLoop:
1505
1511
  self.stats.tool_calls_failed += 1
1506
1512
  self._handle_tool_response(tool_call, error_msg, "failure", decision)
1507
1513
 
1514
+ def _silence_suppressed_failures(self, suppressed: list) -> None:
1515
+ """Add tool result messages for hallucinated tools without TUI events.
1516
+
1517
+ Keeps message history well-formed (assistant tool_call → tool result)
1518
+ while hiding the error from the TUI to avoid confusing the user.
1519
+ """
1520
+ for failed in suppressed:
1521
+ error_msg = f"<{TOOL_ERROR_TAG}>{failed.tool_name}: {failed.error}</{TOOL_ERROR_TAG}>"
1522
+ self.messages.append(
1523
+ self.format_handler.create_failed_tool_response_message(failed, error_msg)
1524
+ )
1525
+ self.stats.tool_calls_failed += 1
1526
+
1508
1527
  async def _handle_tool_calls(
1509
1528
  self, resolved: ResolvedMessage
1510
1529
  ) -> AsyncGenerator[ToolCallEvent | ToolResultEvent | ToolStreamEvent | AssistantEvent]:
1530
+ self._silence_suppressed_failures(resolved.suppressed_failures)
1511
1531
  async for event in self._emit_failed_tool_events(resolved.failed_calls):
1512
1532
  yield event
1513
1533
  for tool_call in resolved.tool_calls:
@@ -1703,10 +1723,10 @@ class AgentLoop:
1703
1723
  Runs every turn but is a no-op when nothing exceeds the caps.
1704
1724
  Truncation is in-place and idempotent.
1705
1725
  """
1706
- KEEP_RECENT = 6 # last N tool messages stay full
1707
- SOFT_CAP_BYTES = 800 # tool result longer than this gets shrunk
1708
- HEAD_BYTES = 400 # bytes kept from the head
1709
- TAIL_BYTES = 100 # bytes kept from the tail
1726
+ KEEP_RECENT = 4 # last N tool messages stay full
1727
+ SOFT_CAP_BYTES = 500 # tool result longer than this gets shrunk
1728
+ HEAD_BYTES = 200 # bytes kept from the head
1729
+ TAIL_BYTES = 60 # bytes kept from the tail
1710
1730
 
1711
1731
  if len(self.messages) < KEEP_RECENT + 4:
1712
1732
  return
@@ -2334,7 +2354,16 @@ class AgentLoop:
2334
2354
  if replace_last_tool:
2335
2355
  msg.content = f"[SYSTEM: {text}]"
2336
2356
  else:
2337
- msg.content = (msg.content or "") + f"\n\n[SYSTEM: {text}]"
2357
+ content = msg.content or ""
2358
+ # Cap at 2 accumulated system notes per message; replace the
2359
+ # last one when the limit is exceeded so repeated admiral
2360
+ # interventions don't unboundedly bloat the context.
2361
+ _SYS_PREFIX = "\n\n[SYSTEM: "
2362
+ if content.count(_SYS_PREFIX) >= 2:
2363
+ last_idx = content.rfind(_SYS_PREFIX)
2364
+ msg.content = content[:last_idx] + _SYS_PREFIX + text + "]"
2365
+ else:
2366
+ msg.content = content + _SYS_PREFIX + text + "]"
2338
2367
  return
2339
2368
 
2340
2369
  # Second try: append to last user message
@@ -2370,6 +2399,30 @@ class AgentLoop:
2370
2399
  if len(recent_sr) >= 2 and recent_sr[0] == recent_sr[1]:
2371
2400
  return "WARNING|search_replace"
2372
2401
 
2402
+ # Early check: write_file with _truncated args twice in a row for the
2403
+ # same path. format.py already embeds the file content in the error,
2404
+ # but Gemma 4 ignores the advisory and retries identically. Mute
2405
+ # write_file for 1 turn so the model must use read_file or
2406
+ # search_replace instead — same pattern as the search_replace check.
2407
+ recent_wf_truncated: list[str] = []
2408
+ for msg in reversed(self.messages[-20:]):
2409
+ if msg.role == Role.assistant and msg.tool_calls:
2410
+ for tc in msg.tool_calls:
2411
+ if tc.function and tc.function.name == "write_file":
2412
+ try:
2413
+ args = json.loads(tc.function.arguments or "{}")
2414
+ if args.get("_truncated"):
2415
+ p = (args.get("file_path") or args.get("path") or "")
2416
+ recent_wf_truncated.append(p)
2417
+ except (json.JSONDecodeError, AttributeError):
2418
+ pass
2419
+ if len(recent_wf_truncated) >= 2:
2420
+ break
2421
+ if (len(recent_wf_truncated) >= 2
2422
+ and recent_wf_truncated[0] == recent_wf_truncated[1]):
2423
+ self._hot_tool_path = ("write_file", recent_wf_truncated[0])
2424
+ return "FORCE_STOP"
2425
+
2373
2426
  sigs: list[str] = []
2374
2427
  tool_names: list[str] = []
2375
2428
  lookback = 0
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import json
4
4
  import logging
5
5
  import re as _re
6
+ from pathlib import Path
6
7
  from typing import TYPE_CHECKING, Any
7
8
 
8
9
  from pydantic import BaseModel, ConfigDict, Field, ValidationError
@@ -165,9 +166,17 @@ class ResolvedMessage(BaseModel):
165
166
  model_config = ConfigDict(frozen=True)
166
167
  tool_calls: list[ResolvedToolCall]
167
168
  failed_calls: list[FailedToolCall] = Field(default_factory=list)
169
+ # Hallucinated tools: need a tool result in message history (to keep the
170
+ # conversation well-formed) but should NOT be shown as errors in the TUI.
171
+ suppressed_failures: list[FailedToolCall] = Field(default_factory=list)
168
172
 
169
173
 
170
174
  class APIToolFormatHandler:
175
+ def __init__(self) -> None:
176
+ # Track per-path truncated-history write_file retries so we can
177
+ # escalate on 2nd+ identical failures (model ignores advisory-only msgs).
178
+ self._truncated_hit_count: dict[str, int] = {}
179
+
171
180
  @property
172
181
  def name(self) -> str:
173
182
  return "api"
@@ -346,12 +355,25 @@ class APIToolFormatHandler:
346
355
  "list_mcp_resources", "list_resources", "search_resources",
347
356
  }
348
357
 
358
+ suppressed_failures = []
349
359
  for parsed_call in parsed.tool_calls:
350
360
  tool_class = active_tools.get(parsed_call.tool_name)
351
361
  if not tool_class:
352
- # Silently drop known hallucinated tools instead of
353
- # showing an error in the TUI
362
+ # Hallucinated tools: add a tool result to keep the message
363
+ # history well-formed (prevents empty_after_tool loops) but
364
+ # route to suppressed_failures so the TUI doesn't show an error.
354
365
  if parsed_call.tool_name in _IGNORE_TOOLS:
366
+ suppressed_failures.append(
367
+ FailedToolCall(
368
+ tool_name=parsed_call.tool_name,
369
+ call_id=parsed_call.call_id,
370
+ error=(
371
+ f"'{parsed_call.tool_name}' is not available. "
372
+ f"Use only tools from your tool list: "
373
+ f"{', '.join(sorted(active_tools.keys())[:8])}."
374
+ ),
375
+ )
376
+ )
355
377
  continue
356
378
  failed_calls.append(
357
379
  FailedToolCall(
@@ -367,6 +389,102 @@ class APIToolFormatHandler:
367
389
  continue
368
390
 
369
391
  args_model, _ = tool_class._get_tool_args_results()
392
+
393
+ # Detect when model copied truncated-history args (our truncation
394
+ # code replaces large tool-call args with {_truncated, _original_bytes,
395
+ # path}). Return a clear advisory instead of a pydantic traceback so
396
+ # the model re-does the call with real arguments rather than retrying
397
+ # the truncated form.
398
+ if (isinstance(parsed_call.raw_args, dict)
399
+ and parsed_call.raw_args.get("_truncated")):
400
+ path_hint = (parsed_call.raw_args.get("path")
401
+ or parsed_call.raw_args.get("file_path")
402
+ or "")
403
+ # Track retry count per path to escalate on 2nd+ offense.
404
+ hit_key = path_hint or "<unknown>"
405
+ hit_count = self._truncated_hit_count.get(hit_key, 0) + 1
406
+ self._truncated_hit_count[hit_key] = hit_count
407
+ escalate = hit_count >= 2
408
+
409
+ # Auto-embed the current file content so the model can
410
+ # rewrite immediately without an extra read_file round-trip.
411
+ file_embed = ""
412
+ if path_hint:
413
+ try:
414
+ p = Path(path_hint)
415
+ if p.exists() and p.is_file():
416
+ raw = p.read_text(errors="replace")
417
+ lines = raw.splitlines()
418
+ max_lines = 120
419
+ if len(lines) <= max_lines:
420
+ file_embed = (
421
+ f"\n\nCurrent file content of `{path_hint}`:\n"
422
+ f"```\n{raw}\n```\n"
423
+ f"Rewrite it now using write_file with the correct content."
424
+ )
425
+ else:
426
+ snippet = "\n".join(lines[:max_lines])
427
+ file_embed = (
428
+ f"\n\nCurrent file content of `{path_hint}` "
429
+ f"(first {max_lines} of {len(lines)} lines):\n"
430
+ f"```\n{snippet}\n```\n"
431
+ f"Use read_file to see the rest, then rewrite with write_file."
432
+ )
433
+ except Exception:
434
+ pass
435
+ if not file_embed and path_hint:
436
+ file_embed = f" Re-read `{path_hint}` with read_file first."
437
+
438
+ if escalate:
439
+ # Model is stuck in a truncated-template retry loop.
440
+ # Show project files and give a concrete directive.
441
+ try:
442
+ py_files = sorted(
443
+ str(p2.relative_to(Path.cwd()))
444
+ for p2 in Path.cwd().rglob("*.py")
445
+ if "__pycache__" not in str(p2) and ".git" not in str(p2)
446
+ )[:20]
447
+ dir_listing = "\n".join(f" {f}" for f in py_files)
448
+ except Exception:
449
+ dir_listing = " (could not list files)"
450
+ tool_name_hint = parsed_call.tool_name
451
+ if tool_name_hint == "search_replace":
452
+ recovery_hint = (
453
+ f"Use read_file on '{path_hint}' to see its current content, "
454
+ f"then call search_replace with fresh <<<<<<< SEARCH / ======= / "
455
+ f">>>>>>> REPLACE markers copied from the actual file text."
456
+ )
457
+ else:
458
+ recovery_hint = (
459
+ f"Use read_file on the target file, then call write_file "
460
+ f"with fully typed content, OR use search_replace to make "
461
+ f"targeted edits without rewriting the whole file."
462
+ )
463
+ escalation_suffix = (
464
+ f"\n\n[REPEATED FAILURE #{hit_count}: your {tool_name_hint} call "
465
+ f"keeps using a stale truncated template for '{path_hint}'. "
466
+ f"You MUST NOT copy args from history. "
467
+ f"Current .py files in project:\n{dir_listing}\n"
468
+ f"{recovery_hint}]"
469
+ )
470
+ else:
471
+ escalation_suffix = ""
472
+
473
+ failed_calls.append(
474
+ FailedToolCall(
475
+ tool_name=parsed_call.tool_name,
476
+ call_id=parsed_call.call_id,
477
+ error=(
478
+ f"your call used a "
479
+ f"truncated history entry as a template (it contained "
480
+ f"'_truncated'/'_original_bytes' instead of real "
481
+ f"arguments).{file_embed} Provide the full required "
482
+ f"arguments.{escalation_suffix}"
483
+ ),
484
+ )
485
+ )
486
+ continue
487
+
370
488
  try:
371
489
  validated_args = args_model.model_validate(parsed_call.raw_args)
372
490
  resolved_calls.append(
@@ -378,15 +496,78 @@ class APIToolFormatHandler:
378
496
  )
379
497
  )
380
498
  except ValidationError as e:
499
+ error_str = str(e)
500
+ if (
501
+ parsed_call.tool_name == "write_file"
502
+ and "path" in error_str
503
+ and "Field required" in error_str
504
+ ):
505
+ # Try to infer path from the first comment line of content.
506
+ # Gemma 4 frequently calls write_file(content="...") without path.
507
+ content_val = parsed_call.raw_args.get("content", "")
508
+ inferred_path: str | None = None
509
+ if content_val:
510
+ for _line in content_val.splitlines()[:5]:
511
+ _line = _line.strip()
512
+ _m = _re.match(
513
+ r'^#\s+([\w./+-]+\.(?:py|js|ts|json|yaml|yml|toml|md|txt|sh|cfg|ini))\s*$',
514
+ _line,
515
+ )
516
+ if _m:
517
+ inferred_path = _m.group(1)
518
+ break
519
+ if inferred_path:
520
+ try:
521
+ _new_args = dict(parsed_call.raw_args)
522
+ _new_args["path"] = inferred_path
523
+ validated_args = args_model.model_validate(_new_args)
524
+ resolved_calls.append(
525
+ ResolvedToolCall(
526
+ tool_name=parsed_call.tool_name,
527
+ tool_class=tool_class,
528
+ validated_args=validated_args,
529
+ call_id=parsed_call.call_id,
530
+ )
531
+ )
532
+ continue
533
+ except ValidationError:
534
+ pass
535
+ # List project .py files as hints so the model can pick the right one
536
+ _candidates: list[str] = []
537
+ try:
538
+ _candidates = [
539
+ str(p.relative_to(Path.cwd()))
540
+ for p in sorted(Path.cwd().rglob("*.py"))
541
+ if "__pycache__" not in str(p) and ".git" not in str(p)
542
+ ][:12]
543
+ except Exception:
544
+ pass
545
+ _hint = (
546
+ f"Project .py files: {', '.join(_candidates)}"
547
+ if _candidates
548
+ else "Use read_file or glob to list available files."
549
+ )
550
+ error_msg = (
551
+ "missing required `path` parameter. "
552
+ "You must pass BOTH `path` AND `content` as separate arguments: "
553
+ 'write_file(path="pkg/file.py", content="..."). '
554
+ f"Do NOT omit `path`. {_hint}"
555
+ )
556
+ else:
557
+ error_msg = f"Invalid arguments: {e}"
381
558
  failed_calls.append(
382
559
  FailedToolCall(
383
560
  tool_name=parsed_call.tool_name,
384
561
  call_id=parsed_call.call_id,
385
- error=f"Invalid arguments: {e}",
562
+ error=error_msg,
386
563
  )
387
564
  )
388
565
 
389
- return ResolvedMessage(tool_calls=resolved_calls, failed_calls=failed_calls)
566
+ return ResolvedMessage(
567
+ tool_calls=resolved_calls,
568
+ failed_calls=failed_calls,
569
+ suppressed_failures=suppressed_failures,
570
+ )
390
571
 
391
572
  def create_tool_response_message(
392
573
  self, tool_call: ResolvedToolCall, result_text: str
@@ -404,13 +404,38 @@ class Bash(
404
404
  self, *, command: str, stdout: str, stderr: str, returncode: int
405
405
  ) -> BashResult:
406
406
  if returncode != 0:
407
- error_msg = f"Command failed: {command!r}\n"
408
- error_msg += f"Return code: {returncode}"
409
- if stderr:
410
- error_msg += f"\nStderr: {stderr}"
411
- if stdout:
412
- error_msg += f"\nStdout: {stdout}"
413
- raise ToolError(error_msg.strip())
407
+ # ADVISORY ONLY never raise ToolError for non-zero exit codes.
408
+ # Raising blocks the model: it gets <tool_error> with no useful
409
+ # output, doesn't know if exit 1 means "no matches" (grep) or a
410
+ # real failure, and retries identically. Same pattern as the
411
+ # timeout handler above. Include a clear exit-code annotation so
412
+ # the model can reason about what happened.
413
+ # See feedback_no_tool_errors_for_loop_detection.md.
414
+ annotation = f"[Exit code {returncode}]"
415
+ if returncode < 0:
416
+ # Negative returncode means killed by a Unix signal.
417
+ try:
418
+ sig_name = signal.Signals(-returncode).name
419
+ except ValueError:
420
+ sig_name = f"signal {-returncode}"
421
+ annotation += (
422
+ f" — process killed by {sig_name}."
423
+ " If this command starts a server or long-running process,"
424
+ " background it with `command &` and verify ports with `ss -tlnp`."
425
+ )
426
+ elif not stdout and not stderr:
427
+ annotation += " (no output)"
428
+ if returncode == 1:
429
+ annotation += (
430
+ " — for grep/find, exit code 1 means no matches found"
431
+ )
432
+ annotated_stdout = (stdout + "\n" + annotation).strip() if stdout else annotation
433
+ return BashResult(
434
+ command=command,
435
+ stdout=annotated_stdout,
436
+ stderr=stderr,
437
+ returncode=returncode,
438
+ )
414
439
 
415
440
  return BashResult(
416
441
  command=command, stdout=stdout, stderr=stderr, returncode=returncode
@@ -445,7 +470,39 @@ class Bash(
445
470
  )
446
471
  except TimeoutError:
447
472
  await _kill_process_tree(proc)
448
- raise self._build_timeout_error(args.command, timeout)
473
+ # ADVISORY ONLY — never raise ToolError on timeout; raising
474
+ # causes the model to retry the exact same command (loop).
475
+ # Track repeat timeouts per command and escalate the hint.
476
+ # See feedback_no_tool_errors_for_loop_detection.md.
477
+ timeout_state = self.state.__dict__.setdefault(
478
+ "_bash_timeout_history", {}
479
+ )
480
+ count = timeout_state.get(args.command, 0) + 1
481
+ timeout_state[args.command] = count
482
+ if count == 1:
483
+ hint = (
484
+ "The command was killed. If it starts a server or "
485
+ "long-running process, background it with `command &` "
486
+ "instead of running it in the foreground."
487
+ )
488
+ else:
489
+ hint = (
490
+ f"[TIMEOUT #{count}] You have timed out {count}x on "
491
+ f"this exact command. Running it again will produce the "
492
+ f"same result. STOP retrying. Background servers with "
493
+ f"`&`, check existing listeners with `ss -tlnp`, or fix "
494
+ f"the underlying cause before re-running."
495
+ )
496
+ yield BashResult(
497
+ command=args.command,
498
+ stdout=(
499
+ f"Command timed out after {timeout}s: {args.command!r}\n"
500
+ f"{hint}"
501
+ ),
502
+ stderr="",
503
+ returncode=124,
504
+ )
505
+ return
449
506
 
450
507
  encoding = _get_subprocess_encoding()
451
508
  stdout = (