drydock-cli 2.6.136__tar.gz → 2.6.138__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 (613) hide show
  1. drydock_cli-2.6.138/Admiral.md +186 -0
  2. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/PKG-INFO +1 -1
  3. drydock_cli-2.6.138/drydock/admiral/__init__.py +15 -0
  4. drydock_cli-2.6.138/drydock/admiral/detectors.py +104 -0
  5. drydock_cli-2.6.138/drydock/admiral/history.py +23 -0
  6. drydock_cli-2.6.138/drydock/admiral/interventions.py +21 -0
  7. drydock_cli-2.6.138/drydock/admiral/worker.py +93 -0
  8. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/app.py +9 -0
  9. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/messages.py +53 -23
  10. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/pyproject.toml +1 -1
  11. drydock_cli-2.6.138/tests/test_admiral.py +75 -0
  12. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.claude/scheduled_tasks.lock +0 -0
  13. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/CODEOWNERS +0 -0
  14. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  15. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  16. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  17. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/workflows/build-and-upload.yml +0 -0
  18. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/workflows/ci.yml +0 -0
  19. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/workflows/issue-labeler.yml +0 -0
  20. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.github/workflows/release.yml +0 -0
  21. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.gitignore +0 -0
  22. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.pre-commit-config.yaml +0 -0
  23. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.python-version +0 -0
  24. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.typos.toml +0 -0
  25. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.vscode/extensions.json +0 -0
  26. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.vscode/launch.json +0 -0
  27. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/.vscode/settings.json +0 -0
  28. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/AGENTS.md +0 -0
  29. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/BASELINE_412.md +0 -0
  30. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/CHANGELOG.md +0 -0
  31. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/CLAUDE.md +0 -0
  32. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/CONTRIBUTING.md +0 -0
  33. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/Drydock_rebrand.md +0 -0
  34. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/LICENSE +0 -0
  35. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/MODEL_SHORTCOMINGS.md +0 -0
  36. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/NOTICE +0 -0
  37. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
  38. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/PRD.md +0 -0
  39. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/README.md +0 -0
  40. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/action.yml +0 -0
  41. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/README.md +0 -0
  42. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results1.tsv +0 -0
  43. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results13.tsv +0 -0
  44. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results14.tsv +0 -0
  45. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results15.tsv +0 -0
  46. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results16.tsv +0 -0
  47. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results17.tsv +0 -0
  48. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results18.tsv +0 -0
  49. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results19.tsv +0 -0
  50. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results2.tsv +0 -0
  51. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results20.tsv +0 -0
  52. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results3.tsv +0 -0
  53. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results4.tsv +0 -0
  54. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results5.tsv +0 -0
  55. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results6.tsv +0 -0
  56. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results7.tsv +0 -0
  57. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results8.tsv +0 -0
  58. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results9.tsv +0 -0
  59. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/baseline_history/results_evolved_v1.tsv +0 -0
  60. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/distribution/zed/LICENSE +0 -0
  61. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/distribution/zed/extension.toml +0 -0
  62. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/distribution/zed/icons/mistral_vibe.svg +0 -0
  63. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/docs/README.md +0 -0
  64. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/docs/acp-setup.md +0 -0
  65. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/docs/proxy-setup.md +0 -0
  66. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/__init__.py +0 -0
  67. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/__init__.py +0 -0
  68. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/acp_agent_loop.py +0 -0
  69. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/acp_logger.py +0 -0
  70. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/entrypoint.py +0 -0
  71. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/__init__.py +0 -0
  72. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/base.py +0 -0
  73. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/bash.py +0 -0
  74. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/read_file.py +0 -0
  75. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/search_replace.py +0 -0
  76. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/todo.py +0 -0
  77. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/builtins/write_file.py +0 -0
  78. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/tools/session_update.py +0 -0
  79. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/acp/utils.py +0 -0
  80. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/__init__.py +0 -0
  81. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/autocompletion/__init__.py +0 -0
  82. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/autocompletion/base.py +0 -0
  83. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/autocompletion/path_completion.py +0 -0
  84. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/autocompletion/slash_command.py +0 -0
  85. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/cli.py +0 -0
  86. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/clipboard.py +0 -0
  87. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/commands.py +0 -0
  88. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/entrypoint.py +0 -0
  89. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/history_manager.py +0 -0
  90. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
  91. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
  92. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
  93. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/terminal_setup.py +0 -0
  94. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/__init__.py +0 -0
  95. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
  96. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/app.tcss +0 -0
  97. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/external_editor.py +0 -0
  98. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
  99. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
  100. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
  101. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
  102. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
  103. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
  104. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
  105. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
  106. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
  107. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
  108. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
  109. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
  110. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
  111. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
  112. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
  113. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
  114. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
  115. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
  116. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
  117. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/compact.py +0 -0
  118. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
  119. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
  120. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
  121. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/loading.py +0 -0
  122. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
  123. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
  124. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
  125. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
  126. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
  127. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
  128. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
  129. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
  130. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
  131. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/tools.py +0 -0
  132. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
  133. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
  134. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/windowing/history.py +0 -0
  135. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
  136. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/textual_ui/windowing/state.py +0 -0
  137. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/__init__.py +0 -0
  138. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
  139. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
  140. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
  141. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
  142. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
  143. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/update.py +0 -0
  144. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/cli/update_notifier/whats_new.py +0 -0
  145. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/__init__.py +0 -0
  146. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/agent_loop.py +0 -0
  147. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/agents/__init__.py +0 -0
  148. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/agents/manager.py +0 -0
  149. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/agents/models.py +0 -0
  150. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/auth/__init__.py +0 -0
  151. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/auth/crypto.py +0 -0
  152. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/auth/github.py +0 -0
  153. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/__init__.py +0 -0
  154. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/completers.py +0 -0
  155. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
  156. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
  157. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
  158. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/store.py +0 -0
  159. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
  160. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/fuzzy.py +0 -0
  161. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/path_prompt.py +0 -0
  162. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
  163. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/build_orchestrator.py +0 -0
  164. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/checkpoint.py +0 -0
  165. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/__init__.py +0 -0
  166. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/_settings.py +0 -0
  167. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/doctor.py +0 -0
  168. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/harness_files/__init__.py +0 -0
  169. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/harness_files/_harness_manager.py +0 -0
  170. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/config/harness_files/_paths.py +0 -0
  171. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/consultant.py +0 -0
  172. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/drydock_states.py +0 -0
  173. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/hooks.py +0 -0
  174. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/__init__.py +0 -0
  175. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/anthropic.py +0 -0
  176. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/base.py +0 -0
  177. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/factory.py +0 -0
  178. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/generic.py +0 -0
  179. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/mistral.py +0 -0
  180. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
  181. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/backend/vertex.py +0 -0
  182. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/exceptions.py +0 -0
  183. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/format.py +0 -0
  184. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/message_utils.py +0 -0
  185. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/llm/types.py +0 -0
  186. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/logger.py +0 -0
  187. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/middleware.py +0 -0
  188. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/output_formatters.py +0 -0
  189. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/paths/__init__.py +0 -0
  190. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/paths/_local_config_walk.py +0 -0
  191. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/paths/_vibe_home.py +0 -0
  192. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/paths/conventions.py +0 -0
  193. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/plan_session.py +0 -0
  194. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/plugins.py +0 -0
  195. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/programmatic.py +0 -0
  196. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/__init__.py +0 -0
  197. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/builder.md +0 -0
  198. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/cli.md +0 -0
  199. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/compact.md +0 -0
  200. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/dangerous_directory.md +0 -0
  201. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/diagnostic.md +0 -0
  202. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/explore.md +0 -0
  203. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/gemma4.md +0 -0
  204. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/planner.md +0 -0
  205. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/project_context.md +0 -0
  206. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/prompts/tests.md +0 -0
  207. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/proxy_setup.py +0 -0
  208. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/agent_memory.py +0 -0
  209. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/checkpoints.py +0 -0
  210. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/session_loader.py +0 -0
  211. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/session_logger.py +0 -0
  212. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/session_migration.py +0 -0
  213. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session/state_file.py +0 -0
  214. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/session_checker.py +0 -0
  215. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/skills/__init__.py +0 -0
  216. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/skills/manager.py +0 -0
  217. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/skills/models.py +0 -0
  218. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/skills/parser.py +0 -0
  219. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/slug.py +0 -0
  220. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/system_prompt.py +0 -0
  221. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/telemetry/__init__.py +0 -0
  222. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/telemetry/send.py +0 -0
  223. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/errors.py +0 -0
  224. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/git.py +0 -0
  225. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/nuage.py +0 -0
  226. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/teleport.py +0 -0
  227. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/teleport/types.py +0 -0
  228. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/base.py +0 -0
  229. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/_task_manager.py +0 -0
  230. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/ask_user_question.py +0 -0
  231. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/bash.py +0 -0
  232. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/cron.py +0 -0
  233. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
  234. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/glob_tool.py +0 -0
  235. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/grep.py +0 -0
  236. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/invoke_skill.py +0 -0
  237. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/lsp.py +0 -0
  238. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/mcp_resources.py +0 -0
  239. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/notebook_edit.py +0 -0
  240. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/powershell.py +0 -0
  241. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
  242. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
  243. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/bash.md +0 -0
  244. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/cron.md +0 -0
  245. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/glob.md +0 -0
  246. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/grep.md +0 -0
  247. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
  248. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
  249. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
  250. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
  251. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
  252. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
  253. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
  254. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
  255. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/task.md +0 -0
  256. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
  257. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/todo.md +0 -0
  258. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
  259. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
  260. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
  261. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
  262. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
  263. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/read_file.py +0 -0
  264. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/search_replace.py +0 -0
  265. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/task.py +0 -0
  266. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/todo.py +0 -0
  267. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/tool_search.py +0 -0
  268. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/webfetch.py +0 -0
  269. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/websearch.py +0 -0
  270. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/worktree.py +0 -0
  271. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/builtins/write_file.py +0 -0
  272. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/injection_guard.py +0 -0
  273. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/manager.py +0 -0
  274. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/mcp/__init__.py +0 -0
  275. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/mcp/registry.py +0 -0
  276. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/mcp/tools.py +0 -0
  277. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/mcp_sampling.py +0 -0
  278. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/ui.py +0 -0
  279. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/tools/utils.py +0 -0
  280. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/trusted_folders.py +0 -0
  281. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/types.py +0 -0
  282. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/core/utils.py +0 -0
  283. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/__init__.py +0 -0
  284. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/base.py +0 -0
  285. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/onboarding.tcss +0 -0
  286. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/__init__.py +0 -0
  287. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/api_key.py +0 -0
  288. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/choice.py +0 -0
  289. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/local_model.py +0 -0
  290. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/onboarding/screens/welcome.py +0 -0
  291. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
  292. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
  293. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/__init__.py +0 -0
  294. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/api-design/SKILL.md +0 -0
  295. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/audit-tests/SKILL.md +0 -0
  296. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/batch/SKILL.md +0 -0
  297. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/commit-code/SKILL.md +0 -0
  298. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/context-summary/SKILL.md +0 -0
  299. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/create-presentation/SKILL.md +0 -0
  300. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/deep-research/SKILL.md +0 -0
  301. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/deploy/SKILL.md +0 -0
  302. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/diff-review/SKILL.md +0 -0
  303. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/doc-gen/SKILL.md +0 -0
  304. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/explain-code/SKILL.md +0 -0
  305. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/explore-code/SKILL.md +0 -0
  306. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/fix-issue/SKILL.md +0 -0
  307. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/git-ops/SKILL.md +0 -0
  308. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/init-project/SKILL.md +0 -0
  309. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/investigate/SKILL.md +0 -0
  310. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/loop/SKILL.md +0 -0
  311. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/migrate/SKILL.md +0 -0
  312. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/perf-analyze/SKILL.md +0 -0
  313. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/plan-impl/SKILL.md +0 -0
  314. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/pr-review/SKILL.md +0 -0
  315. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/refactor/SKILL.md +0 -0
  316. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/regex-help/SKILL.md +0 -0
  317. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/review/SKILL.md +0 -0
  318. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/security-review/SKILL.md +0 -0
  319. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/ship/SKILL.md +0 -0
  320. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/simplify/SKILL.md +0 -0
  321. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/strong-tests/SKILL.md +0 -0
  322. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/skills/test-verify/SKILL.md +0 -0
  323. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock/whats_new.md +0 -0
  324. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock-acp.spec +0 -0
  325. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/drydock_terms.md +0 -0
  326. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/flake.lock +0 -0
  327. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/flake.nix +0 -0
  328. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/README.md +0 -0
  329. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/audit_sampler.py +0 -0
  330. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/auto_generate_tests.py +0 -0
  331. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/auto_release.sh +0 -0
  332. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/auto_test_loop.sh +0 -0
  333. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/backup.sh +0 -0
  334. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/bump_version.py +0 -0
  335. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/comprehensive_loop.py +0 -0
  336. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/deploy_to_github.sh +0 -0
  337. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/discover_cli_tools.sh +0 -0
  338. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/evolve_tests.py +0 -0
  339. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/gen_2000_prompts.py +0 -0
  340. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/install.sh +0 -0
  341. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/llm_balancer.py +0 -0
  342. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/mega_loop.py +0 -0
  343. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/meta_ralph_loop.py +0 -0
  344. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/monitor_swebench.sh +0 -0
  345. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/monitor_test_battery.sh +0 -0
  346. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/notify_release.py +0 -0
  347. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/oss_task_harness.py +0 -0
  348. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/overnight_agents_test.sh +0 -0
  349. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/poll_issues.sh +0 -0
  350. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/port_task.py +0 -0
  351. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/prepare_release.py +0 -0
  352. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/publish_to_pypi.sh +0 -0
  353. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/ralph_loop.py +0 -0
  354. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/session_loop_audit.py +0 -0
  355. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown.py +0 -0
  356. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown_interactive.py +0 -0
  357. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown_regression.sh +0 -0
  358. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown_suite.sh +0 -0
  359. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/shakedown_variance.sh +0 -0
  360. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_prompts_50.txt +0 -0
  361. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_prompts_tool_agent.txt +0 -0
  362. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
  363. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_shakedown.py +0 -0
  364. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/stress_telegram_status.py +0 -0
  365. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/telegram_bot.py +0 -0
  366. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/test_bank.sh +0 -0
  367. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/test_full.sh +0 -0
  368. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/test_smoke.sh +0 -0
  369. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/test_tui_path.py +0 -0
  370. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/tui_test.py +0 -0
  371. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/scripts/vllm_failover.sh +0 -0
  372. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/__init__.py +0 -0
  373. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/conftest.py +0 -0
  374. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_acp.py +0 -0
  375. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_agent_thought.py +0 -0
  376. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_bash.py +0 -0
  377. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_compact_session_updates.py +0 -0
  378. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_content.py +0 -0
  379. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_initialize.py +0 -0
  380. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_list_sessions.py +0 -0
  381. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_load_session.py +0 -0
  382. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_multi_session.py +0 -0
  383. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_new_session.py +0 -0
  384. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_proxy_setup_acp.py +0 -0
  385. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_read_file.py +0 -0
  386. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_search_replace.py +0 -0
  387. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_set_config_option.py +0 -0
  388. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_set_mode.py +0 -0
  389. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_set_model.py +0 -0
  390. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_tool_call_session_update.py +0 -0
  391. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_utils.py +0 -0
  392. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/acp/test_write_file.py +0 -0
  393. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_file_indexer.py +0 -0
  394. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_fuzzy.py +0 -0
  395. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
  396. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_path_completer_recursive.py +0 -0
  397. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_path_completion_controller.py +0 -0
  398. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
  399. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_slash_command_controller.py +0 -0
  400. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
  401. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/__init__.py +0 -0
  402. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/data/__init__.py +0 -0
  403. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/data/fireworks.py +0 -0
  404. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/data/mistral.py +0 -0
  405. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/test_anthropic_adapter.py +0 -0
  406. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/test_backend.py +0 -0
  407. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/test_reasoning_adapter.py +0 -0
  408. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
  409. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
  410. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
  411. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
  412. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_bell_notifications.py +0 -0
  413. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_braille_renderer.py +0 -0
  414. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_clipboard.py +0 -0
  415. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_commands.py +0 -0
  416. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_copy_shortcuts.py +0 -0
  417. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_external_editor.py +0 -0
  418. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_no_markup_static.py +0 -0
  419. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_question_app.py +0 -0
  420. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_spinner.py +0 -0
  421. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_switching_mode.py +0 -0
  422. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_ui_clipboard_notifications.py +0 -0
  423. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
  424. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_ui_session_resume.py +0 -0
  425. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/test_ui_skill_dispatch.py +0 -0
  426. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/textual_ui/__init__.py +0 -0
  427. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/cli/textual_ui/test_session_picker.py +0 -0
  428. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/conftest.py +0 -0
  429. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_agents.py +0 -0
  430. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_auth_crypto.py +0 -0
  431. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_auth_github.py +0 -0
  432. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_config_load_dotenv.py +0 -0
  433. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_config_paths.py +0 -0
  434. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_config_resolution.py +0 -0
  435. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_file_logging.py +0 -0
  436. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_plan_session.py +0 -0
  437. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_proxy_setup.py +0 -0
  438. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_slug.py +0 -0
  439. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_telemetry_send.py +0 -0
  440. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_teleport_git.py +0 -0
  441. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_teleport_nuage.py +0 -0
  442. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_teleport_service.py +0 -0
  443. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_trusted_folders.py +0 -0
  444. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/core/test_utils.py +0 -0
  445. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/common.py +0 -0
  446. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/conftest.py +0 -0
  447. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/mock_server.py +0 -0
  448. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/test_cli_tui_onboarding.py +0 -0
  449. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/test_cli_tui_streaming.py +0 -0
  450. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
  451. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/fixtures/doc_qa_system_prd.md +0 -0
  452. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/mock/__init__.py +0 -0
  453. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/mock/mock_backend_factory.py +0 -0
  454. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/mock/mock_entrypoint.py +0 -0
  455. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/mock/utils.py +0 -0
  456. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/onboarding/test_run_onboarding.py +0 -0
  457. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/onboarding/test_ui_onboarding.py +0 -0
  458. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/session/test_session_loader.py +0 -0
  459. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/session/test_session_logger.py +0 -0
  460. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/session/test_session_migration.py +0 -0
  461. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/skills/conftest.py +0 -0
  462. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/skills/test_manager.py +0 -0
  463. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/skills/test_models.py +0 -0
  464. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/skills/test_parser.py +0 -0
  465. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
  466. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
  467. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
  468. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
  469. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
  470. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
  471. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
  472. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
  473. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
  474. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
  475. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
  476. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
  477. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
  478. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
  479. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
  480. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
  481. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
  482. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
  483. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
  484. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
  485. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
  486. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
  487. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
  488. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
  489. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
  490. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
  491. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
  492. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
  493. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
  494. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
  495. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
  496. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
  497. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
  498. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
  499. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
  500. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
  501. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
  502. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
  503. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
  504. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
  505. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
  506. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
  507. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
  508. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
  509. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
  510. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
  511. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
  512. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
  513. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
  514. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
  515. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
  516. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
  517. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
  518. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
  519. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
  520. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
  521. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
  522. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
  523. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
  524. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
  525. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/base_snapshot_test_app.py +0 -0
  526. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/conftest.py +0 -0
  527. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/snap_compare.py +0 -0
  528. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
  529. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
  530. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
  531. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
  532. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
  533. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
  534. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
  535. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
  536. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
  537. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
  538. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
  539. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
  540. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
  541. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
  542. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/stubs/fake_backend.py +0 -0
  543. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/stubs/fake_client.py +0 -0
  544. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/stubs/fake_tool.py +0 -0
  545. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_auto_compact.py +0 -0
  546. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_backend.py +0 -0
  547. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_observer_streaming.py +0 -0
  548. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_stats.py +0 -0
  549. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_tasks.py +0 -0
  550. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agent_tool_call.py +0 -0
  551. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_agents.py +0 -0
  552. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_build.py +0 -0
  553. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_debug.py +0 -0
  554. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_multiagent.py +0 -0
  555. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_prd.py +0 -0
  556. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_prd_extended.py +0 -0
  557. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_tools.py +0 -0
  558. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_bank_update.py +0 -0
  559. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_build_projects.py +0 -0
  560. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_checkpoint.py +0 -0
  561. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_cli_programmatic_preload.py +0 -0
  562. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_current_bugs.py +0 -0
  563. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_drydock_regression.py +0 -0
  564. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_drydock_tasks.py +0 -0
  565. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_full_regression.py +0 -0
  566. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_history_manager.py +0 -0
  567. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_integration.py +0 -0
  568. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_issue_fixes.py +0 -0
  569. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_loop_detection.py +0 -0
  570. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_message_id.py +0 -0
  571. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_message_merging.py +0 -0
  572. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_middleware.py +0 -0
  573. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_multi_agent.py +0 -0
  574. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_real_failures.py +0 -0
  575. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_real_issues.py +0 -0
  576. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_real_workflow.py +0 -0
  577. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_reasoning_content.py +0 -0
  578. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_smoke.py +0 -0
  579. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_system_prompt.py +0 -0
  580. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_tagged_text.py +0 -0
  581. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_tool_args.py +0 -0
  582. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_ui_external_editor.py +0 -0
  583. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_ui_input_history.py +0 -0
  584. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_user_issues.py +0 -0
  585. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/test_workloads.py +0 -0
  586. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/testbank_helpers.py +0 -0
  587. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_ask_user_question.py +0 -0
  588. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_bash.py +0 -0
  589. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_exit_plan_mode.py +0 -0
  590. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_grep.py +0 -0
  591. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_invoke_context.py +0 -0
  592. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_manager_get_tool_config.py +0 -0
  593. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_mcp.py +0 -0
  594. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_mcp_sampling.py +0 -0
  595. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_task.py +0 -0
  596. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_ui_bash_execution.py +0 -0
  597. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_webfetch.py +0 -0
  598. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/tools/test_websearch.py +0 -0
  599. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
  600. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
  601. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_do_update.py +0 -0
  602. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
  603. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_github_update_gateway.py +0 -0
  604. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
  605. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_ui_update_notification.py +0 -0
  606. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_update_use_case.py +0 -0
  607. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/tests/update_notifier/test_whats_new.py +0 -0
  608. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/uv.lock +0 -0
  609. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/README.md +0 -0
  610. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/cli_subcommand_dispatch.py +0 -0
  611. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/lookup.json +0 -0
  612. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/sql_parser.py +0 -0
  613. {drydock_cli-2.6.136 → drydock_cli-2.6.138}/worked_examples/tree_walking_interpreter.py +0 -0
