drydock-cli 2.7.33__tar.gz → 2.7.34__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 (711) hide show
  1. drydock_cli-2.7.34/.auto_release.lock +1 -0
  2. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/PKG-INFO +1 -1
  3. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/cli.py +21 -1
  4. drydock_cli-2.7.34/drydock/core/config/local_detect.py +120 -0
  5. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/bash.py +22 -0
  6. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/search_replace.py +33 -3
  7. drydock_cli-2.7.34/drydock/graphrag/__init__.py +46 -0
  8. drydock_cli-2.7.34/drydock/graphrag/__main__.py +121 -0
  9. drydock_cli-2.7.34/drydock/graphrag/code_indexer.py +213 -0
  10. drydock_cli-2.7.34/drydock/graphrag/retriever.py +107 -0
  11. drydock_cli-2.7.34/drydock/graphrag/storage.py +399 -0
  12. drydock_cli-2.7.34/drydock/graphrag/text_indexer.py +238 -0
  13. drydock_cli-2.7.34/drydock/steering/__init__.py +62 -0
  14. drydock_cli-2.7.34/drydock/steering/__main__.py +161 -0
  15. drydock_cli-2.7.34/drydock/steering/applier.py +157 -0
  16. drydock_cli-2.7.34/drydock/steering/config.py +51 -0
  17. drydock_cli-2.7.34/drydock/steering/registry.py +131 -0
  18. drydock_cli-2.7.34/drydock/steering/sandbox.py +151 -0
  19. drydock_cli-2.7.34/drydock/steering/vectors.py +133 -0
  20. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/pyproject.toml +1 -1
  21. drydock_cli-2.7.34/tests/test_graphrag.py +208 -0
  22. drydock_cli-2.7.34/tests/test_local_detect.py +168 -0
  23. drydock_cli-2.7.34/tests/test_steering.py +287 -0
  24. drydock_cli-2.7.34/tests/tools/test_bash_echo_escape_loop_breaker.py +80 -0
  25. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_no_op_loop_breaker.py +68 -0
  26. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/trip_log.md +99 -0
  27. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/uv.lock +1 -1
  28. drydock_cli-2.7.33/.auto_release.lock +0 -1
  29. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.claude/scheduled_tasks.lock +0 -0
  30. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.github/CODEOWNERS +0 -0
  31. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  32. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  33. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  34. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.github/workflows/build-and-upload.yml +0 -0
  35. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.github/workflows/ci.yml +0 -0
  36. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.github/workflows/issue-labeler.yml +0 -0
  37. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.github/workflows/release.yml +0 -0
  38. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.gitignore +0 -0
  39. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.perf_baseline_done +0 -0
  40. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.pre-commit-config.yaml +0 -0
  41. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.python-version +0 -0
  42. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.typos.toml +0 -0
  43. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.vscode/extensions.json +0 -0
  44. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.vscode/launch.json +0 -0
  45. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/.vscode/settings.json +0 -0
  46. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/AGENTS.md +0 -0
  47. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/Admiral.md +0 -0
  48. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/BASELINE_412.md +0 -0
  49. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/CHANGELOG.md +0 -0
  50. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/CLAUDE.md +0 -0
  51. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/CONTRIBUTING.md +0 -0
  52. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/DEPLOYMENT.md +0 -0
  53. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/Drydock_rebrand.md +0 -0
  54. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/LICENSE +0 -0
  55. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/MODEL_SHORTCOMINGS.md +0 -0
  56. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/NOTICE +0 -0
  57. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/OVERNIGHT_PROGRESS.md +0 -0
  58. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
  59. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/PERF_SWEEP_PLAN.md +0 -0
  60. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/PRD.md +0 -0
  61. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/README.md +0 -0
  62. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/SOVEREIGN_PRD.md +0 -0
  63. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/TRIAGE_v1.md +0 -0
  64. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/action.yml +0 -0
  65. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/README.md +0 -0
  66. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results1.tsv +0 -0
  67. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results13.tsv +0 -0
  68. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results14.tsv +0 -0
  69. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results15.tsv +0 -0
  70. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results16.tsv +0 -0
  71. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results17.tsv +0 -0
  72. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results18.tsv +0 -0
  73. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results19.tsv +0 -0
  74. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results2.tsv +0 -0
  75. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results20.tsv +0 -0
  76. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results3.tsv +0 -0
  77. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results4.tsv +0 -0
  78. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results5.tsv +0 -0
  79. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results6.tsv +0 -0
  80. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results7.tsv +0 -0
  81. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results8.tsv +0 -0
  82. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results9.tsv +0 -0
  83. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/baseline_history/results_evolved_v1.tsv +0 -0
  84. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/distribution/zed/LICENSE +0 -0
  85. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/distribution/zed/extension.toml +0 -0
  86. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/distribution/zed/icons/mistral_vibe.svg +0 -0
  87. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/docs/README.md +0 -0
  88. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/docs/acp-setup.md +0 -0
  89. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/docs/proxy-setup.md +0 -0
  90. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/__init__.py +0 -0
  91. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/__init__.py +0 -0
  92. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/acp_agent_loop.py +0 -0
  93. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/acp_logger.py +0 -0
  94. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/entrypoint.py +0 -0
  95. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/tools/__init__.py +0 -0
  96. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/tools/base.py +0 -0
  97. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/tools/builtins/bash.py +0 -0
  98. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/tools/builtins/read_file.py +0 -0
  99. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/tools/builtins/search_replace.py +0 -0
  100. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/tools/builtins/todo.py +0 -0
  101. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/tools/builtins/write_file.py +0 -0
  102. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/tools/session_update.py +0 -0
  103. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/acp/utils.py +0 -0
  104. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/__init__.py +0 -0
  105. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/detectors.py +0 -0
  106. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/detectors_proposed.py +0 -0
  107. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/history.py +0 -0
  108. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/interventions.py +0 -0
  109. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/llm_analyzer.py +0 -0
  110. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/metrics.py +0 -0
  111. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/opus_escalator.py +0 -0
  112. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/persistence.py +0 -0
  113. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/policy.py +0 -0
  114. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/proposer.py +0 -0
  115. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/stager.py +0 -0
  116. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/task_classifier.py +0 -0
  117. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/tuning.py +0 -0
  118. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/validator.py +0 -0
  119. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/admiral/worker.py +0 -0
  120. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/__init__.py +0 -0
  121. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/autocompletion/__init__.py +0 -0
  122. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/autocompletion/base.py +0 -0
  123. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/autocompletion/path_completion.py +0 -0
  124. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/autocompletion/slash_command.py +0 -0
  125. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/clipboard.py +0 -0
  126. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/commands.py +0 -0
  127. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/entrypoint.py +0 -0
  128. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/history_manager.py +0 -0
  129. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  130. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  131. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  132. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/terminal_setup.py +0 -0
  133. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/__init__.py +0 -0
  134. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  135. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/app.py +0 -0
  136. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/app.tcss +0 -0
  137. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/external_editor.py +0 -0
  138. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  139. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  140. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  141. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  142. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  143. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  144. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  145. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  146. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  147. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  148. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  149. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  150. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  151. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  152. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  153. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  154. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  155. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  156. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
  157. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  158. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  159. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  160. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  161. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  162. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/messages.py +0 -0
  163. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  164. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  165. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  166. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  167. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  168. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  169. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  170. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  171. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  172. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  173. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  174. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  175. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/windowing/history.py +0 -0
  176. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  177. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/textual_ui/windowing/state.py +0 -0
  178. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/update_notifier/__init__.py +0 -0
  179. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  180. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  181. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  182. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  183. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  184. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/update_notifier/update.py +0 -0
  185. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/cli/update_notifier/whats_new.py +0 -0
  186. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/__init__.py +0 -0
  187. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/agent_loop.py +0 -0
  188. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/agents/__init__.py +0 -0
  189. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/agents/manager.py +0 -0
  190. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/agents/models.py +0 -0
  191. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/auth/__init__.py +0 -0
  192. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/auth/crypto.py +0 -0
  193. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/auth/github.py +0 -0
  194. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/__init__.py +0 -0
  195. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/completers.py +0 -0
  196. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  197. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  198. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  199. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  200. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  201. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/fuzzy.py +0 -0
  202. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/path_prompt.py +0 -0
  203. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  204. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/build_orchestrator.py +0 -0
  205. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/checkpoint.py +0 -0
  206. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/config/__init__.py +0 -0
  207. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/config/_settings.py +0 -0
  208. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/config/doctor.py +0 -0
  209. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/config/harness_files/__init__.py +0 -0
  210. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  211. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/config/harness_files/_paths.py +0 -0
  212. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/consultant.py +0 -0
  213. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/drydock_states.py +0 -0
  214. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/hooks.py +0 -0
  215. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/__init__.py +0 -0
  216. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/backend/anthropic.py +0 -0
  217. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/backend/base.py +0 -0
  218. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/backend/factory.py +0 -0
  219. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/backend/generic.py +0 -0
  220. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/backend/mistral.py +0 -0
  221. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  222. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/backend/vertex.py +0 -0
  223. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/exceptions.py +0 -0
  224. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/format.py +0 -0
  225. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/message_utils.py +0 -0
  226. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/llm/types.py +0 -0
  227. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/logger.py +0 -0
  228. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/middleware.py +0 -0
  229. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/output_formatters.py +0 -0
  230. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/paths/__init__.py +0 -0
  231. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/paths/_drydock_home.py +0 -0
  232. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/paths/_local_config_walk.py +0 -0
  233. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/paths/conventions.py +0 -0
  234. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/plan_session.py +0 -0
  235. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/plugins.py +0 -0
  236. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/programmatic.py +0 -0
  237. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/__init__.py +0 -0
  238. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/builder.md +0 -0
  239. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/cli.md +0 -0
  240. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/compact.md +0 -0
  241. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/dangerous_directory.md +0 -0
  242. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/diagnostic.md +0 -0
  243. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/explore.md +0 -0
  244. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/gemma4.md +0 -0
  245. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/planner.md +0 -0
  246. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/project_context.md +0 -0
  247. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/prompts/tests.md +0 -0
  248. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/proxy_setup.py +0 -0
  249. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/session/agent_memory.py +0 -0
  250. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/session/checkpoints.py +0 -0
  251. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/session/session_loader.py +0 -0
  252. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/session/session_logger.py +0 -0
  253. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/session/session_migration.py +0 -0
  254. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/session/state_file.py +0 -0
  255. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/session_checker.py +0 -0
  256. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/skills/__init__.py +0 -0
  257. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/skills/manager.py +0 -0
  258. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/skills/models.py +0 -0
  259. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/skills/parser.py +0 -0
  260. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/slug.py +0 -0
  261. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/system_prompt.py +0 -0
  262. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/telemetry/__init__.py +0 -0
  263. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/telemetry/send.py +0 -0
  264. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/teleport/errors.py +0 -0
  265. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/teleport/git.py +0 -0
  266. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/teleport/nuage.py +0 -0
  267. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/teleport/teleport.py +0 -0
  268. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/teleport/types.py +0 -0
  269. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/base.py +0 -0
  270. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/_task_manager.py +0 -0
  271. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  272. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/cron.py +0 -0
  273. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  274. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/glob_tool.py +0 -0
  275. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/grep.py +0 -0
  276. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  277. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/lsp.py +0 -0
  278. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  279. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  280. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/powershell.py +0 -0
  281. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  282. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  283. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  284. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  285. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  286. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  287. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  288. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  289. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  290. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  291. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  292. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  293. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  294. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  295. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/task.md +0 -0
  296. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  297. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  298. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  299. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  300. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  301. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  302. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  303. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/read_file.py +0 -0
  304. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/task.py +0 -0
  305. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/todo.py +0 -0
  306. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/tool_search.py +0 -0
  307. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/webfetch.py +0 -0
  308. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/websearch.py +0 -0
  309. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/worktree.py +0 -0
  310. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/builtins/write_file.py +0 -0
  311. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/injection_guard.py +0 -0
  312. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/manager.py +0 -0
  313. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/mcp/__init__.py +0 -0
  314. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/mcp/registry.py +0 -0
  315. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/mcp/tools.py +0 -0
  316. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/mcp_sampling.py +0 -0
  317. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/ui.py +0 -0
  318. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/tools/utils.py +0 -0
  319. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/trusted_folders.py +0 -0
  320. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/types.py +0 -0
  321. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/core/utils.py +0 -0
  322. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/onboarding/__init__.py +0 -0
  323. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/onboarding/base.py +0 -0
  324. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/onboarding/onboarding.tcss +0 -0
  325. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/onboarding/screens/__init__.py +0 -0
  326. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/onboarding/screens/api_key.py +0 -0
  327. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/onboarding/screens/choice.py +0 -0
  328. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/onboarding/screens/local_model.py +0 -0
  329. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/onboarding/screens/welcome.py +0 -0
  330. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  331. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  332. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/__init__.py +0 -0
  333. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/api-design/SKILL.md +0 -0
  334. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/audit-tests/SKILL.md +0 -0
  335. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/batch/SKILL.md +0 -0
  336. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/commit-code/SKILL.md +0 -0
  337. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/context-summary/SKILL.md +0 -0
  338. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/create-presentation/SKILL.md +0 -0
  339. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/deep-research/SKILL.md +0 -0
  340. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/deploy/SKILL.md +0 -0
  341. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/diff-review/SKILL.md +0 -0
  342. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/doc-gen/SKILL.md +0 -0
  343. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/explain-code/SKILL.md +0 -0
  344. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/explore-code/SKILL.md +0 -0
  345. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/fix-issue/SKILL.md +0 -0
  346. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/git-ops/SKILL.md +0 -0
  347. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/init-project/SKILL.md +0 -0
  348. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/investigate/SKILL.md +0 -0
  349. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/loop/SKILL.md +0 -0
  350. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/migrate/SKILL.md +0 -0
  351. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/perf-analyze/SKILL.md +0 -0
  352. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/plan-impl/SKILL.md +0 -0
  353. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/pr-review/SKILL.md +0 -0
  354. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/refactor/SKILL.md +0 -0
  355. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/regex-help/SKILL.md +0 -0
  356. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/review/SKILL.md +0 -0
  357. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/security-review/SKILL.md +0 -0
  358. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/ship/SKILL.md +0 -0
  359. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/simplify/SKILL.md +0 -0
  360. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/strong-tests/SKILL.md +0 -0
  361. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/skills/test-verify/SKILL.md +0 -0
  362. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock/whats_new.md +0 -0
  363. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock-acp.spec +0 -0
  364. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/drydock_terms.md +0 -0
  365. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/flake.lock +0 -0
  366. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/flake.nix +0 -0
  367. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/nohup.out +0 -0
  368. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/perf_results/baseline_1777672181.json +0 -0
  369. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/perf_results/baseline_1777672218.json +0 -0
  370. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/perf_results/baseline_1777672322.json +0 -0
  371. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/perf_results/baseline_1777732278.json +0 -0
  372. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/README.md +0 -0
  373. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/config_base.toml +0 -0
  374. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/config_best.toml +0 -0
  375. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/domain_spec.md +0 -0
  376. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/experimenter.py +0 -0
  377. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/kernel.py +0 -0
  378. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/mini_prd.md +0 -0
  379. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/mini_prompts.txt +0 -0
  380. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/proposer.py +0 -0
  381. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/research/results.tsv +0 -0
  382. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/resume.md +0 -0
  383. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/README.md +0 -0
  384. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/admiral_probe.py +0 -0
  385. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/audit_sampler.py +0 -0
  386. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/auto_generate_tests.py +0 -0
  387. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/auto_release.sh +0 -0
  388. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/auto_test_loop.sh +0 -0
  389. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/autonomous_review.sh +0 -0
  390. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/autonomous_review_prompt.md +0 -0
  391. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/backup.sh +0 -0
  392. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/bump_version.py +0 -0
  393. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/comprehensive_loop.py +0 -0
  394. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/deploy_to_github.sh +0 -0
  395. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/discover_cli_tools.sh +0 -0
  396. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/evolve_tests.py +0 -0
  397. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/gen_2000_prompts.py +0 -0
  398. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/install.sh +0 -0
  399. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/llm_balancer.py +0 -0
  400. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/mega_loop.py +0 -0
  401. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/meta_ralph_loop.py +0 -0
  402. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/monitor_swebench.sh +0 -0
  403. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/monitor_test_battery.sh +0 -0
  404. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/notify_release.py +0 -0
  405. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/oss_task_harness.py +0 -0
  406. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/overnight_agents_test.sh +0 -0
  407. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/perf_baseline_when_idle.sh +0 -0
  408. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/perf_sweep.py +0 -0
  409. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/poll_issues.sh +0 -0
  410. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/port_task.py +0 -0
  411. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/prepare_release.py +0 -0
  412. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/publish_to_pypi.sh +0 -0
  413. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/ralph_loop.py +0 -0
  414. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/research_babysitter.sh +0 -0
  415. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/session_loop_audit.py +0 -0
  416. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/shakedown.py +0 -0
  417. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/shakedown_interactive.py +0 -0
  418. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/shakedown_regression.sh +0 -0
  419. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/shakedown_suite.sh +0 -0
  420. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/shakedown_variance.sh +0 -0
  421. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/stress_babysitter.sh +0 -0
  422. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/stress_prompts_50.txt +0 -0
  423. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/stress_prompts_realuser.txt +0 -0
  424. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/stress_prompts_tool_agent.txt +0 -0
  425. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
  426. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/stress_shakedown.py +0 -0
  427. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/stress_telegram_status.py +0 -0
  428. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/stress_watcher.py +0 -0
  429. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/telegram_bot.py +0 -0
  430. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/test_bank.sh +0 -0
  431. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/test_full.sh +0 -0
  432. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/test_smoke.sh +0 -0
  433. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/test_tui_path.py +0 -0
  434. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/tui_test.py +0 -0
  435. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/scripts/vllm_failover.sh +0 -0
  436. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/test/project/dummy +0 -0
  437. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/__init__.py +0 -0
  438. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/conftest.py +0 -0
  439. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_acp.py +0 -0
  440. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_agent_thought.py +0 -0
  441. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_bash.py +0 -0
  442. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_compact_session_updates.py +0 -0
  443. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_content.py +0 -0
  444. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_initialize.py +0 -0
  445. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_list_sessions.py +0 -0
  446. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_load_session.py +0 -0
  447. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_multi_session.py +0 -0
  448. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_new_session.py +0 -0
  449. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_proxy_setup_acp.py +0 -0
  450. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_read_file.py +0 -0
  451. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_search_replace.py +0 -0
  452. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_set_config_option.py +0 -0
  453. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_set_mode.py +0 -0
  454. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_set_model.py +0 -0
  455. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_tool_call_session_update.py +0 -0
  456. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_utils.py +0 -0
  457. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/acp/test_write_file.py +0 -0
  458. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/autocompletion/test_file_indexer.py +0 -0
  459. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/autocompletion/test_fuzzy.py +0 -0
  460. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  461. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  462. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/autocompletion/test_path_completion_controller.py +0 -0
  463. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  464. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/autocompletion/test_slash_command_controller.py +0 -0
  465. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  466. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/backend/__init__.py +0 -0
  467. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/backend/data/__init__.py +0 -0
  468. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/backend/data/fireworks.py +0 -0
  469. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/backend/data/mistral.py +0 -0
  470. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/backend/test_anthropic_adapter.py +0 -0
  471. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/backend/test_backend.py +0 -0
  472. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/backend/test_generic_adapter_sanitize.py +0 -0
  473. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/backend/test_reasoning_adapter.py +0 -0
  474. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  475. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  476. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  477. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  478. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_bell_notifications.py +0 -0
  479. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_braille_renderer.py +0 -0
  480. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_clipboard.py +0 -0
  481. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_commands.py +0 -0
  482. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_copy_shortcuts.py +0 -0
  483. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_external_editor.py +0 -0
  484. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_no_markup_static.py +0 -0
  485. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_question_app.py +0 -0
  486. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_spinner.py +0 -0
  487. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_switching_mode.py +0 -0
  488. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  489. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  490. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_ui_session_resume.py +0 -0
  491. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/test_ui_skill_dispatch.py +0 -0
  492. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/textual_ui/__init__.py +0 -0
  493. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/cli/textual_ui/test_session_picker.py +0 -0
  494. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/conftest.py +0 -0
  495. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_agents.py +0 -0
  496. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_auth_crypto.py +0 -0
  497. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_auth_github.py +0 -0
  498. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_circuit_breaker_count_escalation.py +0 -0
  499. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_circuit_breaker_readonly_threshold.py +0 -0
  500. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_config_load_dotenv.py +0 -0
  501. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_config_paths.py +0 -0
  502. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_config_resolution.py +0 -0
  503. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_file_logging.py +0 -0
  504. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_plan_session.py +0 -0
  505. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_proxy_setup.py +0 -0
  506. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_slug.py +0 -0
  507. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_telemetry_send.py +0 -0
  508. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_teleport_git.py +0 -0
  509. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_teleport_nuage.py +0 -0
  510. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_teleport_service.py +0 -0
  511. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_trusted_folders.py +0 -0
  512. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/core/test_utils.py +0 -0
  513. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/e2e/common.py +0 -0
  514. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/e2e/conftest.py +0 -0
  515. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/e2e/mock_server.py +0 -0
  516. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  517. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/e2e/test_cli_tui_streaming.py +0 -0
  518. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  519. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/fixtures/doc_qa_system_prd.md +0 -0
  520. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/mock/__init__.py +0 -0
  521. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/mock/mock_backend_factory.py +0 -0
  522. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/mock/mock_entrypoint.py +0 -0
  523. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/mock/utils.py +0 -0
  524. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/onboarding/test_run_onboarding.py +0 -0
  525. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/onboarding/test_ui_onboarding.py +0 -0
  526. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/session/test_session_loader.py +0 -0
  527. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/session/test_session_logger.py +0 -0
  528. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/session/test_session_migration.py +0 -0
  529. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/skills/conftest.py +0 -0
  530. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/skills/test_manager.py +0 -0
  531. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/skills/test_models.py +0 -0
  532. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/skills/test_parser.py +0 -0
  533. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  534. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  535. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  536. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  537. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  538. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  539. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  540. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  541. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  542. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  543. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  544. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  545. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  546. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  547. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  548. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  549. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  550. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  551. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  552. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  553. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  554. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  555. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  556. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  557. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  558. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  559. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  560. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  561. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  562. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  563. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  564. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  565. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  566. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  567. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  568. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  569. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  570. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  571. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  572. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  573. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  574. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  575. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  576. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  577. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  578. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  579. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  580. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  581. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  582. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  583. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  584. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  585. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  586. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  587. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  588. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  589. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  590. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  591. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  592. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  593. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/base_snapshot_test_app.py +0 -0
  594. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/conftest.py +0 -0
  595. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/snap_compare.py +0 -0
  596. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  597. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  598. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  599. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  600. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  601. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  602. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  603. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  604. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  605. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  606. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  607. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  608. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  609. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  610. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/stubs/fake_backend.py +0 -0
  611. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/stubs/fake_client.py +0 -0
  612. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/stubs/fake_tool.py +0 -0
  613. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_admiral.py +0 -0
  614. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_admiral_phase3.py +0 -0
  615. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_admiral_proposed.py +0 -0
  616. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_admiral_struggle_dedup.py +0 -0
  617. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_agent_auto_compact.py +0 -0
  618. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_agent_backend.py +0 -0
  619. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_agent_observer_streaming.py +0 -0
  620. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_agent_stats.py +0 -0
  621. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_agent_tasks.py +0 -0
  622. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_agent_tool_call.py +0 -0
  623. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_agents.py +0 -0
  624. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_bank_build.py +0 -0
  625. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_bank_debug.py +0 -0
  626. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_bank_multiagent.py +0 -0
  627. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_bank_prd.py +0 -0
  628. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_bank_prd_extended.py +0 -0
  629. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_bank_tools.py +0 -0
  630. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_bank_update.py +0 -0
  631. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_build_projects.py +0 -0
  632. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_checkpoint.py +0 -0
  633. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_cli_programmatic_preload.py +0 -0
  634. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_current_bugs.py +0 -0
  635. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_drydock_regression.py +0 -0
  636. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_drydock_tasks.py +0 -0
  637. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_fake_tool_call_paren_syntax.py +0 -0
  638. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_full_regression.py +0 -0
  639. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_hallucinated_tool_suppression.py +0 -0
  640. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_history_manager.py +0 -0
  641. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_integration.py +0 -0
  642. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_issue_fixes.py +0 -0
  643. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_loop_detection.py +0 -0
  644. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_message_id.py +0 -0
  645. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_message_merging.py +0 -0
  646. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_middleware.py +0 -0
  647. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_multi_agent.py +0 -0
  648. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_read_file_not_found_listing.py +0 -0
  649. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_real_failures.py +0 -0
  650. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_real_issues.py +0 -0
  651. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_real_workflow.py +0 -0
  652. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_reasoning_content.py +0 -0
  653. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_search_replace_args_not_truncated.py +0 -0
  654. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_smoke.py +0 -0
  655. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_system_prompt.py +0 -0
  656. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_tagged_text.py +0 -0
  657. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_task_complete_nudge.py +0 -0
  658. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_tool_args.py +0 -0
  659. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_truncate_args_valid_json.py +0 -0
  660. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_truncated_arg_path_hint.py +0 -0
  661. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_truncated_search_replace_escalation.py +0 -0
  662. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_truncated_write_escalation.py +0 -0
  663. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_ui_external_editor.py +0 -0
  664. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_ui_input_history.py +0 -0
  665. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_user_issues.py +0 -0
  666. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_wall_of_text_rescue.py +0 -0
  667. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_workloads.py +0 -0
  668. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/test_write_file_missing_path.py +0 -0
  669. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/testbank_helpers.py +0 -0
  670. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_ask_user_question.py +0 -0
  671. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_bash.py +0 -0
  672. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_exit_plan_mode.py +0 -0
  673. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_grep.py +0 -0
  674. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_invoke_context.py +0 -0
  675. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_manager_gemma_derived_models.py +0 -0
  676. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_manager_get_tool_config.py +0 -0
  677. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_mcp.py +0 -0
  678. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_mcp_sampling.py +0 -0
  679. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_read_file_dedup_alternating_offset.py +0 -0
  680. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_read_file_dedup_reembed.py +0 -0
  681. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_read_file_directory.py +0 -0
  682. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_read_file_limit_truncation.py +0 -0
  683. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_append_fallback.py +0 -0
  684. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_dir_path.py +0 -0
  685. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_empty_content.py +0 -0
  686. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_file_not_found.py +0 -0
  687. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_first_failure_hint.py +0 -0
  688. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_hard_stop.py +0 -0
  689. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_malformed_block.py +0 -0
  690. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_placeholder.py +0 -0
  691. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
  692. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_task.py +0 -0
  693. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_ui_bash_execution.py +0 -0
  694. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_webfetch.py +0 -0
  695. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_websearch.py +0 -0
  696. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
  697. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/tools/test_write_file_missing_path_hint.py +0 -0
  698. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  699. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  700. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/update_notifier/test_do_update.py +0 -0
  701. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  702. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/update_notifier/test_github_update_gateway.py +0 -0
  703. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  704. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/update_notifier/test_ui_update_notification.py +0 -0
  705. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/update_notifier/test_update_use_case.py +0 -0
  706. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/tests/update_notifier/test_whats_new.py +0 -0
  707. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/worked_examples/README.md +0 -0
  708. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/worked_examples/cli_subcommand_dispatch.py +0 -0
  709. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/worked_examples/lookup.json +0 -0
  710. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/worked_examples/sql_parser.py +0 -0
  711. {drydock_cli-2.7.33 → drydock_cli-2.7.34}/worked_examples/tree_walking_interpreter.py +0 -0
