drydock-cli 2.10.11__tar.gz → 3.0.15__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 (804) hide show
  1. {drydock_cli-2.10.11 → drydock_cli-3.0.15}/LICENSE +1 -1
  2. drydock_cli-3.0.15/NOTICE +11 -0
  3. drydock_cli-3.0.15/PKG-INFO +138 -0
  4. drydock_cli-3.0.15/README.md +116 -0
  5. drydock_cli-3.0.15/drydock/__init__.py +10 -0
  6. drydock_cli-3.0.15/drydock/__main__.py +2 -0
  7. drydock_cli-3.0.15/drydock/agent.py +224 -0
  8. drydock_cli-3.0.15/drydock/bash_safety.py +167 -0
  9. drydock_cli-3.0.15/drydock/cli.py +264 -0
  10. drydock_cli-3.0.15/drydock/compaction.py +147 -0
  11. drydock_cli-3.0.15/drydock/config.py +107 -0
  12. drydock_cli-3.0.15/drydock/detect.py +74 -0
  13. drydock_cli-3.0.15/drydock/guards.py +261 -0
  14. drydock_cli-3.0.15/drydock/loop_detect.py +132 -0
  15. drydock_cli-3.0.15/drydock/providers.py +306 -0
  16. drydock_cli-3.0.15/drydock/tool_registry.py +46 -0
  17. drydock_cli-3.0.15/drydock/tools/__init__.py +530 -0
  18. drydock_cli-3.0.15/drydock/tui/__init__.py +4 -0
  19. drydock_cli-3.0.15/drydock/tui/app.py +508 -0
  20. drydock_cli-3.0.15/drydock/tui/approval.py +72 -0
  21. drydock_cli-3.0.15/drydock/tui/messages.py +46 -0
  22. drydock_cli-3.0.15/drydock/tui/widgets.py +245 -0
  23. drydock_cli-3.0.15/drydock/tuning.py +194 -0
  24. drydock_cli-3.0.15/drydock_cli.egg-info/PKG-INFO +138 -0
  25. drydock_cli-3.0.15/drydock_cli.egg-info/SOURCES.txt +43 -0
  26. drydock_cli-3.0.15/drydock_cli.egg-info/dependency_links.txt +1 -0
  27. drydock_cli-3.0.15/drydock_cli.egg-info/entry_points.txt +2 -0
  28. drydock_cli-3.0.15/drydock_cli.egg-info/requires.txt +8 -0
  29. drydock_cli-3.0.15/drydock_cli.egg-info/top_level.txt +1 -0
  30. drydock_cli-3.0.15/pyproject.toml +47 -0
  31. drydock_cli-3.0.15/setup.cfg +4 -0
  32. drydock_cli-3.0.15/tests/test_approval.py +76 -0
  33. drydock_cli-3.0.15/tests/test_back_command.py +57 -0
  34. drydock_cli-3.0.15/tests/test_bash_safety.py +71 -0
  35. drydock_cli-3.0.15/tests/test_compaction.py +112 -0
  36. drydock_cli-3.0.15/tests/test_config.py +88 -0
  37. drydock_cli-3.0.15/tests/test_detect.py +73 -0
  38. drydock_cli-3.0.15/tests/test_guards_and_tools.py +306 -0
  39. drydock_cli-3.0.15/tests/test_hallucinated_tools.py +38 -0
  40. drydock_cli-3.0.15/tests/test_leaked_tool_call.py +105 -0
  41. drydock_cli-3.0.15/tests/test_loop_detect.py +69 -0
  42. drydock_cli-3.0.15/tests/test_providers_unreachable.py +51 -0
  43. drydock_cli-3.0.15/tests/test_tools_undo.py +46 -0
  44. drydock_cli-3.0.15/tests/test_tui.py +309 -0
  45. drydock_cli-3.0.15/tests/test_tuning.py +98 -0
  46. drydock_cli-2.10.11/.gitignore +0 -236
  47. drydock_cli-2.10.11/NOTICE +0 -11
  48. drydock_cli-2.10.11/PKG-INFO +0 -604
  49. drydock_cli-2.10.11/README.md +0 -548
  50. drydock_cli-2.10.11/distribution/zed/LICENSE +0 -1
  51. drydock_cli-2.10.11/docs/README.md +0 -8
  52. drydock_cli-2.10.11/drydock/__init__.py +0 -11
  53. drydock_cli-2.10.11/drydock/__main__.py +0 -17
  54. drydock_cli-2.10.11/drydock/acp/__init__.py +0 -0
  55. drydock_cli-2.10.11/drydock/acp/acp_agent_loop.py +0 -818
  56. drydock_cli-2.10.11/drydock/acp/acp_logger.py +0 -97
  57. drydock_cli-2.10.11/drydock/acp/entrypoint.py +0 -92
  58. drydock_cli-2.10.11/drydock/acp/tools/__init__.py +0 -0
  59. drydock_cli-2.10.11/drydock/acp/tools/base.py +0 -100
  60. drydock_cli-2.10.11/drydock/acp/tools/builtins/bash.py +0 -143
  61. drydock_cli-2.10.11/drydock/acp/tools/builtins/read_file.py +0 -53
  62. drydock_cli-2.10.11/drydock/acp/tools/builtins/search_replace.py +0 -137
  63. drydock_cli-2.10.11/drydock/acp/tools/builtins/todo.py +0 -65
  64. drydock_cli-2.10.11/drydock/acp/tools/builtins/write_file.py +0 -106
  65. drydock_cli-2.10.11/drydock/acp/tools/session_update.py +0 -118
  66. drydock_cli-2.10.11/drydock/acp/utils.py +0 -277
  67. drydock_cli-2.10.11/drydock/admiral/__init__.py +0 -15
  68. drydock_cli-2.10.11/drydock/admiral/detectors.py +0 -139
  69. drydock_cli-2.10.11/drydock/admiral/detectors_proposed.py +0 -226
  70. drydock_cli-2.10.11/drydock/admiral/history.py +0 -23
  71. drydock_cli-2.10.11/drydock/admiral/interventions.py +0 -27
  72. drydock_cli-2.10.11/drydock/admiral/llm_analyzer.py +0 -161
  73. drydock_cli-2.10.11/drydock/admiral/metrics.py +0 -92
  74. drydock_cli-2.10.11/drydock/admiral/opus_escalator.py +0 -138
  75. drydock_cli-2.10.11/drydock/admiral/persistence.py +0 -131
  76. drydock_cli-2.10.11/drydock/admiral/policy.py +0 -134
  77. drydock_cli-2.10.11/drydock/admiral/proposer.py +0 -157
  78. drydock_cli-2.10.11/drydock/admiral/stager.py +0 -147
  79. drydock_cli-2.10.11/drydock/admiral/task_classifier.py +0 -73
  80. drydock_cli-2.10.11/drydock/admiral/tuning.py +0 -131
  81. drydock_cli-2.10.11/drydock/admiral/validator.py +0 -95
  82. drydock_cli-2.10.11/drydock/admiral/worker.py +0 -258
  83. drydock_cli-2.10.11/drydock/cli/__init__.py +0 -0
  84. drydock_cli-2.10.11/drydock/cli/autocompletion/__init__.py +0 -0
  85. drydock_cli-2.10.11/drydock/cli/autocompletion/base.py +0 -22
  86. drydock_cli-2.10.11/drydock/cli/autocompletion/path_completion.py +0 -177
  87. drydock_cli-2.10.11/drydock/cli/autocompletion/slash_command.py +0 -99
  88. drydock_cli-2.10.11/drydock/cli/cli.py +0 -361
  89. drydock_cli-2.10.11/drydock/cli/clipboard.py +0 -171
  90. drydock_cli-2.10.11/drydock/cli/commands.py +0 -230
  91. drydock_cli-2.10.11/drydock/cli/entrypoint.py +0 -426
  92. drydock_cli-2.10.11/drydock/cli/fix_windows_path.py +0 -143
  93. drydock_cli-2.10.11/drydock/cli/history_manager.py +0 -91
  94. drydock_cli-2.10.11/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -45
  95. drydock_cli-2.10.11/drydock/cli/plan_offer/decide_plan_offer.py +0 -95
  96. drydock_cli-2.10.11/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -66
  97. drydock_cli-2.10.11/drydock/cli/terminal_setup.py +0 -336
  98. drydock_cli-2.10.11/drydock/cli/textual_ui/__init__.py +0 -0
  99. drydock_cli-2.10.11/drydock/cli/textual_ui/ansi_markdown.py +0 -62
  100. drydock_cli-2.10.11/drydock/cli/textual_ui/app.py +0 -3191
  101. drydock_cli-2.10.11/drydock/cli/textual_ui/app.tcss +0 -1094
  102. drydock_cli-2.10.11/drydock/cli/textual_ui/external_editor.py +0 -32
  103. drydock_cli-2.10.11/drydock/cli/textual_ui/handlers/__init__.py +0 -5
  104. drydock_cli-2.10.11/drydock/cli/textual_ui/handlers/event_handler.py +0 -235
  105. drydock_cli-2.10.11/drydock/cli/textual_ui/notifications/__init__.py +0 -11
  106. drydock_cli-2.10.11/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  107. drydock_cli-2.10.11/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -60
  108. drydock_cli-2.10.11/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  109. drydock_cli-2.10.11/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -16
  110. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  111. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/approval_app.py +0 -235
  112. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/banner/banner.py +0 -111
  113. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -85
  114. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -58
  115. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -7
  116. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -332
  117. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -58
  118. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -43
  119. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -213
  120. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -460
  121. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -205
  122. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/compact.py +0 -88
  123. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/config_app.py +0 -177
  124. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/context_progress.py +0 -30
  125. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/load_more.py +0 -43
  126. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/loading.py +0 -246
  127. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/messages.py +0 -590
  128. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -11
  129. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/path_display.py +0 -28
  130. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -122
  131. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/question_app.py +0 -507
  132. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/session_picker.py +0 -113
  133. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/spinner.py +0 -210
  134. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/status_message.py +0 -76
  135. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/teleport_message.py +0 -31
  136. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -373
  137. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/tools.py +0 -218
  138. drydock_cli-2.10.11/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -26
  139. drydock_cli-2.10.11/drydock/cli/textual_ui/windowing/__init__.py +0 -29
  140. drydock_cli-2.10.11/drydock/cli/textual_ui/windowing/history.py +0 -106
  141. drydock_cli-2.10.11/drydock/cli/textual_ui/windowing/history_windowing.py +0 -67
  142. drydock_cli-2.10.11/drydock/cli/textual_ui/windowing/state.py +0 -105
  143. drydock_cli-2.10.11/drydock/cli/update_notifier/__init__.py +0 -47
  144. drydock_cli-2.10.11/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -59
  145. drydock_cli-2.10.11/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -101
  146. drydock_cli-2.10.11/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -107
  147. drydock_cli-2.10.11/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -16
  148. drydock_cli-2.10.11/drydock/cli/update_notifier/ports/update_gateway.py +0 -53
  149. drydock_cli-2.10.11/drydock/cli/update_notifier/update.py +0 -139
  150. drydock_cli-2.10.11/drydock/cli/update_notifier/whats_new.py +0 -59
  151. drydock_cli-2.10.11/drydock/core/__init__.py +0 -5
  152. drydock_cli-2.10.11/drydock/core/agent_loop.py +0 -9151
  153. drydock_cli-2.10.11/drydock/core/agents/__init__.py +0 -29
  154. drydock_cli-2.10.11/drydock/core/agents/manager.py +0 -165
  155. drydock_cli-2.10.11/drydock/core/agents/models.py +0 -270
  156. drydock_cli-2.10.11/drydock/core/auth/__init__.py +0 -6
  157. drydock_cli-2.10.11/drydock/core/auth/crypto.py +0 -137
  158. drydock_cli-2.10.11/drydock/core/auth/github.py +0 -178
  159. drydock_cli-2.10.11/drydock/core/auto_solve.py +0 -445
  160. drydock_cli-2.10.11/drydock/core/autocompletion/__init__.py +0 -0
  161. drydock_cli-2.10.11/drydock/core/autocompletion/completers.py +0 -263
  162. drydock_cli-2.10.11/drydock/core/autocompletion/file_indexer/__init__.py +0 -10
  163. drydock_cli-2.10.11/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -168
  164. drydock_cli-2.10.11/drydock/core/autocompletion/file_indexer/indexer.py +0 -187
  165. drydock_cli-2.10.11/drydock/core/autocompletion/file_indexer/store.py +0 -169
  166. drydock_cli-2.10.11/drydock/core/autocompletion/file_indexer/watcher.py +0 -71
  167. drydock_cli-2.10.11/drydock/core/autocompletion/fuzzy.py +0 -189
  168. drydock_cli-2.10.11/drydock/core/autocompletion/path_prompt.py +0 -108
  169. drydock_cli-2.10.11/drydock/core/autocompletion/path_prompt_adapter.py +0 -149
  170. drydock_cli-2.10.11/drydock/core/build_orchestrator.py +0 -760
  171. drydock_cli-2.10.11/drydock/core/checkpoint.py +0 -411
  172. drydock_cli-2.10.11/drydock/core/classifier/__init__.py +0 -50
  173. drydock_cli-2.10.11/drydock/core/classifier/__main__.py +0 -108
  174. drydock_cli-2.10.11/drydock/core/classifier/classifier.py +0 -116
  175. drydock_cli-2.10.11/drydock/core/classifier/dispatcher.py +0 -216
  176. drydock_cli-2.10.11/drydock/core/classifier/rules.py +0 -224
  177. drydock_cli-2.10.11/drydock/core/classifier/signal.py +0 -53
  178. drydock_cli-2.10.11/drydock/core/config/__init__.py +0 -41
  179. drydock_cli-2.10.11/drydock/core/config/_dotenv.py +0 -134
  180. drydock_cli-2.10.11/drydock/core/config/_settings.py +0 -850
  181. drydock_cli-2.10.11/drydock/core/config/doctor.py +0 -222
  182. drydock_cli-2.10.11/drydock/core/config/harness_files/__init__.py +0 -17
  183. drydock_cli-2.10.11/drydock/core/config/harness_files/_harness_manager.py +0 -169
  184. drydock_cli-2.10.11/drydock/core/config/harness_files/_paths.py +0 -8
  185. drydock_cli-2.10.11/drydock/core/config/local_detect.py +0 -147
  186. drydock_cli-2.10.11/drydock/core/config/migrate.py +0 -159
  187. drydock_cli-2.10.11/drydock/core/constraint_extract.py +0 -478
  188. drydock_cli-2.10.11/drydock/core/constraint_hint.py +0 -326
  189. drydock_cli-2.10.11/drydock/core/consultant.py +0 -189
  190. drydock_cli-2.10.11/drydock/core/context_recovery.py +0 -190
  191. drydock_cli-2.10.11/drydock/core/drydock_states.py +0 -184
  192. drydock_cli-2.10.11/drydock/core/goal.py +0 -147
  193. drydock_cli-2.10.11/drydock/core/hooks.py +0 -187
  194. drydock_cli-2.10.11/drydock/core/llm/__init__.py +0 -0
  195. drydock_cli-2.10.11/drydock/core/llm/backend/anthropic.py +0 -634
  196. drydock_cli-2.10.11/drydock/core/llm/backend/base.py +0 -40
  197. drydock_cli-2.10.11/drydock/core/llm/backend/factory.py +0 -7
  198. drydock_cli-2.10.11/drydock/core/llm/backend/generic.py +0 -629
  199. drydock_cli-2.10.11/drydock/core/llm/backend/mistral.py +0 -402
  200. drydock_cli-2.10.11/drydock/core/llm/backend/reasoning_adapter.py +0 -235
  201. drydock_cli-2.10.11/drydock/core/llm/backend/vertex.py +0 -132
  202. drydock_cli-2.10.11/drydock/core/llm/exceptions.py +0 -216
  203. drydock_cli-2.10.11/drydock/core/llm/format.py +0 -783
  204. drydock_cli-2.10.11/drydock/core/llm/grammar/__init__.py +0 -59
  205. drydock_cli-2.10.11/drydock/core/llm/grammar/_llamacpp_converter.py +0 -844
  206. drydock_cli-2.10.11/drydock/core/llm/grammar/policy.py +0 -151
  207. drydock_cli-2.10.11/drydock/core/llm/grammar/policy_union.py +0 -230
  208. drydock_cli-2.10.11/drydock/core/llm/message_utils.py +0 -26
  209. drydock_cli-2.10.11/drydock/core/llm/types.py +0 -126
  210. drydock_cli-2.10.11/drydock/core/logger.py +0 -58
  211. drydock_cli-2.10.11/drydock/core/middleware.py +0 -295
  212. drydock_cli-2.10.11/drydock/core/output_formatters.py +0 -85
  213. drydock_cli-2.10.11/drydock/core/paths/__init__.py +0 -31
  214. drydock_cli-2.10.11/drydock/core/paths/_drydock_home.py +0 -37
  215. drydock_cli-2.10.11/drydock/core/paths/_local_config_walk.py +0 -39
  216. drydock_cli-2.10.11/drydock/core/paths/conventions.py +0 -3
  217. drydock_cli-2.10.11/drydock/core/plan_session.py +0 -24
  218. drydock_cli-2.10.11/drydock/core/plugins.py +0 -138
  219. drydock_cli-2.10.11/drydock/core/programmatic.py +0 -130
  220. drydock_cli-2.10.11/drydock/core/prompts/__init__.py +0 -57
  221. drydock_cli-2.10.11/drydock/core/prompts/builder.md +0 -45
  222. drydock_cli-2.10.11/drydock/core/prompts/cli.md +0 -286
  223. drydock_cli-2.10.11/drydock/core/prompts/compact.md +0 -48
  224. drydock_cli-2.10.11/drydock/core/prompts/dangerous_directory.md +0 -5
  225. drydock_cli-2.10.11/drydock/core/prompts/diagnostic.md +0 -24
  226. drydock_cli-2.10.11/drydock/core/prompts/explore.md +0 -50
  227. drydock_cli-2.10.11/drydock/core/prompts/gemma4.md +0 -213
  228. drydock_cli-2.10.11/drydock/core/prompts/gemma4_math.md +0 -201
  229. drydock_cli-2.10.11/drydock/core/prompts/gemma4_slim.md +0 -115
  230. drydock_cli-2.10.11/drydock/core/prompts/planner.md +0 -35
  231. drydock_cli-2.10.11/drydock/core/prompts/project_context.md +0 -4
  232. drydock_cli-2.10.11/drydock/core/prompts/tests.md +0 -1
  233. drydock_cli-2.10.11/drydock/core/proxy_setup.py +0 -65
  234. drydock_cli-2.10.11/drydock/core/session/agent_memory.py +0 -123
  235. drydock_cli-2.10.11/drydock/core/session/checkpoints.py +0 -122
  236. drydock_cli-2.10.11/drydock/core/session/session_loader.py +0 -275
  237. drydock_cli-2.10.11/drydock/core/session/session_logger.py +0 -510
  238. drydock_cli-2.10.11/drydock/core/session/session_migration.py +0 -41
  239. drydock_cli-2.10.11/drydock/core/session/state_file.py +0 -143
  240. drydock_cli-2.10.11/drydock/core/session_checker.py +0 -163
  241. drydock_cli-2.10.11/drydock/core/skills/__init__.py +0 -7
  242. drydock_cli-2.10.11/drydock/core/skills/manager.py +0 -152
  243. drydock_cli-2.10.11/drydock/core/skills/models.py +0 -118
  244. drydock_cli-2.10.11/drydock/core/skills/parser.py +0 -39
  245. drydock_cli-2.10.11/drydock/core/slug.py +0 -113
  246. drydock_cli-2.10.11/drydock/core/spec_check.py +0 -490
  247. drydock_cli-2.10.11/drydock/core/steering_hook.py +0 -152
  248. drydock_cli-2.10.11/drydock/core/system_prompt.py +0 -356
  249. drydock_cli-2.10.11/drydock/core/telemetry/__init__.py +0 -0
  250. drydock_cli-2.10.11/drydock/core/telemetry/send.py +0 -197
  251. drydock_cli-2.10.11/drydock/core/teleport/errors.py +0 -9
  252. drydock_cli-2.10.11/drydock/core/teleport/git.py +0 -196
  253. drydock_cli-2.10.11/drydock/core/teleport/nuage.py +0 -185
  254. drydock_cli-2.10.11/drydock/core/teleport/teleport.py +0 -212
  255. drydock_cli-2.10.11/drydock/core/teleport/types.py +0 -54
  256. drydock_cli-2.10.11/drydock/core/tools/base.py +0 -355
  257. drydock_cli-2.10.11/drydock/core/tools/builtins/_task_manager.py +0 -166
  258. drydock_cli-2.10.11/drydock/core/tools/builtins/algebra_tool.py +0 -389
  259. drydock_cli-2.10.11/drydock/core/tools/builtins/ask_user_question.py +0 -132
  260. drydock_cli-2.10.11/drydock/core/tools/builtins/bash.py +0 -1553
  261. drydock_cli-2.10.11/drydock/core/tools/builtins/chemistry_tool.py +0 -527
  262. drydock_cli-2.10.11/drydock/core/tools/builtins/count_tool.py +0 -201
  263. drydock_cli-2.10.11/drydock/core/tools/builtins/cron.py +0 -164
  264. drydock_cli-2.10.11/drydock/core/tools/builtins/exit_plan_mode.py +0 -156
  265. drydock_cli-2.10.11/drydock/core/tools/builtins/glob_tool.py +0 -94
  266. drydock_cli-2.10.11/drydock/core/tools/builtins/grep.py +0 -350
  267. drydock_cli-2.10.11/drydock/core/tools/builtins/invoke_skill.py +0 -225
  268. drydock_cli-2.10.11/drydock/core/tools/builtins/linear_algebra_tool.py +0 -420
  269. drydock_cli-2.10.11/drydock/core/tools/builtins/logic_tool.py +0 -483
  270. drydock_cli-2.10.11/drydock/core/tools/builtins/lsp.py +0 -202
  271. drydock_cli-2.10.11/drydock/core/tools/builtins/math_tool.py +0 -236
  272. drydock_cli-2.10.11/drydock/core/tools/builtins/mcp_resources.py +0 -231
  273. drydock_cli-2.10.11/drydock/core/tools/builtins/mechanical_rename.py +0 -283
  274. drydock_cli-2.10.11/drydock/core/tools/builtins/memory_tool.py +0 -352
  275. drydock_cli-2.10.11/drydock/core/tools/builtins/notebook_edit.py +0 -96
  276. drydock_cli-2.10.11/drydock/core/tools/builtins/number_theory_tool.py +0 -418
  277. drydock_cli-2.10.11/drydock/core/tools/builtins/powershell.py +0 -115
  278. drydock_cli-2.10.11/drydock/core/tools/builtins/prolog_tool.py +0 -313
  279. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  280. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -84
  281. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/bash.md +0 -73
  282. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/cron.md +0 -5
  283. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/glob.md +0 -9
  284. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/grep.md +0 -4
  285. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -9
  286. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/lsp.md +0 -9
  287. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -4
  288. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -7
  289. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/powershell.md +0 -6
  290. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/read_file.md +0 -18
  291. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/retrieve.md +0 -22
  292. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/search_replace.md +0 -43
  293. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/swe_bench.md +0 -38
  294. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/task.md +0 -24
  295. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/task_manager.md +0 -8
  296. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/todo.md +0 -199
  297. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/tool_search.md +0 -7
  298. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/webfetch.md +0 -6
  299. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/websearch.md +0 -25
  300. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/worktree.md +0 -7
  301. drydock_cli-2.10.11/drydock/core/tools/builtins/prompts/write_file.md +0 -42
  302. drydock_cli-2.10.11/drydock/core/tools/builtins/read_file.py +0 -475
  303. drydock_cli-2.10.11/drydock/core/tools/builtins/retrieve.py +0 -287
  304. drydock_cli-2.10.11/drydock/core/tools/builtins/search_replace.py +0 -2014
  305. drydock_cli-2.10.11/drydock/core/tools/builtins/set_tool.py +0 -338
  306. drydock_cli-2.10.11/drydock/core/tools/builtins/solve_tool.py +0 -446
  307. drydock_cli-2.10.11/drydock/core/tools/builtins/stats_tool.py +0 -488
  308. drydock_cli-2.10.11/drydock/core/tools/builtins/task.py +0 -247
  309. drydock_cli-2.10.11/drydock/core/tools/builtins/todo.py +0 -222
  310. drydock_cli-2.10.11/drydock/core/tools/builtins/tool_search.py +0 -120
  311. drydock_cli-2.10.11/drydock/core/tools/builtins/units_tool.py +0 -335
  312. drydock_cli-2.10.11/drydock/core/tools/builtins/verify_tool.py +0 -349
  313. drydock_cli-2.10.11/drydock/core/tools/builtins/webfetch.py +0 -202
  314. drydock_cli-2.10.11/drydock/core/tools/builtins/websearch.py +0 -136
  315. drydock_cli-2.10.11/drydock/core/tools/builtins/worktree.py +0 -165
  316. drydock_cli-2.10.11/drydock/core/tools/builtins/write_file.py +0 -988
  317. drydock_cli-2.10.11/drydock/core/tools/injection_guard.py +0 -105
  318. drydock_cli-2.10.11/drydock/core/tools/manager.py +0 -371
  319. drydock_cli-2.10.11/drydock/core/tools/mcp/__init__.py +0 -31
  320. drydock_cli-2.10.11/drydock/core/tools/mcp/registry.py +0 -172
  321. drydock_cli-2.10.11/drydock/core/tools/mcp/tools.py +0 -541
  322. drydock_cli-2.10.11/drydock/core/tools/mcp_sampling.py +0 -115
  323. drydock_cli-2.10.11/drydock/core/tools/ui.py +0 -121
  324. drydock_cli-2.10.11/drydock/core/tools/utils.py +0 -69
  325. drydock_cli-2.10.11/drydock/core/trusted_folders.py +0 -87
  326. drydock_cli-2.10.11/drydock/core/types.py +0 -504
  327. drydock_cli-2.10.11/drydock/core/utils.py +0 -346
  328. drydock_cli-2.10.11/drydock/curiosity/__init__.py +0 -40
  329. drydock_cli-2.10.11/drydock/curiosity/__main__.py +0 -263
  330. drydock_cli-2.10.11/drydock/curiosity/gap_detector.py +0 -485
  331. drydock_cli-2.10.11/drydock/curiosity/ingest.py +0 -680
  332. drydock_cli-2.10.11/drydock/curiosity/item.py +0 -58
  333. drydock_cli-2.10.11/drydock/curiosity/queue.py +0 -112
  334. drydock_cli-2.10.11/drydock/curiosity/surprise.py +0 -112
  335. drydock_cli-2.10.11/drydock/data/cookbook/python/global_rename.md +0 -134
  336. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/biopython_dna.md +0 -116
  337. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/dense_eigenvalue.md +0 -135
  338. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/elf_extraction_js.md +0 -165
  339. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/feal_cryptanalysis.md +0 -124
  340. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/llm_batching_scheduler.md +0 -137
  341. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/mcmc_stan.md +0 -188
  342. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/mips_isa.md +0 -162
  343. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/mobilesam_cell_seg.md +0 -162
  344. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/mteb_retrieve.md +0 -124
  345. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/password_recovery.md +0 -189
  346. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/path_tracing.md +0 -110
  347. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/raman_fitting.md +0 -190
  348. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/regex_chess.md +0 -211
  349. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/sqlite_recovery.md +0 -167
  350. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/vim_macros.md +0 -120
  351. drydock_cli-2.10.11/drydock/data/cookbook/tbench_domains/xss_filter.md +0 -153
  352. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/build_cython_ext.md +0 -529
  353. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/build_pmars.md +0 -108
  354. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/build_pov_ray.md +0 -130
  355. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/cancel_async_tasks.md +0 -172
  356. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/chess_best_move.md +0 -63
  357. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/cobol_modernization.md +0 -158
  358. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/code_from_image.md +0 -111
  359. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/configure_git_webserver.md +0 -134
  360. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/constraints_scheduling.md +0 -196
  361. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/custom_memory_heap_crash.md +0 -109
  362. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/extract_elf.md +0 -86
  363. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/extract_moves_from_video.md +0 -341
  364. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/fix_code_vulnerability.md +0 -145
  365. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/git_leak_recovery.md +0 -55
  366. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/log_summary_date_ranges.md +0 -229
  367. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/model_extraction_relu_logits.md +0 -115
  368. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/mteb_leaderboard.md +0 -76
  369. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/query_optimize.md +0 -213
  370. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/sam_cell_seg.md +0 -410
  371. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/tune_mjcf.md +0 -270
  372. drydock_cli-2.10.11/drydock/data/cookbook/tbench_worked_examples/vulnerable_secret.md +0 -110
  373. drydock_cli-2.10.11/drydock/graphrag/__init__.py +0 -46
  374. drydock_cli-2.10.11/drydock/graphrag/__main__.py +0 -229
  375. drydock_cli-2.10.11/drydock/graphrag/code_indexer.py +0 -213
  376. drydock_cli-2.10.11/drydock/graphrag/retriever.py +0 -146
  377. drydock_cli-2.10.11/drydock/graphrag/storage.py +0 -670
  378. drydock_cli-2.10.11/drydock/graphrag/text_indexer.py +0 -308
  379. drydock_cli-2.10.11/drydock/setup/onboarding/__init__.py +0 -49
  380. drydock_cli-2.10.11/drydock/setup/onboarding/base.py +0 -14
  381. drydock_cli-2.10.11/drydock/setup/onboarding/onboarding.tcss +0 -134
  382. drydock_cli-2.10.11/drydock/setup/onboarding/screens/__init__.py +0 -13
  383. drydock_cli-2.10.11/drydock/setup/onboarding/screens/api_key.py +0 -142
  384. drydock_cli-2.10.11/drydock/setup/onboarding/screens/choice.py +0 -65
  385. drydock_cli-2.10.11/drydock/setup/onboarding/screens/local_model.py +0 -187
  386. drydock_cli-2.10.11/drydock/setup/onboarding/screens/welcome.py +0 -136
  387. drydock_cli-2.10.11/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -185
  388. drydock_cli-2.10.11/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -83
  389. drydock_cli-2.10.11/drydock/skills/__init__.py +0 -0
  390. drydock_cli-2.10.11/drydock/skills/api-design/SKILL.md +0 -32
  391. drydock_cli-2.10.11/drydock/skills/audit-tests/SKILL.md +0 -73
  392. drydock_cli-2.10.11/drydock/skills/batch/SKILL.md +0 -45
  393. drydock_cli-2.10.11/drydock/skills/checklist/SKILL.md +0 -105
  394. drydock_cli-2.10.11/drydock/skills/commit-code/SKILL.md +0 -27
  395. drydock_cli-2.10.11/drydock/skills/constraint-reasoning/SKILL.md +0 -202
  396. drydock_cli-2.10.11/drydock/skills/context-summary/SKILL.md +0 -19
  397. drydock_cli-2.10.11/drydock/skills/create-presentation/SKILL.md +0 -120
  398. drydock_cli-2.10.11/drydock/skills/deep-research/SKILL.md +0 -57
  399. drydock_cli-2.10.11/drydock/skills/deploy/SKILL.md +0 -26
  400. drydock_cli-2.10.11/drydock/skills/diff-review/SKILL.md +0 -16
  401. drydock_cli-2.10.11/drydock/skills/doc-gen/SKILL.md +0 -28
  402. drydock_cli-2.10.11/drydock/skills/explain-code/SKILL.md +0 -27
  403. drydock_cli-2.10.11/drydock/skills/explore-code/SKILL.md +0 -42
  404. drydock_cli-2.10.11/drydock/skills/fix-issue/SKILL.md +0 -33
  405. drydock_cli-2.10.11/drydock/skills/git-ops/SKILL.md +0 -32
  406. drydock_cli-2.10.11/drydock/skills/init-project/SKILL.md +0 -34
  407. drydock_cli-2.10.11/drydock/skills/investigate/SKILL.md +0 -67
  408. drydock_cli-2.10.11/drydock/skills/logic/SKILL.md +0 -139
  409. drydock_cli-2.10.11/drydock/skills/logic/assets/cheat_sheet_full.txt +0 -833
  410. drydock_cli-2.10.11/drydock/skills/loop/SKILL.md +0 -22
  411. drydock_cli-2.10.11/drydock/skills/migrate/SKILL.md +0 -25
  412. drydock_cli-2.10.11/drydock/skills/perf-analyze/SKILL.md +0 -29
  413. drydock_cli-2.10.11/drydock/skills/plan-impl/SKILL.md +0 -45
  414. drydock_cli-2.10.11/drydock/skills/pr-review/SKILL.md +0 -32
  415. drydock_cli-2.10.11/drydock/skills/prove/SKILL.md +0 -148
  416. drydock_cli-2.10.11/drydock/skills/refactor/SKILL.md +0 -37
  417. drydock_cli-2.10.11/drydock/skills/regex-help/SKILL.md +0 -30
  418. drydock_cli-2.10.11/drydock/skills/review/SKILL.md +0 -67
  419. drydock_cli-2.10.11/drydock/skills/security-review/SKILL.md +0 -31
  420. drydock_cli-2.10.11/drydock/skills/ship/SKILL.md +0 -65
  421. drydock_cli-2.10.11/drydock/skills/simplify/SKILL.md +0 -39
  422. drydock_cli-2.10.11/drydock/skills/strong-tests/SKILL.md +0 -94
  423. drydock_cli-2.10.11/drydock/skills/test-verify/SKILL.md +0 -27
  424. drydock_cli-2.10.11/drydock/steering/__init__.py +0 -70
  425. drydock_cli-2.10.11/drydock/steering/__main__.py +0 -161
  426. drydock_cli-2.10.11/drydock/steering/applier.py +0 -300
  427. drydock_cli-2.10.11/drydock/steering/config.py +0 -51
  428. drydock_cli-2.10.11/drydock/steering/registry.py +0 -131
  429. drydock_cli-2.10.11/drydock/steering/sandbox.py +0 -151
  430. drydock_cli-2.10.11/drydock/steering/sidecar/__init__.py +0 -28
  431. drydock_cli-2.10.11/drydock/steering/sidecar/header_parser.py +0 -74
  432. drydock_cli-2.10.11/drydock/steering/sidecar/hooks.py +0 -373
  433. drydock_cli-2.10.11/drydock/steering/sidecar/loader.py +0 -98
  434. drydock_cli-2.10.11/drydock/steering/sidecar/server.py +0 -384
  435. drydock_cli-2.10.11/drydock/steering/train/__init__.py +0 -12
  436. drydock_cli-2.10.11/drydock/steering/train/capture.py +0 -247
  437. drydock_cli-2.10.11/drydock/steering/train/compute_vector.py +0 -375
  438. drydock_cli-2.10.11/drydock/steering/train/extract_pairs.py +0 -443
  439. drydock_cli-2.10.11/drydock/steering/train/scan_sessions.py +0 -311
  440. drydock_cli-2.10.11/drydock/steering/vectors.py +0 -152
  441. drydock_cli-2.10.11/drydock/whats_new.md +0 -31
  442. drydock_cli-2.10.11/install_tests/README.md +0 -84
  443. drydock_cli-2.10.11/install_tests/publish/README.md +0 -78
  444. drydock_cli-2.10.11/install_tests/windows/README.md +0 -59
  445. drydock_cli-2.10.11/pyproject.toml +0 -208
  446. drydock_cli-2.10.11/scripts/README.md +0 -20
  447. drydock_cli-2.10.11/scripts/_archived_eval_harness/README.md +0 -38
  448. drydock_cli-2.10.11/scripts/llm/README.md +0 -80
  449. drydock_cli-2.10.11/tests/__init__.py +0 -5
  450. drydock_cli-2.10.11/tests/acp/conftest.py +0 -97
  451. drydock_cli-2.10.11/tests/acp/test_acp.py +0 -965
  452. drydock_cli-2.10.11/tests/acp/test_agent_thought.py +0 -154
  453. drydock_cli-2.10.11/tests/acp/test_bash.py +0 -496
  454. drydock_cli-2.10.11/tests/acp/test_compact_session_updates.py +0 -81
  455. drydock_cli-2.10.11/tests/acp/test_content.py +0 -149
  456. drydock_cli-2.10.11/tests/acp/test_initialize.py +0 -70
  457. drydock_cli-2.10.11/tests/acp/test_list_sessions.py +0 -242
  458. drydock_cli-2.10.11/tests/acp/test_load_session.py +0 -344
  459. drydock_cli-2.10.11/tests/acp/test_multi_session.py +0 -112
  460. drydock_cli-2.10.11/tests/acp/test_new_session.py +0 -151
  461. drydock_cli-2.10.11/tests/acp/test_proxy_setup_acp.py +0 -271
  462. drydock_cli-2.10.11/tests/acp/test_read_file.py +0 -247
  463. drydock_cli-2.10.11/tests/acp/test_search_replace.py +0 -354
  464. drydock_cli-2.10.11/tests/acp/test_set_config_option.py +0 -317
  465. drydock_cli-2.10.11/tests/acp/test_set_mode.py +0 -201
  466. drydock_cli-2.10.11/tests/acp/test_set_model.py +0 -306
  467. drydock_cli-2.10.11/tests/acp/test_tool_call_session_update.py +0 -44
  468. drydock_cli-2.10.11/tests/acp/test_utils.py +0 -55
  469. drydock_cli-2.10.11/tests/acp/test_write_file.py +0 -277
  470. drydock_cli-2.10.11/tests/autocompletion/conftest.py +0 -27
  471. drydock_cli-2.10.11/tests/autocompletion/test_file_indexer.py +0 -349
  472. drydock_cli-2.10.11/tests/autocompletion/test_fuzzy.py +0 -96
  473. drydock_cli-2.10.11/tests/autocompletion/test_path_completer_fuzzy.py +0 -122
  474. drydock_cli-2.10.11/tests/autocompletion/test_path_completer_recursive.py +0 -69
  475. drydock_cli-2.10.11/tests/autocompletion/test_path_completion_controller.py +0 -258
  476. drydock_cli-2.10.11/tests/autocompletion/test_path_prompt_transformer.py +0 -142
  477. drydock_cli-2.10.11/tests/autocompletion/test_slash_command_controller.py +0 -235
  478. drydock_cli-2.10.11/tests/autocompletion/test_ui_chat_autocompletion.py +0 -309
  479. drydock_cli-2.10.11/tests/backend/__init__.py +0 -0
  480. drydock_cli-2.10.11/tests/backend/data/__init__.py +0 -6
  481. drydock_cli-2.10.11/tests/backend/data/fireworks.py +0 -153
  482. drydock_cli-2.10.11/tests/backend/data/mistral.py +0 -150
  483. drydock_cli-2.10.11/tests/backend/test_anthropic_adapter.py +0 -586
  484. drydock_cli-2.10.11/tests/backend/test_backend.py +0 -437
  485. drydock_cli-2.10.11/tests/backend/test_generic_adapter_sanitize.py +0 -159
  486. drydock_cli-2.10.11/tests/backend/test_reasoning_adapter.py +0 -254
  487. drydock_cli-2.10.11/tests/backend/test_vertex_anthropic_adapter.py +0 -637
  488. drydock_cli-2.10.11/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -32
  489. drydock_cli-2.10.11/tests/cli/plan_offer/test_decide_plan_offer.py +0 -172
  490. drydock_cli-2.10.11/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -147
  491. drydock_cli-2.10.11/tests/cli/test_bell_notifications.py +0 -151
  492. drydock_cli-2.10.11/tests/cli/test_braille_renderer.py +0 -114
  493. drydock_cli-2.10.11/tests/cli/test_clipboard.py +0 -325
  494. drydock_cli-2.10.11/tests/cli/test_commands.py +0 -62
  495. drydock_cli-2.10.11/tests/cli/test_copy_shortcuts.py +0 -59
  496. drydock_cli-2.10.11/tests/cli/test_external_editor.py +0 -72
  497. drydock_cli-2.10.11/tests/cli/test_no_markup_static.py +0 -19
  498. drydock_cli-2.10.11/tests/cli/test_question_app.py +0 -513
  499. drydock_cli-2.10.11/tests/cli/test_spinner.py +0 -16
  500. drydock_cli-2.10.11/tests/cli/test_switching_mode.py +0 -109
  501. drydock_cli-2.10.11/tests/cli/test_ui_clipboard_notifications.py +0 -40
  502. drydock_cli-2.10.11/tests/cli/test_ui_session_incremental_renderer.py +0 -173
  503. drydock_cli-2.10.11/tests/cli/test_ui_session_resume.py +0 -197
  504. drydock_cli-2.10.11/tests/cli/test_ui_skill_dispatch.py +0 -152
  505. drydock_cli-2.10.11/tests/cli/textual_ui/__init__.py +0 -0
  506. drydock_cli-2.10.11/tests/cli/textual_ui/test_session_picker.py +0 -131
  507. drydock_cli-2.10.11/tests/conftest.py +0 -227
  508. drydock_cli-2.10.11/tests/core/test_agents.py +0 -80
  509. drydock_cli-2.10.11/tests/core/test_auth_crypto.py +0 -46
  510. drydock_cli-2.10.11/tests/core/test_auth_github.py +0 -286
  511. drydock_cli-2.10.11/tests/core/test_config_load_dotenv.py +0 -81
  512. drydock_cli-2.10.11/tests/core/test_config_paths.py +0 -345
  513. drydock_cli-2.10.11/tests/core/test_config_resolution.py +0 -123
  514. drydock_cli-2.10.11/tests/core/test_file_logging.py +0 -280
  515. drydock_cli-2.10.11/tests/core/test_plan_session.py +0 -42
  516. drydock_cli-2.10.11/tests/core/test_proxy_setup.py +0 -304
  517. drydock_cli-2.10.11/tests/core/test_slug.py +0 -34
  518. drydock_cli-2.10.11/tests/core/test_telemetry_send.py +0 -374
  519. drydock_cli-2.10.11/tests/core/test_teleport_git.py +0 -327
  520. drydock_cli-2.10.11/tests/core/test_teleport_nuage.py +0 -337
  521. drydock_cli-2.10.11/tests/core/test_teleport_service.py +0 -418
  522. drydock_cli-2.10.11/tests/core/test_trusted_folders.py +0 -268
  523. drydock_cli-2.10.11/tests/core/test_utils.py +0 -19
  524. drydock_cli-2.10.11/tests/e2e/common.py +0 -86
  525. drydock_cli-2.10.11/tests/e2e/conftest.py +0 -82
  526. drydock_cli-2.10.11/tests/e2e/mock_server.py +0 -149
  527. drydock_cli-2.10.11/tests/e2e/test_cli_tui_onboarding.py +0 -31
  528. drydock_cli-2.10.11/tests/e2e/test_cli_tui_streaming.py +0 -51
  529. drydock_cli-2.10.11/tests/e2e/test_cli_tui_tool_approval.py +0 -87
  530. drydock_cli-2.10.11/tests/fixtures/doc_qa_system_prd.md +0 -86
  531. drydock_cli-2.10.11/tests/mock/__init__.py +0 -0
  532. drydock_cli-2.10.11/tests/mock/mock_backend_factory.py +0 -16
  533. drydock_cli-2.10.11/tests/mock/mock_entrypoint.py +0 -65
  534. drydock_cli-2.10.11/tests/mock/utils.py +0 -60
  535. drydock_cli-2.10.11/tests/onboarding/test_run_onboarding.py +0 -60
  536. drydock_cli-2.10.11/tests/onboarding/test_ui_onboarding.py +0 -57
  537. drydock_cli-2.10.11/tests/session/test_session_loader.py +0 -1065
  538. drydock_cli-2.10.11/tests/session/test_session_logger.py +0 -782
  539. drydock_cli-2.10.11/tests/session/test_session_migration.py +0 -177
  540. drydock_cli-2.10.11/tests/skills/conftest.py +0 -62
  541. drydock_cli-2.10.11/tests/skills/test_manager.py +0 -520
  542. drydock_cli-2.10.11/tests/skills/test_models.py +0 -195
  543. drydock_cli-2.10.11/tests/skills/test_parser.py +0 -115
  544. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -136
  545. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -176
  546. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -201
  547. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -206
  548. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -203
  549. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -201
  550. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -201
  551. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -201
  552. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -200
  553. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -200
  554. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -114
  555. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -137
  556. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -200
  557. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -200
  558. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -203
  559. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -202
  560. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -201
  561. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -200
  562. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -137
  563. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -137
  564. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -137
  565. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -137
  566. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -137
  567. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -137
  568. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -136
  569. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -139
  570. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -137
  571. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -139
  572. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -136
  573. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -136
  574. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -136
  575. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -136
  576. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -136
  577. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -140
  578. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -136
  579. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -140
  580. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -139
  581. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -203
  582. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -203
  583. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -203
  584. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -203
  585. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -204
  586. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -202
  587. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -94
  588. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -94
  589. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -104
  590. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -104
  591. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -104
  592. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -94
  593. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -94
  594. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -94
  595. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -95
  596. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -95
  597. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -94
  598. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -94
  599. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -94
  600. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -202
  601. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -203
  602. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -203
  603. drydock_cli-2.10.11/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -202
  604. drydock_cli-2.10.11/tests/snapshots/base_snapshot_test_app.py +0 -69
  605. drydock_cli-2.10.11/tests/snapshots/conftest.py +0 -10
  606. drydock_cli-2.10.11/tests/snapshots/snap_compare.py +0 -20
  607. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -80
  608. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -33
  609. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -38
  610. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -58
  611. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_modes.py +0 -88
  612. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -114
  613. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -129
  614. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_question_app.py +0 -365
  615. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -146
  616. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -45
  617. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_session_resume.py +0 -47
  618. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -75
  619. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_teleport.py +0 -249
  620. drydock_cli-2.10.11/tests/snapshots/test_ui_snapshot_whats_new.py +0 -156
  621. drydock_cli-2.10.11/tests/stress/__init__.py +0 -0
  622. drydock_cli-2.10.11/tests/stress/test_io_thrash.py +0 -740
  623. drydock_cli-2.10.11/tests/stubs/fake_backend.py +0 -149
  624. drydock_cli-2.10.11/tests/stubs/fake_client.py +0 -134
  625. drydock_cli-2.10.11/tests/stubs/fake_tool.py +0 -35
  626. drydock_cli-2.10.11/tests/test_admiral.py +0 -99
  627. drydock_cli-2.10.11/tests/test_admiral_hallucinated_tool_filter.py +0 -89
  628. drydock_cli-2.10.11/tests/test_admiral_intervention_outcome.py +0 -154
  629. drydock_cli-2.10.11/tests/test_admiral_phase3.py +0 -171
  630. drydock_cli-2.10.11/tests/test_admiral_proposed.py +0 -165
  631. drydock_cli-2.10.11/tests/test_admiral_session_id.py +0 -93
  632. drydock_cli-2.10.11/tests/test_admiral_struggle_dedup.py +0 -99
  633. drydock_cli-2.10.11/tests/test_agent_auto_compact.py +0 -148
  634. drydock_cli-2.10.11/tests/test_agent_backend.py +0 -187
  635. drydock_cli-2.10.11/tests/test_agent_observer_streaming.py +0 -643
  636. drydock_cli-2.10.11/tests/test_agent_stats.py +0 -754
  637. drydock_cli-2.10.11/tests/test_agent_tasks.py +0 -234
  638. drydock_cli-2.10.11/tests/test_agent_tool_call.py +0 -531
  639. drydock_cli-2.10.11/tests/test_agents.py +0 -610
  640. drydock_cli-2.10.11/tests/test_algebra_tool.py +0 -194
  641. drydock_cli-2.10.11/tests/test_api_error_recovery.py +0 -194
  642. drydock_cli-2.10.11/tests/test_approval_modal_stray_keys.py +0 -92
  643. drydock_cli-2.10.11/tests/test_auto_retrieve_cookbook_bypass.py +0 -52
  644. drydock_cli-2.10.11/tests/test_auto_retrieve_soft_nudge.py +0 -294
  645. drydock_cli-2.10.11/tests/test_auto_retrieve_wrapper_strip.py +0 -111
  646. drydock_cli-2.10.11/tests/test_auto_solve.py +0 -266
  647. drydock_cli-2.10.11/tests/test_bank_build.py +0 -565
  648. drydock_cli-2.10.11/tests/test_bank_debug.py +0 -1108
  649. drydock_cli-2.10.11/tests/test_bank_multiagent.py +0 -692
  650. drydock_cli-2.10.11/tests/test_bank_prd.py +0 -769
  651. drydock_cli-2.10.11/tests/test_bank_prd_extended.py +0 -765
  652. drydock_cli-2.10.11/tests/test_bank_tools.py +0 -468
  653. drydock_cli-2.10.11/tests/test_bank_update.py +0 -930
  654. drydock_cli-2.10.11/tests/test_broken_tool_isolation.py +0 -74
  655. drydock_cli-2.10.11/tests/test_build_projects.py +0 -272
  656. drydock_cli-2.10.11/tests/test_checkpoint.py +0 -338
  657. drydock_cli-2.10.11/tests/test_chemistry_tool.py +0 -192
  658. drydock_cli-2.10.11/tests/test_classifier.py +0 -275
  659. drydock_cli-2.10.11/tests/test_cli_programmatic_preload.py +0 -144
  660. drydock_cli-2.10.11/tests/test_config_migration.py +0 -128
  661. drydock_cli-2.10.11/tests/test_constraint_extract.py +0 -282
  662. drydock_cli-2.10.11/tests/test_constraint_hint.py +0 -172
  663. drydock_cli-2.10.11/tests/test_context_recovery.py +0 -123
  664. drydock_cli-2.10.11/tests/test_count_tool.py +0 -187
  665. drydock_cli-2.10.11/tests/test_curiosity.py +0 -332
  666. drydock_cli-2.10.11/tests/test_current_bugs.py +0 -148
  667. drydock_cli-2.10.11/tests/test_dispatch_report.py +0 -141
  668. drydock_cli-2.10.11/tests/test_dispatcher.py +0 -188
  669. drydock_cli-2.10.11/tests/test_drydock_regression.py +0 -460
  670. drydock_cli-2.10.11/tests/test_drydock_tasks.py +0 -495
  671. drydock_cli-2.10.11/tests/test_fake_tool_call_paren_syntax.py +0 -90
  672. drydock_cli-2.10.11/tests/test_full_regression.py +0 -199
  673. drydock_cli-2.10.11/tests/test_gemma4_anti_loop_migration.py +0 -137
  674. drydock_cli-2.10.11/tests/test_gemma4_tool_filter.py +0 -95
  675. drydock_cli-2.10.11/tests/test_goal.py +0 -203
  676. drydock_cli-2.10.11/tests/test_grammar.py +0 -431
  677. drydock_cli-2.10.11/tests/test_graphrag.py +0 -208
  678. drydock_cli-2.10.11/tests/test_graphrag_pdf_ingest.py +0 -104
  679. drydock_cli-2.10.11/tests/test_graphrag_worked_examples.py +0 -170
  680. drydock_cli-2.10.11/tests/test_hallucinated_tool_suppression.py +0 -137
  681. drydock_cli-2.10.11/tests/test_history_manager.py +0 -101
  682. drydock_cli-2.10.11/tests/test_hle_aggregate.py +0 -123
  683. drydock_cli-2.10.11/tests/test_integration.py +0 -274
  684. drydock_cli-2.10.11/tests/test_issue_fixes.py +0 -215
  685. drydock_cli-2.10.11/tests/test_linear_algebra_tool.py +0 -237
  686. drydock_cli-2.10.11/tests/test_local_detect.py +0 -268
  687. drydock_cli-2.10.11/tests/test_local_detect_fallback.py +0 -86
  688. drydock_cli-2.10.11/tests/test_logic_tool.py +0 -247
  689. drydock_cli-2.10.11/tests/test_loop_detection.py +0 -1005
  690. drydock_cli-2.10.11/tests/test_loop_regressions_2026_06_06.py +0 -685
  691. drydock_cli-2.10.11/tests/test_math_docs_lazy_injection.py +0 -99
  692. drydock_cli-2.10.11/tests/test_math_tool.py +0 -231
  693. drydock_cli-2.10.11/tests/test_mcp_settings.py +0 -17
  694. drydock_cli-2.10.11/tests/test_mcp_stdio_command_normalization.py +0 -53
  695. drydock_cli-2.10.11/tests/test_mechanical_rename_tool.py +0 -32
  696. drydock_cli-2.10.11/tests/test_mechanical_rename_type_extraction.py +0 -91
  697. drydock_cli-2.10.11/tests/test_memory_tool.py +0 -235
  698. drydock_cli-2.10.11/tests/test_message_id.py +0 -162
  699. drydock_cli-2.10.11/tests/test_message_merging.py +0 -47
  700. drydock_cli-2.10.11/tests/test_middleware.py +0 -607
  701. drydock_cli-2.10.11/tests/test_multi_agent.py +0 -112
  702. drydock_cli-2.10.11/tests/test_number_theory_tool.py +0 -228
  703. drydock_cli-2.10.11/tests/test_prolog_tool.py +0 -203
  704. drydock_cli-2.10.11/tests/test_read_file_not_found_listing.py +0 -69
  705. drydock_cli-2.10.11/tests/test_read_file_notebook_slim.py +0 -114
  706. drydock_cli-2.10.11/tests/test_real_failures.py +0 -91
  707. drydock_cli-2.10.11/tests/test_real_issues.py +0 -257
  708. drydock_cli-2.10.11/tests/test_real_workflow.py +0 -85
  709. drydock_cli-2.10.11/tests/test_reasoning_content.py +0 -572
  710. drydock_cli-2.10.11/tests/test_rejudge_hle.py +0 -187
  711. drydock_cli-2.10.11/tests/test_retrieval_consumer.py +0 -175
  712. drydock_cli-2.10.11/tests/test_retrieve_project_detection.py +0 -63
  713. drydock_cli-2.10.11/tests/test_retrieve_tool.py +0 -189
  714. drydock_cli-2.10.11/tests/test_safe_parse_tool_args.py +0 -85
  715. drydock_cli-2.10.11/tests/test_search_replace_args_not_truncated.py +0 -185
  716. drydock_cli-2.10.11/tests/test_search_replace_syntax_rollback.py +0 -133
  717. drydock_cli-2.10.11/tests/test_session_log_event.py +0 -89
  718. drydock_cli-2.10.11/tests/test_session_publish_on_resume.py +0 -84
  719. drydock_cli-2.10.11/tests/test_set_tool.py +0 -166
  720. drydock_cli-2.10.11/tests/test_smoke.py +0 -175
  721. drydock_cli-2.10.11/tests/test_solve_tool.py +0 -337
  722. drydock_cli-2.10.11/tests/test_specialist_math_tools_hidden.py +0 -95
  723. drydock_cli-2.10.11/tests/test_stats_tool.py +0 -209
  724. drydock_cli-2.10.11/tests/test_steering.py +0 -387
  725. drydock_cli-2.10.11/tests/test_steering_capture.py +0 -292
  726. drydock_cli-2.10.11/tests/test_steering_compute_vector.py +0 -326
  727. drydock_cli-2.10.11/tests/test_steering_extract_pairs.py +0 -264
  728. drydock_cli-2.10.11/tests/test_steering_hook.py +0 -125
  729. drydock_cli-2.10.11/tests/test_steering_sidecar_chat_inputs.py +0 -147
  730. drydock_cli-2.10.11/tests/test_steering_sidecar_hooks.py +0 -324
  731. drydock_cli-2.10.11/tests/test_system_prompt.py +0 -62
  732. drydock_cli-2.10.11/tests/test_tagged_text.py +0 -107
  733. drydock_cli-2.10.11/tests/test_task_complete_nudge.py +0 -59
  734. drydock_cli-2.10.11/tests/test_tool_args.py +0 -243
  735. drydock_cli-2.10.11/tests/test_tool_call_loops_regression_suite.py +0 -609
  736. drydock_cli-2.10.11/tests/test_tool_stop_injected_scope.py +0 -58
  737. drydock_cli-2.10.11/tests/test_truncate_args_valid_json.py +0 -180
  738. drydock_cli-2.10.11/tests/test_truncated_arg_path_hint.py +0 -124
  739. drydock_cli-2.10.11/tests/test_truncated_search_replace_escalation.py +0 -80
  740. drydock_cli-2.10.11/tests/test_truncated_write_escalation.py +0 -106
  741. drydock_cli-2.10.11/tests/test_ui_external_editor.py +0 -69
  742. drydock_cli-2.10.11/tests/test_ui_input_history.py +0 -285
  743. drydock_cli-2.10.11/tests/test_units_tool.py +0 -180
  744. drydock_cli-2.10.11/tests/test_user_issues.py +0 -299
  745. drydock_cli-2.10.11/tests/test_validation_error_scrub.py +0 -508
  746. drydock_cli-2.10.11/tests/test_verify_tool.py +0 -241
  747. drydock_cli-2.10.11/tests/test_wall_of_text_rescue.py +0 -247
  748. drydock_cli-2.10.11/tests/test_workloads.py +0 -441
  749. drydock_cli-2.10.11/tests/test_write_file_missing_path.py +0 -74
  750. drydock_cli-2.10.11/tests/testbank_helpers.py +0 -966
  751. drydock_cli-2.10.11/tests/tools/test_ask_user_question.py +0 -188
  752. drydock_cli-2.10.11/tests/tools/test_bash.py +0 -154
  753. drydock_cli-2.10.11/tests/tools/test_bash_binary_grep_hint.py +0 -45
  754. drydock_cli-2.10.11/tests/tools/test_bash_consec_empty_search.py +0 -82
  755. drydock_cli-2.10.11/tests/tools/test_bash_echo_escape_loop_breaker.py +0 -80
  756. drydock_cli-2.10.11/tests/tools/test_bash_empty_search_loop_breaker.py +0 -77
  757. drydock_cli-2.10.11/tests/tools/test_bash_error_loop_breaker.py +0 -87
  758. drydock_cli-2.10.11/tests/tools/test_bash_exact_cmd_loop_breaker.py +0 -86
  759. drydock_cli-2.10.11/tests/tools/test_bash_heredoc_confirmation.py +0 -106
  760. drydock_cli-2.10.11/tests/tools/test_bash_kill_exit1_annotation.py +0 -45
  761. drydock_cli-2.10.11/tests/tools/test_bash_python_c_syntaxerr_loop_breaker.py +0 -57
  762. drydock_cli-2.10.11/tests/tools/test_exit_plan_mode.py +0 -265
  763. drydock_cli-2.10.11/tests/tools/test_grep.py +0 -374
  764. drydock_cli-2.10.11/tests/tools/test_hallucinated_retrieval_redirect.py +0 -88
  765. drydock_cli-2.10.11/tests/tools/test_invoke_context.py +0 -106
  766. drydock_cli-2.10.11/tests/tools/test_manager_gemma_derived_models.py +0 -74
  767. drydock_cli-2.10.11/tests/tools/test_manager_get_tool_config.py +0 -478
  768. drydock_cli-2.10.11/tests/tools/test_mcp.py +0 -553
  769. drydock_cli-2.10.11/tests/tools/test_mcp_sampling.py +0 -171
  770. drydock_cli-2.10.11/tests/tools/test_pre_rename_hook.py +0 -209
  771. drydock_cli-2.10.11/tests/tools/test_read_file_dedup_alternating_offset.py +0 -109
  772. drydock_cli-2.10.11/tests/tools/test_read_file_dedup_reembed.py +0 -138
  773. drydock_cli-2.10.11/tests/tools/test_read_file_directory.py +0 -64
  774. drydock_cli-2.10.11/tests/tools/test_read_file_limit_truncation.py +0 -75
  775. drydock_cli-2.10.11/tests/tools/test_search_replace_append_fallback.py +0 -121
  776. drydock_cli-2.10.11/tests/tools/test_search_replace_dir_path.py +0 -165
  777. drydock_cli-2.10.11/tests/tools/test_search_replace_empty_content.py +0 -89
  778. drydock_cli-2.10.11/tests/tools/test_search_replace_file_not_found.py +0 -108
  779. drydock_cli-2.10.11/tests/tools/test_search_replace_first_failure_hint.py +0 -133
  780. drydock_cli-2.10.11/tests/tools/test_search_replace_hard_stop.py +0 -136
  781. drydock_cli-2.10.11/tests/tools/test_search_replace_malformed_block.py +0 -131
  782. drydock_cli-2.10.11/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -235
  783. drydock_cli-2.10.11/tests/tools/test_search_replace_placeholder.py +0 -77
  784. drydock_cli-2.10.11/tests/tools/test_search_replace_refused_loop_breaker.py +0 -144
  785. drydock_cli-2.10.11/tests/tools/test_task.py +0 -212
  786. drydock_cli-2.10.11/tests/tools/test_ui_bash_execution.py +0 -120
  787. drydock_cli-2.10.11/tests/tools/test_webfetch.py +0 -253
  788. drydock_cli-2.10.11/tests/tools/test_websearch.py +0 -221
  789. drydock_cli-2.10.11/tests/tools/test_write_file_dedup_missing_imports.py +0 -102
  790. drydock_cli-2.10.11/tests/tools/test_write_file_missing_main_module.py +0 -114
  791. drydock_cli-2.10.11/tests/tools/test_write_file_missing_path_hint.py +0 -78
  792. drydock_cli-2.10.11/tests/tools/test_write_file_multifile_rename.py +0 -179
  793. drydock_cli-2.10.11/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -17
  794. drydock_cli-2.10.11/tests/update_notifier/adapters/fake_update_gateway.py +0 -22
  795. drydock_cli-2.10.11/tests/update_notifier/test_do_update.py +0 -74
  796. drydock_cli-2.10.11/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -119
  797. drydock_cli-2.10.11/tests/update_notifier/test_github_update_gateway.py +0 -245
  798. drydock_cli-2.10.11/tests/update_notifier/test_pypi_update_gateway.py +0 -155
  799. drydock_cli-2.10.11/tests/update_notifier/test_ui_update_notification.py +0 -389
  800. drydock_cli-2.10.11/tests/update_notifier/test_update_use_case.py +0 -302
  801. drydock_cli-2.10.11/tests/update_notifier/test_whats_new.py +0 -161
  802. drydock_cli-2.10.11/uv.lock +0 -2229
  803. drydock_cli-2.10.11/web/README.md +0 -62
  804. drydock_cli-2.10.11/worked_examples/README.md +0 -21
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright 2025 Mistral AI
189
+ Copyright 2026 Frank Bobe III
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
@@ -0,0 +1,11 @@
1
+ Drydock
2
+ Copyright 2026 Frank Bobe III
3
+
4
+ This product is an original, clean-room implementation. It contains no source
5
+ code from Anthropic's Claude Code, from Mistral's mistral-vibe, or from any
6
+ other third-party project. UX conventions common to terminal coding agents
7
+ were emulated from first principles; no third-party code, prompt text, or
8
+ branding was copied.
9
+
10
+ Licensed under the Apache License, Version 2.0 (the "License"); see the
11
+ LICENSE file for the full text.
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.4
2
+ Name: drydock-cli
3
+ Version: 3.0.15
4
+ Summary: Drydock — a local, provider-agnostic terminal coding agent for local LLMs
5
+ Author: Frank Bobe III
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/fbobe321/drydock
8
+ Project-URL: Repository, https://github.com/fbobe321/drydock
9
+ Project-URL: Issues, https://github.com/fbobe321/drydock/issues
10
+ Requires-Python: >=3.12
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ License-File: NOTICE
14
+ Requires-Dist: openai>=1.0
15
+ Requires-Dist: textual>=0.80
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest; extra == "dev"
18
+ Requires-Dist: pytest-timeout; extra == "dev"
19
+ Requires-Dist: ruff; extra == "dev"
20
+ Requires-Dist: pyright; extra == "dev"
21
+ Dynamic: license-file
22
+
23
+ # ⚓ Drydock
24
+
25
+ A local-first, provider-agnostic **terminal coding agent** for your own LLM.
26
+ No accounts, no telemetry, no cloud — the only network call it makes is to
27
+ the model endpoint you configure. Primary target: **Gemma-4-26B-A4B** served
28
+ by llama.cpp on a single workstation.
29
+
30
+ > **v3 — clean-room rebuild.** Drydock is being rebuilt as an original,
31
+ > Apache-2.0 codebase owned end to end (no upstream fork). Every release is
32
+ > gated by a credential-exfiltration scanner that blocks anything reaching
33
+ > off-box. See [`HARNESS_DESIGN.md`](HARNESS_DESIGN.md) and
34
+ > [`docs/PRD.md`](docs/PRD.md).
35
+
36
+ ## Why
37
+
38
+ A coding agent should build real projects from your machine without sending
39
+ your code or credentials anywhere. Drydock runs entirely against a local
40
+ model, feels like a first-class terminal agent, and keeps its data plane on
41
+ your box.
42
+
43
+ ## Status
44
+
45
+ Shipping. Published on PyPI as **`drydock-cli`** (v3.x). The Textual TUI is the
46
+ default surface: a scrolling transcript with streamed assistant text, collapsible
47
+ tool cards, a live nautical activity line, and a multi-line prompt. The agent
48
+ loop, OpenAI-compatible provider, two-tier compaction, and the core tools
49
+ (Read/Write/Edit/Bash/Glob/Grep) are in, with Gemma reliability hardening verified.
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pip install drydock-cli
55
+ drydock
56
+ ```
57
+
58
+ Requires Python 3.12+. From source instead:
59
+ `git clone https://github.com/fbobe321/drydock-v3.git && cd drydock-v3 && pip install -e .`
60
+
61
+ On first launch with no config, Drydock probes localhost for a running local
62
+ LLM (llama.cpp/vLLM `:8000`, Ollama `:11434`, LM Studio `:1234`) and wires up
63
+ the first one it finds — no account or API-key prompt. Override anytime with
64
+ `--model` / `--provider` / `--base-url` or `~/.drydock/config.toml`.
65
+
66
+ ## Using it
67
+
68
+ Type a task and press **Enter**. Drydock reads/writes/edits files and runs
69
+ commands to do the work, showing each as a collapsible tool card.
70
+
71
+ - **Enter** submits · **Ctrl+J** newline (multi-line prompts)
72
+ - **↑ / ↓** recall command history (persists across sessions)
73
+ - **PgUp / PgDn** (and **Ctrl+Home/End**) scroll the transcript
74
+ - **Ctrl+O** expand/collapse tool output · **drag + Ctrl+C** copy a selection
75
+ - **Ctrl+C twice** (or **Ctrl+D**, `/quit`) to exit
76
+ - A live activity line shows progress while it works:
77
+ `◡ Keelhauling… (12s · ↓ 6.2k tokens · thinking with high effort)`
78
+ - Submit while it's working and the prompt **queues** (drains in order)
79
+ - Slash commands: `/model [name]` · `/cwd [path]` · `/undo` (revert last write)
80
+ · `/back` (rewind last turn) · `/status` · `/clear` · `/help` · `/quit`
81
+
82
+ It honors `AGENTS.md` / `DRYDOCK.md` in the working directory for project
83
+ conventions.
84
+
85
+ ## Safety
86
+
87
+ Two tiers, plus advisory guards — all designed so legitimate work is never
88
+ blocked:
89
+
90
+ - **Catastrophic denylist** — commands like `rm -rf /`, `mkfs`, raw block-device
91
+ writes, and fork bombs are refused outright (never run).
92
+ - **Approval prompt** — sensitive-but-legitimate commands (`sudo`, package
93
+ installs, network fetches, `git push`) pause for **Allow / Always / Deny**.
94
+ - **Advisory write guards** — Drydock flags (never blocks) Python syntax errors,
95
+ stub-only files, imports of sibling modules that don't exist yet, bare
96
+ `raise` outside an except, and refuses to write git conflict-marker content.
97
+
98
+ Point it at a local OpenAI-compatible endpoint (e.g. llama.cpp's `server-cuda`
99
+ serving Gemma 4 26B).
100
+
101
+ ## Model server (reference setup)
102
+
103
+ Drydock is provider-agnostic, but it's tuned and measured against this rig:
104
+
105
+ - **Model:** Gemma-4-26B-A4B-it (26B MoE, ~4B active/token), Unsloth `Q3_K_M`
106
+ GGUF, served by `ghcr.io/ggml-org/llama.cpp:server-cuda` with `--jinja`.
107
+ - **GPUs:** 2× NVIDIA RTX 4060 Ti 16GB. The Q3_K_M weights (~13 GB) fit on a
108
+ **single 16 GB card**, so each GPU runs a **full, independent instance** —
109
+ two cards give two parallel instances for throughput; the model is **not**
110
+ tensor-split or "pooled" across both.
111
+ - **Context:** 64k (`-c 65536`) with `q8_0` KV-cache quantization
112
+ (`-ctk q8_0 -ctv q8_0`) — 64k @ q8 fits roughly the same VRAM as 32k @ f16.
113
+ - **Throughput:** ~**64 tok/s** decode, ~94 tok/s prompt (per instance, Q3_K_M).
114
+ - **Minimum:** any single 16 GB+ CUDA card runs it.
115
+
116
+ ## Principles
117
+
118
+ - **Clean provenance** — original code only; nothing copied from any other
119
+ project.
120
+ - **Local-only data plane** — no telemetry, no phone-home, no hardcoded
121
+ third-party hosts, no credential transmission.
122
+ - **Advisory, never blocking** — loop/safety mechanisms inject better
123
+ context; they never hard-stop legitimate work.
124
+ - **The scanner is law** — `scripts/security_scan.py` gates every release.
125
+
126
+ ## Security scan
127
+
128
+ ```bash
129
+ python3 scripts/security_scan.py drydock/ # scan the source tree
130
+ python3 scripts/security_scan.py dist/*.whl # scan a built wheel
131
+ ```
132
+
133
+ Exit 2 (HIGH finding) blocks a release.
134
+
135
+ ## License
136
+
137
+ Apache-2.0, © 2026 Frank Bobe III. See [`LICENSE`](LICENSE) and
138
+ [`NOTICE`](NOTICE).
@@ -0,0 +1,116 @@
1
+ # ⚓ Drydock
2
+
3
+ A local-first, provider-agnostic **terminal coding agent** for your own LLM.
4
+ No accounts, no telemetry, no cloud — the only network call it makes is to
5
+ the model endpoint you configure. Primary target: **Gemma-4-26B-A4B** served
6
+ by llama.cpp on a single workstation.
7
+
8
+ > **v3 — clean-room rebuild.** Drydock is being rebuilt as an original,
9
+ > Apache-2.0 codebase owned end to end (no upstream fork). Every release is
10
+ > gated by a credential-exfiltration scanner that blocks anything reaching
11
+ > off-box. See [`HARNESS_DESIGN.md`](HARNESS_DESIGN.md) and
12
+ > [`docs/PRD.md`](docs/PRD.md).
13
+
14
+ ## Why
15
+
16
+ A coding agent should build real projects from your machine without sending
17
+ your code or credentials anywhere. Drydock runs entirely against a local
18
+ model, feels like a first-class terminal agent, and keeps its data plane on
19
+ your box.
20
+
21
+ ## Status
22
+
23
+ Shipping. Published on PyPI as **`drydock-cli`** (v3.x). The Textual TUI is the
24
+ default surface: a scrolling transcript with streamed assistant text, collapsible
25
+ tool cards, a live nautical activity line, and a multi-line prompt. The agent
26
+ loop, OpenAI-compatible provider, two-tier compaction, and the core tools
27
+ (Read/Write/Edit/Bash/Glob/Grep) are in, with Gemma reliability hardening verified.
28
+
29
+ ## Install
30
+
31
+ ```bash
32
+ pip install drydock-cli
33
+ drydock
34
+ ```
35
+
36
+ Requires Python 3.12+. From source instead:
37
+ `git clone https://github.com/fbobe321/drydock-v3.git && cd drydock-v3 && pip install -e .`
38
+
39
+ On first launch with no config, Drydock probes localhost for a running local
40
+ LLM (llama.cpp/vLLM `:8000`, Ollama `:11434`, LM Studio `:1234`) and wires up
41
+ the first one it finds — no account or API-key prompt. Override anytime with
42
+ `--model` / `--provider` / `--base-url` or `~/.drydock/config.toml`.
43
+
44
+ ## Using it
45
+
46
+ Type a task and press **Enter**. Drydock reads/writes/edits files and runs
47
+ commands to do the work, showing each as a collapsible tool card.
48
+
49
+ - **Enter** submits · **Ctrl+J** newline (multi-line prompts)
50
+ - **↑ / ↓** recall command history (persists across sessions)
51
+ - **PgUp / PgDn** (and **Ctrl+Home/End**) scroll the transcript
52
+ - **Ctrl+O** expand/collapse tool output · **drag + Ctrl+C** copy a selection
53
+ - **Ctrl+C twice** (or **Ctrl+D**, `/quit`) to exit
54
+ - A live activity line shows progress while it works:
55
+ `◡ Keelhauling… (12s · ↓ 6.2k tokens · thinking with high effort)`
56
+ - Submit while it's working and the prompt **queues** (drains in order)
57
+ - Slash commands: `/model [name]` · `/cwd [path]` · `/undo` (revert last write)
58
+ · `/back` (rewind last turn) · `/status` · `/clear` · `/help` · `/quit`
59
+
60
+ It honors `AGENTS.md` / `DRYDOCK.md` in the working directory for project
61
+ conventions.
62
+
63
+ ## Safety
64
+
65
+ Two tiers, plus advisory guards — all designed so legitimate work is never
66
+ blocked:
67
+
68
+ - **Catastrophic denylist** — commands like `rm -rf /`, `mkfs`, raw block-device
69
+ writes, and fork bombs are refused outright (never run).
70
+ - **Approval prompt** — sensitive-but-legitimate commands (`sudo`, package
71
+ installs, network fetches, `git push`) pause for **Allow / Always / Deny**.
72
+ - **Advisory write guards** — Drydock flags (never blocks) Python syntax errors,
73
+ stub-only files, imports of sibling modules that don't exist yet, bare
74
+ `raise` outside an except, and refuses to write git conflict-marker content.
75
+
76
+ Point it at a local OpenAI-compatible endpoint (e.g. llama.cpp's `server-cuda`
77
+ serving Gemma 4 26B).
78
+
79
+ ## Model server (reference setup)
80
+
81
+ Drydock is provider-agnostic, but it's tuned and measured against this rig:
82
+
83
+ - **Model:** Gemma-4-26B-A4B-it (26B MoE, ~4B active/token), Unsloth `Q3_K_M`
84
+ GGUF, served by `ghcr.io/ggml-org/llama.cpp:server-cuda` with `--jinja`.
85
+ - **GPUs:** 2× NVIDIA RTX 4060 Ti 16GB. The Q3_K_M weights (~13 GB) fit on a
86
+ **single 16 GB card**, so each GPU runs a **full, independent instance** —
87
+ two cards give two parallel instances for throughput; the model is **not**
88
+ tensor-split or "pooled" across both.
89
+ - **Context:** 64k (`-c 65536`) with `q8_0` KV-cache quantization
90
+ (`-ctk q8_0 -ctv q8_0`) — 64k @ q8 fits roughly the same VRAM as 32k @ f16.
91
+ - **Throughput:** ~**64 tok/s** decode, ~94 tok/s prompt (per instance, Q3_K_M).
92
+ - **Minimum:** any single 16 GB+ CUDA card runs it.
93
+
94
+ ## Principles
95
+
96
+ - **Clean provenance** — original code only; nothing copied from any other
97
+ project.
98
+ - **Local-only data plane** — no telemetry, no phone-home, no hardcoded
99
+ third-party hosts, no credential transmission.
100
+ - **Advisory, never blocking** — loop/safety mechanisms inject better
101
+ context; they never hard-stop legitimate work.
102
+ - **The scanner is law** — `scripts/security_scan.py` gates every release.
103
+
104
+ ## Security scan
105
+
106
+ ```bash
107
+ python3 scripts/security_scan.py drydock/ # scan the source tree
108
+ python3 scripts/security_scan.py dist/*.whl # scan a built wheel
109
+ ```
110
+
111
+ Exit 2 (HIGH finding) blocks a release.
112
+
113
+ ## License
114
+
115
+ Apache-2.0, © 2026 Frank Bobe III. See [`LICENSE`](LICENSE) and
116
+ [`NOTICE`](NOTICE).
@@ -0,0 +1,10 @@
1
+ """DryDock — local coding agent."""
2
+ from importlib.metadata import PackageNotFoundError, version as _version
3
+
4
+ try:
5
+ # Authoritative: the installed distribution's version. Keeps --version and
6
+ # the TUI banner in sync with the published wheel automatically.
7
+ __version__ = _version("drydock-cli")
8
+ except PackageNotFoundError:
9
+ # Running from source before install (e.g. PYTHONPATH dev runs).
10
+ __version__ = "3.0.15"
@@ -0,0 +1,2 @@
1
+ from drydock.cli import main
2
+ main()
@@ -0,0 +1,224 @@
1
+ """Core agent loop — multi-turn tool-calling with any LLM.
2
+
3
+ DryDock v3 — clean, provider-agnostic, no model-specific hacks.
4
+ """
5
+ from __future__ import annotations
6
+
7
+ from dataclasses import dataclass, field
8
+ from typing import Generator
9
+
10
+ from drydock.providers import stream, AssistantTurn, TextChunk
11
+ from drydock.tool_registry import schemas, execute
12
+ from drydock.tools import register_all
13
+
14
+ # Register the built-in tools as a side effect of importing the agent. This is
15
+ # explicit (not a bare side-effect import) so a linter can't "helpfully" delete
16
+ # it: without it the registry is empty, the model is offered no tools, and it
17
+ # emits tool calls as TEXT — which is exactly how the empty-registry regression
18
+ # manifested. register_all() is idempotent.
19
+ register_all()
20
+ from drydock.compaction import maybe_compact, emergency_compact, is_context_length_error
21
+ from drydock.loop_detect import LoopTracker
22
+ from drydock.tuning import (
23
+ filter_tool_schemas,
24
+ hallucinated_tool_message,
25
+ thinking_level_for_turn,
26
+ )
27
+
28
+
29
+ # ── Event types ───────────────────────────────────────────────────────────
30
+
31
+ @dataclass
32
+ class ToolStart:
33
+ name: str
34
+ inputs: dict
35
+
36
+ @dataclass
37
+ class ToolEnd:
38
+ name: str
39
+ result: str
40
+
41
+ @dataclass
42
+ class TurnDone:
43
+ input_tokens: int
44
+ output_tokens: int
45
+
46
+ @dataclass
47
+ class AgentState:
48
+ """Mutable session state."""
49
+ messages: list = field(default_factory=list)
50
+ total_input_tokens: int = 0
51
+ total_output_tokens: int = 0
52
+ turn_count: int = 0
53
+ current_effort: str = "" # "high"/"low" of the in-flight LLM call (for the UI)
54
+
55
+
56
+ def drop_last_turn(messages: list) -> bool:
57
+ """Remove the last user message and everything after it (the assistant
58
+ replies + tool results for that turn). Returns True if a turn was dropped.
59
+
60
+ Cutting at a user-message boundary keeps the history valid — the remaining
61
+ list ends with a complete prior turn and never leaves an orphaned tool
62
+ result (those all followed the removed user message).
63
+ """
64
+ for i in range(len(messages) - 1, -1, -1):
65
+ if messages[i].get("role") == "user":
66
+ del messages[i:]
67
+ return True
68
+ return False
69
+
70
+
71
+ # ── Agent loop ────────────────────────────────────────────────────────────
72
+
73
+ def run(
74
+ user_message: str,
75
+ state: AgentState,
76
+ config: dict,
77
+ system_prompt: str,
78
+ ) -> Generator:
79
+ """Multi-turn agent loop.
80
+
81
+ Yields: TextChunk | ToolStart | ToolEnd | TurnDone
82
+
83
+ The loop continues as long as the model makes tool calls.
84
+ When the model responds with text only (no tools), the turn ends.
85
+ """
86
+ state.messages.append({"role": "user", "content": user_message})
87
+
88
+ max_turns = config.get("max_turns", 200)
89
+ max_tool_calls = config.get("max_tool_calls", 0) # 0 = unlimited
90
+ tool_call_count = 0
91
+ session_has_edited = False
92
+ leaked_call_retries = 0
93
+ run_iteration = 0 # stream calls within THIS run() (resets per user message)
94
+ loop_tracker = LoopTracker()
95
+
96
+ while state.turn_count < max_turns:
97
+ state.turn_count += 1
98
+ run_iteration += 1
99
+ assistant_turn: AssistantTurn | None = None
100
+
101
+ # Compact context if approaching limit
102
+ maybe_compact(state, config)
103
+
104
+ # Force tool use on first turn to prevent the model from just outputting text
105
+ turn_config = dict(config)
106
+ if state.turn_count == 1 and config.get("force_first_tool", False):
107
+ turn_config["tool_choice"] = "required"
108
+ # Adaptive reasoning budget: high to PLAN the response to the user's new
109
+ # message (first iteration of this run), low for routine continuation
110
+ # turns that just consume tool results — cuts latency without hurting
111
+ # correctness (verified: same answer, fewer tokens). The provider only
112
+ # forwards it to endpoints that accept reasoning_effort.
113
+ if "reasoning_effort" not in turn_config:
114
+ level = thinking_level_for_turn(run_iteration, is_user_turn=(run_iteration == 1))
115
+ turn_config["reasoning_effort"] = "high" if level == "high" else "low"
116
+ # Expose the in-flight effort to the UI (GIL-atomic string read in the
117
+ # status line; no message plumbing needed).
118
+ state.current_effort = turn_config.get("reasoning_effort", "")
119
+ # After many calls without editing, don't force but the nudge message handles it
120
+
121
+ # Stream from LLM — with retry on context-length 400 error
122
+ retries = 0
123
+ while retries < 2:
124
+ try:
125
+ for event in stream(
126
+ model=turn_config["model"],
127
+ system=system_prompt,
128
+ messages=state.messages,
129
+ tool_schemas=filter_tool_schemas(schemas(), turn_config.get("model")),
130
+ config=turn_config,
131
+ ):
132
+ if isinstance(event, TextChunk):
133
+ yield event
134
+ elif isinstance(event, AssistantTurn):
135
+ assistant_turn = event
136
+ break # success
137
+ except Exception as e:
138
+ err = str(e)
139
+ if is_context_length_error(err):
140
+ retries += 1
141
+ limit = config.get("context_limit", 131072)
142
+ state.messages = emergency_compact(state.messages, limit)
143
+ if retries >= 2:
144
+ raise
145
+ yield TextChunk("\n[context limit hit — compacting and retrying...]\n")
146
+ else:
147
+ raise
148
+
149
+ if assistant_turn is None:
150
+ break
151
+
152
+ # Record assistant message
153
+ state.messages.append({
154
+ "role": "assistant",
155
+ "content": assistant_turn.text,
156
+ "tool_calls": assistant_turn.tool_calls,
157
+ })
158
+
159
+ state.total_input_tokens += assistant_turn.input_tokens
160
+ state.total_output_tokens += assistant_turn.output_tokens
161
+ yield TurnDone(assistant_turn.input_tokens, assistant_turn.output_tokens)
162
+
163
+ # No tool calls = conversation complete — UNLESS the model emitted a
164
+ # tool call as text (a Gemma quirk the API can't structure). In that
165
+ # case nudge it to use the real function interface and retry, instead
166
+ # of ending the turn with nothing done. Capped so it can never spin.
167
+ if not assistant_turn.tool_calls:
168
+ if assistant_turn.had_leaked_call and leaked_call_retries < 2:
169
+ leaked_call_retries += 1
170
+ state.messages.append({
171
+ "role": "user",
172
+ "content": (
173
+ "[SYSTEM] Your tool call came through as plain text, so "
174
+ "it did not run. Call the tool using the function/tool "
175
+ "interface — not text, no <|tool_call> markers. Use the "
176
+ "exact tool names (Write, Read, Edit, Bash). Try again."
177
+ ),
178
+ })
179
+ continue
180
+ break
181
+
182
+ # Execute each tool call
183
+ for tc in assistant_turn.tool_calls:
184
+ tool_call_count += 1
185
+ if tc["name"] in ("Edit", "Write"):
186
+ session_has_edited = True
187
+
188
+ # Check tool call limit
189
+ if max_tool_calls > 0 and tool_call_count > max_tool_calls:
190
+ state.messages.append({
191
+ "role": "tool",
192
+ "tool_call_id": tc["id"],
193
+ "name": tc["name"],
194
+ "content": "[Tool call limit reached. Respond with your final answer now.]",
195
+ })
196
+ continue
197
+
198
+ yield ToolStart(tc["name"], tc["input"])
199
+
200
+ # Redirect hallucinated tool names to a benign hint instead of a
201
+ # "tool not found" error the model would loop on.
202
+ halluc = hallucinated_tool_message(tc["name"])
203
+ result = halluc if halluc is not None else execute(tc["name"], tc["input"], config)
204
+ # Guide (never block) on exact-repeat tool calls: prepend an
205
+ # advisory note when the same call is made again.
206
+ result = loop_tracker.annotate(tc["name"], tc["input"], result)
207
+
208
+ yield ToolEnd(tc["name"], result)
209
+
210
+ # Append tool result
211
+ state.messages.append({
212
+ "role": "tool",
213
+ "tool_call_id": tc["id"],
214
+ "name": tc["name"],
215
+ "content": result,
216
+ })
217
+
218
+ # Nudge: if past 15 tool calls without any edits, inject gentle guidance
219
+ if tool_call_count == 15 and not session_has_edited and config.get("force_first_tool"):
220
+ state.messages.append({
221
+ "role": "user",
222
+ "content": "[SYSTEM] Reminder: you should call Edit to fix the bug soon. "
223
+ "Read the file if you haven't already, then make your edit.",
224
+ })
@@ -0,0 +1,167 @@
1
+ """Bash command safety denylist.
2
+
3
+ `tool_bash` runs `shell=True`, so a single hallucinated or careless command
4
+ could wipe the user's disk. This module screens a command *before* it runs and
5
+ refuses only the small set of patterns that are catastrophic and irreversible
6
+ *and* have no legitimate place in a coding task: wiping the filesystem root or
7
+ home, writing raw to a block device, reformatting a disk, or a classic fork
8
+ bomb.
9
+
10
+ The bar is deliberately high. Ordinary destructive-but-scoped work
11
+ (`rm -rf build/`, `rm -rf node_modules`, `git reset --hard`) is NOT blocked —
12
+ that is real coding work and blocking it would be the kind of net-negative
13
+ circuit breaker we have learned to avoid. When something *is* blocked, the
14
+ tool returns a plain refusal string (it never raises), so the model gets clear
15
+ feedback and can choose a safer command instead of looping on an exception.
16
+
17
+ All logic original to Drydock.
18
+ """
19
+ from __future__ import annotations
20
+
21
+ import re
22
+
23
+ # Each entry: (compiled pattern, human reason). A reason of None marks the
24
+ # special rm rule, which needs a second check on the delete target (below).
25
+ # Patterns match against the whitespace-normalized command string. Keep them
26
+ # narrow — a false positive blocks legitimate work and erodes trust.
27
+ _RULES: list[tuple[re.Pattern[str], str | None]] = [
28
+ # rm -rf targeting the filesystem root, home, or a root-level wildcard.
29
+ # Matches: rm -rf /, rm -fr /*, rm -rf ~, rm -rf $HOME, rm -rf / (trailing).
30
+ (
31
+ re.compile(
32
+ r"\brm\b[^|;&]*\s-[a-z]*r[a-z]*f|\brm\b[^|;&]*\s-[a-z]*f[a-z]*r",
33
+ re.IGNORECASE,
34
+ ),
35
+ None, # placeholder; rm needs a second check on the target (below)
36
+ ),
37
+ # Raw write to a whole block device (dd of=/dev/sda, > /dev/nvme0n1).
38
+ (
39
+ re.compile(r"\bof=/dev/(?:sd|nvme|hd|vd|xvd|mmcblk)", re.IGNORECASE),
40
+ "writes a raw image directly onto a block device, destroying the disk",
41
+ ),
42
+ (
43
+ re.compile(r">\s*/dev/(?:sd|nvme|hd|vd|xvd|mmcblk)", re.IGNORECASE),
44
+ "redirects output onto a raw block device, corrupting the disk",
45
+ ),
46
+ # Reformat a filesystem.
47
+ (
48
+ re.compile(r"\bmkfs(?:\.\w+)?\b", re.IGNORECASE),
49
+ "reformats a filesystem, erasing everything on it",
50
+ ),
51
+ # Repartition / zero a disk.
52
+ (
53
+ re.compile(r"\bdd\b[^|;&]*\bof=/dev/", re.IGNORECASE),
54
+ "uses dd to overwrite a device node",
55
+ ),
56
+ # Classic fork bomb.
57
+ (
58
+ re.compile(r":\(\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;\s*:"),
59
+ "is a fork bomb that will exhaust the system's process table",
60
+ ),
61
+ # Recursively strip all permissions / ownership from the root.
62
+ (
63
+ re.compile(r"\b(?:chmod|chown)\b[^|;&]*\s-[a-z]*R[a-z]*\s[^|;&]*\s/(?:\s|$)", re.IGNORECASE),
64
+ "recursively changes permissions/ownership of the filesystem root",
65
+ ),
66
+ ]
67
+
68
+ # rm targets that mean "the whole world." Checked only when the command is an
69
+ # `rm -rf`-style recursive force delete.
70
+ _RM_CATASTROPHIC_TARGET = re.compile(
71
+ r"\brm\b[^|;&]*\s"
72
+ r"(?:/|~|\$HOME|/\*|/\s|\.\s*/?\s*\*|--no-preserve-root)"
73
+ r"(?:\s|$|/\*)",
74
+ re.IGNORECASE,
75
+ )
76
+
77
+
78
+ def dangerous_command(command: str) -> str | None:
79
+ """Return a refusal reason if the command is catastrophic, else None.
80
+
81
+ Conservative by design: only the patterns above trip it. Everything
82
+ else — including scoped `rm -rf subdir/` — passes through untouched.
83
+ """
84
+ if not command or not command.strip():
85
+ return None
86
+ cmd = " ".join(command.split()) # normalize whitespace
87
+
88
+ for pattern, reason in _RULES:
89
+ if reason is None:
90
+ # The rm rule: recursive-force flag present *and* a world target.
91
+ if pattern.search(cmd) and _rm_hits_world(cmd):
92
+ return (
93
+ "deletes the filesystem root or home directory recursively"
94
+ )
95
+ continue
96
+ if pattern.search(cmd):
97
+ return reason
98
+ return None
99
+
100
+
101
+ def _rm_hits_world(cmd: str) -> bool:
102
+ """True if an `rm -rf` command targets / ~ $HOME or a root-level wildcard."""
103
+ if _RM_CATASTROPHIC_TARGET.search(cmd):
104
+ return True
105
+ # `--no-preserve-root` is never used for legitimate scoped deletes.
106
+ if "--no-preserve-root" in cmd.lower():
107
+ return True
108
+ return False
109
+
110
+
111
+ def refusal_message(command: str, reason: str) -> str:
112
+ """The string returned to the model in place of running the command."""
113
+ return (
114
+ f"REFUSED: this command {reason}. Drydock will not run it.\n"
115
+ f"Command: {command.strip()}\n"
116
+ f"If this was a mistake, run a narrower command scoped to the specific "
117
+ f"files or directory you intend to change."
118
+ )
119
+
120
+
121
+ # ── Approval tier ───────────────────────────────────────────────────────────
122
+ # Commands that are legitimate but consequential: they should RUN, but only
123
+ # after the user okays them. This is distinct from the catastrophic denylist
124
+ # above (which is never run). Each entry: (pattern, human reason).
125
+ _APPROVAL_RULES: list[tuple[re.Pattern[str], str]] = [
126
+ (
127
+ re.compile(r"\b(?:sudo|doas)\b", re.IGNORECASE),
128
+ "runs with elevated privileges (sudo)",
129
+ ),
130
+ (
131
+ re.compile(
132
+ r"\b(?:apt|apt-get|dnf|yum|pacman|zypper|apk|brew)\b\s+"
133
+ r"(?:install|remove|purge|upgrade|update|add)\b",
134
+ re.IGNORECASE,
135
+ ),
136
+ "installs or removes system packages",
137
+ ),
138
+ (
139
+ re.compile(
140
+ r"\b(?:pip|pip3|pipx|npm|pnpm|yarn|cargo|gem|go)\b\s+"
141
+ r"(?:install|add|i)\b",
142
+ re.IGNORECASE,
143
+ ),
144
+ "installs packages from a network index",
145
+ ),
146
+ (
147
+ re.compile(r"\b(?:curl|wget)\b", re.IGNORECASE),
148
+ "fetches content from the network",
149
+ ),
150
+ (
151
+ re.compile(r"\bgit\s+push\b", re.IGNORECASE),
152
+ "pushes commits to a remote repository",
153
+ ),
154
+ ]
155
+
156
+
157
+ def requires_approval(command: str) -> str | None:
158
+ """Return a reason if the command is sensitive enough to need user
159
+ approval before running, else None. Assumes the catastrophic denylist
160
+ (dangerous_command) has already passed."""
161
+ if not command or not command.strip():
162
+ return None
163
+ cmd = " ".join(command.split())
164
+ for pattern, reason in _APPROVAL_RULES:
165
+ if pattern.search(cmd):
166
+ return reason
167
+ return None