@@ -0,0 +1,186 @@
1
+ # PRD: Admiral + Drydock (Adaptive Agent Orchestration System)
2
+
3
+ ## 1. Overview
4
+ * **Execution Harness:** Drydock
5
+ * **Orchestration & Meta-Learning Layer:** Admiral
6
+ * **Vision:** Create an observable, self-tuning LLM harness. Drydock handles the deterministic execution of agentic tasks (tools, loops, file ops), while Admiral operates as an out-of-band supervisor that detects failure patterns, dynamically updates execution parameters, and controls the system's learning rate to prevent behavioral degradation.
7
+
8
+ ## 2. Core Problem
9
+ Current agent harnesses suffer from architectural fragility:
10
+ * **Static Execution:** They rely on hardcoded routing logic and brittle system prompts.
11
+ * **Zero Self-Awareness:** They cannot detect when they are stuck in a logical loop or hallucinating tool calls.
12
+ * **Lack of Domain Adaptation:** A coding agent and a research agent require different tolerances for loops and errors, but standard harnesses treat them identically.
13
+ * **The Root Issue:** We are deploying non-deterministic intelligence inside rigid, deterministic boxes.
14
+
15
+ ## 3. System Architecture
16
+ The system utilizes a dual-layer approach, strictly separating the "doing" from the "supervising."
17
+
18
+ ```text
19
+ [ User Interface (TUI / CLI) ]
20
+ |
21
+ v
22
+ [ ADMIRAL (Meta-Controller) ] <--- Telemetry & Logs
23
+ | |
24
+ State Config |
25
+ v |
26
+ [ DRYDOCK (Execution Engine) ] ----+
27
+ |
28
+ [ LLM Kernel ] <--> [ Tool / Env Runtime ]
29
+ ```
30
+
31
+ ## 4. Core Components
32
+
33
+ ### 4.1 Admiral (The Orchestrator)
34
+ Admiral does not execute tasks. It ingests telemetry, evaluates execution health, and pushes state updates to Drydock.
35
+
36
+ * **A. Telemetry Ingestion:** Processes structured logs from Drydock (token usage, tool call frequency, error stack traces, execution latency).
37
+ * **B. Pattern & Anomaly Detection:**
38
+ * *Loop Detection:* Identifies repeated sequential tool calls with identical outputs.
39
+ * *Struggle Detection:* Identifies high token burn with zero file modifications or task progression.
40
+ * **C. State-Driven Modification (Not Code-Rewriting):**
41
+ * Admiral modifies Drydock's behavior by updating its **State Config** (e.g., system prompt matrices, tool-access blocklists, max-loop constraints). It does *not* rewrite source code.
42
+ * **D. Learning Rate Scheduler:**
43
+ * Controls how fast Admiral can alter Drydock's baseline configuration.
44
+ * *Cold Start:* High tolerance for manual interventions, low threshold for prompt tweaks.
45
+ * *Stable:* High threshold for baseline changes; relies on localized session memory.
46
+ * **E. Interventions & Versioning:**
47
+ * Pauses Drydock when a failure threshold is crossed.
48
+ * Prompts the user via TUI: *"Loop detected. Propose dropping [WebSearch] tool and appending directive: 'Use grep instead'. Approve? (Y/N)"*
49
+ * Maintains a Git-like history of all config state changes for instant rollbacks.
50
+
51
+ ### 4.2 Drydock (The Execution Harness)
52
+ Drydock is a highly modular, state-driven execution loop.
53
+
54
+ * **A. State-Hydrated Execution:** Drydock boots up by reading the config injected by Admiral. If Admiral alters the system prompt or revokes a tool mid-flight, Drydock adopts the new state on the next loop iteration.
55
+ * **B. Modular Primitives:**
56
+ * *Planner:* Maps the initial task.
57
+ * *Executor:* Formats the prompt and parses the LLM output.
58
+ * *Tool Router:* Safely executes the requested local commands.
59
+ * **C. Telemetry Emitter:** Emits a standardized JSON log for every step (e.g., `{"step": 4, "action": "tool_call", "tool": "bash", "status": "error", "latency": "1.2s"}`) directly to Admiral.
60
+
61
+ ## 5. Example Execution Flow (Stuck State Mitigation)
62
+ 1. **Drydock:** Attempts to run a broken Python script 4 times. Each time, the LLM hallucinates the same incorrect fix.
63
+ 2. **Drydock:** Emits 4 identical error logs to the telemetry stream.
64
+ 3. **Admiral:** Detects the pattern. The confidence score for a "Logic Loop" hits 0.95.
65
+ 4. **Admiral:** Issues a `PAUSE` signal to Drydock.
66
+ 5. **Admiral (via TUI):** *"Drydock is looping on a syntax error. Suggestion: Inject context directive 'Stop attempting to fix lines 40-50, rewrite the function from scratch.' Apply? (Y/n)"*
67
+ 6. **User:** Hits 'Y'.
68
+ 7. **Admiral:** Updates Drydock's temporary session config with the new directive. Issues `RESUME`.
69
+ 8. **Drydock:** Re-evaluates the prompt with the new directive and breaks the loop.
70
+
71
+ ## 6. Project Risks & Mitigations
72
+ * **Risk:** The system becomes too complex to debug (who broke it, Admiral or the LLM?).
73
+ * *Mitigation:* Strict, readable audit logs. Every change Admiral makes to Drydock's state must be written to a plain-text `admiral_history.log`.
74
+ * **Risk:** Overfitting to specific user quirks.
75
+ * *Mitigation:* Separate the memory stores. Maintain a `Session State` (wiped every run) and a `Global State` (persistent). Admiral must prove a fix works across multiple sessions before committing it to the Global State.
76
+ * **Risk:** "Hallucinated" fixes by Admiral.
77
+ * *Mitigation:* Admiral uses hardcoded heuristic triggers for Phase 1 MVP, *not* an LLM, to decide when to intervene.
78
+
79
+ ## 7. MVP Scope (Phase 1)
80
+ * **Drydock:** Basic CLI/TUI that can execute shell commands, read/write files, and query an LLM. Must emit structured JSON logs.
81
+ * **Admiral:** A background Python thread that tails Drydock's logs.
82
+ * **Features:**
83
+ * Regex-based loop detection.
84
+ * Hard pause capability.
85
+ * Ability to let the user manually inject a new system prompt directive mid-run without restarting the context window.
86
+
87
+ ***
88
+
89
+ ## 8. Implementation Status (2026-04-17)
90
+
91
+ ### Phase 1 — SHIPPED (module present in v2.6.137, wiring in flight for v2.6.138)
92
+
93
+ Architecture: **in-process** (option C). Admiral runs as an asyncio.Task
94
+ inside the Textual app's event loop — same process as the agent, no IPC.
95
+ Auto-apply default (no Y/N approval) per user directive.
96
+
97
+ Files:
98
+ * `drydock/admiral/__init__.py` — public API (`attach(agent_loop)`).
99
+ * `drydock/admiral/detectors.py` — `detect_tool_call_loop`,
100
+ `detect_struggle`, `run_all`. Pure functions; return `Finding(code, directive)`.
101
+ * `drydock/admiral/interventions.py` — `apply(agent_loop, finding)` →
102
+ calls `AgentLoop._inject_system_note` + appends to audit log.
103
+ * `drydock/admiral/history.py` — append-only timestamped log at
104
+ `~/.vibe/logs/admiral_history.log`.
105
+ * `drydock/admiral/worker.py` — `AdmiralWorker` async task that polls
106
+ every 5s, dedup window 60s per finding code.
107
+ * `tests/test_admiral.py` — 5 tests for detector correctness.
108
+
109
+ Integration:
110
+ * `drydock/cli/textual_ui/app.py::on_mount` — `admiral.attach(agent_loop)`
111
+ after approval callbacks are set. Stored on `self._admiral`. Any Admiral
112
+ import/startup error is logged but never prevents the TUI from starting.
113
+
114
+ Detectors (Phase 1):
115
+ 1. **Loop detection** — 3+ identical (tool_name + arguments) calls in a
116
+ row → inject directive telling the model to stop the loop.
117
+ 2. **Struggle detection** — 20+ non-write tool calls since the last
118
+ `write_file`/`search_replace`/`edit_file` → inject "write code or
119
+ tell the user you're stuck."
120
+
121
+ ### Phase 2 — DESIGNED (target v2.6.139+)
122
+
123
+ Escalation ladder for when heuristics aren't enough:
124
+
125
+ ```
126
+ [Admiral detector fires]
127
+ |
128
+ v
129
+ [local Gemma 4 meta-analysis] — send the last N turns + the finding to
130
+ the local vLLM endpoint asking "what
131
+ is really going wrong? what directive
132
+ would unstick the agent?"
133
+ |
134
+ v (low confidence / model also stumped)
135
+ [Claude Code (Opus) escalation] — shell out to `claude -p "<analysis>"`
136
+ (or the Anthropic SDK) for a second
137
+ opinion. Cap at N escalations per
138
+ session.
139
+ |
140
+ v
141
+ [Admiral applies Opus's directive via _inject_system_note]
142
+ ```
143
+
144
+ Open design questions for Phase 2:
145
+ * Local LLM reuse: should Admiral reuse the agent's own backend
146
+ connection, or open its own at a different temperature?
147
+ → **Lean:** reuse `AgentLoop.backend` with a separate message list
148
+ and lower temperature (0.1 vs 0.7) so the analysis is deterministic.
149
+ * Opus access: `claude -p` CLI or `anthropic` SDK?
150
+ → **Lean:** SDK when `ANTHROPIC_API_KEY` is set; fall back to
151
+ `claude -p` when not (so users who already have Claude Code auth
152
+ don't need to re-enter a key).
153
+ * Rate-limiting: prevent Opus blast during a bad run. Max 3 escalations
154
+ per session by default. Override via env var.
155
+
156
+ ### Phase 3 — IDEAS (not started)
157
+
158
+ * **Learning-rate scheduler (PRD §4.1.D)** — cold start accepts many
159
+ tweaks, stable mode accepts few. Implement by tracking how many
160
+ interventions the user manually undid via slash-commands.
161
+ * **Session vs Global memory (PRD §6)** — session state wiped per run;
162
+ global state only promoted if a fix worked across ≥2 sessions.
163
+ * **TUI widget** — a collapsible Admiral panel showing recent findings
164
+ and their outcomes, so the user can audit the supervisor.
165
+
166
+ ## 9. Continuity Notes (if this session is lost)
167
+
168
+ If you restart mid-Phase-2:
169
+ * **What ships:** `drydock/admiral/` (Phase 1, working) + PRD (this
170
+ file). Check `git log --oneline -20` — Phase 1 commit should name
171
+ "Admiral Phase 1".
172
+ * **What's missing:** `drydock/admiral/llm_analyzer.py` (local LLM)
173
+ and `drydock/admiral/opus_escalator.py` (Claude Code fallback).
174
+ Neither exists yet — start them from the Phase 2 section above.
175
+ * **Audit log:** `~/.vibe/logs/admiral_history.log` shows every
176
+ intervention Admiral has applied in real user sessions.
177
+ * **User directives recorded so far in this session:**
178
+ - Architecture: option C (in-process Textual worker).
179
+ - Approval: auto-apply, no Y/N dialog.
180
+ - Phase 2: Admiral uses local LLM first; escalates to Claude Code
181
+ (Opus) when stumped.
182
+ - Keep updating this PRD as work progresses so a session loss
183
+ doesn't cost context.
184
+
185
+ ***
186
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drydock-cli
3
- Version: 2.6.136
3
+ Version: 2.6.138
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
@@ -0,0 +1,15 @@
1
+ """Admiral — meta-controller that supervises drydock sessions.
2
+
3
+ Phase 1: heuristic loop and struggle detection, auto-applied interventions
4
+ via the existing `_inject_system_note` channel. All interventions are
5
+ logged to `~/.vibe/logs/admiral_history.log` for post-hoc review.
6
+
7
+ The detectors read the live message list of an AgentLoop; the worker
8
+ runs as a Textual background task so it lives in the same event loop
9
+ as the agent (no threading, no IPC). See Admiral.md for the PRD.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ from drydock.admiral.worker import AdmiralWorker, attach
14
+
15
+ __all__ = ["AdmiralWorker", "attach"]
@@ -0,0 +1,104 @@
1
+ """Heuristic detectors that inspect the live message list.
2
+
3
+ Each detector is a pure function: take the messages, return a
4
+ `Finding(code, directive)` if it fires, or `None`. Findings are
5
+ idempotent within a short window — callers dedup before intervening.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from collections.abc import Sequence
10
+ from dataclasses import dataclass
11
+
12
+ from drydock.core.types import LLMMessage, Role
13
+
14
+
15
+ WRITE_TOOLS: frozenset[str] = frozenset({"write_file", "search_replace", "edit_file"})
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class Finding:
20
+ code: str # stable ID used for dedup, e.g. "loop:write_file:/p/x.py"
21
+ directive: str # text to inject into the conversation
22
+
23
+
24
+ def _tool_sig(tc) -> str: # ToolCall — keep loose to avoid circular import
25
+ name = tc.function.name or ""
26
+ args = tc.function.arguments or ""
27
+ return f"{name}::{args}"
28
+
29
+
30
+ def detect_tool_call_loop(messages: Sequence[LLMMessage], window: int = 3) -> Finding | None:
31
+ """Fires when the last `window` assistant tool calls are byte-identical.
32
+
33
+ Drydock already has its own loop prevention; this catches the cases
34
+ where the existing system warns-but-doesn't-stop and the model
35
+ ignored the warning.
36
+ """
37
+ sigs: list[str] = []
38
+ for m in reversed(messages):
39
+ if m.role != Role.assistant or not m.tool_calls:
40
+ continue
41
+ for tc in m.tool_calls:
42
+ sigs.append(_tool_sig(tc))
43
+ if len(sigs) >= window:
44
+ break
45
+ if len(sigs) >= window:
46
+ break
47
+ if len(sigs) < window:
48
+ return None
49
+ if len(set(sigs)) != 1:
50
+ return None
51
+ sig = sigs[0]
52
+ return Finding(
53
+ code=f"loop:{sig[:80]}",
54
+ directive=(
55
+ f"Admiral: you have called the same tool with identical arguments "
56
+ f"{window} times in a row. The next call will almost certainly "
57
+ f"produce the same result. Stop this path, try a different "
58
+ f"approach, or tell the user what's blocking you."
59
+ ),
60
+ )
61
+
62
+
63
+ def detect_struggle(messages: Sequence[LLMMessage], threshold: int = 20) -> Finding | None:
64
+ """Fires when `threshold` tool calls have happened without any write.
65
+
66
+ Reading + grepping forever without writing code is the classic
67
+ "stuck exploring" failure mode.
68
+ """
69
+ calls_since_write = 0
70
+ last_write_tool: str | None = None
71
+ for m in messages:
72
+ if m.role != Role.assistant or not m.tool_calls:
73
+ continue
74
+ for tc in m.tool_calls:
75
+ name = tc.function.name or ""
76
+ if name in WRITE_TOOLS:
77
+ calls_since_write = 0
78
+ last_write_tool = name
79
+ else:
80
+ calls_since_write += 1
81
+ if calls_since_write < threshold:
82
+ return None
83
+ hint = (
84
+ "Either (a) you already have enough context — commit to a plan and "
85
+ "start writing code now, or (b) you're genuinely stuck — stop and "
86
+ "report what's blocking you to the user."
87
+ )
88
+ return Finding(
89
+ code=f"struggle:{calls_since_write}:{last_write_tool or 'none'}",
90
+ directive=(
91
+ f"Admiral: you have made {calls_since_write} tool calls without "
92
+ f"writing or editing any file. {hint}"
93
+ ),
94
+ )
95
+
96
+
97
+ def run_all(messages: Sequence[LLMMessage]) -> list[Finding]:
98
+ """Run every detector and return all findings that fire."""
99
+ results: list[Finding] = []
100
+ for fn in (detect_tool_call_loop, detect_struggle):
101
+ f = fn(messages)
102
+ if f is not None:
103
+ results.append(f)
104
+ return results
@@ -0,0 +1,23 @@
1
+ """Plain-text audit log for every intervention Admiral applies.
2
+
3
+ Per the PRD: "Every change Admiral makes to Drydock's state must be
4
+ written to a plain-text admiral_history.log." Kept simple on purpose —
5
+ no JSON, no rotation logic, just append-only timestamped lines.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from datetime import datetime, timezone
10
+ from pathlib import Path
11
+
12
+
13
+ def _log_path() -> Path:
14
+ d = Path.home() / ".vibe" / "logs"
15
+ d.mkdir(parents=True, exist_ok=True)
16
+ return d / "admiral_history.log"
17
+
18
+
19
+ def append(event: str, detail: str) -> None:
20
+ ts = datetime.now(timezone.utc).isoformat(timespec="seconds")
21
+ line = f"{ts} | {event} | {detail}\n"
22
+ with _log_path().open("a") as f:
23
+ f.write(line)
@@ -0,0 +1,21 @@
1
+ """Apply interventions by injecting into the running AgentLoop.
2
+
3
+ The injection path is the same `_inject_system_note` drydock's own
4
+ safety checks use — Admiral is just another source of directives.
5
+ Every intervention writes to the audit log.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING
10
+
11
+ from drydock.admiral import history
12
+ from drydock.admiral.detectors import Finding
13
+
14
+ if TYPE_CHECKING:
15
+ from drydock.core.agent_loop import AgentLoop
16
+
17
+
18
+ def apply(agent_loop: AgentLoop, finding: Finding) -> None:
19
+ """Inject the finding's directive into the live conversation."""
20
+ agent_loop._inject_system_note(finding.directive)
21
+ history.append("intervention", f"{finding.code} :: {finding.directive[:160]}")
@@ -0,0 +1,93 @@
1
+ """AdmiralWorker — periodic supervisor running inside the Textual app.
2
+
3
+ Phase 1 behaviour:
4
+ - Every ~5s, inspect the live AgentLoop message list.
5
+ - Run all detectors.
6
+ - For each finding NOT seen in the last `DEDUP_WINDOW_SEC` seconds,
7
+ auto-apply the intervention.
8
+ - Log both findings (with auto-apply decision) and bootstrap/stop
9
+ events to ~/.vibe/logs/admiral_history.log.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ import asyncio
14
+ import logging
15
+ import time
16
+ from typing import TYPE_CHECKING
17
+
18
+ from drydock.admiral import detectors, history, interventions
19
+
20
+ if TYPE_CHECKING:
21
+ from drydock.core.agent_loop import AgentLoop
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+ POLL_INTERVAL_SEC = 5.0
26
+ DEDUP_WINDOW_SEC = 60.0
27
+
28
+
29
+ class AdmiralWorker:
30
+ """Async task that supervises one AgentLoop.
31
+
32
+ Not a Textual worker class — it's just an asyncio.Task you spawn
33
+ from inside the TUI app's event loop. Lives alongside the agent,
34
+ stops when the agent stops.
35
+ """
36
+
37
+ def __init__(self, agent_loop: AgentLoop) -> None:
38
+ self.agent_loop = agent_loop
39
+ self._task: asyncio.Task | None = None
40
+ self._recent_findings: dict[str, float] = {} # code -> timestamp
41
+
42
+ def start(self) -> None:
43
+ if self._task is not None and not self._task.done():
44
+ return
45
+ self._task = asyncio.create_task(self._run(), name="admiral-worker")
46
+ history.append("bootstrap", "AdmiralWorker started")
47
+
48
+ def stop(self) -> None:
49
+ if self._task is None:
50
+ return
51
+ self._task.cancel()
52
+ self._task = None
53
+ history.append("shutdown", "AdmiralWorker stopped")
54
+
55
+ async def _run(self) -> None:
56
+ try:
57
+ while True:
58
+ await asyncio.sleep(POLL_INTERVAL_SEC)
59
+ try:
60
+ self._tick()
61
+ except Exception as e:
62
+ # Detector bugs must never crash the agent — log and continue.
63
+ logger.warning("Admiral tick error: %s", e)
64
+ history.append("error", f"tick failed: {e}")
65
+ except asyncio.CancelledError:
66
+ raise
67
+
68
+ def _tick(self) -> None:
69
+ now = time.monotonic()
70
+ # Garbage-collect old dedup entries so long sessions don't leak.
71
+ self._recent_findings = {
72
+ code: ts for code, ts in self._recent_findings.items()
73
+ if now - ts < DEDUP_WINDOW_SEC
74
+ }
75
+ findings = detectors.run_all(list(self.agent_loop.messages))
76
+ for f in findings:
77
+ last = self._recent_findings.get(f.code)
78
+ if last is not None and (now - last) < DEDUP_WINDOW_SEC:
79
+ continue
80
+ self._recent_findings[f.code] = now
81
+ interventions.apply(self.agent_loop, f)
82
+
83
+
84
+ def attach(agent_loop: AgentLoop) -> AdmiralWorker:
85
+ """Start an AdmiralWorker supervising the given agent loop.
86
+
87
+ Returns the worker handle so the caller can stop it on shutdown.
88
+ Safe to call multiple times — a fresh worker replaces any prior
89
+ one, but that's the caller's responsibility to track.
90
+ """
91
+ worker = AdmiralWorker(agent_loop)
92
+ worker.start()
93
+ return worker
@@ -288,6 +288,7 @@ class VibeApp(App): # noqa: PLR0904
288
288
  self._last_escape_time: float | None = None
289
289
  self._banner: Banner | None = None
290
290
  self._whats_new_message: WhatsNewMessage | None = None
291
+ self._admiral = None # type: ignore[var-annotated]
291
292
  self._cached_messages_area: Widget | None = None
292
293
  self._cached_chat: ChatScroll | None = None
293
294
  self._cached_loading_area: Widget | None = None
@@ -353,6 +354,14 @@ class VibeApp(App): # noqa: PLR0904
353
354
  self.agent_loop.set_user_input_callback(self._user_input_callback)
354
355
  self._refresh_profile_widgets()
355
356
 
357
+ try:
358
+ from drydock.admiral import attach as _admiral_attach
359
+ self._admiral = _admiral_attach(self.agent_loop)
360
+ except Exception as e:
361
+ # Admiral must never prevent the TUI from starting.
362
+ import logging
363
+ logging.getLogger(__name__).warning("Admiral failed to start: %s", e)
364
+
356
365
  chat_input_container = self.query_one(ChatInputContainer)
357
366
  chat_input_container.focus_input()
358
367
  await self._resolve_plan()
@@ -114,32 +114,63 @@ class StreamingMessageBase(Static):
114
114
  _INLINE_ENUM_RE = re.compile(r" (?=\d{1,2}\. [A-Z])")
115
115
  _INLINE_HEADING_RE = re.compile(r" (?=\*\*[A-Z][A-Za-z ]{1,20}:\*\*)")
116
116
  _INLINE_DASH_BULLET_RE = re.compile(r"(?<=[.!?]) (?=- [A-Z])")
117
+ _SENTENCE_BOUNDARY_RE = re.compile(r"(?<=[.!?]) (?=[A-Z])")
118
+ _INLINE_CAPWORD_HEADING_RE = re.compile(
119
+ r"(?<=[.!?]) (?=[A-Z][A-Za-z]{1,15}:\s)"
120
+ )
121
+
122
+
123
+ def _sentence_chunks(text: str, group: int = 2) -> str:
124
+ """Break a long flat string into paragraphs every `group` sentences.
125
+
126
+ Conservative: only fires when there are at least 2 sentences to
127
+ split between. Splits on real sentence boundaries (`. `, `! `, `? `
128
+ followed by a capital).
129
+ """
130
+ sentences = _SENTENCE_BOUNDARY_RE.split(text)
131
+ if len(sentences) < 2:
132
+ return text
133
+ paragraphs: list[str] = []
134
+ for i in range(0, len(sentences), group):
135
+ paragraphs.append(" ".join(sentences[i:i + group]))
136
+ return "\n\n".join(paragraphs)
117
137
 
118
138
 
119
139
  def _break_walls_of_text(text: str) -> str:
120
- """Insert line breaks before inline enumerations and bold headings
121
- in a flat string with no newlines.
122
-
123
- Gemma 4 often emits responses like `Changes: 1. Added X 2. Added Y
124
- 3. Fixed Z` as a single paragraph with zero `\\n`. The Markdown
125
- widget renders that as one long line, which users correctly call
126
- "a wall of text". We can't insert newlines the model didn't write
127
- inside a code fence, but we can break up inline numbered items
128
- (` 1. Foo 2. Bar `) and inline bold headings (` **Usage:** `) into
129
- separate markdown blocks by injecting `\\n` before the enumeration
130
- or heading marker. Conservative patterns only must match a space
131
- followed by `\\d+\\. [A-Z]` or `**Heading:**`.
132
-
133
- Runs OUTSIDE code fences only.
140
+ """Make flat, low-newline assistant responses readable.
141
+
142
+ Gemma 4 regularly emits responses with zero `\\n` — either a block
143
+ of enumerated items jammed together (`Changes: 1. A 2. B 3. C`) or
144
+ a long paragraph of prose (`I fixed X. The Y class now uses Z.
145
+ All tests pass.`). The Markdown widget renders both as one line.
146
+
147
+ Strategy, applied in order:
148
+ 1. Break before inline `**Heading:**` markers.
149
+ 2. Break before inline numbered items (` 1. Foo 2. Bar`).
150
+ 3. Break before inline `CapWord:` mini-headings (`Changes: ...`).
151
+ 4. If still a wall (long + zero newlines), split every 2 sentences
152
+ at real sentence boundaries so readers get paragraph breaks.
153
+
154
+ Conservative guards: nothing fires unless the chunk is >200 chars
155
+ and has fewer than 3 newlines. Short responses and already-
156
+ structured markdown pass through untouched.
134
157
  """
135
- if not text or "\n" in text and text.count("\n") >= 2:
158
+ if not text or len(text) < 200:
136
159
  return text
137
- # Only intervene for "wall of text" — long, low-newline content.
138
- if len(text) < 200:
160
+ nl = text.count("\n")
161
+ if nl >= 3:
139
162
  return text
140
- out = _INLINE_ENUM_RE.sub("\n", text)
141
- out = _INLINE_HEADING_RE.sub("\n\n", out)
163
+ out = _INLINE_HEADING_RE.sub("\n\n", text)
164
+ out = _INLINE_ENUM_RE.sub("\n", out)
142
165
  out = _INLINE_DASH_BULLET_RE.sub("\n", out)
166
+ out = _INLINE_CAPWORD_HEADING_RE.sub("\n\n", out)
167
+ # If inline markers didn't produce any breaks AND the text is long
168
+ # enough that one paragraph hurts readability, split at sentence
169
+ # boundaries. group=1 = each sentence on its own paragraph (most
170
+ # aggressive — user-requested in issue #8 reopen). Threshold is
171
+ # 250 so medium-length responses also get paragraphs.
172
+ if "\n" not in out and len(out) > 250:
173
+ out = _sentence_chunks(out, group=1)
143
174
  return out
144
175
 
145
176
 
@@ -166,10 +197,9 @@ def _preserve_line_breaks(text: str) -> str:
166
197
  """
167
198
  if not text:
168
199
  return text
169
- # First pass: if the whole chunk has no newlines, try to rescue
170
- # inline-enumeration wall-of-text.
171
- if "\n" not in text:
172
- text = _break_walls_of_text(text)
200
+ # First pass: rescue wall-of-text responses (flat prose, inline
201
+ # enumerations, inline bold headings). See _break_walls_of_text.
202
+ text = _break_walls_of_text(text)
173
203
  out: list[str] = []
174
204
  in_fence = False
175
205
  lines = text.split("\n")
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "drydock-cli"
3
- version = "2.6.136"
3
+ version = "2.6.138"
4
4
  description = "Local-first CLI coding agent — tested with Gemma 4 26B via vLLM"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -0,0 +1,75 @@
1
+ """Unit tests for Admiral's Phase 1 detectors."""
2
+ from __future__ import annotations
3
+
4
+ from drydock.admiral.detectors import detect_struggle, detect_tool_call_loop, run_all
5
+ from drydock.core.types import FunctionCall, LLMMessage, Role, ToolCall
6
+
7
+
8
+ def _assistant(tool: str, args: str = "{}") -> LLMMessage:
9
+ return LLMMessage(
10
+ role=Role.assistant,
11
+ content="",
12
+ tool_calls=[ToolCall(function=FunctionCall(name=tool, arguments=args))],
13
+ )
14
+
15
+
16
+ def test_loop_fires_on_three_identical_tool_calls() -> None:
17
+ msgs = [
18
+ LLMMessage(role=Role.user, content="go"),
19
+ _assistant("read_file", '{"path":"x.py"}'),
20
+ LLMMessage(role=Role.tool, content="result"),
21
+ _assistant("read_file", '{"path":"x.py"}'),
22
+ LLMMessage(role=Role.tool, content="result"),
23
+ _assistant("read_file", '{"path":"x.py"}'),
24
+ LLMMessage(role=Role.tool, content="result"),
25
+ ]
26
+ f = detect_tool_call_loop(msgs)
27
+ assert f is not None
28
+ assert "Admiral" in f.directive
29
+ assert f.code.startswith("loop:")
30
+
31
+
32
+ def test_loop_no_fire_on_varied_args() -> None:
33
+ msgs = [
34
+ _assistant("read_file", '{"path":"x.py"}'),
35
+ LLMMessage(role=Role.tool, content="r"),
36
+ _assistant("read_file", '{"path":"y.py"}'),
37
+ LLMMessage(role=Role.tool, content="r"),
38
+ _assistant("read_file", '{"path":"z.py"}'),
39
+ LLMMessage(role=Role.tool, content="r"),
40
+ ]
41
+ assert detect_tool_call_loop(msgs) is None
42
+
43
+
44
+ def test_struggle_fires_after_many_reads_without_write() -> None:
45
+ msgs: list[LLMMessage] = [LLMMessage(role=Role.user, content="build it")]
46
+ for i in range(25):
47
+ msgs.append(_assistant("read_file", f'{{"path":"f{i}.py"}}'))
48
+ msgs.append(LLMMessage(role=Role.tool, content="..."))
49
+ f = detect_struggle(msgs)
50
+ assert f is not None
51
+ assert "without writing" in f.directive
52
+
53
+
54
+ def test_struggle_resets_on_write() -> None:
55
+ msgs: list[LLMMessage] = []
56
+ for i in range(15):
57
+ msgs.append(_assistant("read_file", f'{{"path":"f{i}.py"}}'))
58
+ msgs.append(LLMMessage(role=Role.tool, content="..."))
59
+ msgs.append(_assistant("write_file", '{"path":"new.py","content":"x"}'))
60
+ msgs.append(LLMMessage(role=Role.tool, content="ok"))
61
+ for i in range(3):
62
+ msgs.append(_assistant("read_file", f'{{"path":"check{i}.py"}}'))
63
+ msgs.append(LLMMessage(role=Role.tool, content="..."))
64
+ assert detect_struggle(msgs) is None
65
+
66
+
67
+ def test_run_all_returns_multiple_findings() -> None:
68
+ msgs: list[LLMMessage] = []
69
+ for i in range(25):
70
+ msgs.append(_assistant("read_file", '{"path":"x.py"}')) # same args -> loop
71
+ msgs.append(LLMMessage(role=Role.tool, content="..."))
72
+ findings = run_all(msgs)
73
+ codes = {f.code.split(":")[0] for f in findings}
74
+ assert "loop" in codes
75
+ assert "struggle" in codes