@@ -0,0 +1 @@
1
+ 2365970
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 2.7.33
3
+ Version: 2.7.34
4
4
  Summary: Local-first CLI coding agent — tested with Gemma 4 26B via vLLM
5
5
  Project-URL: Homepage, https://github.com/fbobe321/drydock
6
6
  Project-URL: Repository, https://github.com/fbobe321/drydock
@@ -68,8 +68,28 @@ def bootstrap_config_files() -> None:
68
68
  if not config_file.exists():
69
69
  try:
70
70
  config_file.parent.mkdir(parents=True, exist_ok=True)
71
+ default = DrydockConfig.create_default()
72
+ # Auto-detect a running local LLM server (llama.cpp, Ollama,
73
+ # vLLM, LM Studio). If found, point the default config at it
74
+ # and set local as the active model — so a fresh install with
75
+ # a local server already running starts up without demanding
76
+ # a Mistral API key.
77
+ try:
78
+ from drydock.core.config.local_detect import (
79
+ detect_local_llm,
80
+ patch_config_for_local,
81
+ )
82
+ info = detect_local_llm()
83
+ if info is not None:
84
+ patch_config_for_local(default, info)
85
+ rprint(
86
+ f"[green]Detected {info.label} at {info.api_base} — "
87
+ f"using model '{info.model_name}'.[/]"
88
+ )
89
+ except Exception as e: # detection must never break first launch
90
+ logger.debug("local-LLM detection failed: %s", e)
71
91
  with config_file.open("wb") as f:
