drydock-cli 2.7.38__tar.gz → 2.7.39__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.
- drydock_cli-2.7.39/.auto_release.lock +1 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/PKG-INFO +1 -1
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/agent_loop.py +170 -1
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/steering_hook.py +18 -6
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/bash.py +71 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/pyproject.toml +1 -1
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_issue_fixes.py +101 -1
- drydock_cli-2.7.39/tests/tools/test_bash_exact_cmd_loop_breaker.py +59 -0
- drydock_cli-2.7.39/tests/tools/test_bash_python_c_syntaxerr_loop_breaker.py +57 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/trip_log.md +183 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/uv.lock +1 -1
- drydock_cli-2.7.38/.auto_release.lock +0 -1
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.claude/scheduled_tasks.lock +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.gitignore +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.perf_baseline_done +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.python-version +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.typos.toml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.vscode/extensions.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.vscode/launch.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/.vscode/settings.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/AGENTS.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/Admiral.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/BASELINE_412.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/CHANGELOG.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/CLAUDE.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/DEPLOYMENT.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/Drydock_rebrand.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/HLE_PRD.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/JETSON_BENCH.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/LICENSE +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/MODEL_SHORTCOMINGS.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/NOTICE +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/OVERNIGHT_PROGRESS.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/PERF_SWEEP_PLAN.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/PRD.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/SOVEREIGN_PRD.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/TRIAGE_v1.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/action.yml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results1.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results13.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results14.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results15.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results16.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results17.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results18.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results19.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results2.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results20.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results3.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results4.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results5.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results6.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results7.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results8.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results9.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/baseline_history/results_evolved_v1.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/docs/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/docs/acp-setup.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/detectors.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/detectors_proposed.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/history.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/interventions.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/llm_analyzer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/metrics.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/opus_escalator.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/persistence.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/policy.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/proposer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/stager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/task_classifier.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/tuning.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/validator.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/admiral/worker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/checkpoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/classifier/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/classifier/__main__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/classifier/classifier.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/classifier/dispatcher.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/classifier/rules.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/classifier/signal.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/config/doctor.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/config/local_detect.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/context_recovery.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/format.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/logger.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/paths/_drydock_home.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/gemma4.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/slug.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/_task_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/retrieve.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/retrieve.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/types.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/core/utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/graphrag/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/graphrag/__main__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/graphrag/code_indexer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/graphrag/retriever.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/graphrag/storage.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/graphrag/text_indexer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/onboarding/screens/choice.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/onboarding/screens/local_model.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/audit-tests/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/strong-tests/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/steering/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/steering/__main__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/steering/applier.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/steering/config.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/steering/registry.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/steering/sandbox.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/steering/vectors.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock/whats_new.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock-acp.spec +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/drydock_terms.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/flake.lock +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/flake.nix +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/nohup.out +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/perf_results/baseline_1777672181.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/perf_results/baseline_1777672218.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/perf_results/baseline_1777672322.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/perf_results/baseline_1777732278.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/perf_results/baseline_1777811293.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/perf_results/baseline_1777811401.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/config_base.toml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/config_best.toml +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/domain_spec.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/experimenter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/kernel.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/mini_prd.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/mini_prompts.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/proposer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/research/results.tsv +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/resume.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/admiral_probe.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/audit_sampler.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/auto_generate_tests.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/auto_release.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/auto_test_loop.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/autonomous_review.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/autonomous_review_prompt.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/backup.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/bump_version.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/classify_pulse.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/comprehensive_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/consume_retrieval_queue.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/discover_cli_tools.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/evolve_tests.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/gen_2000_prompts.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/hle_eval.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/hle_eval_seed.jsonl +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/install.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/llm_balancer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/mega_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/meta_ralph_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/monitor_swebench.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/monitor_test_battery.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/notify_release.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/oss_task_harness.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/overnight_agents_test.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/perf_baseline_when_idle.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/perf_sweep.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/poll_issues.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/port_task.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/prepare_release.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/queue_top.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/ralph_loop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/research_babysitter.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/session_loop_audit.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/shakedown.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/shakedown_interactive.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/shakedown_regression.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/shakedown_suite.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/shakedown_variance.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/stress_babysitter.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/stress_prompts_50.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/stress_prompts_realuser.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/stress_prompts_tool_agent.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/stress_shakedown.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/stress_telegram_status.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/stress_watcher.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/telegram_bot.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/test_bank.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/test_full.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/test_smoke.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/test_tui_path.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/tui_test.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/scripts/vllm_failover.sh +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/test/project/dummy +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/backend/test_generic_adapter_sanitize.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_circuit_breaker_count_escalation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_circuit_breaker_readonly_threshold.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/e2e/common.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/fixtures/doc_qa_system_prd.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/mock/utils.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_admiral.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_admiral_phase3.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_admiral_proposed.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_admiral_struggle_dedup.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_agents.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_checkpoint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_classifier.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_context_recovery.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_dispatcher.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_fake_tool_call_paren_syntax.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_graphrag.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_hallucinated_tool_suppression.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_integration.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_local_detect.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_message_id.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_middleware.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_read_file_not_found_listing.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_retrieval_consumer.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_retrieve_tool.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_search_replace_args_not_truncated.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_smoke.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_steering.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_steering_hook.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_task_complete_nudge.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_tool_args.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_truncate_args_valid_json.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_truncated_arg_path_hint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_truncated_search_replace_escalation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_truncated_write_escalation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_wall_of_text_rescue.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_workloads.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/test_write_file_missing_path.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_bash_binary_grep_hint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_bash_consec_empty_search.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_bash_echo_escape_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_bash_empty_search_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_bash_error_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_bash_heredoc_confirmation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_bash_kill_exit1_annotation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_hallucinated_retrieval_redirect.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_manager_gemma_derived_models.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_read_file_dedup_alternating_offset.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_read_file_dedup_reembed.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_read_file_directory.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_read_file_limit_truncation.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_append_fallback.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_dir_path.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_empty_content.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_file_not_found.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_first_failure_hint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_hard_stop.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_malformed_block.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_placeholder.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/tools/test_write_file_missing_path_hint.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/worked_examples/README.md +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/worked_examples/cli_subcommand_dispatch.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/worked_examples/lookup.json +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/worked_examples/sql_parser.py +0 -0
- {drydock_cli-2.7.38 → drydock_cli-2.7.39}/worked_examples/tree_walking_interpreter.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2749816
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.39
|
|
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
|
|
@@ -693,6 +693,25 @@ class AgentLoop:
|
|
|
693
693
|
_ar_t1 = time.perf_counter()
|
|
694
694
|
logger.warning("[TIMING] _auto_route_task: %.2fs", _ar_t1 - _ar_t0)
|
|
695
695
|
|
|
696
|
+
# === AUTO-PREFETCH RETRIEVE ===
|
|
697
|
+
# HLE Phase 1 finding (memory: project_graphrag_underused.md): Gemma 4
|
|
698
|
+
# almost never calls retrieve() on its own for general-knowledge
|
|
699
|
+
# questions — it defaults to web_search instead. So a curated
|
|
700
|
+
# GraphRAG corpus is invisible to the model unless we surface it
|
|
701
|
+
# automatically. This hook runs retrieve(query=user_msg[:300]) and,
|
|
702
|
+
# if there are real hits (above a quality threshold), prepends them
|
|
703
|
+
# as a system note BEFORE the first LLM call. Zero behavior change
|
|
704
|
+
# when the index has nothing relevant; pure lift when it does.
|
|
705
|
+
#
|
|
706
|
+
# Env-gated via DRYDOCK_AUTO_RETRIEVE so existing workflows are
|
|
707
|
+
# unaffected. Set to "1" or "true" to enable.
|
|
708
|
+
if os.environ.get("DRYDOCK_AUTO_RETRIEVE", "").strip().lower() in ("1", "true", "yes"):
|
|
709
|
+
logger.warning("[AUTO-RETRIEVE] hook entry, query=%r", (user_msg or "")[:80])
|
|
710
|
+
try:
|
|
711
|
+
self._auto_prefetch_retrieve(user_msg)
|
|
712
|
+
except Exception as _e:
|
|
713
|
+
logger.warning("auto-prefetch retrieve failed (skipped): %s", _e, exc_info=True)
|
|
714
|
+
|
|
696
715
|
try:
|
|
697
716
|
should_break_loop = False
|
|
698
717
|
tool_turns = 0
|
|
@@ -1885,7 +1904,30 @@ class AgentLoop:
|
|
|
1885
1904
|
if len(cleaned) != len(self.messages):
|
|
1886
1905
|
self.messages.reset(cleaned)
|
|
1887
1906
|
|
|
1888
|
-
# Fix 2:
|
|
1907
|
+
# Fix 2: Drop empty assistant messages (no content AND no tool_calls).
|
|
1908
|
+
# These violate the OpenAI schema and cause 400 errors on the next LLM
|
|
1909
|
+
# call. They arise when the model returns only thinking/reasoning tokens
|
|
1910
|
+
# (which get stripped) and stall-retry exhaustion leaves the empty msg
|
|
1911
|
+
# in history. An assistant message that follows a tool result must have
|
|
1912
|
+
# either content or tool_calls; if neither, drop it along with any
|
|
1913
|
+
# orphaned tool result messages that precede it (to keep role ordering
|
|
1914
|
+
# valid).
|
|
1915
|
+
cleaned2: list[LLMMessage] = []
|
|
1916
|
+
for msg in self.messages:
|
|
1917
|
+
if (msg.role == Role.assistant
|
|
1918
|
+
and not (msg.content or "").strip()
|
|
1919
|
+
and not msg.tool_calls):
|
|
1920
|
+
# Skip empty assistant — also drop any immediately preceding
|
|
1921
|
+
# tool result that would be left dangling without a matching
|
|
1922
|
+
# assistant turn.
|
|
1923
|
+
while cleaned2 and cleaned2[-1].role == Role.tool:
|
|
1924
|
+
cleaned2.pop()
|
|
1925
|
+
else:
|
|
1926
|
+
cleaned2.append(msg)
|
|
1927
|
+
if len(cleaned2) != len(self.messages):
|
|
1928
|
+
self.messages.reset(cleaned2)
|
|
1929
|
+
|
|
1930
|
+
# Fix 3: If last message is assistant, add a user "Continue." prompt.
|
|
1889
1931
|
# The auto-Continue exists so Gemma 4 keeps executing multi-step plans
|
|
1890
1932
|
# without stopping prematurely at an intermediate text response. For
|
|
1891
1933
|
# stress runs against prompts that don't need tool calls (pure
|
|
@@ -2776,6 +2818,133 @@ class AgentLoop:
|
|
|
2776
2818
|
|
|
2777
2819
|
return None
|
|
2778
2820
|
|
|
2821
|
+
def _auto_prefetch_retrieve(self, user_msg: str) -> None:
|
|
2822
|
+
"""Auto-fetch relevant chunks from GraphRAG and inject as system note.
|
|
2823
|
+
|
|
2824
|
+
Runs synchronously (the GraphRAG retriever is a fast SQLite query).
|
|
2825
|
+
Caps the query length at 300 chars and the injected context at 2000
|
|
2826
|
+
chars to avoid blowing context budget on long user prompts.
|
|
2827
|
+
|
|
2828
|
+
Quality gate: only inject if at least one text-chunk hit has score
|
|
2829
|
+
>= 8.0 (the indexer's score is roughly TF-IDF magnitude). Below
|
|
2830
|
+
that, the retrieval is probably noise and would just bloat the
|
|
2831
|
+
prompt.
|
|
2832
|
+
|
|
2833
|
+
See memory/project_graphrag_underused.md for why this exists:
|
|
2834
|
+
Gemma 4 doesn't call retrieve() on its own for general-knowledge
|
|
2835
|
+
questions, so a curated index is invisible without a hook like
|
|
2836
|
+
this one.
|
|
2837
|
+
"""
|
|
2838
|
+
try:
|
|
2839
|
+
from drydock.graphrag import Index
|
|
2840
|
+
db = os.environ.get("DRYDOCK_GRAPHRAG_DB") or str(
|
|
2841
|
+
Path.home() / ".drydock" / "graphrag.sqlite"
|
|
2842
|
+
)
|
|
2843
|
+
if not Path(db).is_file():
|
|
2844
|
+
logger.warning("[AUTO-RETRIEVE] db missing: %s", db)
|
|
2845
|
+
return
|
|
2846
|
+
idx = Index(db)
|
|
2847
|
+
except Exception as e:
|
|
2848
|
+
logger.warning("[AUTO-RETRIEVE] setup failed: %s", e, exc_info=True)
|
|
2849
|
+
return
|
|
2850
|
+
|
|
2851
|
+
# Extract the actual question from boilerplate. HLE-style prompts
|
|
2852
|
+
# are wrapped: "Answer this question. End your response with...
|
|
2853
|
+
# QUESTION: <real text>". Without this strip the retrieve query
|
|
2854
|
+
# matches scaffolding (CLAUDE.md learnings, etc.) instead of the
|
|
2855
|
+
# actual content. Also strip "FINAL ANSWER:" trailing instructions.
|
|
2856
|
+
raw = (user_msg or "")
|
|
2857
|
+
q_marker = raw.find("QUESTION:")
|
|
2858
|
+
if q_marker >= 0:
|
|
2859
|
+
raw = raw[q_marker + len("QUESTION:"):]
|
|
2860
|
+
# Drop trailing answer-format instructions
|
|
2861
|
+
for stopper in ("FINAL ANSWER:", "Your answer", "Format your", "End your response"):
|
|
2862
|
+
idx_ = raw.find(stopper)
|
|
2863
|
+
if idx_ > 50: # only strip if there's still meaningful content
|
|
2864
|
+
raw = raw[:idx_]
|
|
2865
|
+
query = raw.strip()[:400]
|
|
2866
|
+
if len(query) < 10:
|
|
2867
|
+
logger.warning("[AUTO-RETRIEVE] query too short (%d chars)", len(query))
|
|
2868
|
+
return
|
|
2869
|
+
logger.warning("[AUTO-RETRIEVE] extracted query: %r", query[:120])
|
|
2870
|
+
|
|
2871
|
+
try:
|
|
2872
|
+
result = idx.retrieve(query, symbol_limit=0, text_limit=4)
|
|
2873
|
+
except Exception as e:
|
|
2874
|
+
logger.warning("[AUTO-RETRIEVE] query failed: %s", e, exc_info=True)
|
|
2875
|
+
return
|
|
2876
|
+
|
|
2877
|
+
text_hits = getattr(result, "text", None) or getattr(result, "text_hits", []) or []
|
|
2878
|
+
QUALITY_THRESHOLD = 8.0
|
|
2879
|
+
good_hits = [h for h in text_hits if getattr(h, "score", 0) >= QUALITY_THRESHOLD]
|
|
2880
|
+
logger.warning("[AUTO-RETRIEVE] %d total hits, %d above threshold %.1f",
|
|
2881
|
+
len(text_hits), len(good_hits), QUALITY_THRESHOLD)
|
|
2882
|
+
if not good_hits:
|
|
2883
|
+
return
|
|
2884
|
+
|
|
2885
|
+
# Build the system note. Cap at ~2000 chars total.
|
|
2886
|
+
chunks = []
|
|
2887
|
+
budget = 2000
|
|
2888
|
+
for h in good_hits[:3]:
|
|
2889
|
+
text = (getattr(h, "content", "") or "").strip()
|
|
2890
|
+
score = float(getattr(h, "score", 0))
|
|
2891
|
+
file_ = getattr(h, "file", "") or "?"
|
|
2892
|
+
s, e = getattr(h, "start_line", 0), getattr(h, "end_line", 0)
|
|
2893
|
+
piece = f"--- {file_}:{s}-{e} (score={score:.1f}) ---\n{text}"
|
|
2894
|
+
if len(piece) > budget:
|
|
2895
|
+
piece = piece[:budget] + "..."
|
|
2896
|
+
chunks.append(piece)
|
|
2897
|
+
budget -= len(piece) + 4
|
|
2898
|
+
if budget <= 0:
|
|
2899
|
+
break
|
|
2900
|
+
|
|
2901
|
+
# SYNTHETIC TOOL CALL: instead of mutating the user message
|
|
2902
|
+
# (which iter6-9 proved is treated as scaffolding by Gemma 4 — it
|
|
2903
|
+
# ignores inline references and trusts its training prior), spawn
|
|
2904
|
+
# a fake assistant->tool message pair that LOOKS like the model
|
|
2905
|
+
# called retrieve() and got results. Models trust tool outputs
|
|
2906
|
+
# as authoritative input.
|
|
2907
|
+
#
|
|
2908
|
+
# Sequence:
|
|
2909
|
+
# user -> [our synthetic assistant with tool_call retrieve]
|
|
2910
|
+
# -> [our synthetic tool result with the chunks]
|
|
2911
|
+
# -> real LLM turn begins from there
|
|
2912
|
+
from drydock.core.types import ToolCall, FunctionCall as _FC
|
|
2913
|
+
import uuid
|
|
2914
|
+
|
|
2915
|
+
tool_call_id = f"auto-retrieve-{uuid.uuid4().hex[:16]}"
|
|
2916
|
+
tool_args = json.dumps({"query": (user_msg or "")[:200]})
|
|
2917
|
+
synth_assistant = LLMMessage(
|
|
2918
|
+
role=Role.assistant,
|
|
2919
|
+
content="",
|
|
2920
|
+
tool_calls=[
|
|
2921
|
+
ToolCall(
|
|
2922
|
+
id=tool_call_id,
|
|
2923
|
+
function=_FC(name="retrieve", arguments=tool_args),
|
|
2924
|
+
type="function",
|
|
2925
|
+
)
|
|
2926
|
+
],
|
|
2927
|
+
)
|
|
2928
|
+
# Format chunks as the retrieve tool's actual output shape.
|
|
2929
|
+
formatted = "=== TEXT ===\n\n" + "\n\n".join(chunks)
|
|
2930
|
+
synth_tool = LLMMessage(
|
|
2931
|
+
role=Role.tool,
|
|
2932
|
+
content=formatted,
|
|
2933
|
+
name="retrieve",
|
|
2934
|
+
tool_call_id=tool_call_id,
|
|
2935
|
+
)
|
|
2936
|
+
self.messages.append(synth_assistant)
|
|
2937
|
+
self.messages.append(synth_tool)
|
|
2938
|
+
|
|
2939
|
+
logger.warning(
|
|
2940
|
+
"[AUTO-RETRIEVE] synthesized retrieve tool result: %d chunks "
|
|
2941
|
+
"(top score %.1f, content %d chars), msgs now %d",
|
|
2942
|
+
len(chunks),
|
|
2943
|
+
max(float(getattr(h, "score", 0)) for h in good_hits),
|
|
2944
|
+
len(formatted),
|
|
2945
|
+
len(self.messages),
|
|
2946
|
+
)
|
|
2947
|
+
|
|
2779
2948
|
async def _auto_route_task(self, user_msg: str) -> None:
|
|
2780
2949
|
"""Lightweight auto-context: list project files and key docs.
|
|
2781
2950
|
|
|
@@ -52,7 +52,9 @@ def _initialize() -> _CachedSteering | None:
|
|
|
52
52
|
|
|
53
53
|
try:
|
|
54
54
|
from drydock.steering import (
|
|
55
|
+
LogitBiasSteeringApplier,
|
|
55
56
|
LogOnlySteeringApplier,
|
|
57
|
+
NullSteeringApplier,
|
|
56
58
|
SteeringConfig,
|
|
57
59
|
load_registry,
|
|
58
60
|
)
|
|
@@ -63,13 +65,23 @@ def _initialize() -> _CachedSteering | None:
|
|
|
63
65
|
root = os.environ.get("DRYDOCK_STEERING_ROOT") or None
|
|
64
66
|
registry = load_registry(root)
|
|
65
67
|
config = SteeringConfig.from_mode_names(mode_names)
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
|
|
68
|
+
# Applier selection via DRYDOCK_STEERING_APPLIER:
|
|
69
|
+
# "log_only" (default) : log-only, no inference change
|
|
70
|
+
# "logit_bias" : token-level steering via vLLM logit_bias
|
|
71
|
+
# (manifest must carry tags.tokens_boost
|
|
72
|
+
# and/or tags.tokens_suppress)
|
|
73
|
+
# "null" : no-op (same as not setting MODES at all)
|
|
74
|
+
# Real activation steering (VllmSidecarSteeringApplier) lands later.
|
|
75
|
+
kind = os.environ.get("DRYDOCK_STEERING_APPLIER", "log_only").strip().lower()
|
|
76
|
+
if kind == "logit_bias":
|
|
77
|
+
applier = LogitBiasSteeringApplier()
|
|
78
|
+
elif kind == "null":
|
|
79
|
+
applier = NullSteeringApplier()
|
|
80
|
+
else:
|
|
81
|
+
applier = LogOnlySteeringApplier()
|
|
69
82
|
logger.info(
|
|
70
|
-
"steering: enabled, modes=%s, registry=%s",
|
|
71
|
-
mode_names,
|
|
72
|
-
registry.root,
|
|
83
|
+
"steering: enabled, modes=%s, applier=%s, registry=%s",
|
|
84
|
+
mode_names, applier.kind, registry.root,
|
|
73
85
|
)
|
|
74
86
|
return _CachedSteering(config=config, registry=registry, applier=applier)
|
|
75
87
|
|
|
@@ -586,6 +586,10 @@ class Bash(
|
|
|
586
586
|
state = self.state.__dict__.setdefault("_bash_history", {})
|
|
587
587
|
# Track total error-exit calls per command (regardless of output).
|
|
588
588
|
err_state = self.state.__dict__.setdefault("_bash_err_count", {})
|
|
589
|
+
# Track total run count per exact command regardless of output or
|
|
590
|
+
# exit code. Catches benchmark/timeit loops where output varies
|
|
591
|
+
# each run (timings differ) so the hash check never fires.
|
|
592
|
+
run_count_state = self.state.__dict__.setdefault("_bash_run_count", {})
|
|
589
593
|
# Track consecutive empty-stdout search commands (any command, not
|
|
590
594
|
# just identical ones). The model semantic-loops by trying different
|
|
591
595
|
# search terms for a non-existent target:
|
|
@@ -595,6 +599,73 @@ class Bash(
|
|
|
595
599
|
_consec_empty_search_state = self.state.__dict__.setdefault(
|
|
596
600
|
"_consec_empty_searches", {"count": 0}
|
|
597
601
|
)
|
|
602
|
+
# python -c / python3 -c SyntaxError loop-breaker.
|
|
603
|
+
# The model truncates multi-line inline scripts; each re-run
|
|
604
|
+
# produces a SyntaxError but with slightly different stderr
|
|
605
|
+
# (different column/line), so the hash check never fires.
|
|
606
|
+
# Track cross-command: any python3 -c that hits SyntaxError.
|
|
607
|
+
_python_c_err_state = self.state.__dict__.setdefault(
|
|
608
|
+
"_python_c_syntaxerr_count", 0
|
|
609
|
+
)
|
|
610
|
+
_is_python_c_syntaxerr = (
|
|
611
|
+
returncode != 0
|
|
612
|
+
and "SyntaxError" in stderr_raw
|
|
613
|
+
and bool(__import__("re").search(r"\bpython3?\s+-c\b", args.command))
|
|
614
|
+
)
|
|
615
|
+
if _is_python_c_syntaxerr:
|
|
616
|
+
self.state.__dict__["_python_c_syntaxerr_count"] = _python_c_err_state + 1
|
|
617
|
+
if _python_c_err_state >= 1:
|
|
618
|
+
_cnt = _python_c_err_state + 1
|
|
619
|
+
yield self._build_result(
|
|
620
|
+
command=args.command,
|
|
621
|
+
stdout=(
|
|
622
|
+
f"[LOOP-BREAKER: `python3 -c '...'` has hit SyntaxError "
|
|
623
|
+
f"{_cnt} times. Inline -c scripts get truncated by the "
|
|
624
|
+
f"shell when they contain newlines or quotes. "
|
|
625
|
+
f"Write the script to a file first, then run it:\n"
|
|
626
|
+
f" write_file path='/tmp/script.py' content='...'\n"
|
|
627
|
+
f" bash command='python3 /tmp/script.py'\n"
|
|
628
|
+
f"Do NOT retry the inline -c form again.]"
|
|
629
|
+
),
|
|
630
|
+
stderr="",
|
|
631
|
+
returncode=returncode,
|
|
632
|
+
)
|
|
633
|
+
return
|
|
634
|
+
|
|
635
|
+
# Exact-command repetition loop-breaker: fires when the same
|
|
636
|
+
# command text is run 5+ times regardless of output or exit code.
|
|
637
|
+
# Catches benchmark/timeit/import-check loops where each run has
|
|
638
|
+
# varying output (timings, object ids) that defeats the hash check.
|
|
639
|
+
# Excludes commands that write files (heredoc, redirect, sed -i)
|
|
640
|
+
# since those legitimately run the same form multiple times.
|
|
641
|
+
_is_write_cmd = bool(
|
|
642
|
+
__import__("re").search(
|
|
643
|
+
r"(>|>>|\bsed\s+-i\b|\btee\b|\bcat\s+<<|\bprintf\b.*>)",
|
|
644
|
+
args.command,
|
|
645
|
+
)
|
|
646
|
+
)
|
|
647
|
+
if not _is_write_cmd:
|
|
648
|
+
_run_cnt = run_count_state.get(args.command, 0) + 1
|
|
649
|
+
run_count_state[args.command] = _run_cnt
|
|
650
|
+
if _run_cnt >= 5:
|
|
651
|
+
cmd_preview = args.command[:80]
|
|
652
|
+
yield self._build_result(
|
|
653
|
+
command=args.command,
|
|
654
|
+
stdout=(
|
|
655
|
+
f"[LOOP-BREAKER: `{cmd_preview}` has been run "
|
|
656
|
+
f"{_run_cnt} times this session with the same "
|
|
657
|
+
f"command text. The output is stable — re-running "
|
|
658
|
+
f"it will not produce new information. "
|
|
659
|
+
f"Stop repeating this command and move on to the "
|
|
660
|
+
f"next task step. If you are benchmarking, one "
|
|
661
|
+
f"run is enough. If you are checking an import, "
|
|
662
|
+
f"the result is already known.]\n{stdout}"
|
|
663
|
+
),
|
|
664
|
+
stderr=stderr,
|
|
665
|
+
returncode=returncode,
|
|
666
|
+
)
|
|
667
|
+
return
|
|
668
|
+
|
|
598
669
|
if returncode != 0:
|
|
599
670
|
err_count = err_state.get(args.command, 0) + 1
|
|
600
671
|
err_state[args.command] = err_count
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Regression tests for GitHub issues #4, #5, #6."""
|
|
1
|
+
"""Regression tests for GitHub issues #4, #5, #6, #14."""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
import os
|
|
@@ -116,3 +116,103 @@ class TestIssue6BashAllowlistBasename:
|
|
|
116
116
|
# Returns None (caller prompts for approval) — not ALWAYS.
|
|
117
117
|
from drydock.core.tools.base import ToolPermission
|
|
118
118
|
assert res != ToolPermission.ALWAYS
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# Issue #14: empty assistant messages (no content, no tool_calls) persist in
|
|
122
|
+
# history after stall-retry exhaustion and cause 400 errors on the next turn.
|
|
123
|
+
# _sanitize_message_ordering must drop them before the next LLM call.
|
|
124
|
+
|
|
125
|
+
class TestIssue14EmptyAssistantDropped:
|
|
126
|
+
def _make_minimal_agent(self):
|
|
127
|
+
from drydock.core.agent_loop import AgentLoop
|
|
128
|
+
from drydock.core.types import MessageList
|
|
129
|
+
al = object.__new__(AgentLoop)
|
|
130
|
+
al.messages = MessageList()
|
|
131
|
+
# stubs for methods called by _sanitize_message_ordering
|
|
132
|
+
al._truncate_old_tool_results = lambda: None
|
|
133
|
+
al._proactive_prune_write_oscillation = lambda: None
|
|
134
|
+
import os as _os
|
|
135
|
+
al._os = _os
|
|
136
|
+
return al
|
|
137
|
+
|
|
138
|
+
def test_empty_assistant_dropped(self):
|
|
139
|
+
"""Empty assistant message (no content, no tool_calls) is dropped."""
|
|
140
|
+
from drydock.core.agent_loop import AgentLoop
|
|
141
|
+
from drydock.core.types import LLMMessage, Role, MessageList
|
|
142
|
+
import os
|
|
143
|
+
al = object.__new__(AgentLoop)
|
|
144
|
+
al.messages = MessageList()
|
|
145
|
+
al._truncate_old_tool_results = lambda: None
|
|
146
|
+
al._proactive_prune_write_oscillation = lambda: None
|
|
147
|
+
|
|
148
|
+
al.messages.append(LLMMessage(role=Role.user, content="hello"))
|
|
149
|
+
al.messages.append(LLMMessage(role=Role.assistant, content=None)) # empty — bug
|
|
150
|
+
|
|
151
|
+
original_env = os.environ.get("DRYDOCK_AUTO_CONTINUE_DISABLE")
|
|
152
|
+
os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = "1"
|
|
153
|
+
try:
|
|
154
|
+
al._sanitize_message_ordering()
|
|
155
|
+
finally:
|
|
156
|
+
if original_env is None:
|
|
157
|
+
os.environ.pop("DRYDOCK_AUTO_CONTINUE_DISABLE", None)
|
|
158
|
+
else:
|
|
159
|
+
os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = original_env
|
|
160
|
+
|
|
161
|
+
roles = [m.role for m in al.messages]
|
|
162
|
+
assert Role.assistant not in roles, f"Empty assistant must be dropped; got {roles}"
|
|
163
|
+
|
|
164
|
+
def test_empty_assistant_with_preceding_tool_result_both_dropped(self):
|
|
165
|
+
"""Tool result immediately before an empty assistant is also dropped
|
|
166
|
+
to avoid a dangling tool message with no matching assistant turn."""
|
|
167
|
+
from drydock.core.agent_loop import AgentLoop
|
|
168
|
+
from drydock.core.types import LLMMessage, Role, MessageList, ToolCall, FunctionCall
|
|
169
|
+
import os
|
|
170
|
+
al = object.__new__(AgentLoop)
|
|
171
|
+
al.messages = MessageList()
|
|
172
|
+
al._truncate_old_tool_results = lambda: None
|
|
173
|
+
al._proactive_prune_write_oscillation = lambda: None
|
|
174
|
+
|
|
175
|
+
al.messages.append(LLMMessage(role=Role.user, content="do it"))
|
|
176
|
+
al.messages.append(LLMMessage(
|
|
177
|
+
role=Role.assistant,
|
|
178
|
+
content=None,
|
|
179
|
+
tool_calls=[ToolCall(id="c1", function=FunctionCall(name="bash", arguments="{}"))],
|
|
180
|
+
))
|
|
181
|
+
al.messages.append(LLMMessage(role=Role.tool, content="ok", tool_call_id="c1"))
|
|
182
|
+
al.messages.append(LLMMessage(role=Role.assistant, content=None)) # empty — bug
|
|
183
|
+
|
|
184
|
+
os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = "1"
|
|
185
|
+
try:
|
|
186
|
+
al._sanitize_message_ordering()
|
|
187
|
+
finally:
|
|
188
|
+
os.environ.pop("DRYDOCK_AUTO_CONTINUE_DISABLE", None)
|
|
189
|
+
|
|
190
|
+
roles = [m.role for m in al.messages]
|
|
191
|
+
# The empty assistant AND its preceding orphan tool result should be gone
|
|
192
|
+
assert roles == [Role.user, Role.assistant, Role.tool] or roles == [Role.user], \
|
|
193
|
+
f"Unexpected roles after sanitize: {roles}"
|
|
194
|
+
# The productive assistant (with tool_calls) must survive
|
|
195
|
+
productive = [m for m in al.messages if m.role == Role.assistant]
|
|
196
|
+
assert all(m.tool_calls for m in productive), "Non-empty assistant must keep tool_calls"
|
|
197
|
+
|
|
198
|
+
def test_non_empty_assistant_preserved(self):
|
|
199
|
+
"""Assistant messages with content are never dropped."""
|
|
200
|
+
from drydock.core.agent_loop import AgentLoop
|
|
201
|
+
from drydock.core.types import LLMMessage, Role, MessageList
|
|
202
|
+
import os
|
|
203
|
+
al = object.__new__(AgentLoop)
|
|
204
|
+
al.messages = MessageList()
|
|
205
|
+
al._truncate_old_tool_results = lambda: None
|
|
206
|
+
al._proactive_prune_write_oscillation = lambda: None
|
|
207
|
+
|
|
208
|
+
al.messages.append(LLMMessage(role=Role.user, content="hi"))
|
|
209
|
+
al.messages.append(LLMMessage(role=Role.assistant, content="I'm here"))
|
|
210
|
+
|
|
211
|
+
os.environ["DRYDOCK_AUTO_CONTINUE_DISABLE"] = "1"
|
|
212
|
+
try:
|
|
213
|
+
al._sanitize_message_ordering()
|
|
214
|
+
finally:
|
|
215
|
+
os.environ.pop("DRYDOCK_AUTO_CONTINUE_DISABLE", None)
|
|
216
|
+
|
|
217
|
+
roles = [m.role for m in al.messages]
|
|
218
|
+
assert Role.assistant in roles, "Non-empty assistant must not be dropped"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Regression tests for the exact-command repetition loop-breaker.
|
|
2
|
+
|
|
3
|
+
The model sometimes reruns the same bash command 5+ times (timeit benchmarks,
|
|
4
|
+
import-check one-liners, etc.) even though each run's output varies slightly
|
|
5
|
+
(different timing, different object id). The hash-based dedup never fires
|
|
6
|
+
because hashes differ. This loop-breaker fires on the 5th identical run
|
|
7
|
+
regardless of output content.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
13
|
+
from tests.mock.utils import collect_result
|
|
14
|
+
from drydock.core.tools.base import BaseToolState
|
|
15
|
+
from drydock.core.tools.builtins.bash import Bash, BashArgs, BashToolConfig
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def bash(tmp_path, monkeypatch):
|
|
20
|
+
monkeypatch.chdir(tmp_path)
|
|
21
|
+
config = BashToolConfig()
|
|
22
|
+
return Bash(config=config, state=BaseToolState())
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@pytest.mark.asyncio
|
|
26
|
+
async def test_four_runs_no_breaker(bash, tmp_path):
|
|
27
|
+
"""Running the same command 4 times does not trigger the loop-breaker."""
|
|
28
|
+
cmd = "echo hello_unique_test_marker"
|
|
29
|
+
for _ in range(4):
|
|
30
|
+
result = await collect_result(bash.run(BashArgs(command=cmd)))
|
|
31
|
+
assert "LOOP-BREAKER" not in result.stdout
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.mark.asyncio
|
|
35
|
+
async def test_fifth_run_triggers_loop_breaker(bash, tmp_path):
|
|
36
|
+
"""5th run of the same exact command triggers the loop-breaker."""
|
|
37
|
+
cmd = "echo identical_cmd_loop_test"
|
|
38
|
+
for _ in range(5):
|
|
39
|
+
result = await collect_result(bash.run(BashArgs(command=cmd)))
|
|
40
|
+
assert "LOOP-BREAKER" in result.stdout
|
|
41
|
+
assert "5" in result.stdout
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@pytest.mark.asyncio
|
|
45
|
+
async def test_write_command_exempt(bash, tmp_path):
|
|
46
|
+
"""Commands that write files (> redirect) are exempt from the counter."""
|
|
47
|
+
outfile = tmp_path / "out.txt"
|
|
48
|
+
cmd = f"echo data > {outfile}"
|
|
49
|
+
for _ in range(5):
|
|
50
|
+
result = await collect_result(bash.run(BashArgs(command=cmd)))
|
|
51
|
+
assert "LOOP-BREAKER" not in result.stdout
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@pytest.mark.asyncio
|
|
55
|
+
async def test_distinct_commands_no_breaker(bash, tmp_path):
|
|
56
|
+
"""Different commands don't share the run counter."""
|
|
57
|
+
for i in range(6):
|
|
58
|
+
result = await collect_result(bash.run(BashArgs(command=f"echo cmd_{i}")))
|
|
59
|
+
assert "LOOP-BREAKER" not in result.stdout
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Regression tests for the python3 -c SyntaxError loop-breaker.
|
|
2
|
+
|
|
3
|
+
The model often truncates multi-line inline scripts, gets a SyntaxError,
|
|
4
|
+
and retries with slightly different content. Because each stderr differs
|
|
5
|
+
(different column/line), the hash-based dedup never fires. The dedicated
|
|
6
|
+
cross-command counter catches this on the 2nd failure and redirects to
|
|
7
|
+
write_file.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
13
|
+
from tests.mock.utils import collect_result
|
|
14
|
+
from drydock.core.tools.base import BaseToolState
|
|
15
|
+
from drydock.core.tools.builtins.bash import Bash, BashArgs, BashToolConfig
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def bash(tmp_path, monkeypatch):
|
|
20
|
+
monkeypatch.chdir(tmp_path)
|
|
21
|
+
config = BashToolConfig()
|
|
22
|
+
return Bash(config=config, state=BaseToolState())
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@pytest.mark.asyncio
|
|
26
|
+
async def test_first_syntaxerr_passes_through(bash):
|
|
27
|
+
"""First python3 -c SyntaxError is returned normally (no loop-breaker yet)."""
|
|
28
|
+
result = await collect_result(bash.run(BashArgs(command="python3 -c \"print('hello\"")))
|
|
29
|
+
assert "LOOP-BREAKER" not in result.stdout
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@pytest.mark.asyncio
|
|
33
|
+
async def test_second_syntaxerr_triggers_loop_breaker(bash):
|
|
34
|
+
"""Second python3 -c SyntaxError (different command) triggers the loop-breaker."""
|
|
35
|
+
# Truncated strings produce SyntaxError (unterminated string literal)
|
|
36
|
+
await collect_result(bash.run(BashArgs(command="python3 -c \"x = {'key': 'val\"")))
|
|
37
|
+
result = await collect_result(bash.run(BashArgs(command="python3 -c \"y = {'k2': 'v2\"")))
|
|
38
|
+
assert "LOOP-BREAKER" in result.stdout
|
|
39
|
+
assert "write_file" in result.stdout.lower() or "Write the script" in result.stdout
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.mark.asyncio
|
|
43
|
+
async def test_loop_breaker_only_fires_on_syntaxerr(bash):
|
|
44
|
+
"""ImportError (no SyntaxError) does not increment the python3 -c counter."""
|
|
45
|
+
# ImportError — not a SyntaxError; shouldn't accumulate in the counter
|
|
46
|
+
cmd = "python3 -c \"import nonexistent_pkg_xyz_abc\""
|
|
47
|
+
await collect_result(bash.run(BashArgs(command=cmd)))
|
|
48
|
+
result = await collect_result(bash.run(BashArgs(command=cmd)))
|
|
49
|
+
assert "LOOP-BREAKER" not in result.stdout or "python3 -c" not in result.stdout
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@pytest.mark.asyncio
|
|
53
|
+
async def test_successful_python_c_does_not_accumulate(bash):
|
|
54
|
+
"""Successful python3 -c runs don't trigger the breaker."""
|
|
55
|
+
await collect_result(bash.run(BashArgs(command="python3 -c \"print(1+1)\"")))
|
|
56
|
+
result = await collect_result(bash.run(BashArgs(command="python3 -c \"print(2+2)\"")))
|
|
57
|
+
assert "LOOP-BREAKER" not in result.stdout
|