drydock-cli 2.10.12__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 (805) hide show
  1. {drydock_cli-2.10.12 → 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.12/.gitignore +0 -236
  47. drydock_cli-2.10.12/NOTICE +0 -11
  48. drydock_cli-2.10.12/PKG-INFO +0 -604
  49. drydock_cli-2.10.12/README.md +0 -548
  50. drydock_cli-2.10.12/distribution/zed/LICENSE +0 -1
  51. drydock_cli-2.10.12/docs/README.md +0 -8
  52. drydock_cli-2.10.12/drydock/__init__.py +0 -11
  53. drydock_cli-2.10.12/drydock/__main__.py +0 -17
  54. drydock_cli-2.10.12/drydock/acp/__init__.py +0 -0
  55. drydock_cli-2.10.12/drydock/acp/acp_agent_loop.py +0 -818
  56. drydock_cli-2.10.12/drydock/acp/acp_logger.py +0 -97
  57. drydock_cli-2.10.12/drydock/acp/entrypoint.py +0 -92
  58. drydock_cli-2.10.12/drydock/acp/tools/__init__.py +0 -0
  59. drydock_cli-2.10.12/drydock/acp/tools/base.py +0 -100
  60. drydock_cli-2.10.12/drydock/acp/tools/builtins/bash.py +0 -143
  61. drydock_cli-2.10.12/drydock/acp/tools/builtins/read_file.py +0 -53
  62. drydock_cli-2.10.12/drydock/acp/tools/builtins/search_replace.py +0 -137
  63. drydock_cli-2.10.12/drydock/acp/tools/builtins/todo.py +0 -65
  64. drydock_cli-2.10.12/drydock/acp/tools/builtins/write_file.py +0 -106
  65. drydock_cli-2.10.12/drydock/acp/tools/session_update.py +0 -118
  66. drydock_cli-2.10.12/drydock/acp/utils.py +0 -277
  67. drydock_cli-2.10.12/drydock/admiral/__init__.py +0 -15
  68. drydock_cli-2.10.12/drydock/admiral/detectors.py +0 -139
  69. drydock_cli-2.10.12/drydock/admiral/detectors_proposed.py +0 -226
  70. drydock_cli-2.10.12/drydock/admiral/history.py +0 -23
  71. drydock_cli-2.10.12/drydock/admiral/interventions.py +0 -27
  72. drydock_cli-2.10.12/drydock/admiral/llm_analyzer.py +0 -161
  73. drydock_cli-2.10.12/drydock/admiral/metrics.py +0 -92
  74. drydock_cli-2.10.12/drydock/admiral/opus_escalator.py +0 -138
  75. drydock_cli-2.10.12/drydock/admiral/persistence.py +0 -131
  76. drydock_cli-2.10.12/drydock/admiral/policy.py +0 -134
  77. drydock_cli-2.10.12/drydock/admiral/proposer.py +0 -157
  78. drydock_cli-2.10.12/drydock/admiral/stager.py +0 -147
  79. drydock_cli-2.10.12/drydock/admiral/task_classifier.py +0 -73
  80. drydock_cli-2.10.12/drydock/admiral/tuning.py +0 -131
  81. drydock_cli-2.10.12/drydock/admiral/validator.py +0 -95
  82. drydock_cli-2.10.12/drydock/admiral/worker.py +0 -258
  83. drydock_cli-2.10.12/drydock/cli/__init__.py +0 -0
  84. drydock_cli-2.10.12/drydock/cli/autocompletion/__init__.py +0 -0
  85. drydock_cli-2.10.12/drydock/cli/autocompletion/base.py +0 -22
  86. drydock_cli-2.10.12/drydock/cli/autocompletion/path_completion.py +0 -177
  87. drydock_cli-2.10.12/drydock/cli/autocompletion/slash_command.py +0 -99
  88. drydock_cli-2.10.12/drydock/cli/cli.py +0 -361
  89. drydock_cli-2.10.12/drydock/cli/clipboard.py +0 -171
  90. drydock_cli-2.10.12/drydock/cli/commands.py +0 -230
  91. drydock_cli-2.10.12/drydock/cli/entrypoint.py +0 -426
  92. drydock_cli-2.10.12/drydock/cli/fix_windows_path.py +0 -143
  93. drydock_cli-2.10.12/drydock/cli/history_manager.py +0 -91
  94. drydock_cli-2.10.12/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -45
  95. drydock_cli-2.10.12/drydock/cli/plan_offer/decide_plan_offer.py +0 -95
  96. drydock_cli-2.10.12/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -66
  97. drydock_cli-2.10.12/drydock/cli/terminal_setup.py +0 -336
  98. drydock_cli-2.10.12/drydock/cli/textual_ui/__init__.py +0 -0
  99. drydock_cli-2.10.12/drydock/cli/textual_ui/ansi_markdown.py +0 -62
  100. drydock_cli-2.10.12/drydock/cli/textual_ui/app.py +0 -3191
  101. drydock_cli-2.10.12/drydock/cli/textual_ui/app.tcss +0 -1094
  102. drydock_cli-2.10.12/drydock/cli/textual_ui/external_editor.py +0 -32
  103. drydock_cli-2.10.12/drydock/cli/textual_ui/handlers/__init__.py +0 -5
  104. drydock_cli-2.10.12/drydock/cli/textual_ui/handlers/event_handler.py +0 -235
  105. drydock_cli-2.10.12/drydock/cli/textual_ui/notifications/__init__.py +0 -11
  106. drydock_cli-2.10.12/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  107. drydock_cli-2.10.12/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -60
  108. drydock_cli-2.10.12/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  109. drydock_cli-2.10.12/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -16
  110. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  111. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/approval_app.py +0 -235
  112. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/banner/banner.py +0 -111
  113. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -85
  114. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -58
  115. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -7
  116. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -332
  117. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -58
  118. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -43
  119. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -213
  120. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -460
  121. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -205
  122. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/compact.py +0 -88
  123. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/config_app.py +0 -177
  124. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/context_progress.py +0 -30
  125. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/load_more.py +0 -43
  126. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/loading.py +0 -246
  127. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/messages.py +0 -590
  128. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -11
  129. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/path_display.py +0 -28
  130. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -122
  131. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/question_app.py +0 -507
  132. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/session_picker.py +0 -113
  133. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/spinner.py +0 -210
  134. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/status_message.py +0 -76
  135. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/teleport_message.py +0 -31
  136. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -373
  137. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/tools.py +0 -218
  138. drydock_cli-2.10.12/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -26
  139. drydock_cli-2.10.12/drydock/cli/textual_ui/windowing/__init__.py +0 -29
  140. drydock_cli-2.10.12/drydock/cli/textual_ui/windowing/history.py +0 -106
  141. drydock_cli-2.10.12/drydock/cli/textual_ui/windowing/history_windowing.py +0 -67
  142. drydock_cli-2.10.12/drydock/cli/textual_ui/windowing/state.py +0 -105
  143. drydock_cli-2.10.12/drydock/cli/update_notifier/__init__.py +0 -47
  144. drydock_cli-2.10.12/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -59
  145. drydock_cli-2.10.12/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -101
  146. drydock_cli-2.10.12/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -107
  147. drydock_cli-2.10.12/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -16
  148. drydock_cli-2.10.12/drydock/cli/update_notifier/ports/update_gateway.py +0 -53
  149. drydock_cli-2.10.12/drydock/cli/update_notifier/update.py +0 -139
  150. drydock_cli-2.10.12/drydock/cli/update_notifier/whats_new.py +0 -59
  151. drydock_cli-2.10.12/drydock/core/__init__.py +0 -5
  152. drydock_cli-2.10.12/drydock/core/agent_loop.py +0 -9151
  153. drydock_cli-2.10.12/drydock/core/agents/__init__.py +0 -29
  154. drydock_cli-2.10.12/drydock/core/agents/manager.py +0 -165
  155. drydock_cli-2.10.12/drydock/core/agents/models.py +0 -270
  156. drydock_cli-2.10.12/drydock/core/auth/__init__.py +0 -6
  157. drydock_cli-2.10.12/drydock/core/auth/crypto.py +0 -137
  158. drydock_cli-2.10.12/drydock/core/auth/github.py +0 -178
  159. drydock_cli-2.10.12/drydock/core/auto_solve.py +0 -445
  160. drydock_cli-2.10.12/drydock/core/autocompletion/__init__.py +0 -0
  161. drydock_cli-2.10.12/drydock/core/autocompletion/completers.py +0 -263
  162. drydock_cli-2.10.12/drydock/core/autocompletion/file_indexer/__init__.py +0 -10
  163. drydock_cli-2.10.12/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -168
  164. drydock_cli-2.10.12/drydock/core/autocompletion/file_indexer/indexer.py +0 -187
  165. drydock_cli-2.10.12/drydock/core/autocompletion/file_indexer/store.py +0 -169
  166. drydock_cli-2.10.12/drydock/core/autocompletion/file_indexer/watcher.py +0 -71
  167. drydock_cli-2.10.12/drydock/core/autocompletion/fuzzy.py +0 -189
  168. drydock_cli-2.10.12/drydock/core/autocompletion/path_prompt.py +0 -108
  169. drydock_cli-2.10.12/drydock/core/autocompletion/path_prompt_adapter.py +0 -149
  170. drydock_cli-2.10.12/drydock/core/build_orchestrator.py +0 -760
  171. drydock_cli-2.10.12/drydock/core/checkpoint.py +0 -411
  172. drydock_cli-2.10.12/drydock/core/classifier/__init__.py +0 -50
  173. drydock_cli-2.10.12/drydock/core/classifier/__main__.py +0 -108
  174. drydock_cli-2.10.12/drydock/core/classifier/classifier.py +0 -116
  175. drydock_cli-2.10.12/drydock/core/classifier/dispatcher.py +0 -216
  176. drydock_cli-2.10.12/drydock/core/classifier/rules.py +0 -224
  177. drydock_cli-2.10.12/drydock/core/classifier/signal.py +0 -53
  178. drydock_cli-2.10.12/drydock/core/config/__init__.py +0 -41
  179. drydock_cli-2.10.12/drydock/core/config/_dotenv.py +0 -134
  180. drydock_cli-2.10.12/drydock/core/config/_settings.py +0 -850
  181. drydock_cli-2.10.12/drydock/core/config/doctor.py +0 -222
  182. drydock_cli-2.10.12/drydock/core/config/harness_files/__init__.py +0 -17
  183. drydock_cli-2.10.12/drydock/core/config/harness_files/_harness_manager.py +0 -169
  184. drydock_cli-2.10.12/drydock/core/config/harness_files/_paths.py +0 -8
  185. drydock_cli-2.10.12/drydock/core/config/local_detect.py +0 -147
  186. drydock_cli-2.10.12/drydock/core/config/migrate.py +0 -159
  187. drydock_cli-2.10.12/drydock/core/constraint_extract.py +0 -478
  188. drydock_cli-2.10.12/drydock/core/constraint_hint.py +0 -326
  189. drydock_cli-2.10.12/drydock/core/consultant.py +0 -189
  190. drydock_cli-2.10.12/drydock/core/context_recovery.py +0 -190
  191. drydock_cli-2.10.12/drydock/core/drydock_states.py +0 -184
  192. drydock_cli-2.10.12/drydock/core/goal.py +0 -147
  193. drydock_cli-2.10.12/drydock/core/hooks.py +0 -187
  194. drydock_cli-2.10.12/drydock/core/llm/__init__.py +0 -0
  195. drydock_cli-2.10.12/drydock/core/llm/backend/anthropic.py +0 -634
  196. drydock_cli-2.10.12/drydock/core/llm/backend/base.py +0 -40
  197. drydock_cli-2.10.12/drydock/core/llm/backend/factory.py +0 -7
  198. drydock_cli-2.10.12/drydock/core/llm/backend/generic.py +0 -629
  199. drydock_cli-2.10.12/drydock/core/llm/backend/mistral.py +0 -402
  200. drydock_cli-2.10.12/drydock/core/llm/backend/reasoning_adapter.py +0 -235
  201. drydock_cli-2.10.12/drydock/core/llm/backend/vertex.py +0 -132
  202. drydock_cli-2.10.12/drydock/core/llm/exceptions.py +0 -216
  203. drydock_cli-2.10.12/drydock/core/llm/format.py +0 -783
  204. drydock_cli-2.10.12/drydock/core/llm/grammar/__init__.py +0 -59
  205. drydock_cli-2.10.12/drydock/core/llm/grammar/_llamacpp_converter.py +0 -844
  206. drydock_cli-2.10.12/drydock/core/llm/grammar/policy.py +0 -151
  207. drydock_cli-2.10.12/drydock/core/llm/grammar/policy_union.py +0 -230
  208. drydock_cli-2.10.12/drydock/core/llm/message_utils.py +0 -26
  209. drydock_cli-2.10.12/drydock/core/llm/types.py +0 -126
  210. drydock_cli-2.10.12/drydock/core/logger.py +0 -58
  211. drydock_cli-2.10.12/drydock/core/middleware.py +0 -295
  212. drydock_cli-2.10.12/drydock/core/output_formatters.py +0 -85
  213. drydock_cli-2.10.12/drydock/core/paths/__init__.py +0 -31
  214. drydock_cli-2.10.12/drydock/core/paths/_drydock_home.py +0 -37
  215. drydock_cli-2.10.12/drydock/core/paths/_local_config_walk.py +0 -39
  216. drydock_cli-2.10.12/drydock/core/paths/conventions.py +0 -3
  217. drydock_cli-2.10.12/drydock/core/plan_session.py +0 -24
  218. drydock_cli-2.10.12/drydock/core/plugins.py +0 -138
  219. drydock_cli-2.10.12/drydock/core/programmatic.py +0 -130
  220. drydock_cli-2.10.12/drydock/core/prompts/__init__.py +0 -57
  221. drydock_cli-2.10.12/drydock/core/prompts/builder.md +0 -45
  222. drydock_cli-2.10.12/drydock/core/prompts/cli.md +0 -286
  223. drydock_cli-2.10.12/drydock/core/prompts/compact.md +0 -48
  224. drydock_cli-2.10.12/drydock/core/prompts/dangerous_directory.md +0 -5
  225. drydock_cli-2.10.12/drydock/core/prompts/diagnostic.md +0 -24
  226. drydock_cli-2.10.12/drydock/core/prompts/explore.md +0 -50
  227. drydock_cli-2.10.12/drydock/core/prompts/gemma4.md +0 -213
  228. drydock_cli-2.10.12/drydock/core/prompts/gemma4_math.md +0 -201
  229. drydock_cli-2.10.12/drydock/core/prompts/gemma4_slim.md +0 -115
  230. drydock_cli-2.10.12/drydock/core/prompts/planner.md +0 -35
  231. drydock_cli-2.10.12/drydock/core/prompts/project_context.md +0 -4
  232. drydock_cli-2.10.12/drydock/core/prompts/tests.md +0 -1
  233. drydock_cli-2.10.12/drydock/core/proxy_setup.py +0 -65
  234. drydock_cli-2.10.12/drydock/core/session/agent_memory.py +0 -123
  235. drydock_cli-2.10.12/drydock/core/session/checkpoints.py +0 -122
  236. drydock_cli-2.10.12/drydock/core/session/session_loader.py +0 -275
  237. drydock_cli-2.10.12/drydock/core/session/session_logger.py +0 -510
  238. drydock_cli-2.10.12/drydock/core/session/session_migration.py +0 -41
  239. drydock_cli-2.10.12/drydock/core/session/state_file.py +0 -143
  240. drydock_cli-2.10.12/drydock/core/session_checker.py +0 -163
  241. drydock_cli-2.10.12/drydock/core/skills/__init__.py +0 -7
  242. drydock_cli-2.10.12/drydock/core/skills/manager.py +0 -152
  243. drydock_cli-2.10.12/drydock/core/skills/models.py +0 -118
  244. drydock_cli-2.10.12/drydock/core/skills/parser.py +0 -39
  245. drydock_cli-2.10.12/drydock/core/slug.py +0 -113
  246. drydock_cli-2.10.12/drydock/core/spec_check.py +0 -490
  247. drydock_cli-2.10.12/drydock/core/steering_hook.py +0 -152
  248. drydock_cli-2.10.12/drydock/core/system_prompt.py +0 -356
  249. drydock_cli-2.10.12/drydock/core/telemetry/__init__.py +0 -0
  250. drydock_cli-2.10.12/drydock/core/telemetry/send.py +0 -197
  251. drydock_cli-2.10.12/drydock/core/teleport/errors.py +0 -9
  252. drydock_cli-2.10.12/drydock/core/teleport/git.py +0 -196
  253. drydock_cli-2.10.12/drydock/core/teleport/nuage.py +0 -185
  254. drydock_cli-2.10.12/drydock/core/teleport/teleport.py +0 -212
  255. drydock_cli-2.10.12/drydock/core/teleport/types.py +0 -54
  256. drydock_cli-2.10.12/drydock/core/tools/base.py +0 -355
  257. drydock_cli-2.10.12/drydock/core/tools/builtins/_task_manager.py +0 -166
  258. drydock_cli-2.10.12/drydock/core/tools/builtins/algebra_tool.py +0 -389
  259. drydock_cli-2.10.12/drydock/core/tools/builtins/ask_user_question.py +0 -132
  260. drydock_cli-2.10.12/drydock/core/tools/builtins/bash.py +0 -1553
  261. drydock_cli-2.10.12/drydock/core/tools/builtins/chemistry_tool.py +0 -527
  262. drydock_cli-2.10.12/drydock/core/tools/builtins/count_tool.py +0 -201
  263. drydock_cli-2.10.12/drydock/core/tools/builtins/cron.py +0 -164
  264. drydock_cli-2.10.12/drydock/core/tools/builtins/exit_plan_mode.py +0 -156
  265. drydock_cli-2.10.12/drydock/core/tools/builtins/glob_tool.py +0 -94
  266. drydock_cli-2.10.12/drydock/core/tools/builtins/grep.py +0 -350
  267. drydock_cli-2.10.12/drydock/core/tools/builtins/invoke_skill.py +0 -225
  268. drydock_cli-2.10.12/drydock/core/tools/builtins/linear_algebra_tool.py +0 -420
  269. drydock_cli-2.10.12/drydock/core/tools/builtins/logic_tool.py +0 -483
  270. drydock_cli-2.10.12/drydock/core/tools/builtins/lsp.py +0 -202
  271. drydock_cli-2.10.12/drydock/core/tools/builtins/math_tool.py +0 -236
  272. drydock_cli-2.10.12/drydock/core/tools/builtins/mcp_resources.py +0 -231
  273. drydock_cli-2.10.12/drydock/core/tools/builtins/mechanical_rename.py +0 -283
  274. drydock_cli-2.10.12/drydock/core/tools/builtins/memory_tool.py +0 -352
  275. drydock_cli-2.10.12/drydock/core/tools/builtins/notebook_edit.py +0 -96
  276. drydock_cli-2.10.12/drydock/core/tools/builtins/number_theory_tool.py +0 -418
  277. drydock_cli-2.10.12/drydock/core/tools/builtins/powershell.py +0 -115
  278. drydock_cli-2.10.12/drydock/core/tools/builtins/prolog_tool.py +0 -313
  279. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  280. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -84
  281. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/bash.md +0 -73
  282. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/cron.md +0 -5
  283. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/glob.md +0 -9
  284. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/grep.md +0 -4
  285. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -9
  286. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/lsp.md +0 -9
  287. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -4
  288. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -7
  289. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/powershell.md +0 -6
  290. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/read_file.md +0 -18
  291. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/retrieve.md +0 -22
  292. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/search_replace.md +0 -43
  293. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/swe_bench.md +0 -38
  294. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/task.md +0 -24
  295. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/task_manager.md +0 -8
  296. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/todo.md +0 -199
  297. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/tool_search.md +0 -7
  298. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/webfetch.md +0 -6
  299. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/websearch.md +0 -25
  300. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/worktree.md +0 -7
  301. drydock_cli-2.10.12/drydock/core/tools/builtins/prompts/write_file.md +0 -42
  302. drydock_cli-2.10.12/drydock/core/tools/builtins/read_file.py +0 -475
  303. drydock_cli-2.10.12/drydock/core/tools/builtins/retrieve.py +0 -287
  304. drydock_cli-2.10.12/drydock/core/tools/builtins/search_replace.py +0 -2014
  305. drydock_cli-2.10.12/drydock/core/tools/builtins/set_tool.py +0 -338
  306. drydock_cli-2.10.12/drydock/core/tools/builtins/solve_tool.py +0 -446
  307. drydock_cli-2.10.12/drydock/core/tools/builtins/stats_tool.py +0 -488
  308. drydock_cli-2.10.12/drydock/core/tools/builtins/task.py +0 -247
  309. drydock_cli-2.10.12/drydock/core/tools/builtins/todo.py +0 -222
  310. drydock_cli-2.10.12/drydock/core/tools/builtins/tool_search.py +0 -120
  311. drydock_cli-2.10.12/drydock/core/tools/builtins/units_tool.py +0 -335
  312. drydock_cli-2.10.12/drydock/core/tools/builtins/verify_tool.py +0 -349
  313. drydock_cli-2.10.12/drydock/core/tools/builtins/webfetch.py +0 -202
  314. drydock_cli-2.10.12/drydock/core/tools/builtins/websearch.py +0 -136
  315. drydock_cli-2.10.12/drydock/core/tools/builtins/worktree.py +0 -165
  316. drydock_cli-2.10.12/drydock/core/tools/builtins/write_file.py +0 -988
  317. drydock_cli-2.10.12/drydock/core/tools/injection_guard.py +0 -105
  318. drydock_cli-2.10.12/drydock/core/tools/manager.py +0 -371
  319. drydock_cli-2.10.12/drydock/core/tools/mcp/__init__.py +0 -31
  320. drydock_cli-2.10.12/drydock/core/tools/mcp/registry.py +0 -172
  321. drydock_cli-2.10.12/drydock/core/tools/mcp/tools.py +0 -541
  322. drydock_cli-2.10.12/drydock/core/tools/mcp_sampling.py +0 -115
  323. drydock_cli-2.10.12/drydock/core/tools/ui.py +0 -121
  324. drydock_cli-2.10.12/drydock/core/tools/utils.py +0 -69
  325. drydock_cli-2.10.12/drydock/core/trusted_folders.py +0 -87
  326. drydock_cli-2.10.12/drydock/core/types.py +0 -504
  327. drydock_cli-2.10.12/drydock/core/utils.py +0 -346
  328. drydock_cli-2.10.12/drydock/curiosity/__init__.py +0 -40
  329. drydock_cli-2.10.12/drydock/curiosity/__main__.py +0 -263
  330. drydock_cli-2.10.12/drydock/curiosity/gap_detector.py +0 -485
  331. drydock_cli-2.10.12/drydock/curiosity/ingest.py +0 -680
  332. drydock_cli-2.10.12/drydock/curiosity/item.py +0 -58
  333. drydock_cli-2.10.12/drydock/curiosity/queue.py +0 -112
  334. drydock_cli-2.10.12/drydock/curiosity/surprise.py +0 -112
  335. drydock_cli-2.10.12/drydock/data/cookbook/python/global_rename.md +0 -134
  336. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/biopython_dna.md +0 -116
  337. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/dense_eigenvalue.md +0 -135
  338. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/elf_extraction_js.md +0 -165
  339. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/feal_cryptanalysis.md +0 -124
  340. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/gcode_to_text.md +0 -184
  341. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/llm_batching_scheduler.md +0 -137
  342. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/mcmc_stan.md +0 -188
  343. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/mips_isa.md +0 -162
  344. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/mobilesam_cell_seg.md +0 -162
  345. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/mteb_retrieve.md +0 -124
  346. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/password_recovery.md +0 -189
  347. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/path_tracing.md +0 -110
  348. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/raman_fitting.md +0 -190
  349. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/regex_chess.md +0 -211
  350. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/sqlite_recovery.md +0 -167
  351. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/vim_macros.md +0 -120
  352. drydock_cli-2.10.12/drydock/data/cookbook/tbench_domains/xss_filter.md +0 -153
  353. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/build_cython_ext.md +0 -529
  354. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/build_pmars.md +0 -108
  355. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/build_pov_ray.md +0 -130
  356. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/cancel_async_tasks.md +0 -172
  357. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/chess_best_move.md +0 -63
  358. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/cobol_modernization.md +0 -158
  359. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/code_from_image.md +0 -111
  360. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/configure_git_webserver.md +0 -134
  361. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/constraints_scheduling.md +0 -196
  362. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/custom_memory_heap_crash.md +0 -109
  363. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/extract_elf.md +0 -86
  364. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/extract_moves_from_video.md +0 -341
  365. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/fix_code_vulnerability.md +0 -145
  366. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/git_leak_recovery.md +0 -55
  367. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/log_summary_date_ranges.md +0 -229
  368. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/model_extraction_relu_logits.md +0 -115
  369. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/mteb_leaderboard.md +0 -76
  370. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/query_optimize.md +0 -213
  371. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/sam_cell_seg.md +0 -410
  372. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/tune_mjcf.md +0 -270
  373. drydock_cli-2.10.12/drydock/data/cookbook/tbench_worked_examples/vulnerable_secret.md +0 -110
  374. drydock_cli-2.10.12/drydock/graphrag/__init__.py +0 -46
  375. drydock_cli-2.10.12/drydock/graphrag/__main__.py +0 -229
  376. drydock_cli-2.10.12/drydock/graphrag/code_indexer.py +0 -213
  377. drydock_cli-2.10.12/drydock/graphrag/retriever.py +0 -146
  378. drydock_cli-2.10.12/drydock/graphrag/storage.py +0 -670
  379. drydock_cli-2.10.12/drydock/graphrag/text_indexer.py +0 -308
  380. drydock_cli-2.10.12/drydock/setup/onboarding/__init__.py +0 -49
  381. drydock_cli-2.10.12/drydock/setup/onboarding/base.py +0 -14
  382. drydock_cli-2.10.12/drydock/setup/onboarding/onboarding.tcss +0 -134
  383. drydock_cli-2.10.12/drydock/setup/onboarding/screens/__init__.py +0 -13
  384. drydock_cli-2.10.12/drydock/setup/onboarding/screens/api_key.py +0 -142
  385. drydock_cli-2.10.12/drydock/setup/onboarding/screens/choice.py +0 -65
  386. drydock_cli-2.10.12/drydock/setup/onboarding/screens/local_model.py +0 -187
  387. drydock_cli-2.10.12/drydock/setup/onboarding/screens/welcome.py +0 -136
  388. drydock_cli-2.10.12/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -185
  389. drydock_cli-2.10.12/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -83
  390. drydock_cli-2.10.12/drydock/skills/__init__.py +0 -0
  391. drydock_cli-2.10.12/drydock/skills/api-design/SKILL.md +0 -32
  392. drydock_cli-2.10.12/drydock/skills/audit-tests/SKILL.md +0 -73
  393. drydock_cli-2.10.12/drydock/skills/batch/SKILL.md +0 -45
  394. drydock_cli-2.10.12/drydock/skills/checklist/SKILL.md +0 -105
  395. drydock_cli-2.10.12/drydock/skills/commit-code/SKILL.md +0 -27
  396. drydock_cli-2.10.12/drydock/skills/constraint-reasoning/SKILL.md +0 -202
  397. drydock_cli-2.10.12/drydock/skills/context-summary/SKILL.md +0 -19
  398. drydock_cli-2.10.12/drydock/skills/create-presentation/SKILL.md +0 -120
  399. drydock_cli-2.10.12/drydock/skills/deep-research/SKILL.md +0 -57
  400. drydock_cli-2.10.12/drydock/skills/deploy/SKILL.md +0 -26
  401. drydock_cli-2.10.12/drydock/skills/diff-review/SKILL.md +0 -16
  402. drydock_cli-2.10.12/drydock/skills/doc-gen/SKILL.md +0 -28
  403. drydock_cli-2.10.12/drydock/skills/explain-code/SKILL.md +0 -27
  404. drydock_cli-2.10.12/drydock/skills/explore-code/SKILL.md +0 -42
  405. drydock_cli-2.10.12/drydock/skills/fix-issue/SKILL.md +0 -33
  406. drydock_cli-2.10.12/drydock/skills/git-ops/SKILL.md +0 -32
  407. drydock_cli-2.10.12/drydock/skills/init-project/SKILL.md +0 -34
  408. drydock_cli-2.10.12/drydock/skills/investigate/SKILL.md +0 -67
  409. drydock_cli-2.10.12/drydock/skills/logic/SKILL.md +0 -139
  410. drydock_cli-2.10.12/drydock/skills/logic/assets/cheat_sheet_full.txt +0 -833
  411. drydock_cli-2.10.12/drydock/skills/loop/SKILL.md +0 -22
  412. drydock_cli-2.10.12/drydock/skills/migrate/SKILL.md +0 -25
  413. drydock_cli-2.10.12/drydock/skills/perf-analyze/SKILL.md +0 -29
  414. drydock_cli-2.10.12/drydock/skills/plan-impl/SKILL.md +0 -45
  415. drydock_cli-2.10.12/drydock/skills/pr-review/SKILL.md +0 -32
  416. drydock_cli-2.10.12/drydock/skills/prove/SKILL.md +0 -148
  417. drydock_cli-2.10.12/drydock/skills/refactor/SKILL.md +0 -37
  418. drydock_cli-2.10.12/drydock/skills/regex-help/SKILL.md +0 -30
  419. drydock_cli-2.10.12/drydock/skills/review/SKILL.md +0 -67
  420. drydock_cli-2.10.12/drydock/skills/security-review/SKILL.md +0 -31
  421. drydock_cli-2.10.12/drydock/skills/ship/SKILL.md +0 -65
  422. drydock_cli-2.10.12/drydock/skills/simplify/SKILL.md +0 -39
  423. drydock_cli-2.10.12/drydock/skills/strong-tests/SKILL.md +0 -94
  424. drydock_cli-2.10.12/drydock/skills/test-verify/SKILL.md +0 -27
  425. drydock_cli-2.10.12/drydock/steering/__init__.py +0 -70
  426. drydock_cli-2.10.12/drydock/steering/__main__.py +0 -161
  427. drydock_cli-2.10.12/drydock/steering/applier.py +0 -300
  428. drydock_cli-2.10.12/drydock/steering/config.py +0 -51
  429. drydock_cli-2.10.12/drydock/steering/registry.py +0 -131
  430. drydock_cli-2.10.12/drydock/steering/sandbox.py +0 -151
  431. drydock_cli-2.10.12/drydock/steering/sidecar/__init__.py +0 -28
  432. drydock_cli-2.10.12/drydock/steering/sidecar/header_parser.py +0 -74
  433. drydock_cli-2.10.12/drydock/steering/sidecar/hooks.py +0 -373
  434. drydock_cli-2.10.12/drydock/steering/sidecar/loader.py +0 -98
  435. drydock_cli-2.10.12/drydock/steering/sidecar/server.py +0 -384
  436. drydock_cli-2.10.12/drydock/steering/train/__init__.py +0 -12
  437. drydock_cli-2.10.12/drydock/steering/train/capture.py +0 -247
  438. drydock_cli-2.10.12/drydock/steering/train/compute_vector.py +0 -375
  439. drydock_cli-2.10.12/drydock/steering/train/extract_pairs.py +0 -443
  440. drydock_cli-2.10.12/drydock/steering/train/scan_sessions.py +0 -311
  441. drydock_cli-2.10.12/drydock/steering/vectors.py +0 -152
  442. drydock_cli-2.10.12/drydock/whats_new.md +0 -31
  443. drydock_cli-2.10.12/install_tests/README.md +0 -84
  444. drydock_cli-2.10.12/install_tests/publish/README.md +0 -78
  445. drydock_cli-2.10.12/install_tests/windows/README.md +0 -59
  446. drydock_cli-2.10.12/pyproject.toml +0 -208
  447. drydock_cli-2.10.12/scripts/README.md +0 -20
  448. drydock_cli-2.10.12/scripts/_archived_eval_harness/README.md +0 -38
  449. drydock_cli-2.10.12/scripts/llm/README.md +0 -80
  450. drydock_cli-2.10.12/tests/__init__.py +0 -5
  451. drydock_cli-2.10.12/tests/acp/conftest.py +0 -97
  452. drydock_cli-2.10.12/tests/acp/test_acp.py +0 -965
  453. drydock_cli-2.10.12/tests/acp/test_agent_thought.py +0 -154
  454. drydock_cli-2.10.12/tests/acp/test_bash.py +0 -496
  455. drydock_cli-2.10.12/tests/acp/test_compact_session_updates.py +0 -81
  456. drydock_cli-2.10.12/tests/acp/test_content.py +0 -149
  457. drydock_cli-2.10.12/tests/acp/test_initialize.py +0 -70
  458. drydock_cli-2.10.12/tests/acp/test_list_sessions.py +0 -242
  459. drydock_cli-2.10.12/tests/acp/test_load_session.py +0 -344
  460. drydock_cli-2.10.12/tests/acp/test_multi_session.py +0 -112
  461. drydock_cli-2.10.12/tests/acp/test_new_session.py +0 -151
  462. drydock_cli-2.10.12/tests/acp/test_proxy_setup_acp.py +0 -271
  463. drydock_cli-2.10.12/tests/acp/test_read_file.py +0 -247
  464. drydock_cli-2.10.12/tests/acp/test_search_replace.py +0 -354
  465. drydock_cli-2.10.12/tests/acp/test_set_config_option.py +0 -317
  466. drydock_cli-2.10.12/tests/acp/test_set_mode.py +0 -201
  467. drydock_cli-2.10.12/tests/acp/test_set_model.py +0 -306
  468. drydock_cli-2.10.12/tests/acp/test_tool_call_session_update.py +0 -44
  469. drydock_cli-2.10.12/tests/acp/test_utils.py +0 -55
  470. drydock_cli-2.10.12/tests/acp/test_write_file.py +0 -277
  471. drydock_cli-2.10.12/tests/autocompletion/conftest.py +0 -27
  472. drydock_cli-2.10.12/tests/autocompletion/test_file_indexer.py +0 -349
  473. drydock_cli-2.10.12/tests/autocompletion/test_fuzzy.py +0 -96
  474. drydock_cli-2.10.12/tests/autocompletion/test_path_completer_fuzzy.py +0 -122
  475. drydock_cli-2.10.12/tests/autocompletion/test_path_completer_recursive.py +0 -69
  476. drydock_cli-2.10.12/tests/autocompletion/test_path_completion_controller.py +0 -258
  477. drydock_cli-2.10.12/tests/autocompletion/test_path_prompt_transformer.py +0 -142
  478. drydock_cli-2.10.12/tests/autocompletion/test_slash_command_controller.py +0 -235
  479. drydock_cli-2.10.12/tests/autocompletion/test_ui_chat_autocompletion.py +0 -309
  480. drydock_cli-2.10.12/tests/backend/__init__.py +0 -0
  481. drydock_cli-2.10.12/tests/backend/data/__init__.py +0 -6
  482. drydock_cli-2.10.12/tests/backend/data/fireworks.py +0 -153
  483. drydock_cli-2.10.12/tests/backend/data/mistral.py +0 -150
  484. drydock_cli-2.10.12/tests/backend/test_anthropic_adapter.py +0 -586
  485. drydock_cli-2.10.12/tests/backend/test_backend.py +0 -437
  486. drydock_cli-2.10.12/tests/backend/test_generic_adapter_sanitize.py +0 -159
  487. drydock_cli-2.10.12/tests/backend/test_reasoning_adapter.py +0 -254
  488. drydock_cli-2.10.12/tests/backend/test_vertex_anthropic_adapter.py +0 -637
  489. drydock_cli-2.10.12/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -32
  490. drydock_cli-2.10.12/tests/cli/plan_offer/test_decide_plan_offer.py +0 -172
  491. drydock_cli-2.10.12/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -147
  492. drydock_cli-2.10.12/tests/cli/test_bell_notifications.py +0 -151
  493. drydock_cli-2.10.12/tests/cli/test_braille_renderer.py +0 -114
  494. drydock_cli-2.10.12/tests/cli/test_clipboard.py +0 -325
  495. drydock_cli-2.10.12/tests/cli/test_commands.py +0 -62
  496. drydock_cli-2.10.12/tests/cli/test_copy_shortcuts.py +0 -59
  497. drydock_cli-2.10.12/tests/cli/test_external_editor.py +0 -72
  498. drydock_cli-2.10.12/tests/cli/test_no_markup_static.py +0 -19
  499. drydock_cli-2.10.12/tests/cli/test_question_app.py +0 -513
  500. drydock_cli-2.10.12/tests/cli/test_spinner.py +0 -16
  501. drydock_cli-2.10.12/tests/cli/test_switching_mode.py +0 -109
  502. drydock_cli-2.10.12/tests/cli/test_ui_clipboard_notifications.py +0 -40
  503. drydock_cli-2.10.12/tests/cli/test_ui_session_incremental_renderer.py +0 -173
  504. drydock_cli-2.10.12/tests/cli/test_ui_session_resume.py +0 -197
  505. drydock_cli-2.10.12/tests/cli/test_ui_skill_dispatch.py +0 -152
  506. drydock_cli-2.10.12/tests/cli/textual_ui/__init__.py +0 -0
  507. drydock_cli-2.10.12/tests/cli/textual_ui/test_session_picker.py +0 -131
  508. drydock_cli-2.10.12/tests/conftest.py +0 -227
  509. drydock_cli-2.10.12/tests/core/test_agents.py +0 -80
  510. drydock_cli-2.10.12/tests/core/test_auth_crypto.py +0 -46
  511. drydock_cli-2.10.12/tests/core/test_auth_github.py +0 -286
  512. drydock_cli-2.10.12/tests/core/test_config_load_dotenv.py +0 -81
  513. drydock_cli-2.10.12/tests/core/test_config_paths.py +0 -345
  514. drydock_cli-2.10.12/tests/core/test_config_resolution.py +0 -123
  515. drydock_cli-2.10.12/tests/core/test_file_logging.py +0 -280
  516. drydock_cli-2.10.12/tests/core/test_plan_session.py +0 -42
  517. drydock_cli-2.10.12/tests/core/test_proxy_setup.py +0 -304
  518. drydock_cli-2.10.12/tests/core/test_slug.py +0 -34
  519. drydock_cli-2.10.12/tests/core/test_telemetry_send.py +0 -374
  520. drydock_cli-2.10.12/tests/core/test_teleport_git.py +0 -327
  521. drydock_cli-2.10.12/tests/core/test_teleport_nuage.py +0 -337
  522. drydock_cli-2.10.12/tests/core/test_teleport_service.py +0 -418
  523. drydock_cli-2.10.12/tests/core/test_trusted_folders.py +0 -268
  524. drydock_cli-2.10.12/tests/core/test_utils.py +0 -19
  525. drydock_cli-2.10.12/tests/e2e/common.py +0 -86
  526. drydock_cli-2.10.12/tests/e2e/conftest.py +0 -82
  527. drydock_cli-2.10.12/tests/e2e/mock_server.py +0 -149
  528. drydock_cli-2.10.12/tests/e2e/test_cli_tui_onboarding.py +0 -31
  529. drydock_cli-2.10.12/tests/e2e/test_cli_tui_streaming.py +0 -51
  530. drydock_cli-2.10.12/tests/e2e/test_cli_tui_tool_approval.py +0 -87
  531. drydock_cli-2.10.12/tests/fixtures/doc_qa_system_prd.md +0 -86
  532. drydock_cli-2.10.12/tests/mock/__init__.py +0 -0
  533. drydock_cli-2.10.12/tests/mock/mock_backend_factory.py +0 -16
  534. drydock_cli-2.10.12/tests/mock/mock_entrypoint.py +0 -65
  535. drydock_cli-2.10.12/tests/mock/utils.py +0 -60
  536. drydock_cli-2.10.12/tests/onboarding/test_run_onboarding.py +0 -60
  537. drydock_cli-2.10.12/tests/onboarding/test_ui_onboarding.py +0 -57
  538. drydock_cli-2.10.12/tests/session/test_session_loader.py +0 -1065
  539. drydock_cli-2.10.12/tests/session/test_session_logger.py +0 -782
  540. drydock_cli-2.10.12/tests/session/test_session_migration.py +0 -177
  541. drydock_cli-2.10.12/tests/skills/conftest.py +0 -62
  542. drydock_cli-2.10.12/tests/skills/test_manager.py +0 -520
  543. drydock_cli-2.10.12/tests/skills/test_models.py +0 -195
  544. drydock_cli-2.10.12/tests/skills/test_parser.py +0 -115
  545. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -136
  546. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -176
  547. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -201
  548. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -206
  549. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -203
  550. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -201
  551. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -201
  552. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -201
  553. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -200
  554. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -200
  555. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -114
  556. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -137
  557. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -200
  558. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -200
  559. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -203
  560. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -202
  561. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -201
  562. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -200
  563. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -137
  564. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -137
  565. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -137
  566. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -137
  567. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -137
  568. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -137
  569. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -136
  570. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -139
  571. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -137
  572. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -139
  573. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -136
  574. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -136
  575. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -136
  576. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -136
  577. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -136
  578. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -140
  579. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -136
  580. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -140
  581. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -139
  582. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -203
  583. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -203
  584. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -203
  585. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -203
  586. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -204
  587. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -202
  588. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -94
  589. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -94
  590. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -104
  591. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -104
  592. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -104
  593. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -94
  594. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -94
  595. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -94
  596. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -95
  597. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -95
  598. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -94
  599. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -94
  600. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -94
  601. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -202
  602. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -203
  603. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -203
  604. drydock_cli-2.10.12/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -202
  605. drydock_cli-2.10.12/tests/snapshots/base_snapshot_test_app.py +0 -69
  606. drydock_cli-2.10.12/tests/snapshots/conftest.py +0 -10
  607. drydock_cli-2.10.12/tests/snapshots/snap_compare.py +0 -20
  608. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -80
  609. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -33
  610. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -38
  611. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -58
  612. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_modes.py +0 -88
  613. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -114
  614. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -129
  615. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_question_app.py +0 -365
  616. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -146
  617. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -45
  618. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_session_resume.py +0 -47
  619. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -75
  620. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_teleport.py +0 -249
  621. drydock_cli-2.10.12/tests/snapshots/test_ui_snapshot_whats_new.py +0 -156
  622. drydock_cli-2.10.12/tests/stress/__init__.py +0 -0
  623. drydock_cli-2.10.12/tests/stress/test_io_thrash.py +0 -740
  624. drydock_cli-2.10.12/tests/stubs/fake_backend.py +0 -149
  625. drydock_cli-2.10.12/tests/stubs/fake_client.py +0 -134
  626. drydock_cli-2.10.12/tests/stubs/fake_tool.py +0 -35
  627. drydock_cli-2.10.12/tests/test_admiral.py +0 -99
  628. drydock_cli-2.10.12/tests/test_admiral_hallucinated_tool_filter.py +0 -89
  629. drydock_cli-2.10.12/tests/test_admiral_intervention_outcome.py +0 -154
  630. drydock_cli-2.10.12/tests/test_admiral_phase3.py +0 -171
  631. drydock_cli-2.10.12/tests/test_admiral_proposed.py +0 -165
  632. drydock_cli-2.10.12/tests/test_admiral_session_id.py +0 -93
  633. drydock_cli-2.10.12/tests/test_admiral_struggle_dedup.py +0 -99
  634. drydock_cli-2.10.12/tests/test_agent_auto_compact.py +0 -148
  635. drydock_cli-2.10.12/tests/test_agent_backend.py +0 -187
  636. drydock_cli-2.10.12/tests/test_agent_observer_streaming.py +0 -643
  637. drydock_cli-2.10.12/tests/test_agent_stats.py +0 -754
  638. drydock_cli-2.10.12/tests/test_agent_tasks.py +0 -234
  639. drydock_cli-2.10.12/tests/test_agent_tool_call.py +0 -531
  640. drydock_cli-2.10.12/tests/test_agents.py +0 -610
  641. drydock_cli-2.10.12/tests/test_algebra_tool.py +0 -194
  642. drydock_cli-2.10.12/tests/test_api_error_recovery.py +0 -194
  643. drydock_cli-2.10.12/tests/test_approval_modal_stray_keys.py +0 -92
  644. drydock_cli-2.10.12/tests/test_auto_retrieve_cookbook_bypass.py +0 -52
  645. drydock_cli-2.10.12/tests/test_auto_retrieve_soft_nudge.py +0 -294
  646. drydock_cli-2.10.12/tests/test_auto_retrieve_wrapper_strip.py +0 -111
  647. drydock_cli-2.10.12/tests/test_auto_solve.py +0 -266
  648. drydock_cli-2.10.12/tests/test_bank_build.py +0 -565
  649. drydock_cli-2.10.12/tests/test_bank_debug.py +0 -1108
  650. drydock_cli-2.10.12/tests/test_bank_multiagent.py +0 -692
  651. drydock_cli-2.10.12/tests/test_bank_prd.py +0 -769
  652. drydock_cli-2.10.12/tests/test_bank_prd_extended.py +0 -765
  653. drydock_cli-2.10.12/tests/test_bank_tools.py +0 -468
  654. drydock_cli-2.10.12/tests/test_bank_update.py +0 -930
  655. drydock_cli-2.10.12/tests/test_broken_tool_isolation.py +0 -74
  656. drydock_cli-2.10.12/tests/test_build_projects.py +0 -272
  657. drydock_cli-2.10.12/tests/test_checkpoint.py +0 -338
  658. drydock_cli-2.10.12/tests/test_chemistry_tool.py +0 -192
  659. drydock_cli-2.10.12/tests/test_classifier.py +0 -275
  660. drydock_cli-2.10.12/tests/test_cli_programmatic_preload.py +0 -144
  661. drydock_cli-2.10.12/tests/test_config_migration.py +0 -128
  662. drydock_cli-2.10.12/tests/test_constraint_extract.py +0 -282
  663. drydock_cli-2.10.12/tests/test_constraint_hint.py +0 -172
  664. drydock_cli-2.10.12/tests/test_context_recovery.py +0 -123
  665. drydock_cli-2.10.12/tests/test_count_tool.py +0 -187
  666. drydock_cli-2.10.12/tests/test_curiosity.py +0 -332
  667. drydock_cli-2.10.12/tests/test_current_bugs.py +0 -148
  668. drydock_cli-2.10.12/tests/test_dispatch_report.py +0 -141
  669. drydock_cli-2.10.12/tests/test_dispatcher.py +0 -188
  670. drydock_cli-2.10.12/tests/test_drydock_regression.py +0 -460
  671. drydock_cli-2.10.12/tests/test_drydock_tasks.py +0 -495
  672. drydock_cli-2.10.12/tests/test_fake_tool_call_paren_syntax.py +0 -90
  673. drydock_cli-2.10.12/tests/test_full_regression.py +0 -199
  674. drydock_cli-2.10.12/tests/test_gemma4_anti_loop_migration.py +0 -137
  675. drydock_cli-2.10.12/tests/test_gemma4_tool_filter.py +0 -95
  676. drydock_cli-2.10.12/tests/test_goal.py +0 -203
  677. drydock_cli-2.10.12/tests/test_grammar.py +0 -431
  678. drydock_cli-2.10.12/tests/test_graphrag.py +0 -208
  679. drydock_cli-2.10.12/tests/test_graphrag_pdf_ingest.py +0 -104
  680. drydock_cli-2.10.12/tests/test_graphrag_worked_examples.py +0 -170
  681. drydock_cli-2.10.12/tests/test_hallucinated_tool_suppression.py +0 -137
  682. drydock_cli-2.10.12/tests/test_history_manager.py +0 -101
  683. drydock_cli-2.10.12/tests/test_hle_aggregate.py +0 -123
  684. drydock_cli-2.10.12/tests/test_integration.py +0 -274
  685. drydock_cli-2.10.12/tests/test_issue_fixes.py +0 -215
  686. drydock_cli-2.10.12/tests/test_linear_algebra_tool.py +0 -237
  687. drydock_cli-2.10.12/tests/test_local_detect.py +0 -268
  688. drydock_cli-2.10.12/tests/test_local_detect_fallback.py +0 -86
  689. drydock_cli-2.10.12/tests/test_logic_tool.py +0 -247
  690. drydock_cli-2.10.12/tests/test_loop_detection.py +0 -1005
  691. drydock_cli-2.10.12/tests/test_loop_regressions_2026_06_06.py +0 -685
  692. drydock_cli-2.10.12/tests/test_math_docs_lazy_injection.py +0 -99
  693. drydock_cli-2.10.12/tests/test_math_tool.py +0 -231
  694. drydock_cli-2.10.12/tests/test_mcp_settings.py +0 -17
  695. drydock_cli-2.10.12/tests/test_mcp_stdio_command_normalization.py +0 -53
  696. drydock_cli-2.10.12/tests/test_mechanical_rename_tool.py +0 -32
  697. drydock_cli-2.10.12/tests/test_mechanical_rename_type_extraction.py +0 -91
  698. drydock_cli-2.10.12/tests/test_memory_tool.py +0 -235
  699. drydock_cli-2.10.12/tests/test_message_id.py +0 -162
  700. drydock_cli-2.10.12/tests/test_message_merging.py +0 -47
  701. drydock_cli-2.10.12/tests/test_middleware.py +0 -607
  702. drydock_cli-2.10.12/tests/test_multi_agent.py +0 -112
  703. drydock_cli-2.10.12/tests/test_number_theory_tool.py +0 -228
  704. drydock_cli-2.10.12/tests/test_prolog_tool.py +0 -203
  705. drydock_cli-2.10.12/tests/test_read_file_not_found_listing.py +0 -69
  706. drydock_cli-2.10.12/tests/test_read_file_notebook_slim.py +0 -114
  707. drydock_cli-2.10.12/tests/test_real_failures.py +0 -91
  708. drydock_cli-2.10.12/tests/test_real_issues.py +0 -257
  709. drydock_cli-2.10.12/tests/test_real_workflow.py +0 -85
  710. drydock_cli-2.10.12/tests/test_reasoning_content.py +0 -572
  711. drydock_cli-2.10.12/tests/test_rejudge_hle.py +0 -187
  712. drydock_cli-2.10.12/tests/test_retrieval_consumer.py +0 -175
  713. drydock_cli-2.10.12/tests/test_retrieve_project_detection.py +0 -63
  714. drydock_cli-2.10.12/tests/test_retrieve_tool.py +0 -189
  715. drydock_cli-2.10.12/tests/test_safe_parse_tool_args.py +0 -85
  716. drydock_cli-2.10.12/tests/test_search_replace_args_not_truncated.py +0 -185
  717. drydock_cli-2.10.12/tests/test_search_replace_syntax_rollback.py +0 -133
  718. drydock_cli-2.10.12/tests/test_session_log_event.py +0 -89
  719. drydock_cli-2.10.12/tests/test_session_publish_on_resume.py +0 -84
  720. drydock_cli-2.10.12/tests/test_set_tool.py +0 -166
  721. drydock_cli-2.10.12/tests/test_smoke.py +0 -175
  722. drydock_cli-2.10.12/tests/test_solve_tool.py +0 -337
  723. drydock_cli-2.10.12/tests/test_specialist_math_tools_hidden.py +0 -95
  724. drydock_cli-2.10.12/tests/test_stats_tool.py +0 -209
  725. drydock_cli-2.10.12/tests/test_steering.py +0 -387
  726. drydock_cli-2.10.12/tests/test_steering_capture.py +0 -292
  727. drydock_cli-2.10.12/tests/test_steering_compute_vector.py +0 -326
  728. drydock_cli-2.10.12/tests/test_steering_extract_pairs.py +0 -264
  729. drydock_cli-2.10.12/tests/test_steering_hook.py +0 -125
  730. drydock_cli-2.10.12/tests/test_steering_sidecar_chat_inputs.py +0 -147
  731. drydock_cli-2.10.12/tests/test_steering_sidecar_hooks.py +0 -324
  732. drydock_cli-2.10.12/tests/test_system_prompt.py +0 -62
  733. drydock_cli-2.10.12/tests/test_tagged_text.py +0 -107
  734. drydock_cli-2.10.12/tests/test_task_complete_nudge.py +0 -59
  735. drydock_cli-2.10.12/tests/test_tool_args.py +0 -243
  736. drydock_cli-2.10.12/tests/test_tool_call_loops_regression_suite.py +0 -609
  737. drydock_cli-2.10.12/tests/test_tool_stop_injected_scope.py +0 -58
  738. drydock_cli-2.10.12/tests/test_truncate_args_valid_json.py +0 -180
  739. drydock_cli-2.10.12/tests/test_truncated_arg_path_hint.py +0 -124
  740. drydock_cli-2.10.12/tests/test_truncated_search_replace_escalation.py +0 -80
  741. drydock_cli-2.10.12/tests/test_truncated_write_escalation.py +0 -106
  742. drydock_cli-2.10.12/tests/test_ui_external_editor.py +0 -69
  743. drydock_cli-2.10.12/tests/test_ui_input_history.py +0 -285
  744. drydock_cli-2.10.12/tests/test_units_tool.py +0 -180
  745. drydock_cli-2.10.12/tests/test_user_issues.py +0 -299
  746. drydock_cli-2.10.12/tests/test_validation_error_scrub.py +0 -508
  747. drydock_cli-2.10.12/tests/test_verify_tool.py +0 -241
  748. drydock_cli-2.10.12/tests/test_wall_of_text_rescue.py +0 -247
  749. drydock_cli-2.10.12/tests/test_workloads.py +0 -441
  750. drydock_cli-2.10.12/tests/test_write_file_missing_path.py +0 -74
  751. drydock_cli-2.10.12/tests/testbank_helpers.py +0 -966
  752. drydock_cli-2.10.12/tests/tools/test_ask_user_question.py +0 -188
  753. drydock_cli-2.10.12/tests/tools/test_bash.py +0 -154
  754. drydock_cli-2.10.12/tests/tools/test_bash_binary_grep_hint.py +0 -45
  755. drydock_cli-2.10.12/tests/tools/test_bash_consec_empty_search.py +0 -82
  756. drydock_cli-2.10.12/tests/tools/test_bash_echo_escape_loop_breaker.py +0 -80
  757. drydock_cli-2.10.12/tests/tools/test_bash_empty_search_loop_breaker.py +0 -77
  758. drydock_cli-2.10.12/tests/tools/test_bash_error_loop_breaker.py +0 -87
  759. drydock_cli-2.10.12/tests/tools/test_bash_exact_cmd_loop_breaker.py +0 -86
  760. drydock_cli-2.10.12/tests/tools/test_bash_heredoc_confirmation.py +0 -106
  761. drydock_cli-2.10.12/tests/tools/test_bash_kill_exit1_annotation.py +0 -45
  762. drydock_cli-2.10.12/tests/tools/test_bash_python_c_syntaxerr_loop_breaker.py +0 -57
  763. drydock_cli-2.10.12/tests/tools/test_exit_plan_mode.py +0 -265
  764. drydock_cli-2.10.12/tests/tools/test_grep.py +0 -374
  765. drydock_cli-2.10.12/tests/tools/test_hallucinated_retrieval_redirect.py +0 -88
  766. drydock_cli-2.10.12/tests/tools/test_invoke_context.py +0 -106
  767. drydock_cli-2.10.12/tests/tools/test_manager_gemma_derived_models.py +0 -74
  768. drydock_cli-2.10.12/tests/tools/test_manager_get_tool_config.py +0 -478
  769. drydock_cli-2.10.12/tests/tools/test_mcp.py +0 -553
  770. drydock_cli-2.10.12/tests/tools/test_mcp_sampling.py +0 -171
  771. drydock_cli-2.10.12/tests/tools/test_pre_rename_hook.py +0 -209
  772. drydock_cli-2.10.12/tests/tools/test_read_file_dedup_alternating_offset.py +0 -109
  773. drydock_cli-2.10.12/tests/tools/test_read_file_dedup_reembed.py +0 -138
  774. drydock_cli-2.10.12/tests/tools/test_read_file_directory.py +0 -64
  775. drydock_cli-2.10.12/tests/tools/test_read_file_limit_truncation.py +0 -75
  776. drydock_cli-2.10.12/tests/tools/test_search_replace_append_fallback.py +0 -121
  777. drydock_cli-2.10.12/tests/tools/test_search_replace_dir_path.py +0 -165
  778. drydock_cli-2.10.12/tests/tools/test_search_replace_empty_content.py +0 -89
  779. drydock_cli-2.10.12/tests/tools/test_search_replace_file_not_found.py +0 -108
  780. drydock_cli-2.10.12/tests/tools/test_search_replace_first_failure_hint.py +0 -133
  781. drydock_cli-2.10.12/tests/tools/test_search_replace_hard_stop.py +0 -136
  782. drydock_cli-2.10.12/tests/tools/test_search_replace_malformed_block.py +0 -131
  783. drydock_cli-2.10.12/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -235
  784. drydock_cli-2.10.12/tests/tools/test_search_replace_placeholder.py +0 -77
  785. drydock_cli-2.10.12/tests/tools/test_search_replace_refused_loop_breaker.py +0 -144
  786. drydock_cli-2.10.12/tests/tools/test_task.py +0 -212
  787. drydock_cli-2.10.12/tests/tools/test_ui_bash_execution.py +0 -120
  788. drydock_cli-2.10.12/tests/tools/test_webfetch.py +0 -253
  789. drydock_cli-2.10.12/tests/tools/test_websearch.py +0 -221
  790. drydock_cli-2.10.12/tests/tools/test_write_file_dedup_missing_imports.py +0 -102
  791. drydock_cli-2.10.12/tests/tools/test_write_file_missing_main_module.py +0 -114
  792. drydock_cli-2.10.12/tests/tools/test_write_file_missing_path_hint.py +0 -78
  793. drydock_cli-2.10.12/tests/tools/test_write_file_multifile_rename.py +0 -179
  794. drydock_cli-2.10.12/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -17
  795. drydock_cli-2.10.12/tests/update_notifier/adapters/fake_update_gateway.py +0 -22
  796. drydock_cli-2.10.12/tests/update_notifier/test_do_update.py +0 -74
  797. drydock_cli-2.10.12/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -119
  798. drydock_cli-2.10.12/tests/update_notifier/test_github_update_gateway.py +0 -245
  799. drydock_cli-2.10.12/tests/update_notifier/test_pypi_update_gateway.py +0 -155
  800. drydock_cli-2.10.12/tests/update_notifier/test_ui_update_notification.py +0 -389
  801. drydock_cli-2.10.12/tests/update_notifier/test_update_use_case.py +0 -302
  802. drydock_cli-2.10.12/tests/update_notifier/test_whats_new.py +0 -161
  803. drydock_cli-2.10.12/uv.lock +0 -2229
  804. drydock_cli-2.10.12/web/README.md +0 -62
  805. drydock_cli-2.10.12/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