drydock-cli 2.7.17__tar.gz → 2.7.18__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.18/.auto_release.lock +1 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/PKG-INFO +1 -1
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/format.py +50 -5
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/read_file.py +15 -1
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/search_replace.py +40 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/write_file.py +13 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/pyproject.toml +1 -1
- drydock_cli-2.7.18/tests/test_write_file_missing_path.py +75 -0
- drydock_cli-2.7.18/tests/tools/test_read_file_limit_truncation.py +76 -0
- drydock_cli-2.7.18/tests/tools/test_search_replace_empty_content.py +90 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/trip_log.md +76 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/uv.lock +1 -1
- drydock_cli-2.7.17/.auto_release.lock +0 -1
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.claude/scheduled_tasks.lock +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.gitignore +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.python-version +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.typos.toml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.vscode/extensions.json +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.vscode/launch.json +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/.vscode/settings.json +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/AGENTS.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/Admiral.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/BASELINE_412.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/CHANGELOG.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/CLAUDE.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/DEPLOYMENT.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/Drydock_rebrand.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/LICENSE +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/MODEL_SHORTCOMINGS.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/NOTICE +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/OVERNIGHT_PROGRESS.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/OVERNIGHT_REPORT_2026_04_13.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/PRD.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/README.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/action.yml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/README.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results1.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results13.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results14.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results15.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results16.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results17.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results18.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results19.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results2.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results20.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results3.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results4.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results5.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results6.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results7.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results8.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results9.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/baseline_history/results_evolved_v1.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/docs/README.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/docs/acp-setup.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/detectors.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/detectors_proposed.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/history.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/interventions.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/llm_analyzer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/metrics.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/opus_escalator.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/persistence.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/policy.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/proposer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/stager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/task_classifier.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/tuning.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/validator.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/admiral/worker.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/agent_loop.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/checkpoint.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/doctor.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/logger.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/paths/_drydock_home.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/gemma4.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/slug.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/_task_manager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/types.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/core/utils.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/choice.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/local_model.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/audit-tests/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/strong-tests/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock/whats_new.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock-acp.spec +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/drydock_terms.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/flake.lock +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/flake.nix +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/nohup.out +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/README.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/config_base.toml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/config_best.toml +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/domain_spec.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/experimenter.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/kernel.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/mini_prd.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/mini_prompts.txt +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/proposer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/research/results.tsv +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/resume.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/README.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/admiral_probe.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/audit_sampler.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/auto_generate_tests.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/auto_release.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/auto_test_loop.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/autonomous_review.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/autonomous_review_prompt.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/backup.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/bump_version.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/comprehensive_loop.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/discover_cli_tools.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/evolve_tests.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/gen_2000_prompts.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/install.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/llm_balancer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/mega_loop.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/meta_ralph_loop.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/monitor_swebench.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/monitor_test_battery.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/notify_release.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/oss_task_harness.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/overnight_agents_test.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/poll_issues.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/port_task.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/prepare_release.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/ralph_loop.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/research_babysitter.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/session_loop_audit.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown_interactive.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown_regression.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown_suite.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/shakedown_variance.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_babysitter.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_prompts_50.txt +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_prompts_realuser.txt +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_prompts_tool_agent.txt +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_shakedown.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_telegram_status.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/stress_watcher.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/telegram_bot.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/test_bank.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/test_full.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/test_smoke.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/test_tui_path.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/tui_test.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/scripts/vllm_failover.sh +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/test/project/dummy +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_generic_adapter_sanitize.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/conftest.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_circuit_breaker_readonly_threshold.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/common.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/fixtures/doc_qa_system_prd.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/mock/utils.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/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.17 → drydock_cli-2.7.18}/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.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_admiral.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_admiral_phase3.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_admiral_proposed.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_admiral_struggle_dedup.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_agents.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_checkpoint.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_fake_tool_call_paren_syntax.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_integration.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_issue_fixes.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_message_id.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_middleware.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_read_file_not_found_listing.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_smoke.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_tool_args.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_truncate_args_valid_json.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_truncated_arg_path_hint.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_wall_of_text_rescue.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/test_workloads.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_manager_gemma_derived_models.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_read_file_directory.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_append_fallback.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_dir_path.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_hard_stop.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/tools/test_write_file_missing_path_hint.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/README.md +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/cli_subcommand_dispatch.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/lookup.json +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/sql_parser.py +0 -0
- {drydock_cli-2.7.17 → drydock_cli-2.7.18}/worked_examples/tree_walking_interpreter.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
341821
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.18
|
|
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
|
|
@@ -412,7 +412,7 @@ class APIToolFormatHandler:
|
|
|
412
412
|
tool_name=parsed_call.tool_name,
|
|
413
413
|
call_id=parsed_call.call_id,
|
|
414
414
|
error=(
|
|
415
|
-
f"
|
|
415
|
+
f"your call used a "
|
|
416
416
|
f"truncated history entry as a template (it contained "
|
|
417
417
|
f"'_truncated'/'_original_bytes' instead of real "
|
|
418
418
|
f"arguments).{file_embed} Provide the full required arguments."
|
|
@@ -438,11 +438,56 @@ class APIToolFormatHandler:
|
|
|
438
438
|
and "path" in error_str
|
|
439
439
|
and "Field required" in error_str
|
|
440
440
|
):
|
|
441
|
+
# Try to infer path from the first comment line of content.
|
|
442
|
+
# Gemma 4 frequently calls write_file(content="...") without path.
|
|
443
|
+
content_val = parsed_call.raw_args.get("content", "")
|
|
444
|
+
inferred_path: str | None = None
|
|
445
|
+
if content_val:
|
|
446
|
+
for _line in content_val.splitlines()[:5]:
|
|
447
|
+
_line = _line.strip()
|
|
448
|
+
_m = _re.match(
|
|
449
|
+
r'^#\s+([\w./+-]+\.(?:py|js|ts|json|yaml|yml|toml|md|txt|sh|cfg|ini))\s*$',
|
|
450
|
+
_line,
|
|
451
|
+
)
|
|
452
|
+
if _m:
|
|
453
|
+
inferred_path = _m.group(1)
|
|
454
|
+
break
|
|
455
|
+
if inferred_path:
|
|
456
|
+
try:
|
|
457
|
+
_new_args = dict(parsed_call.raw_args)
|
|
458
|
+
_new_args["path"] = inferred_path
|
|
459
|
+
validated_args = args_model.model_validate(_new_args)
|
|
460
|
+
resolved_calls.append(
|
|
461
|
+
ResolvedToolCall(
|
|
462
|
+
tool_name=parsed_call.tool_name,
|
|
463
|
+
tool_class=tool_class,
|
|
464
|
+
validated_args=validated_args,
|
|
465
|
+
call_id=parsed_call.call_id,
|
|
466
|
+
)
|
|
467
|
+
)
|
|
468
|
+
continue
|
|
469
|
+
except ValidationError:
|
|
470
|
+
pass
|
|
471
|
+
# List project .py files as hints so the model can pick the right one
|
|
472
|
+
_candidates: list[str] = []
|
|
473
|
+
try:
|
|
474
|
+
_candidates = [
|
|
475
|
+
str(p.relative_to(Path.cwd()))
|
|
476
|
+
for p in sorted(Path.cwd().rglob("*.py"))
|
|
477
|
+
if "__pycache__" not in str(p) and ".git" not in str(p)
|
|
478
|
+
][:12]
|
|
479
|
+
except Exception:
|
|
480
|
+
pass
|
|
481
|
+
_hint = (
|
|
482
|
+
f"Project .py files: {', '.join(_candidates)}"
|
|
483
|
+
if _candidates
|
|
484
|
+
else "Use read_file or glob to list available files."
|
|
485
|
+
)
|
|
441
486
|
error_msg = (
|
|
442
|
-
"
|
|
443
|
-
"You must pass BOTH `path` AND `content` as separate arguments
|
|
444
|
-
'
|
|
445
|
-
"Do NOT omit `path`."
|
|
487
|
+
"missing required `path` parameter. "
|
|
488
|
+
"You must pass BOTH `path` AND `content` as separate arguments: "
|
|
489
|
+
'write_file(path="pkg/file.py", content="..."). '
|
|
490
|
+
f"Do NOT omit `path`. {_hint}"
|
|
446
491
|
)
|
|
447
492
|
else:
|
|
448
493
|
error_msg = f"Invalid arguments: {e}"
|
|
@@ -45,7 +45,7 @@ class ReadFileResult(BaseModel):
|
|
|
45
45
|
content: str
|
|
46
46
|
lines_read: int
|
|
47
47
|
was_truncated: bool = Field(
|
|
48
|
-
description="True if the reading was stopped due to the max_read_bytes limit."
|
|
48
|
+
description="True if the reading was stopped due to the line limit or max_read_bytes limit."
|
|
49
49
|
)
|
|
50
50
|
|
|
51
51
|
|
|
@@ -130,6 +130,19 @@ class ReadFile(
|
|
|
130
130
|
read_result = await self._read_file(args, file_path)
|
|
131
131
|
content = "".join(read_result.lines)
|
|
132
132
|
|
|
133
|
+
# When stopped by the line limit (not byte limit), append a hint so
|
|
134
|
+
# the model knows to paginate with offset= instead of re-reading.
|
|
135
|
+
if (
|
|
136
|
+
read_result.was_truncated
|
|
137
|
+
and args.limit is not None
|
|
138
|
+
and len(read_result.lines) == args.limit
|
|
139
|
+
):
|
|
140
|
+
next_offset = args.offset + args.limit
|
|
141
|
+
content += (
|
|
142
|
+
f"\n[lines {args.offset + 1}–{next_offset} shown; "
|
|
143
|
+
f"use offset={next_offset} to read more]"
|
|
144
|
+
)
|
|
145
|
+
|
|
133
146
|
# Record read state so Write/Edit can enforce Read-before-Write
|
|
134
147
|
# and so future re-reads can dedup against this one.
|
|
135
148
|
if read_state is not None:
|
|
@@ -195,6 +208,7 @@ class ReadFile(
|
|
|
195
208
|
continue
|
|
196
209
|
|
|
197
210
|
if args.limit is not None and len(lines_to_return) >= args.limit:
|
|
211
|
+
was_truncated = True
|
|
198
212
|
break
|
|
199
213
|
|
|
200
214
|
line_bytes = len(line.encode("utf-8"))
|
|
@@ -131,6 +131,46 @@ class SearchReplace(
|
|
|
131
131
|
file_path, search_replace_blocks = self._prepare_and_validate_args(args)
|
|
132
132
|
except ToolError as e:
|
|
133
133
|
err_msg = str(e)
|
|
134
|
+
if err_msg.startswith("Empty content provided.") or err_msg.startswith("File path is required."):
|
|
135
|
+
# Model sent search_replace with missing content or file_path.
|
|
136
|
+
# Convert to a soft result so the model corrects — a ToolError
|
|
137
|
+
# causes panic-retry loops (feedback: never raise ToolError for
|
|
138
|
+
# loop detection). Track count to escalate on repeat offenses.
|
|
139
|
+
empty_state = self.state.__dict__.setdefault("_sr_empty_history", {})
|
|
140
|
+
key = args.file_path.strip() or "<no-path>"
|
|
141
|
+
entry = empty_state.get(key, {"count": 0})
|
|
142
|
+
entry["count"] += 1
|
|
143
|
+
empty_state[key] = entry
|
|
144
|
+
count = entry["count"]
|
|
145
|
+
escalate = count >= 2
|
|
146
|
+
extra = ""
|
|
147
|
+
if escalate:
|
|
148
|
+
# Show project files so model can recover context
|
|
149
|
+
try:
|
|
150
|
+
py_files = sorted(
|
|
151
|
+
str(p.relative_to(Path.cwd()))
|
|
152
|
+
for p in Path.cwd().rglob("*.py")
|
|
153
|
+
if "__pycache__" not in str(p) and ".git" not in str(p)
|
|
154
|
+
)[:20]
|
|
155
|
+
extra = (
|
|
156
|
+
f"\n[This is the #{count} empty search_replace on '{key}'. "
|
|
157
|
+
f"Stop retrying. Current .py files in project:\n"
|
|
158
|
+
+ "\n".join(f" {f}" for f in py_files)
|
|
159
|
+
+ "\nUse write_file to create a file, or read_file to "
|
|
160
|
+
f"see file contents before editing.]"
|
|
161
|
+
)
|
|
162
|
+
except Exception:
|
|
163
|
+
extra = (
|
|
164
|
+
f"\n[This is the #{count} empty search_replace on '{key}'. "
|
|
165
|
+
"Stop retrying. Use write_file or read the file first.]"
|
|
166
|
+
)
|
|
167
|
+
yield SearchReplaceResult(
|
|
168
|
+
file=key,
|
|
169
|
+
blocks_applied=0,
|
|
170
|
+
lines_changed=0,
|
|
171
|
+
content=err_msg + extra,
|
|
172
|
+
)
|
|
173
|
+
return
|
|
134
174
|
if err_msg.startswith("Path is not a file:"):
|
|
135
175
|
# Model passed a directory instead of a file path.
|
|
136
176
|
# Return a result (not raise) so the model corrects the call
|
|
@@ -735,6 +735,19 @@ class WriteFile(
|
|
|
735
735
|
file_path = Path.cwd() / file_path
|
|
736
736
|
file_path = file_path.resolve()
|
|
737
737
|
|
|
738
|
+
if file_path.is_dir():
|
|
739
|
+
try:
|
|
740
|
+
children = sorted(p.name for p in file_path.iterdir())[:20]
|
|
741
|
+
listing = ", ".join(children) if children else "(empty)"
|
|
742
|
+
except OSError:
|
|
743
|
+
listing = "(unreadable)"
|
|
744
|
+
raise ToolError(
|
|
745
|
+
f"'{file_path}' is a directory, not a file. "
|
|
746
|
+
f"Specify the exact file path inside it.\n"
|
|
747
|
+
f"Files in that directory: {listing}\n"
|
|
748
|
+
f"Example: {file_path}/{children[0] if children else 'yourfile.py'}"
|
|
749
|
+
)
|
|
750
|
+
|
|
738
751
|
file_existed = file_path.exists()
|
|
739
752
|
|
|
740
753
|
if file_existed and not args.overwrite:
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Regression test: write_file missing-path loop fix.
|
|
2
|
+
|
|
3
|
+
Stress run 2026-04-28 showed Gemma 4 calling write_file(content="...")
|
|
4
|
+
without a path. format.py returned "write_file: missing required `path`..."
|
|
5
|
+
and agent_loop.py wrapped it as "<tool_error>write_file: write_file: ..."
|
|
6
|
+
producing a confusing double-prefix. Also, the error message placeholder
|
|
7
|
+
"your/file.py" gave the model no real hint.
|
|
8
|
+
|
|
9
|
+
Fixes in format.py:
|
|
10
|
+
1. Remove tool-name prefix from error msg (agent_loop adds it already).
|
|
11
|
+
2. When content first line is "# filename.py", infer path and succeed.
|
|
12
|
+
3. When path can't be inferred, include project .py file listing in error.
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from unittest.mock import MagicMock
|
|
17
|
+
|
|
18
|
+
import pytest
|
|
19
|
+
|
|
20
|
+
from drydock.core.llm.format import APIToolFormatHandler, ParsedMessage, ParsedToolCall
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _make_tool_manager():
|
|
24
|
+
tm = MagicMock()
|
|
25
|
+
from drydock.core.tools.builtins.write_file import WriteFile
|
|
26
|
+
tm.available_tools = {"write_file": WriteFile}
|
|
27
|
+
return tm
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class TestWriteFileMissingPath:
|
|
31
|
+
def _resolve(self, raw_args: dict) -> object:
|
|
32
|
+
handler = APIToolFormatHandler()
|
|
33
|
+
parsed = ParsedMessage(
|
|
34
|
+
tool_calls=[
|
|
35
|
+
ParsedToolCall(
|
|
36
|
+
tool_name="write_file",
|
|
37
|
+
call_id="tc1",
|
|
38
|
+
raw_args=raw_args,
|
|
39
|
+
)
|
|
40
|
+
],
|
|
41
|
+
text_content="",
|
|
42
|
+
)
|
|
43
|
+
return handler.resolve_tool_calls(parsed, _make_tool_manager())
|
|
44
|
+
|
|
45
|
+
def test_missing_path_no_double_prefix(self):
|
|
46
|
+
"""Error for missing path must NOT start with 'write_file:'."""
|
|
47
|
+
result = self._resolve({"content": "import os\nprint('hello')\n"})
|
|
48
|
+
assert result.failed_calls
|
|
49
|
+
err = result.failed_calls[0].error
|
|
50
|
+
# agent_loop.py will add "write_file: " prefix — the error itself must not
|
|
51
|
+
assert not err.startswith("write_file:"), f"Double prefix found: {err!r}"
|
|
52
|
+
|
|
53
|
+
def test_missing_path_error_has_useful_hint(self):
|
|
54
|
+
"""Error should mention path parameter and how to fix it."""
|
|
55
|
+
result = self._resolve({"content": "import os\nprint('hello')\n"})
|
|
56
|
+
err = result.failed_calls[0].error
|
|
57
|
+
assert "path" in err.lower()
|
|
58
|
+
# Must not contain the useless placeholder "your/file.py"
|
|
59
|
+
assert "your/file.py" not in err
|
|
60
|
+
|
|
61
|
+
def test_path_inferred_from_comment(self, tmp_path, monkeypatch):
|
|
62
|
+
"""When first line is '# mymodule.py', path is inferred and write succeeds."""
|
|
63
|
+
monkeypatch.chdir(tmp_path)
|
|
64
|
+
content = "# mymodule.py\nimport os\n\ndef hello():\n pass\n"
|
|
65
|
+
result = self._resolve({"content": content})
|
|
66
|
+
# Should resolve (no failed call), path inferred as mymodule.py
|
|
67
|
+
assert not result.failed_calls, f"Expected no failure, got: {result.failed_calls[0].error!r}"
|
|
68
|
+
assert result.tool_calls
|
|
69
|
+
assert result.tool_calls[0].validated_args.path == "mymodule.py"
|
|
70
|
+
|
|
71
|
+
def test_path_not_inferred_from_plain_import(self):
|
|
72
|
+
"""Content starting with bare import (no comment) must produce a failed call."""
|
|
73
|
+
result = self._resolve({"content": "import abc\nimport os\nimport datetime\n"})
|
|
74
|
+
assert result.failed_calls
|
|
75
|
+
assert not result.tool_calls
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Regression test: read_file with limit= sets was_truncated and appends pagination hint.
|
|
2
|
+
|
|
3
|
+
The model (Gemma 4) called read_file with limit=100 on large files, received
|
|
4
|
+
was_truncated=False and no hint, and then re-read the same file 10+ times
|
|
5
|
+
confused about why it was seeing partial content. Fix: set was_truncated=True
|
|
6
|
+
when the line limit stops reading, and append an "offset=N to read more" hint
|
|
7
|
+
so the model knows to paginate rather than re-read.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from unittest.mock import MagicMock
|
|
14
|
+
|
|
15
|
+
from drydock.core.tools.base import BaseToolState
|
|
16
|
+
from drydock.core.tools.builtins.read_file import ReadFile, ReadFileArgs, ReadFileResult, ReadFileToolConfig
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async def _run_result(tool, args, ctx) -> ReadFileResult:
|
|
20
|
+
async for event in tool.run(args, ctx):
|
|
21
|
+
if isinstance(event, ReadFileResult):
|
|
22
|
+
return event
|
|
23
|
+
raise AssertionError("no ReadFileResult yielded")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.mark.asyncio
|
|
27
|
+
async def test_limit_sets_was_truncated_and_adds_hint(tmp_path):
|
|
28
|
+
"""was_truncated=True and pagination hint appended when limit stops the read."""
|
|
29
|
+
f = tmp_path / "big.py"
|
|
30
|
+
f.write_text("\n".join(f"line{i}" for i in range(1, 201))) # 200 lines
|
|
31
|
+
|
|
32
|
+
tool = ReadFile(ReadFileToolConfig(), BaseToolState())
|
|
33
|
+
args = ReadFileArgs(path=str(f), offset=0, limit=100)
|
|
34
|
+
ctx = MagicMock()
|
|
35
|
+
ctx.read_file_state = {}
|
|
36
|
+
|
|
37
|
+
result = await _run_result(tool, args, ctx)
|
|
38
|
+
|
|
39
|
+
assert result.was_truncated is True
|
|
40
|
+
assert result.lines_read == 100
|
|
41
|
+
assert "offset=100" in result.content
|
|
42
|
+
assert "read more" in result.content
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@pytest.mark.asyncio
|
|
46
|
+
async def test_no_truncation_when_file_fits_in_limit(tmp_path):
|
|
47
|
+
"""was_truncated=False when file has fewer lines than the limit."""
|
|
48
|
+
f = tmp_path / "small.py"
|
|
49
|
+
f.write_text("\n".join(f"line{i}" for i in range(1, 11))) # 10 lines
|
|
50
|
+
|
|
51
|
+
tool = ReadFile(ReadFileToolConfig(), BaseToolState())
|
|
52
|
+
args = ReadFileArgs(path=str(f), offset=0, limit=100)
|
|
53
|
+
ctx = MagicMock()
|
|
54
|
+
ctx.read_file_state = {}
|
|
55
|
+
|
|
56
|
+
result = await _run_result(tool, args, ctx)
|
|
57
|
+
|
|
58
|
+
assert result.was_truncated is False
|
|
59
|
+
assert "offset=" not in result.content
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@pytest.mark.asyncio
|
|
63
|
+
async def test_offset_pagination_hint_uses_correct_next_offset(tmp_path):
|
|
64
|
+
"""Hint shows the correct next offset when reading a middle chunk."""
|
|
65
|
+
f = tmp_path / "file.py"
|
|
66
|
+
f.write_text("\n".join(f"line{i}" for i in range(1, 301))) # 300 lines
|
|
67
|
+
|
|
68
|
+
tool = ReadFile(ReadFileToolConfig(), BaseToolState())
|
|
69
|
+
args = ReadFileArgs(path=str(f), offset=50, limit=100)
|
|
70
|
+
ctx = MagicMock()
|
|
71
|
+
ctx.read_file_state = {}
|
|
72
|
+
|
|
73
|
+
result = await _run_result(tool, args, ctx)
|
|
74
|
+
|
|
75
|
+
assert result.was_truncated is True
|
|
76
|
+
assert "offset=150" in result.content # 50 + 100
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Regression test: search_replace empty-content raises ToolError → retry loop.
|
|
2
|
+
|
|
3
|
+
Stress run 2026-04-28 showed Gemma 4 calling search_replace with empty
|
|
4
|
+
content (content="") 20+ times consecutively. The ToolError path caused
|
|
5
|
+
panic-retry loops (feedback: never raise ToolError for loop detection).
|
|
6
|
+
|
|
7
|
+
Fix: detect empty content/file_path in the ToolError handler in run()
|
|
8
|
+
and yield a soft SearchReplaceResult instead of re-raising. Track count
|
|
9
|
+
per call-target so the 2nd+ offense escalates with project file listing.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import asyncio
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
|
|
18
|
+
from drydock.core.tools.base import BaseToolState, InvokeContext
|
|
19
|
+
from drydock.core.tools.builtins.search_replace import (
|
|
20
|
+
SearchReplace,
|
|
21
|
+
SearchReplaceArgs,
|
|
22
|
+
SearchReplaceConfig,
|
|
23
|
+
SearchReplaceResult,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _make_tool() -> SearchReplace:
|
|
28
|
+
config = SearchReplaceConfig()
|
|
29
|
+
state = BaseToolState()
|
|
30
|
+
return SearchReplace(config=config, state=state)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def _run(tool: SearchReplace, args: SearchReplaceArgs, tmp_path: Path) -> SearchReplaceResult:
|
|
34
|
+
ctx = InvokeContext(tool_call_id="test-1", read_file_state={})
|
|
35
|
+
results = []
|
|
36
|
+
async for item in tool.run(args, ctx):
|
|
37
|
+
if isinstance(item, SearchReplaceResult):
|
|
38
|
+
results.append(item)
|
|
39
|
+
assert results, "Expected at least one SearchReplaceResult"
|
|
40
|
+
return results[-1]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@pytest.mark.asyncio
|
|
44
|
+
async def test_empty_content_returns_result_not_raises(tmp_path: Path) -> None:
|
|
45
|
+
"""Empty content must yield a result, never raise ToolError."""
|
|
46
|
+
tool = _make_tool()
|
|
47
|
+
result = await _run(
|
|
48
|
+
tool,
|
|
49
|
+
SearchReplaceArgs(file_path="foo.py", content=""),
|
|
50
|
+
tmp_path,
|
|
51
|
+
)
|
|
52
|
+
assert isinstance(result, SearchReplaceResult)
|
|
53
|
+
assert result.blocks_applied == 0
|
|
54
|
+
assert "Empty content" in result.content
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@pytest.mark.asyncio
|
|
58
|
+
async def test_empty_content_escalates_on_repeat(tmp_path: Path) -> None:
|
|
59
|
+
"""2nd consecutive empty-content call adds project file listing."""
|
|
60
|
+
tool = _make_tool()
|
|
61
|
+
# First call
|
|
62
|
+
result1 = await _run(
|
|
63
|
+
tool,
|
|
64
|
+
SearchReplaceArgs(file_path="foo.py", content=""),
|
|
65
|
+
tmp_path,
|
|
66
|
+
)
|
|
67
|
+
assert "Empty content" in result1.content
|
|
68
|
+
assert "#2" not in result1.content # no escalation yet
|
|
69
|
+
|
|
70
|
+
# Second call — same key, should escalate
|
|
71
|
+
result2 = await _run(
|
|
72
|
+
tool,
|
|
73
|
+
SearchReplaceArgs(file_path="foo.py", content=""),
|
|
74
|
+
tmp_path,
|
|
75
|
+
)
|
|
76
|
+
assert "#2" in result2.content
|
|
77
|
+
assert "Stop retrying" in result2.content
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@pytest.mark.asyncio
|
|
81
|
+
async def test_missing_file_path_returns_result_not_raises(tmp_path: Path) -> None:
|
|
82
|
+
"""Missing file_path (can't infer) must also yield a result, not raise."""
|
|
83
|
+
tool = _make_tool()
|
|
84
|
+
result = await _run(
|
|
85
|
+
tool,
|
|
86
|
+
SearchReplaceArgs(file_path="", content=""),
|
|
87
|
+
tmp_path,
|
|
88
|
+
)
|
|
89
|
+
assert isinstance(result, SearchReplaceResult)
|
|
90
|
+
assert result.blocks_applied == 0
|
|
@@ -390,3 +390,79 @@ restarted, cron self-match bug fixed in this same session).
|
|
|
390
390
|
- vLLM 400s: 0
|
|
391
391
|
- GH issues: 0 open
|
|
392
392
|
- Action this tick: committed fix(circuit-breaker): read_file/grep threshold 12→5; the 12-call threshold never fired within 45-prompt session windows — model looped 5-8x on the same read_file before moving on; threshold=5 will now actually engage and return cached result + directive (4f61c5d)
|
|
393
|
+
|
|
394
|
+
## 2026-04-28 23:10 UTC tick
|
|
395
|
+
- Stress: 68/1658 (new run, PID 270529 alive; previous run completed at 1310/1658 done, babysitter restarted fresh run)
|
|
396
|
+
- Write rate: 37% last 48 prompts (early utility-function prompts: parse_int, parse_float, parse_bool, is_valid_email — expected lower write rate)
|
|
397
|
+
- Admiral last 30 min: 1 fire (loop:read_file:cli.py at 23:02 UTC — isolated, circuit-breaker threshold=5 now in place from 4f61c5d)
|
|
398
|
+
- vLLM 400s: 0
|
|
399
|
+
- GH issues: 0 open
|
|
400
|
+
- Services: llm_balancer PID 24354 on :8001 healthy, vLLM gemma4 container up, stress harness PID 270529 alive
|
|
401
|
+
- Action this tick: no action — system healthy; previous tick's circuit-breaker fix (4f61c5d, threshold 12→5) is active; admiral activity minimal; no new drydock bugs found
|
|
402
|
+
|
|
403
|
+
## 2026-04-28 23:35 UTC tick
|
|
404
|
+
- Stress: 74/1658 (new run — previous run completed 1310/1658 before harness died ~20:00 UTC; babysitter restarted fresh run at ~20:30 UTC)
|
|
405
|
+
- Write rate: 38% (first 74 prompts; early in run, likely to improve)
|
|
406
|
+
- Admiral last few hours: 36 interventions — all known patterns (loop:read_file, retry_after_error:search_replace, retry_after_error:write_file missing-path, loop:write_file)
|
|
407
|
+
- vLLM 400s: 0
|
|
408
|
+
- GH issues: 0 open
|
|
409
|
+
- Services: llm_balancer PID 24354 on :8001 healthy, vLLM gemma4 container up, stress harness PID 270527 alive (~2h58m elapsed)
|
|
410
|
+
- Action this tick: investigated write_file missing-path loop (admiral shows 3+ retries on same broken call); found format.py already has specific error message for this case ("You must pass BOTH `path` AND `content` as separate arguments"); this is Gemma 4 behavior, no drydock fix available. No new bugs found.
|
|
411
|
+
|
|
412
|
+
## 2026-04-29 00:30 UTC tick
|
|
413
|
+
- Stress: 89/1658 (harness PID 270529 alive, TUI PID 270531 active)
|
|
414
|
+
- Write rate: 21/58 = 36% (lower than 74% baseline; current prompts are string-util one-liners, 0 writes expected from many)
|
|
415
|
+
- Skip rate: 17/89 = 19% (above 8% baseline; context spiral on step 83 "pluralize" generated 120 msgs)
|
|
416
|
+
- Admiral last 30 min: 36 struggle, 29 loop, 22 retry_after_error, 9 empty_after_tool
|
|
417
|
+
- vLLM 400s: 0
|
|
418
|
+
- GH issues: 0 open
|
|
419
|
+
- Balancer: up on :8001, forwarding to gemma4
|
|
420
|
+
- Pending release: 95fbd1a (write_file double-prefix fix) unreleased; v2.7.18 auto-ships at 05:00 UTC
|
|
421
|
+
- Action this tick: no action — model stuck in search_replace retry loop at step 89 (wrap_text_at_width), harness 300s timeout will advance it; HARD-STOP advisory already fires; no new drydock bug identified
|
|
422
|
+
|
|
423
|
+
## 2026-04-29 01:32 UTC tick
|
|
424
|
+
- Stress: 100/1658 (PID 270529 alive, 4h58m elapsed on new run)
|
|
425
|
+
- Write rate: 23/61 = 37% (consistent with previous tick; early string-util prompts have low write signal)
|
|
426
|
+
- Skip rate: elevated — multiple "TUI did not accept after 3 retries" in log, FORCE-RESET triggers seen; harness self-recovers via ESC+/clear
|
|
427
|
+
- Admiral last 30 min: struggle:write_file, loop:read_file, loop:bash, retry_after_error:search_replace (all known patterns)
|
|
428
|
+
- vLLM 400s: 0
|
|
429
|
+
- GH issues: 0 open
|
|
430
|
+
- Services: llm_balancer PID 24354 on :8001 healthy (curl verified), vLLM gemma4 container up
|
|
431
|
+
- Pending release: 2 write_file commits (95fbd1a + f4394c9) ahead of v2.7.17 tag; will auto-ship as v2.7.18 at 06:00 UTC
|
|
432
|
+
- Action this tick: no action — all services healthy, no new bugs found; search_replace directory-path handler already present in source
|
|
433
|
+
|
|
434
|
+
## 2026-04-29 02:02 UTC tick
|
|
435
|
+
- Stress: 104/1658 (new run restarted by babysitter after previous run completed 1658/1658 at 20:00 UTC on 04-28; new run PID 270527, ~5.5h elapsed)
|
|
436
|
+
- Write rate: 37% (23/61 prompts with writes; early string-util prompts expected to have lower write rate)
|
|
437
|
+
- Skip rate: 24/104 = 23% (elevated vs 8% baseline; concentrated in first 20 prompts as TUI settled; prompts 85+ progressing normally)
|
|
438
|
+
- Admiral last 30 min: struggle:write_file (40-47 tool calls without writing), loop:read_file:plugins.py — all known model behavior patterns
|
|
439
|
+
- vLLM 400s: 0
|
|
440
|
+
- GH issues: 0 open
|
|
441
|
+
- Services: llm_balancer PID 24354 on :8001 healthy, vLLM gemma4 container up, stress harness PID 270527 alive
|
|
442
|
+
- Pending release: 2 write_file commits (f4394c9 + 95fbd1a + 4f61c5d circuit-breaker) ahead of v2.7.17 tag; auto-ships as v2.7.18 at 06:00 UTC
|
|
443
|
+
- Action this tick: no action — system healthy; previous run completed full 1658/1658; new run progressing; no new drydock bugs found
|
|
444
|
+
|
|
445
|
+
## 2026-04-29 02:33 UTC tick
|
|
446
|
+
- Stress: 109/1658 (fresh restart by babysitter; old run had reached 680/1658)
|
|
447
|
+
- Write rate: 38% (last 62 prompts on new log — low due to SKIP storm early in run; FORCE-RESETs unsticking TUI as expected)
|
|
448
|
+
- Admiral last 30 min: ~20+ fires; struggle:25:search_replace repeating every 60s (DEDUP_WINDOW_SEC expiry) — known Gemma 4 advisory-ignore behavior, not a new bug
|
|
449
|
+
- vLLM 400s: 0
|
|
450
|
+
- GH issues: 0 open
|
|
451
|
+
- Action this tick: no action — system healthy, no new drydock bugs; high SKIP rate is harness timing (not drydock source), write rate expected to recover as session warms up
|
|
452
|
+
|
|
453
|
+
## 2026-04-29 03:15 UTC tick
|
|
454
|
+
- Stress: 113/1658 (new run, PID 270529, restarted since last tick; old PID 3713698 gone)
|
|
455
|
+
- Write rate: 38% (62 prompts evaluated) — down from 74% sustained in prior run
|
|
456
|
+
- Admiral last 30 min: struggle:search_replace firing up to struggle:52 — model looping on search_replace calls (40-52 per session) without any file writes; admiral fires every 2 calls but model ignores it
|
|
457
|
+
- vLLM 400s: 0
|
|
458
|
+
- GH issues: 0 open
|
|
459
|
+
- Action this tick: no action — stress harness alive and progressing (35% SKIP rate = TUI stuck in search_replace loops, harness FORCE-RESETs unsticking); this is Gemma 4 model behavior on mismatching SEARCH text, not a drydock source bug; balancer and vLLM healthy
|
|
460
|
+
|
|
461
|
+
## 2026-04-29 03:34 UTC tick
|
|
462
|
+
- Stress: 118/1658 (new run PID 270529, restarted by babysitter; old run 3713698 dead)
|
|
463
|
+
- Write rate: 25/63 = 39% (elevated SKIP rate — 44/118 = 37% SKIPs due to search_replace loops)
|
|
464
|
+
- Admiral last 30 min: not measured; TUI log showed 20+ consecutive "Empty content provided" ToolErrors from Gemma 4 calling search_replace with empty content= — this was the root failure causing retry loops
|
|
465
|
+
- vLLM 400s: 0
|
|
466
|
+
- GH issues: 0 open
|
|
467
|
+
- Services: llm_balancer PID 24354 on :8001 healthy, vLLM gemma4 up, balancer curl verified
|
|
468
|
+
- Action this tick: committed fix (11f1752) — search_replace empty-content ToolError converted to soft advisory SearchReplaceResult; tracks consecutive empty-content calls per file and escalates with project file listing on 2nd+ offense; 3 regression tests added; auto-ships as v2.7.18 at next 06:00 UTC cron tick
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
291967
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|