72
- tomli_w.dump(DrydockConfig.create_default(), f)
92
+ tomli_w.dump(default, f)
73
93
  except Exception as e:
74
94
  rprint(f"[yellow]Could not create default config file: {e}[/]")
75
95
 
@@ -0,0 +1,120 @@
1
+ """Auto-detection of a running local LLM server on first launch.
2
+
3
+ Drydock's product pitch is "works out of the box with vLLM/Ollama/LM Studio/
4
+ llama.cpp — no API key required." That promise was broken for fresh installs:
5
+ the default `active_model` was the Mistral cloud devstral-2, which fired a
6
+ `MissingAPIKeyError` and dropped the user into the onboarding flow. Users who
7
+ already had a local server running still had to walk through the onboarding
8
+ screens.
9
+
10
+ This module probes the four common local-LLM endpoints with a short
11
+ HTTP timeout. If any responds with an OpenAI-compatible `/models` listing,
12
+ we capture the api_base and the first model id, and the bootstrap path
13
+ writes a config that points at it directly. Net effect: a user with a
14
+ running local server gets a working drydock on first launch with zero
15
+ prompts.
16
+
17
+ The probe is kept dependency-free (stdlib `urllib`) so it cannot break
18
+ on import in environments where `httpx`/`requests` aren't yet installed.
19
+ """
20
+ from __future__ import annotations
21
+
22
+ import json
23
+ import urllib.error
24
+ import urllib.request
25
+ from dataclasses import dataclass
26
+
27
+
28
+ # (label, api_base) — order matters: try most-likely first.
29
+ # We try llama-server first (per the upstream PRD draft's recommended
30
+ # Q3_K_M setup), then Ollama (largest install base of the four), then
31
+ # vLLM (drydock's own dev stack), then LM Studio.
32
+ _CANDIDATE_ENDPOINTS: list[tuple[str, str]] = [
33
+ ("llama.cpp", "http://127.0.0.1:8080/v1"),
34
+ ("Ollama", "http://127.0.0.1:11434/v1"),
35
+ ("vLLM", "http://127.0.0.1:8000/v1"),
36
+ ("LM Studio", "http://127.0.0.1:1234/v1"),
37
+ ]
38
+
39
+ _PER_REQUEST_TIMEOUT_S = 0.8
40
+
41
+
42
+ @dataclass(frozen=True)
43
+ class LocalServerInfo:
44
+ label: str # "vLLM" / "Ollama" / etc — informational only
45
+ api_base: str # full URL ending in /v1
46
+ model_name: str # first model id reported by the server
47
+
48
+
49
+ def detect_local_llm() -> LocalServerInfo | None:
50
+ """Probe the candidate endpoints; return the first one that answers.
51
+
52
+ A "good" response is HTTP 200 from `<api_base>/models` returning JSON
53
+ of the form `{"data": [{"id": "..."}, ...]}` (the OpenAI standard).
54
+ Servers that don't expose this (e.g. raw Ollama on port 11434/api/*)
55
+ are skipped — drydock needs the OpenAI-compatible surface anyway.
56
+
57
+ Total worst-case wall time: ~3.2 s when all four endpoints are
58
+ unreachable. In practice each socket connect to a closed port fails
59
+ in single-digit ms, so an "all-miss" probe is typically <50 ms.
60
+ """
61
+ for label, api_base in _CANDIDATE_ENDPOINTS:
62
+ info = _probe_one(label, api_base)
63
+ if info is not None:
64
+ return info
65
+ return None
66
+
67
+
68
+ def _probe_one(label: str, api_base: str) -> LocalServerInfo | None:
69
+ url = f"{api_base.rstrip('/')}/models"
70
+ req = urllib.request.Request(url, method="GET")
71
+ try:
72
+ with urllib.request.urlopen(req, timeout=_PER_REQUEST_TIMEOUT_S) as resp:
73
+ if resp.status != 200:
74
+ return None
75
+ payload = json.loads(resp.read().decode("utf-8", errors="replace"))
76
+ except (urllib.error.URLError, OSError, ValueError, TimeoutError):
77
+ return None
78
+
79
+ models = payload.get("data") if isinstance(payload, dict) else None
80
+ if not isinstance(models, list) or not models:
81
+ return None
82
+
83
+ first = models[0]
84
+ if not isinstance(first, dict):
85
+ return None
86
+ model_name = first.get("id")
87
+ if not isinstance(model_name, str) or not model_name:
88
+ return None
89
+
90
+ return LocalServerInfo(label=label, api_base=api_base, model_name=model_name)
91
+
92
+
93
+ def patch_config_for_local(
94
+ config: dict, info: LocalServerInfo
95
+ ) -> None:
96
+ """Mutate a default-config dict in place so the detected local server
97
+ is the active model.
98
+
99
+ Strategy: keep the existing `llamacpp` provider entry but point it at
100
+ the detected api_base, and update the `local` model's name to the
101
+ detected model id. Set `active_model = "local"`. This preserves the
102
+ rest of the user's config (other providers, models, settings) — we
103
+ only touch the entries that matter for the local path.
104
+ """
105
+ config["active_model"] = "local"
106
+
107
+ providers = config.get("providers")
108
+ if isinstance(providers, list):
109
+ for provider in providers:
110
+ if isinstance(provider, dict) and provider.get("name") == "llamacpp":
111
+ provider["api_base"] = info.api_base
112
+ # api_key_env_var stays empty — local server doesn't need one
113
+ break
114
+
115
+ models = config.get("models")
116
+ if isinstance(models, list):
117
+ for model in models:
118
+ if isinstance(model, dict) and model.get("alias") == "local":
119
+ model["name"] = info.model_name
120
+ break
@@ -547,6 +547,15 @@ class Bash(
547
547
  _is_heredoc_write = bool(_re.search(
548
548
  r"cat\s+<<\s*['\"]?EOF['\"]?\s+>", args.command
549
549
  ))
550
+ # Detect echo -e / printf with \n or \t escape sequences.
551
+ # These loops when the shell doesn't interpret the escapes
552
+ # (e.g. dash ignores echo -e; backslash doubling in quoting
553
+ # turns \t into literal \t instead of a tab). The generic
554
+ # "EDIT SOURCE CODE" hint is wrong here — the model needs
555
+ # to use $'...' quoting or write_file instead.
556
+ _is_echo_escape = bool(_re.search(
557
+ r'(?:echo\s+.*-[eE]|printf)\b', args.command
558
+ ) and _re.search(r'\\[nt]', args.command))
550
559
  if _is_heredoc_write:
551
560
  notice = (
552
561
  f"[NOTICE: this is the #{entry['count']}th identical "
@@ -558,6 +567,19 @@ class Bash(
558
567
  f"then fix it with write_file or search_replace with "
559
568
  f"CORRECTED content. Do NOT re-run this cat command.]"
560
569
  )
570
+ elif _is_echo_escape:
571
+ notice = (
572
+ f"[NOTICE: this is the #{entry['count']}th identical "
573
+ f"run of `{cmd_preview}` — escape sequences (\\n, \\t) "
574
+ f"in echo -e / printf are NOT being interpreted correctly. "
575
+ f"This shell may be /bin/sh (dash) where echo -e is a "
576
+ f"no-op, or backslash doubling in quoting is consuming "
577
+ f"the escape. "
578
+ f"Use ANSI $'...' quoting: printf $'name\\\\tage\\\\n' "
579
+ f"OR use Python: python3 -c \"print('name\\\\tage')\" "
580
+ f"OR use write_file to create the test file directly. "
581
+ f"Do NOT re-run this command unchanged.]"
582
+ )
561
583
  else:
562
584
  notice = (
563
585
  f"[NOTICE: this is the #{entry['count']} identical "
@@ -565,6 +565,38 @@ class SearchReplace(
565
565
  # "edited successfully (+0 lines)" path for this structural no-op.
566
566
  noop_blocks = [b for b in search_replace_blocks if b.search == b.replace]
567
567
  if noop_blocks:
568
+ noop_state = self.state.__dict__.setdefault("_sr_noop_history", {})
569
+ noop_key = str(file_path)
570
+ noop_entry = noop_state.get(noop_key, {"count": 0})
571
+ noop_entry["count"] += 1
572
+ noop_state[noop_key] = noop_entry
573
+ noop_count = noop_entry["count"]
574
+ if noop_count >= 2:
575
+ try:
576
+ body = original_content[:3000]
577
+ tail = (
578
+ f"\n...[truncated, {original_content.count(chr(10))} lines total]"
579
+ if len(original_content) > 3000 else ""
580
+ )
581
+ extra = (
582
+ f"\n\n[HARD-STOP: #{noop_count} consecutive SEARCH==REPLACE no-op "
583
+ f"on {file_path.name}. Your SEARCH and REPLACE blocks are still "
584
+ f"byte-identical — this call can never change anything. "
585
+ f"DO NOT retry search_replace on this file again. "
586
+ f"REQUIRED: call write_file with overwrite=True and the complete "
587
+ f"corrected file content. Current file:\n"
588
+ f"-----FILE START-----\n{body}{tail}\n-----FILE END-----]"
589
+ )
590
+ except Exception:
591
+ extra = (
592
+ f"\n\n[HARD-STOP: #{noop_count} consecutive SEARCH==REPLACE no-op "
593
+ f"on {file_path.name}. Stop retrying. Use write_file overwrite=True.]"
594
+ )
595
+ else:
596
+ extra = (
597
+ f" Re-read the file with read_file, identify what you actually need "
598
+ f"to change, and send a corrected SEARCH/REPLACE block."
599
+ )
568
600
  yield SearchReplaceResult(
569
601
  file=str(file_path),
570
602
  blocks_applied=0,
@@ -572,9 +604,7 @@ class SearchReplace(
572
604
  warnings=[],
573
605
  content=(
574
606
  f"{file_path.name}: ALREADY CORRECT — the SEARCH and REPLACE text "
575
- f"are byte-identical, so this block can never make any change. "
576
- f"Re-read the file with read_file, identify what you actually need "
577
- f"to change, and send a corrected SEARCH/REPLACE block."
607
+ f"are byte-identical, so this block can never make any change.{extra}"
578
608
  ),
579
609
  )
580
610
  return
@@ -0,0 +1,46 @@
1
+ """GraphRAG — persistent context module for Drydock Sovereign v2.
2
+
3
+ A first-class deployable module per the SOVEREIGN_PRD. Phase-2 deliverable.
4
+
5
+ This first cut focuses on the two highest-volume failure shapes from
6
+ TRIAGE_v1.md:
7
+
8
+ 1. **Code graph** — symbol → definition site lookup, including parent-class
9
+ chains across packages. Mitigates pattern 4 (inheritance blindness:
10
+ model reads `flask/wrappers.py` 13× looking for `is_json` when the
11
+ answer is in werkzeug's parent class).
12
+
13
+ 2. **Project memory** — chunked markdown / text retrieval with citations.
14
+ Mitigates pattern 10c (multi-module rewrites exceed working-memory
15
+ budget) by giving the model a way to recall PRD goals and per-module
16
+ contracts across sessions.
17
+
18
+ Local-only by design: SQLite storage, stdlib + scikit-learn for TF-IDF
19
+ (swap-in for embeddings is a v1 concern). No remote services.
20
+
21
+ Public surface:
22
+ from drydock.graphrag import Index, retrieve_symbols, retrieve_text
23
+ from drydock.graphrag.retriever import Retriever, RetrievalResult
24
+
25
+ CLI entry point:
26
+ python -m drydock.graphrag ingest <path>
27
+ python -m drydock.graphrag query <text>
28
+ python -m drydock.graphrag symbols <name>
29
+ """
30
+ from __future__ import annotations
31
+
32
+ from drydock.graphrag.retriever import (
33
+ RetrievalResult,
34
+ Retriever,
35
+ SymbolHit,
36
+ TextHit,
37
+ )
38
+ from drydock.graphrag.storage import Index
39
+
40
+ __all__ = [
41
+ "Index",
42
+ "Retriever",
43
+ "RetrievalResult",
44
+ "SymbolHit",
45
+ "TextHit",
46
+ ]
@@ -0,0 +1,121 @@
1
+ """GraphRAG CLI — `python -m drydock.graphrag <subcommand>`.
2
+
3
+ Subcommands:
4
+
5
+ ingest <path> Walk the path, index .py + .md/.txt into the DB.
6
+ query <text> Run a retrieval and print symbol+text hits.
7
+ symbol <name> Look up a class/function by name or qualname.
8
+ chain <qualname> Walk the inheritance chain for a class.
9
+ stats Show counts.
10
+
11
+ Default DB path: $DRYDOCK_GRAPHRAG_DB or ~/.drydock/graphrag.sqlite
12
+ """
13
+ from __future__ import annotations
14
+
15
+ import argparse
16
+ import os
17
+ import sys
18
+ from pathlib import Path
19
+
20
+ from drydock.graphrag.storage import Index
21
+
22
+
23
+ def _default_db_path() -> str:
24
+ env = os.environ.get("DRYDOCK_GRAPHRAG_DB")
25
+ if env:
26
+ return env
27
+ return str(Path.home() / ".drydock" / "graphrag.sqlite")
28
+
29
+
30
+ def _build_parser() -> argparse.ArgumentParser:
31
+ p = argparse.ArgumentParser(
32
+ prog="drydock.graphrag",
33
+ description="GraphRAG: code-graph + text retrieval for Drydock.",
34
+ )
35
+ p.add_argument(
36
+ "--db",
37
+ default=_default_db_path(),
38
+ help="SQLite path (default: $DRYDOCK_GRAPHRAG_DB or ~/.drydock/graphrag.sqlite)",
39
+ )
40
+ sub = p.add_subparsers(dest="cmd", required=True)
41
+
42
+ sp_ingest = sub.add_parser("ingest", help="Index a directory or file")
43
+ sp_ingest.add_argument("path", help="Path to a project root or single file")
44
+
45
+ sp_query = sub.add_parser("query", help="Retrieve mixed symbol+text hits")
46
+ sp_query.add_argument("text", nargs="+", help="Query text")
47
+ sp_query.add_argument("--text-limit", type=int, default=5)
48
+ sp_query.add_argument("--symbol-limit", type=int, default=5)
49
+
50
+ sp_sym = sub.add_parser("symbol", help="Look up a symbol by name")
51
+ sp_sym.add_argument("name")
52
+ sp_sym.add_argument("--limit", type=int, default=10)
53
+
54
+ sp_chain = sub.add_parser(
55
+ "chain", help="Walk the inheritance chain for a class"
56
+ )
57
+ sp_chain.add_argument("qualname")
58
+
59
+ sub.add_parser("stats", help="Show DB counts")
60
+
61
+ return p
62
+
63
+
64
+ def main(argv: list[str] | None = None) -> int:
65
+ args = _build_parser().parse_args(argv)
66
+ idx = Index(args.db)
67
+
68
+ if args.cmd == "ingest":
69
+ counts = idx.ingest_path(args.path)
70
+ print(
71
+ f"Ingested {counts['files']} files: "
72
+ f"{counts['symbols']} symbols, {counts['chunks']} text chunks."
73
+ )
74
+ print(f"DB: {args.db}")
75
+ return 0
76
+
77
+ if args.cmd == "query":
78
+ query_text = " ".join(args.text)
79
+ result = idx.retrieve(
80
+ query_text,
81
+ symbol_limit=args.symbol_limit,
82
+ text_limit=args.text_limit,
83
+ )
84
+ print(result.format())
85
+ return 0 if not result.is_empty() else 1
86
+
87
+ if args.cmd == "symbol":
88
+ hits = idx.find_symbol(args.name)[: args.limit]
89
+ if not hits:
90
+ print(f"No symbol found for '{args.name}'.")
91
+ return 1
92
+ for h in hits:
93
+ print(h.format())
94
+ return 0
95
+
96
+ if args.cmd == "chain":
97
+ chain = idx.inheritance_chain(args.qualname)
98
+ if not chain:
99
+ print(f"No class found for '{args.qualname}'.")
100
+ return 1
101
+ for i, h in enumerate(chain):
102
+ indent = " " * i
103
+ arrow = "" if i == 0 else "↳ "
104
+ print(f"{indent}{arrow}{h.format()}")
105
+ return 0
106
+
107
+ if args.cmd == "stats":
108
+ s = idx.stats()
109
+ print(
110
+ f"symbols: {s['symbols']}\n"
111
+ f"text chunks: {s['chunks']}\n"
112
+ f"unique terms: {s['unique_terms']}\n"
113
+ f"DB: {args.db}"
114
+ )
115
+ return 0
116
+
117
+ return 1
118
+
119
+
120
+ if __name__ == "__main__":
121
+ sys.exit(main())
@@ -0,0 +1,213 @@
1
+ """AST-based code symbol indexer — extracts class/function/method defs
2
+ with parent-class info and qualified names.
3
+
4
+ Scope choice: stdlib `ast` only. We don't try to evaluate annotations or
5
+ follow imports across files at index time — that's a v1 problem. What we
6
+ DO record is enough to mitigate pattern 4 from MODEL_SHORTCOMINGS:
7
+
8
+ Q: where is `is_json` defined?
9
+ A: werkzeug/wrappers/request.py:412 (method on Request class)
10
+
11
+ Q: what does flask.wrappers.Request inherit from?
12
+ A: ['werkzeug.wrappers.Request', 'JSONMixin']
13
+
14
+ The indexer walks .py files, extracts defs with `Visit*` AST visitors,
15
+ and yields `SymbolRecord` entries. Storage layer (`storage.py`) writes
16
+ these to SQLite.
17
+ """
18
+ from __future__ import annotations
19
+
20
+ import ast
21
+ from dataclasses import dataclass, field
22
+ from pathlib import Path
23
+ from typing import Iterator
24
+
25
+
26
+ # Files we never index (vendored, generated, junk).
27
+ _SKIP_DIR_NAMES = frozenset({
28
+ "__pycache__", ".git", ".venv", "venv", "node_modules",
29
+ ".tox", "dist", "build", ".mypy_cache", ".pytest_cache",
30
+ "site-packages", # avoid indexing installed packages
31
+ ".eggs", "egg-info",
32
+ })
33
+
34
+ _MAX_FILE_BYTES = 1_000_000 # skip giant generated files
35
+
36
+
37
+ @dataclass
38
+ class SymbolRecord:
39
+ """One indexed symbol — flat shape, ready to write to SQLite."""
40
+ name: str
41
+ qualname: str
42
+ kind: str # "class" | "function" | "method"
43
+ file: str # absolute path
44
+ line: int # 1-based
45
+ end_line: int # 1-based, inclusive
46
+ parents: list[str] = field(default_factory=list)
47
+ docstring: str = ""
48
+
49
+ @property
50
+ def citation_id(self) -> str:
51
+ return f"{self.file}:{self.line}"
52
+
53
+
54
+ def index_path(root: str | Path) -> Iterator[SymbolRecord]:
55
+ """Walk `root` recursively, yield a SymbolRecord per def found.
56
+
57
+ `root` may be a single file or a directory. Symlinks and skip-dirs
58
+ are pruned. Parse errors on individual files are swallowed (we yield
59
+ nothing for that file and continue).
60
+ """
61
+ root = Path(root).resolve()
62
+ if root.is_file() and root.suffix == ".py":
63
+ yield from _index_file(root)
64
+ return
65
+ if not root.is_dir():
66
+ return
67
+
68
+ for path in _walk_python_files(root):
69
+ try:
70
+ yield from _index_file(path)
71
+ except (SyntaxError, ValueError, UnicodeDecodeError):
72
+ # Index what we can; skip what we can't parse.
73
+ continue
74
+
75
+
76
+ def _walk_python_files(root: Path) -> Iterator[Path]:
77
+ stack: list[Path] = [root]
78
+ while stack:
79
+ current = stack.pop()
80
+ try:
81
+ entries = list(current.iterdir())
82
+ except (PermissionError, OSError):
83
+ continue
84
+ for entry in entries:
85
+ if entry.is_symlink():
86
+ continue
87
+ if entry.is_dir():
88
+ if entry.name in _SKIP_DIR_NAMES or entry.name.startswith("."):
89
+ continue
90
+ stack.append(entry)
91
+ elif entry.suffix == ".py" and entry.is_file():
92
+ try:
93
+ if entry.stat().st_size > _MAX_FILE_BYTES:
94
+ continue
95
+ except OSError:
96
+ continue
97
+ yield entry
98
+
99
+
100
+ def _index_file(path: Path) -> Iterator[SymbolRecord]:
101
+ text = path.read_text(encoding="utf-8", errors="replace")
102
+ tree = ast.parse(text, filename=str(path))
103
+ module_qualname = _module_qualname_for(path)
104
+ # Build the file's import alias map so base classes can be resolved
105
+ # to their canonical qualname (`from werkzeug.wrappers import Request
106
+ # as WR` → `WR -> werkzeug.wrappers.Request`).
107
+ alias_map = _build_alias_map(tree)
108
+ yield from _walk_node(tree, path, module_qualname, [], alias_map)
109
+
110
+
111
+ def _build_alias_map(tree: ast.AST) -> dict[str, str]:
112
+ """Walk top-level `Import` / `ImportFrom` nodes and build the
113
+ {local_name: canonical_qualname} map. Only top-level imports — we
114
+ don't trace conditional/function-local imports (rare and usually
115
+ not load-bearing for class hierarchies)."""
116
+ alias_map: dict[str, str] = {}
117
+ for node in ast.iter_child_nodes(tree):
118
+ if isinstance(node, ast.Import):
119
+ for alias in node.names:
120
+ local = alias.asname or alias.name.split(".")[0]
121
+ # `import a.b.c` → local "a" → canonical "a.b.c"? No —
122
+ # use the full dotted name as the canonical for `as`
123
+ # cases, otherwise the bare name.
124
+ canonical = alias.asname and alias.name or alias.name
125
+ alias_map[local] = canonical
126
+ elif isinstance(node, ast.ImportFrom):
127
+ module = node.module or ""
128
+ for alias in node.names:
129
+ local = alias.asname or alias.name
130
+ canonical = f"{module}.{alias.name}" if module else alias.name
131
+ alias_map[local] = canonical
132
+ return alias_map
133
+
134
+
135
+ def _walk_node(
136
+ node: ast.AST,
137
+ file: Path,
138
+ module_qualname: str,
139
+ qual_stack: list[str],
140
+ alias_map: dict[str, str],
141
+ ) -> Iterator[SymbolRecord]:
142
+ """Recursive AST walk. `qual_stack` is the chain of enclosing class /
143
+ function names so we can build qualified names like
144
+ `Foo.bar.helper` for nested defs."""
145
+ for child in ast.iter_child_nodes(node):
146
+ if isinstance(child, ast.ClassDef):
147
+ inner_qual = qual_stack + [child.name]
148
+ raw_parents = [_unparse(b) for b in child.bases]
149
+ resolved = [alias_map.get(p, p) for p in raw_parents]
150
+ yield SymbolRecord(
151
+ name=child.name,
152
+ qualname=_join_qual(module_qualname, inner_qual),
153
+ kind="class",
154
+ file=str(file),
155
+ line=child.lineno,
156
+ end_line=getattr(child, "end_lineno", child.lineno),
157
+ parents=resolved,
158
+ docstring=ast.get_docstring(child) or "",
159
+ )
160
+ yield from _walk_node(child, file, module_qualname, inner_qual, alias_map)
161
+ elif isinstance(child, (ast.FunctionDef, ast.AsyncFunctionDef)):
162
+ inner_qual = qual_stack + [child.name]
163
+ kind = "method" if (qual_stack and qual_stack[-1][0].isupper()) else "function"
164
+ yield SymbolRecord(
165
+ name=child.name,
166
+ qualname=_join_qual(module_qualname, inner_qual),
167
+ kind=kind,
168
+ file=str(file),
169
+ line=child.lineno,
170
+ end_line=getattr(child, "end_lineno", child.lineno),
171
+ parents=[],
172
+ docstring=ast.get_docstring(child) or "",
173
+ )
174
+ yield from _walk_node(child, file, module_qualname, inner_qual, alias_map)
175
+ else:
176
+ yield from _walk_node(child, file, module_qualname, qual_stack, alias_map)
177
+
178
+
179
+ def _module_qualname_for(file: Path) -> str:
180
+ """Best-effort module qualname. Uses `__init__.py` walks to detect
181
+ packages; falls back to the bare stem if we can't tell."""
182
+ parts: list[str] = [file.stem if file.stem != "__init__" else ""]
183
+ parent = file.parent
184
+ while parent != parent.parent:
185
+ if (parent / "__init__.py").is_file():
186
+ parts.insert(0, parent.name)
187
+ parent = parent.parent
188
+ else:
189
+ break
190
+ return ".".join(p for p in parts if p)
191
+
192
+
193
+ def _join_qual(module_qualname: str, parts: list[str]) -> str:
194
+ chain = ".".join(parts)
195
+ if module_qualname:
196
+ return f"{module_qualname}.{chain}" if chain else module_qualname
197
+ return chain
198
+
199
+
200
+ def _unparse(node: ast.AST) -> str:
201
+ """Best-effort string rendering of an AST node (Python 3.9+ has
202
+ ast.unparse). Used for base-class names."""
203
+ try:
204
+ return ast.unparse(node)
205
+ except Exception:
206
+ if isinstance(node, ast.Name):
207
+ return node.id
208
+ if isinstance(node, ast.Attribute):
209
+ try:
210
+ return f"{_unparse(node.value)}.{node.attr}"
211
+ except Exception:
212
+ return node.attr
213
+ return "<unparseable>"