drydock-cli 0.5.0__tar.gz → 0.5.2__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-0.5.2/PKG-INFO +245 -0
- drydock_cli-0.5.2/README.md +191 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/agent_loop.py +12 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/middleware.py +40 -12
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/prompts/cli.md +10 -0
- drydock_cli-0.5.2/drydock/core/session/state_file.py +143 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/search_replace.py +7 -3
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/write_file.py +6 -0
- drydock_cli-0.5.2/drydock/core/tools/injection_guard.py +105 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/pyproject.toml +1 -1
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_drydock_tasks.py +111 -0
- drydock_cli-0.5.0/PKG-INFO +0 -681
- drydock_cli-0.5.0/README.md +0 -627
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.github/CODEOWNERS +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.github/workflows/ci.yml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.github/workflows/release.yml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.gitignore +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.pre-commit-config.yaml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.python-version +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.typos.toml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.vscode/extensions.json +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.vscode/launch.json +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/.vscode/settings.json +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/AGENTS.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/CHANGELOG.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/CLAUDE.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/CONTRIBUTING.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/Drydock_rebrand.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/LICENSE +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/NOTICE +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/PRD.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/action.yml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/distribution/zed/LICENSE +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/distribution/zed/extension.toml +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/docs/README.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/docs/acp-setup.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/docs/proxy-setup.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/acp/utils.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/cli.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/commands.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/agents/models.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/auth/github.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/format.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/llm/types.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/logger.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/paths/_vibe_home.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/plan_session.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/programmatic.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/skills/models.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/slug.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/base.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/types.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/core/utils.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/skills/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock/whats_new.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock-acp.spec +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/drydock_terms.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/flake.lock +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/flake.nix +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/scripts/README.md +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/scripts/bump_version.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/scripts/install.sh +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/scripts/prepare_release.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/conftest.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_acp.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_bash.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_content.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_utils.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/backend/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/backend/test_backend.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_commands.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/conftest.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_agents.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_slug.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/core/test_utils.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/e2e/common.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/e2e/conftest.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/mock/__init__.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/mock/utils.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/skills/conftest.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/skills/test_manager.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/skills/test_models.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/skills/test_parser.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_agent_backend.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_agent_stats.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_agents.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_history_manager.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_message_id.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_message_merging.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_middleware.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_system_prompt.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_tagged_text.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_bash.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_grep.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_task.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-0.5.0 → drydock_cli-0.5.2}/uv.lock +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: drydock-cli
|
|
3
|
+
Version: 0.5.2
|
|
4
|
+
Summary: Drydock — nautical CLI coding agent
|
|
5
|
+
Project-URL: Homepage, https://github.com/fbobe321/drydock
|
|
6
|
+
Project-URL: Repository, https://github.com/fbobe321/drydock
|
|
7
|
+
Project-URL: Issues, https://github.com/fbobe321/drydock/issues
|
|
8
|
+
Project-URL: Documentation, https://github.com/fbobe321/drydock#readme
|
|
9
|
+
Author: Drydock contributors, Mistral AI (original)
|
|
10
|
+
License: Apache-2.0
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
License-File: NOTICE
|
|
13
|
+
Keywords: ai,cli,coding-assistant,developer-tools,drydock,llm,nautical
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: >=3.12
|
|
25
|
+
Requires-Dist: agent-client-protocol==0.8.1
|
|
26
|
+
Requires-Dist: anyio>=4.12.0
|
|
27
|
+
Requires-Dist: cachetools>=5.5.0
|
|
28
|
+
Requires-Dist: cryptography<=46.0.3,>=44.0.0
|
|
29
|
+
Requires-Dist: gitpython>=3.1.46
|
|
30
|
+
Requires-Dist: giturlparse>=0.14.0
|
|
31
|
+
Requires-Dist: google-auth>=2.0.0
|
|
32
|
+
Requires-Dist: httpx>=0.28.1
|
|
33
|
+
Requires-Dist: keyring>=25.6.0
|
|
34
|
+
Requires-Dist: markdownify>=1.2.2
|
|
35
|
+
Requires-Dist: mcp>=1.14.0
|
|
36
|
+
Requires-Dist: mistralai==1.12.4
|
|
37
|
+
Requires-Dist: packaging>=24.1
|
|
38
|
+
Requires-Dist: pexpect>=4.9.0
|
|
39
|
+
Requires-Dist: pydantic-settings>=2.12.0
|
|
40
|
+
Requires-Dist: pydantic>=2.12.4
|
|
41
|
+
Requires-Dist: pyperclip>=1.11.0
|
|
42
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
43
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
44
|
+
Requires-Dist: requests>=2.20.0
|
|
45
|
+
Requires-Dist: rich>=14.0.0
|
|
46
|
+
Requires-Dist: textual-speedups>=0.2.1
|
|
47
|
+
Requires-Dist: textual>=7.4.0
|
|
48
|
+
Requires-Dist: tomli-w>=1.2.0
|
|
49
|
+
Requires-Dist: tree-sitter-bash>=0.25.1
|
|
50
|
+
Requires-Dist: tree-sitter>=0.25.2
|
|
51
|
+
Requires-Dist: watchfiles>=1.1.1
|
|
52
|
+
Requires-Dist: zstandard>=0.25.0
|
|
53
|
+
Description-Content-Type: text/markdown
|
|
54
|
+
|
|
55
|
+
# DryDock
|
|
56
|
+
|
|
57
|
+
[](https://www.python.org/downloads/release/python-3120/)
|
|
58
|
+
[](https://github.com/fbobe321/drydock/blob/main/LICENSE)
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
| | |
|
|
62
|
+
)_) )_) )_)
|
|
63
|
+
)___))___))___)\
|
|
64
|
+
)____)____)_____)\\
|
|
65
|
+
_____|____|____|____\\\__
|
|
66
|
+
---\ /----
|
|
67
|
+
\_________________/
|
|
68
|
+
~~~~ ~~~ ~~~~ ~~~ ~~~~
|
|
69
|
+
~~~ ~~~~ ~~~ ~~~ ~~~
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Nautical CLI coding agent. Chart your course. Execute with precision.**
|
|
73
|
+
|
|
74
|
+
DryDock is a command-line coding assistant that works with any LLM provider. It provides a conversational interface to your codebase, allowing you to use natural language to explore, modify, and interact with your projects through a powerful set of tools.
|
|
75
|
+
|
|
76
|
+
> [!WARNING]
|
|
77
|
+
> DryDock works on Windows, but we officially support and target UNIX environments.
|
|
78
|
+
|
|
79
|
+
### Install
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install drydock-cli
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Or with uv:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
uv tool install drydock-cli
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Features
|
|
92
|
+
|
|
93
|
+
- **Interactive Chat**: A conversational AI agent that understands your requests and breaks down complex tasks.
|
|
94
|
+
- **Powerful Toolset**: Read, write, and patch files. Execute shell commands. Search code with `grep`. Manage todos. Delegate to subagents.
|
|
95
|
+
- **Project-Aware Context**: DryDock automatically scans your project's file structure and Git status.
|
|
96
|
+
- **Conda/Pip Support**: Auto-approves `pip install`, `conda install`, `pytest`, and other dev commands.
|
|
97
|
+
- **Bundled Skills**: Ships with skills like `create-presentation` for PowerPoint generation.
|
|
98
|
+
- **MCP Support**: Connect Model Context Protocol servers for extended capabilities.
|
|
99
|
+
- **Safety First**: Tool execution approval with `--dangerously-skip-permissions` for full auto-approve.
|
|
100
|
+
|
|
101
|
+
### Built-in Agents
|
|
102
|
+
|
|
103
|
+
- **`default`**: Standard agent that requires approval for tool executions.
|
|
104
|
+
- **`plan`**: Read-only agent for exploration and planning.
|
|
105
|
+
- **`accept-edits`**: Auto-approves file edits only.
|
|
106
|
+
- **`auto-approve`**: Auto-approves all tool executions.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
drydock --agent plan
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Quick Start
|
|
113
|
+
|
|
114
|
+
1. Navigate to your project directory and run:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
drydock
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
2. First run creates a config at `~/.drydock/config.toml` and prompts for your API key.
|
|
121
|
+
|
|
122
|
+
3. Start chatting:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
> Can you find all TODO comments in this project?
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Usage
|
|
129
|
+
|
|
130
|
+
### Interactive Mode
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
drydock # Start interactive session
|
|
134
|
+
drydock "Fix the login bug" # Start with a prompt
|
|
135
|
+
drydock --continue # Resume last session
|
|
136
|
+
drydock --resume abc123 # Resume specific session
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Keyboard shortcuts:**
|
|
140
|
+
- `Ctrl+C` — Cancel current operation (double-tap to quit)
|
|
141
|
+
- `Shift+Tab` — Toggle auto-approve mode
|
|
142
|
+
- `Ctrl+O` — Toggle tool output
|
|
143
|
+
- `Ctrl+G` — Open external editor
|
|
144
|
+
- `@` — File path autocompletion
|
|
145
|
+
- `!command` — Run shell command directly
|
|
146
|
+
|
|
147
|
+
### Programmatic Mode
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
drydock --prompt "Analyze the codebase" --max-turns 5 --output json
|
|
151
|
+
drydock --dangerously-skip-permissions -p "Fix all lint errors"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Trust Folder System
|
|
155
|
+
|
|
156
|
+
DryDock includes a trust folder system. When you run DryDock in a directory with a `.drydock` folder, it asks you to confirm trust. Managed via `~/.drydock/trusted_folders.toml`.
|
|
157
|
+
|
|
158
|
+
## Configuration
|
|
159
|
+
|
|
160
|
+
DryDock is configured via `config.toml`. It looks first in `./.drydock/config.toml`, then `~/.drydock/config.toml`.
|
|
161
|
+
|
|
162
|
+
### API Key
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
drydock --setup # Interactive setup
|
|
166
|
+
export MISTRAL_API_KEY="your_key" # Or set env var
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Keys are saved to `~/.drydock/.env`.
|
|
170
|
+
|
|
171
|
+
### Custom Agents
|
|
172
|
+
|
|
173
|
+
Create agent configs in `~/.drydock/agents/`:
|
|
174
|
+
|
|
175
|
+
```toml
|
|
176
|
+
# ~/.drydock/agents/redteam.toml
|
|
177
|
+
active_model = "devstral-2"
|
|
178
|
+
system_prompt_id = "redteam"
|
|
179
|
+
disabled_tools = ["search_replace", "write_file"]
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
drydock --agent redteam
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Custom Prompts
|
|
187
|
+
|
|
188
|
+
Create markdown files in `~/.drydock/prompts/`:
|
|
189
|
+
|
|
190
|
+
```toml
|
|
191
|
+
system_prompt_id = "my_custom_prompt"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Skills
|
|
195
|
+
|
|
196
|
+
DryDock discovers skills from:
|
|
197
|
+
1. Custom paths in `config.toml` via `skill_paths`
|
|
198
|
+
2. Project `.drydock/skills/` or `.agents/skills/`
|
|
199
|
+
3. Global `~/.drydock/skills/`
|
|
200
|
+
4. Bundled skills (shipped with the package)
|
|
201
|
+
|
|
202
|
+
### MCP Servers
|
|
203
|
+
|
|
204
|
+
```toml
|
|
205
|
+
[[mcp_servers]]
|
|
206
|
+
name = "fetch_server"
|
|
207
|
+
transport = "stdio"
|
|
208
|
+
command = "uvx"
|
|
209
|
+
args = ["mcp-server-fetch"]
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Custom DryDock Home
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
export DRYDOCK_HOME="/path/to/custom/home"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
This affects where DryDock looks for `config.toml`, `.env`, `agents/`, `prompts/`, `skills/`, and `logs/`.
|
|
219
|
+
|
|
220
|
+
## Slash Commands
|
|
221
|
+
|
|
222
|
+
Type `/help` in the input for available commands. Create custom slash commands via the skills system.
|
|
223
|
+
|
|
224
|
+
## Session Management
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
drydock --continue # Continue last session
|
|
228
|
+
drydock --resume abc123 # Resume specific session
|
|
229
|
+
drydock --workdir /path/to/dir # Set working directory
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Resources
|
|
233
|
+
|
|
234
|
+
- [CHANGELOG](CHANGELOG.md)
|
|
235
|
+
- [CONTRIBUTING](CONTRIBUTING.md)
|
|
236
|
+
- [ACP Setup](docs/acp-setup.md) — Editor/IDE integration
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
Copyright 2025 Mistral AI (original work)
|
|
241
|
+
Copyright 2026 DryDock contributors (modifications)
|
|
242
|
+
|
|
243
|
+
Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.
|
|
244
|
+
|
|
245
|
+
DryDock is a fork of [mistralai/mistral-vibe](https://github.com/mistralai/mistral-vibe) (Apache 2.0). See [NOTICE](NOTICE) for attribution.
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# DryDock
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/release/python-3120/)
|
|
4
|
+
[](https://github.com/fbobe321/drydock/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
| | |
|
|
8
|
+
)_) )_) )_)
|
|
9
|
+
)___))___))___)\
|
|
10
|
+
)____)____)_____)\\
|
|
11
|
+
_____|____|____|____\\\__
|
|
12
|
+
---\ /----
|
|
13
|
+
\_________________/
|
|
14
|
+
~~~~ ~~~ ~~~~ ~~~ ~~~~
|
|
15
|
+
~~~ ~~~~ ~~~ ~~~ ~~~
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Nautical CLI coding agent. Chart your course. Execute with precision.**
|
|
19
|
+
|
|
20
|
+
DryDock is a command-line coding assistant that works with any LLM provider. It provides a conversational interface to your codebase, allowing you to use natural language to explore, modify, and interact with your projects through a powerful set of tools.
|
|
21
|
+
|
|
22
|
+
> [!WARNING]
|
|
23
|
+
> DryDock works on Windows, but we officially support and target UNIX environments.
|
|
24
|
+
|
|
25
|
+
### Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install drydock-cli
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Or with uv:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv tool install drydock-cli
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- **Interactive Chat**: A conversational AI agent that understands your requests and breaks down complex tasks.
|
|
40
|
+
- **Powerful Toolset**: Read, write, and patch files. Execute shell commands. Search code with `grep`. Manage todos. Delegate to subagents.
|
|
41
|
+
- **Project-Aware Context**: DryDock automatically scans your project's file structure and Git status.
|
|
42
|
+
- **Conda/Pip Support**: Auto-approves `pip install`, `conda install`, `pytest`, and other dev commands.
|
|
43
|
+
- **Bundled Skills**: Ships with skills like `create-presentation` for PowerPoint generation.
|
|
44
|
+
- **MCP Support**: Connect Model Context Protocol servers for extended capabilities.
|
|
45
|
+
- **Safety First**: Tool execution approval with `--dangerously-skip-permissions` for full auto-approve.
|
|
46
|
+
|
|
47
|
+
### Built-in Agents
|
|
48
|
+
|
|
49
|
+
- **`default`**: Standard agent that requires approval for tool executions.
|
|
50
|
+
- **`plan`**: Read-only agent for exploration and planning.
|
|
51
|
+
- **`accept-edits`**: Auto-approves file edits only.
|
|
52
|
+
- **`auto-approve`**: Auto-approves all tool executions.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
drydock --agent plan
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
1. Navigate to your project directory and run:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
drydock
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
2. First run creates a config at `~/.drydock/config.toml` and prompts for your API key.
|
|
67
|
+
|
|
68
|
+
3. Start chatting:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
> Can you find all TODO comments in this project?
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
### Interactive Mode
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
drydock # Start interactive session
|
|
80
|
+
drydock "Fix the login bug" # Start with a prompt
|
|
81
|
+
drydock --continue # Resume last session
|
|
82
|
+
drydock --resume abc123 # Resume specific session
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Keyboard shortcuts:**
|
|
86
|
+
- `Ctrl+C` — Cancel current operation (double-tap to quit)
|
|
87
|
+
- `Shift+Tab` — Toggle auto-approve mode
|
|
88
|
+
- `Ctrl+O` — Toggle tool output
|
|
89
|
+
- `Ctrl+G` — Open external editor
|
|
90
|
+
- `@` — File path autocompletion
|
|
91
|
+
- `!command` — Run shell command directly
|
|
92
|
+
|
|
93
|
+
### Programmatic Mode
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
drydock --prompt "Analyze the codebase" --max-turns 5 --output json
|
|
97
|
+
drydock --dangerously-skip-permissions -p "Fix all lint errors"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Trust Folder System
|
|
101
|
+
|
|
102
|
+
DryDock includes a trust folder system. When you run DryDock in a directory with a `.drydock` folder, it asks you to confirm trust. Managed via `~/.drydock/trusted_folders.toml`.
|
|
103
|
+
|
|
104
|
+
## Configuration
|
|
105
|
+
|
|
106
|
+
DryDock is configured via `config.toml`. It looks first in `./.drydock/config.toml`, then `~/.drydock/config.toml`.
|
|
107
|
+
|
|
108
|
+
### API Key
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
drydock --setup # Interactive setup
|
|
112
|
+
export MISTRAL_API_KEY="your_key" # Or set env var
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Keys are saved to `~/.drydock/.env`.
|
|
116
|
+
|
|
117
|
+
### Custom Agents
|
|
118
|
+
|
|
119
|
+
Create agent configs in `~/.drydock/agents/`:
|
|
120
|
+
|
|
121
|
+
```toml
|
|
122
|
+
# ~/.drydock/agents/redteam.toml
|
|
123
|
+
active_model = "devstral-2"
|
|
124
|
+
system_prompt_id = "redteam"
|
|
125
|
+
disabled_tools = ["search_replace", "write_file"]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
drydock --agent redteam
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Custom Prompts
|
|
133
|
+
|
|
134
|
+
Create markdown files in `~/.drydock/prompts/`:
|
|
135
|
+
|
|
136
|
+
```toml
|
|
137
|
+
system_prompt_id = "my_custom_prompt"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Skills
|
|
141
|
+
|
|
142
|
+
DryDock discovers skills from:
|
|
143
|
+
1. Custom paths in `config.toml` via `skill_paths`
|
|
144
|
+
2. Project `.drydock/skills/` or `.agents/skills/`
|
|
145
|
+
3. Global `~/.drydock/skills/`
|
|
146
|
+
4. Bundled skills (shipped with the package)
|
|
147
|
+
|
|
148
|
+
### MCP Servers
|
|
149
|
+
|
|
150
|
+
```toml
|
|
151
|
+
[[mcp_servers]]
|
|
152
|
+
name = "fetch_server"
|
|
153
|
+
transport = "stdio"
|
|
154
|
+
command = "uvx"
|
|
155
|
+
args = ["mcp-server-fetch"]
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Custom DryDock Home
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
export DRYDOCK_HOME="/path/to/custom/home"
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This affects where DryDock looks for `config.toml`, `.env`, `agents/`, `prompts/`, `skills/`, and `logs/`.
|
|
165
|
+
|
|
166
|
+
## Slash Commands
|
|
167
|
+
|
|
168
|
+
Type `/help` in the input for available commands. Create custom slash commands via the skills system.
|
|
169
|
+
|
|
170
|
+
## Session Management
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
drydock --continue # Continue last session
|
|
174
|
+
drydock --resume abc123 # Resume specific session
|
|
175
|
+
drydock --workdir /path/to/dir # Set working directory
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Resources
|
|
179
|
+
|
|
180
|
+
- [CHANGELOG](CHANGELOG.md)
|
|
181
|
+
- [CONTRIBUTING](CONTRIBUTING.md)
|
|
182
|
+
- [ACP Setup](docs/acp-setup.md) — Editor/IDE integration
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
Copyright 2025 Mistral AI (original work)
|
|
187
|
+
Copyright 2026 DryDock contributors (modifications)
|
|
188
|
+
|
|
189
|
+
Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.
|
|
190
|
+
|
|
191
|
+
DryDock is a fork of [mistralai/mistral-vibe](https://github.com/mistralai/mistral-vibe) (Apache 2.0). See [NOTICE](NOTICE) for attribution.
|
|
@@ -288,6 +288,18 @@ class AgentLoop:
|
|
|
288
288
|
|
|
289
289
|
async def act(self, msg: str) -> AsyncGenerator[BaseEvent]:
|
|
290
290
|
self._clean_message_history()
|
|
291
|
+
|
|
292
|
+
# Load project state for cross-session context
|
|
293
|
+
try:
|
|
294
|
+
from drydock.core.session.state_file import load_state
|
|
295
|
+
state_content = load_state()
|
|
296
|
+
if state_content:
|
|
297
|
+
self._inject_system_note(
|
|
298
|
+
f"Previous session state:\n{state_content[:500]}"
|
|
299
|
+
)
|
|
300
|
+
except Exception:
|
|
301
|
+
pass # Non-critical
|
|
302
|
+
|
|
291
303
|
async for event in self._conversation_loop(msg):
|
|
292
304
|
yield event
|
|
293
305
|
|
|
@@ -98,35 +98,63 @@ class AutoCompactMiddleware:
|
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
class ContextWarningMiddleware:
|
|
101
|
+
"""Tiered context warnings inspired by GSD's context monitoring.
|
|
102
|
+
|
|
103
|
+
Warns at multiple thresholds as context fills up:
|
|
104
|
+
- 50% used: soft warning ("you're halfway through")
|
|
105
|
+
- 65% used: moderate warning ("wrap up current task")
|
|
106
|
+
- 75% used: critical warning ("finish NOW or compact")
|
|
107
|
+
- 85% used: emergency ("stop exploring, make final edit")
|
|
108
|
+
|
|
109
|
+
Debounced: only warns every 5 tool calls to avoid spamming.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
_TIERS = [
|
|
113
|
+
(0.50, "soft", "You've used {pct:.0f}% of context ({used:,}/{max:,} tokens). Start wrapping up your current task."),
|
|
114
|
+
(0.65, "moderate", "Context at {pct:.0f}%. Stop exploring — finish your current edit and verify it works."),
|
|
115
|
+
(0.75, "critical", "Context at {pct:.0f}% — CRITICAL. Make your final edit NOW. No more grep/read_file. Use /compact if you need to continue."),
|
|
116
|
+
(0.85, "emergency", "Context nearly full ({pct:.0f}%). You MUST stop after this turn. Apply your fix with search_replace immediately or the session will degrade."),
|
|
117
|
+
]
|
|
118
|
+
|
|
101
119
|
def __init__(
|
|
102
120
|
self, threshold_percent: float = 0.5, max_context: int | None = None
|
|
103
121
|
) -> None:
|
|
104
122
|
self.threshold_percent = threshold_percent
|
|
105
123
|
self.max_context = max_context
|
|
106
|
-
self.
|
|
124
|
+
self._tier_warned: set[str] = set()
|
|
125
|
+
self._calls_since_last_warn = 0
|
|
126
|
+
self._debounce_interval = 5
|
|
107
127
|
|
|
108
128
|
async def before_turn(self, context: ConversationContext) -> MiddlewareResult:
|
|
109
|
-
|
|
129
|
+
max_context = self.max_context
|
|
130
|
+
if max_context is None or max_context == 0:
|
|
110
131
|
return MiddlewareResult()
|
|
111
132
|
|
|
112
|
-
|
|
113
|
-
|
|
133
|
+
self._calls_since_last_warn += 1
|
|
134
|
+
|
|
135
|
+
# Debounce: don't warn on every single turn
|
|
136
|
+
if self._calls_since_last_warn < self._debounce_interval:
|
|
114
137
|
return MiddlewareResult()
|
|
115
138
|
|
|
116
|
-
|
|
117
|
-
self.has_warned = True
|
|
139
|
+
pct_used = context.stats.context_tokens / max_context
|
|
118
140
|
|
|
119
|
-
|
|
120
|
-
|
|
141
|
+
# Find the highest tier we've crossed but haven't warned about
|
|
142
|
+
for threshold, tier_name, template in reversed(self._TIERS):
|
|
143
|
+
if pct_used >= threshold and tier_name not in self._tier_warned:
|
|
144
|
+
self._tier_warned.add(tier_name)
|
|
145
|
+
self._calls_since_last_warn = 0
|
|
121
146
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
147
|
+
warning_msg = f"<{VIBE_WARNING_TAG}>{template.format(pct=pct_used * 100, used=context.stats.context_tokens, max=max_context)}</{VIBE_WARNING_TAG}>"
|
|
148
|
+
return MiddlewareResult(
|
|
149
|
+
action=MiddlewareAction.INJECT_MESSAGE, message=warning_msg
|
|
150
|
+
)
|
|
151
|
+
break
|
|
125
152
|
|
|
126
153
|
return MiddlewareResult()
|
|
127
154
|
|
|
128
155
|
def reset(self, reset_reason: ResetReason = ResetReason.STOP) -> None:
|
|
129
|
-
self.
|
|
156
|
+
self._tier_warned.clear()
|
|
157
|
+
self._calls_since_last_warn = 0
|
|
130
158
|
|
|
131
159
|
|
|
132
160
|
def make_plan_agent_reminder(plan_file_path: str) -> str:
|
|
@@ -59,6 +59,16 @@ Flip-flopping (add X → remove X → add X) is a critical failure. Commit to a
|
|
|
59
59
|
Ambiguous Prompts
|
|
60
60
|
If the user's message is very short or ambiguous (e.g., "test", "check", "fix"), ask what they want before exploring the filesystem. Do NOT start scanning directories or running `find` on a vague prompt. Ask: "What would you like me to test/check/fix?"
|
|
61
61
|
|
|
62
|
+
Deviation Handling
|
|
63
|
+
When your fix attempt hits unexpected issues, follow these rules:
|
|
64
|
+
1. **Bug in your fix** → Auto-fix immediately. Re-read the error, adjust your edit, retry.
|
|
65
|
+
2. **Missing dependency/import** → Auto-resolve. Add the import or install the package.
|
|
66
|
+
3. **Blocking issue** (wrong file, missing context) → Auto-resolve by grepping for the right location.
|
|
67
|
+
4. **Architectural decision** (should we refactor? change the API? add a new module?) → STOP and ask the user. Do NOT make architectural decisions unilaterally.
|
|
68
|
+
5. **Scope change** (the fix requires changes to 5+ files, or touches unrelated code) → STOP and ask the user before proceeding.
|
|
69
|
+
|
|
70
|
+
Rules 1-3: fix silently. Rules 4-5: always ask.
|
|
71
|
+
|
|
62
72
|
Response Format
|
|
63
73
|
No Noise
|
|
64
74
|
No greetings, outros, hedging, puffery, or tool narration.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""Structured state file for cross-session memory.
|
|
2
|
+
|
|
3
|
+
Maintains a `.drydock/state.md` file in the project directory that tracks:
|
|
4
|
+
- Current task and status
|
|
5
|
+
- Files modified in this session
|
|
6
|
+
- Key decisions made
|
|
7
|
+
- Blockers and next steps
|
|
8
|
+
|
|
9
|
+
Max 100 lines. Loaded on session start, updated on session end.
|
|
10
|
+
Enables "resume where I left off" workflows.
|
|
11
|
+
|
|
12
|
+
Inspired by GSD's STATE.md concept.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
_MAX_LINES = 100
|
|
24
|
+
_STATE_FILENAME = "state.md"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _get_state_path(project_dir: Path | None = None) -> Path:
|
|
28
|
+
"""Get the path to the state file."""
|
|
29
|
+
base = project_dir or Path.cwd()
|
|
30
|
+
return base / ".drydock" / _STATE_FILENAME
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def load_state(project_dir: Path | None = None) -> str:
|
|
34
|
+
"""Load the state file content, or empty string if it doesn't exist."""
|
|
35
|
+
path = _get_state_path(project_dir)
|
|
36
|
+
try:
|
|
37
|
+
if path.exists():
|
|
38
|
+
content = path.read_text(encoding="utf-8")
|
|
39
|
+
logger.info("Loaded session state from %s (%d lines)", path, content.count("\n"))
|
|
40
|
+
return content
|
|
41
|
+
except (OSError, PermissionError) as e:
|
|
42
|
+
logger.warning("Could not read state file %s: %s", path, e)
|
|
43
|
+
return ""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def save_state(
|
|
47
|
+
project_dir: Path | None = None,
|
|
48
|
+
*,
|
|
49
|
+
current_task: str = "",
|
|
50
|
+
files_modified: list[str] | None = None,
|
|
51
|
+
decisions: list[str] | None = None,
|
|
52
|
+
blockers: list[str] | None = None,
|
|
53
|
+
next_steps: list[str] | None = None,
|
|
54
|
+
custom_notes: str = "",
|
|
55
|
+
) -> None:
|
|
56
|
+
"""Save the state file with structured session information."""
|
|
57
|
+
path = _get_state_path(project_dir)
|
|
58
|
+
|
|
59
|
+
lines: list[str] = [
|
|
60
|
+
f"# DryDock Session State",
|
|
61
|
+
f"_Updated: {datetime.now().strftime('%Y-%m-%d %H:%M')}_",
|
|
62
|
+
"",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
if current_task:
|
|
66
|
+
lines.extend([f"## Current Task", current_task, ""])
|
|
67
|
+
|
|
68
|
+
if files_modified:
|
|
69
|
+
lines.append("## Files Modified")
|
|
70
|
+
for f in files_modified[-20:]: # Keep last 20
|
|
71
|
+
lines.append(f"- `{f}`")
|
|
72
|
+
lines.append("")
|
|
73
|
+
|
|
74
|
+
if decisions:
|
|
75
|
+
lines.append("## Decisions")
|
|
76
|
+
for d in decisions[-10:]: # Keep last 10
|
|
77
|
+
lines.append(f"- {d}")
|
|
78
|
+
lines.append("")
|
|
79
|
+
|
|
80
|
+
if blockers:
|
|
81
|
+
lines.append("## Blockers")
|
|
82
|
+
for b in blockers:
|
|
83
|
+
lines.append(f"- {b}")
|
|
84
|
+
lines.append("")
|
|
85
|
+
|
|
86
|
+
if next_steps:
|
|
87
|
+
lines.append("## Next Steps")
|
|
88
|
+
for n in next_steps:
|
|
89
|
+
lines.append(f"- {n}")
|
|
90
|
+
lines.append("")
|
|
91
|
+
|
|
92
|
+
if custom_notes:
|
|
93
|
+
lines.extend(["## Notes", custom_notes, ""])
|
|
94
|
+
|
|
95
|
+
# Enforce max lines
|
|
96
|
+
content = "\n".join(lines[:_MAX_LINES])
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
100
|
+
path.write_text(content, encoding="utf-8")
|
|
101
|
+
logger.info("Saved session state to %s", path)
|
|
102
|
+
except (OSError, PermissionError) as e:
|
|
103
|
+
logger.warning("Could not write state file %s: %s", path, e)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def update_state_files_modified(
|
|
107
|
+
project_dir: Path | None = None,
|
|
108
|
+
files: list[str] | None = None,
|
|
109
|
+
) -> None:
|
|
110
|
+
"""Quick update: append modified files to the state without rewriting everything."""
|
|
111
|
+
if not files:
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
path = _get_state_path(project_dir)
|
|
115
|
+
try:
|
|
116
|
+
existing = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
117
|
+
|
|
118
|
+
if "## Files Modified" not in existing:
|
|
119
|
+
# Append a new section
|
|
120
|
+
existing += "\n## Files Modified\n"
|
|
121
|
+
|
|
122
|
+
for f in files:
|
|
123
|
+
entry = f"- `{f}`"
|
|
124
|
+
if entry not in existing:
|
|
125
|
+
existing += f"{entry}\n"
|
|
126
|
+
|
|
127
|
+
# Enforce max lines
|
|
128
|
+
lines = existing.split("\n")[:_MAX_LINES]
|
|
129
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
130
|
+
path.write_text("\n".join(lines), encoding="utf-8")
|
|
131
|
+
except (OSError, PermissionError):
|
|
132
|
+
pass # Non-critical
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def clear_state(project_dir: Path | None = None) -> None:
|
|
136
|
+
"""Remove the state file."""
|
|
137
|
+
path = _get_state_path(project_dir)
|
|
138
|
+
try:
|
|
139
|
+
if path.exists():
|
|
140
|
+
path.unlink()
|
|
141
|
+
logger.info("Cleared session state at %s", path)
|
|
142
|
+
except (OSError, PermissionError):
|
|
143
|
+
pass
|