deepagents-code 0.1.54__tar.gz → 0.1.55__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.
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/CHANGELOG.md +26 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/COMMANDS.md +4 -2
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/PKG-INFO +3 -3
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_build_info.py +1 -1
- deepagents_code-0.1.55/deepagents_code/_dep_floor_check.py +587 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_env_vars.py +23 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_session_stats.py +33 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/app.py +577 -130
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/app.tcss +2 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/command_registry.py +13 -4
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/config.py +3 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/config_manifest.py +40 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/cost_tracking.py +18 -3
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/extras_info.py +12 -12
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/main.py +362 -108
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/model_config.py +124 -4
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/discovery.py +148 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/manifest.py +9 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/models.py +2 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/store.py +27 -4
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/modals/plugin_manager/__init__.py +46 -3
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/modals/plugin_manager/models.py +1 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/modals/plugin_manager/tabs.py +1 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/textual_adapter.py +11 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/_inline_prompt.py +54 -9
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/approval.py +8 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/ask_user.py +4 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/chat_input.py +2 -2
- deepagents_code-0.1.55/deepagents_code/tui/widgets/context_usage.py +169 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/cwd_switch.py +6 -4
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/message_store.py +5 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/messages.py +291 -57
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/model_selector.py +301 -42
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/startup_tip.py +1 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/status.py +250 -130
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/subagent_panel.py +2 -28
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/update_check.py +146 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/pyproject.toml +3 -2
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/scripts/install.sh +309 -43
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/conftest.py +9 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/test_trust.py +102 -2
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/plugins/test_plugins_p0.py +114 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_app.py +432 -14
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_charset.py +2 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_config.py +10 -2
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_config_manifest.py +36 -0
- deepagents_code-0.1.55/tests/unit_tests/test_dep_floor_check.py +701 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_extras_info.py +32 -9
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_install_script.py +542 -20
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_main.py +492 -9
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_main_acp_mode.py +61 -9
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_main_args.py +50 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_mcp_tools.py +10 -3
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_model_config.py +221 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_resume_state.py +27 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_session_stats.py +3 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_startup_fast_paths.py +52 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_update_check.py +272 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_version.py +76 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/modals/plugin_manager/test_structure.py +26 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/test_textual_adapter.py +25 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_approval.py +36 -1
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_ask_user.py +6 -2
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_message_store.py +3 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_messages.py +601 -9
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_model_selector.py +828 -55
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_status.py +120 -56
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_subagent_panel.py +4 -5
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_thread_selector.py +31 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/uv.lock +27 -7
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/.gitignore +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/AGENTS.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/ARCHITECTURE.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/DEVELOPMENT.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/HOOKS.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/LICENSE +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/Makefile +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/PRICING.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/README.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_constants.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_debug_buffer.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_fake_models.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_glm_5p2_profile.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_invocation.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_markdown.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_paths.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_repository_bounds.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/_tool_stream.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/agent.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/approval_mode.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/auto_mode.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/built_in_skills/deepagents-thread-inspector/SKILL.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/built_in_skills/deepagents-thread-inspector/scripts/inspect_sessions.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/bundled_prices.README.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/bundled_prices.json +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/commands/auth.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/commands/config.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/commands/extras.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/commands/mcp.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/commands/tools.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/launch/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/launch/server.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/launch/server_manager.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/non_interactive.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/client/remote_client.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/diff_utils.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/doctor.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/file_ops.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/goal_rubric.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/goal_state_notice.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/goal_tools.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/capabilities.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/client.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/client_lifecycle.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/context.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/engine.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/env.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/envelope.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/interrupt.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/legacy.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/loading.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/manager.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/migration.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/models/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/models/adapters.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/models/config.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/models/domain.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/models/transport.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/models/wire.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/permissions.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/presenter.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/projection.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/reducer.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/runner.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/runtime.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/server_middleware.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/snapshot.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/tools.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/transcript.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/trust.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/hooks/validate_terminal_sequence.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/json_types.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_config.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/mcp_tools.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/offload_middleware.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/paste_collapse.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/_json.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/adapters/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/adapters/hooks.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/adapters/mcp.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/adapters/skills.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/adapters/skills_middleware.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/commands_cli.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/marketplace.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/plugins/substitution.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/reasoning_effort.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/reliable_rubric.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/server_graph.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/sessions.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/skills/merge.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/skills/trust.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tool_catalog.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tool_display.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/modals/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/modals/plugin_manager/content.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/modals/plugin_manager/plugin_manager.tcss +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/modals/plugin_manager/state.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/modals/resume_compact.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/screens/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/_copy_spans.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/_js_eval_display.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/_links.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/_paste_textarea.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/auth.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/auto_mode_notice.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/debug_console.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/diff.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/effort_selector.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/goal_review.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/goal_status.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/history.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/install_confirm.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/loading.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/plugin_reload.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/skill_trust.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/thread_agent_switch.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/thread_selector.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/tool_renderers.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/update_available.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/update_confirm.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/welcome.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/tui/widgets/yolo_mode_notice.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/ui.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/hatch_build.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/images/tui.png +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/README.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/benchmarks/test_local_context_benchmarks.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/test_auto_approve_remote.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/test_goal_criteria_remote.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/test_offload_server_side.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/client/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/client/commands/test_auth.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/client/commands/test_extras.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/client/commands/test_mcp.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/client/commands/test_tools.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/models/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/models/test_models.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/test_client_lifecycle.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/test_configuration.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/test_engine.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/test_execution.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/test_manager.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/test_presenter.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/test_server_lifecycle.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/hooks/test_transcript.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/plugins/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/plugins/test_marketplace.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/plugins/test_plugin_hooks.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/plugins/test_store.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/skills/test_merge.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/skills/test_skill_trust.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/skills/test_thread_inspector.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/smoke_tests/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/smoke_tests/conftest.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/smoke_tests/test_system_prompt.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test__tool_stream.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_approval_mode.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_args.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_ask_user_types.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_auth_web_search_restart.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_auto_mode.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_config_recursion_limit.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_cost_tracking.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_cursor_style.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_debug_buffer.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_debug_console.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_diff_utils.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_doctor.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_glm_5p2_profile.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_goal_criteria_client.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_goal_rubric.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_goal_state_notice.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_goal_state_persistence.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_goal_tools.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_hatch_build.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_install_command.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_invocation.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_json_types.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_mcp_config.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_paths.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_reasoning_effort.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_reliable_rubric.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_repository_bounds.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_rubric_cli.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_server.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_startup_blocking.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_threads_resume.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_tool_catalog.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_transcript_virtualization.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tools/test_tool_arg_schemas.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/modals/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/modals/plugin_manager/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/test_subagent_stream.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_agent_selector.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_auth_widgets.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_auto_mode_notice.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_autocomplete.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_chat_input.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_copy_spans.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_cwd_switch.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_diff.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_goal_review.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_history.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_inline_prompt.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_install_confirm.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_launch_init.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_links.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_loading.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_notification_center.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_notification_detail.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_notification_settings.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_plugin_reload.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_skill_trust_screen.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_startup_tip.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_thread_agent_switch.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_tool_renderers.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_update_available.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_update_confirm.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_update_progress.py +0 -0
- {deepagents_code-0.1.54 → deepagents_code-0.1.55}/tests/unit_tests/tui/widgets/test_welcome.py +0 -0
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.55](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.54...deepagents-code==0.1.55) (2026-08-12)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- Added a `/context` usage report for inspecting context consumption ([#5407](https://github.com/langchain-ai/deepagents/issues/5407)).
|
|
10
|
+
- Added a cache and context status row for at-a-glance session state ([#5408](https://github.com/langchain-ai/deepagents/issues/5408)).
|
|
11
|
+
- Added configurable warnings when a session exceeds the configured cost threshold ([#5405](https://github.com/langchain-ai/deepagents/issues/5405)).
|
|
12
|
+
- Added support for persisting and reconfiguring ACP sessions ([#5366](https://github.com/langchain-ai/deepagents/issues/5366)).
|
|
13
|
+
- Added automatic updates for installed plugins ([#5368](https://github.com/langchain-ai/deepagents/issues/5368)).
|
|
14
|
+
- Added a toggle for diff line numbers ([#5427](https://github.com/langchain-ai/deepagents/issues/5427)).
|
|
15
|
+
- `Ctrl+S` in `/auto model` now stores `[models].auto_classifier` ([#5313](https://github.com/langchain-ai/deepagents/issues/5313)).
|
|
16
|
+
|
|
17
|
+
### Fixes
|
|
18
|
+
|
|
19
|
+
- Restored edit diffs in resumed threads ([#5391](https://github.com/langchain-ai/deepagents/issues/5391)).
|
|
20
|
+
- Added a resume hint after crashes ([#5412](https://github.com/langchain-ai/deepagents/issues/5412)).
|
|
21
|
+
- Clarified the project hooks trust prompt and stopped prompting for user hooks ([#5426](https://github.com/langchain-ai/deepagents/issues/5426)).
|
|
22
|
+
- Cleared dynamic subagents on the next turn ([#5437](https://github.com/langchain-ai/deepagents/issues/5437)).
|
|
23
|
+
- Improved grouped tool summaries by counting distinct targets ([#5409](https://github.com/langchain-ai/deepagents/issues/5409)).
|
|
24
|
+
- Improved ask-user choice wrapping and selection styling ([#5442](https://github.com/langchain-ai/deepagents/issues/5442)).
|
|
25
|
+
- Serialized `dcode` self-upgrades across processes ([#5252](https://github.com/langchain-ai/deepagents/issues/5252)).
|
|
26
|
+
- Added warnings for stale dependencies in editable installs ([#5386](https://github.com/langchain-ai/deepagents/issues/5386)).
|
|
27
|
+
- Hid incomplete extras from version output ([#5352](https://github.com/langchain-ai/deepagents/issues/5352)).
|
|
28
|
+
- Removed the optional-provider startup tip ([#5421](https://github.com/langchain-ai/deepagents/issues/5421)).
|
|
29
|
+
- Removed the “Message restored to input” toast ([#5253](https://github.com/langchain-ai/deepagents/issues/5253)).
|
|
30
|
+
|
|
5
31
|
## [0.1.54](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.53...deepagents-code==0.1.54) (2026-08-07)
|
|
6
32
|
|
|
7
33
|
### Features
|
|
@@ -8,16 +8,17 @@ Regenerate this file with `make commands-catalog` after changing command names,
|
|
|
8
8
|
aliases, descriptions, visibility, or hidden-command metadata.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
## Public (
|
|
11
|
+
## Public (40)
|
|
12
12
|
|
|
13
13
|
| Command | Aliases | Description |
|
|
14
14
|
| --- | --- | --- |
|
|
15
15
|
| `/agents` | | Browse and switch between available agents |
|
|
16
16
|
| `/auth` | `/connect` | Connect and manage provider and service credentials |
|
|
17
|
-
| `/auto` | | Switch to Auto approval mode
|
|
17
|
+
| `/auto` | | Switch to Auto approval mode or manage its classifier model |
|
|
18
18
|
| `/auto-update` | | Turn automatic updates on or off |
|
|
19
19
|
| `/changelog` | | Open the changelog in a browser |
|
|
20
20
|
| `/clear` | | Clear the chat and start a new thread |
|
|
21
|
+
| `/context` | | Show current context window usage |
|
|
21
22
|
| `/copy` | | Copy the latest assistant message to clipboard |
|
|
22
23
|
| `/cost` | | Show estimated thread cost |
|
|
23
24
|
| `/docs` | | Open the docs |
|
|
@@ -28,6 +29,7 @@ aliases, descriptions, visibility, or hidden-command metadata.
|
|
|
28
29
|
| `/goal` | | Set and manage a persistent objective with acceptance criteria |
|
|
29
30
|
| `/help` | | Show help and available commands |
|
|
30
31
|
| `/install` | | Install an optional integration |
|
|
32
|
+
| `/line-numbers` | | Show or hide line numbers in file diffs |
|
|
31
33
|
| `/manual` | | Switch to Manual approval mode |
|
|
32
34
|
| `/mcp` | | Manage MCP servers and authentication |
|
|
33
35
|
| `/model` | | Switch models or edit model settings |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.55
|
|
4
4
|
Summary: Terminal coding agent built on the Deep Agents SDK - works with any model, with persistent memory, customizable skills, subagents, and approval controls.
|
|
5
5
|
Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
|
|
6
6
|
Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
|
|
@@ -28,7 +28,7 @@ Classifier: Topic :: Terminals
|
|
|
28
28
|
Requires-Python: <4.0,>=3.11
|
|
29
29
|
Requires-Dist: aiosqlite<1.0.0,>=0.22.1
|
|
30
30
|
Requires-Dist: anyio<5.0.0,>=4.14.2
|
|
31
|
-
Requires-Dist: deepagents-acp<1.0.0,>=0.0.
|
|
31
|
+
Requires-Dist: deepagents-acp<1.0.0,>=0.0.10
|
|
32
32
|
Requires-Dist: deepagents==0.7.5
|
|
33
33
|
Requires-Dist: filelock<3.30,>=3.29.7
|
|
34
34
|
Requires-Dist: genai-prices<0.2.0,>=0.1.1
|
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
"""Best-effort runtime dependency floor check for editable dev installs.
|
|
2
|
+
|
|
3
|
+
Editable installs resolve dependencies once at install time and nothing
|
|
4
|
+
re-checks them afterwards, so after `pyproject.toml` floors are bumped on
|
|
5
|
+
`main` a stale editable venv silently runs new source against old deps.
|
|
6
|
+
This module detects editable installs via PEP 610 metadata and warns at
|
|
7
|
+
startup when an installed runtime dependency is older than the floor the
|
|
8
|
+
checkout declares. Released installs (uv tool / PyPI wheel) carry no
|
|
9
|
+
editable `direct_url.json` record and skip the check entirely, so end
|
|
10
|
+
users pay no startup cost here.
|
|
11
|
+
|
|
12
|
+
Interactive launches on a terminal stop on a blocking pre-TUI prompt
|
|
13
|
+
(continue / mute / abort); headless launches, subcommands, and interactive
|
|
14
|
+
launches whose stdin is piped get a single stderr warning per launch instead,
|
|
15
|
+
since they have no answerable prompt and must never block. A dismissed
|
|
16
|
+
(muted) mismatch is remembered per checkout as a fingerprint of the offending
|
|
17
|
+
distributions and stays silent until the mismatch itself changes.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import hashlib
|
|
23
|
+
import importlib.metadata
|
|
24
|
+
import json
|
|
25
|
+
import logging
|
|
26
|
+
import os
|
|
27
|
+
import shlex
|
|
28
|
+
import subprocess # noqa: S404 # only `list2cmdline` string quoting, never executed
|
|
29
|
+
import sys
|
|
30
|
+
import tempfile
|
|
31
|
+
import threading
|
|
32
|
+
import tomllib
|
|
33
|
+
from contextlib import contextmanager, suppress
|
|
34
|
+
from dataclasses import dataclass
|
|
35
|
+
from pathlib import Path
|
|
36
|
+
from typing import TYPE_CHECKING
|
|
37
|
+
|
|
38
|
+
from deepagents_code.config import _is_editable_install
|
|
39
|
+
|
|
40
|
+
if TYPE_CHECKING:
|
|
41
|
+
from collections.abc import Iterator
|
|
42
|
+
|
|
43
|
+
from deepagents_code.main import _TrustPromptOutcome
|
|
44
|
+
|
|
45
|
+
logger = logging.getLogger(__name__)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True)
|
|
49
|
+
class _FloorViolation:
|
|
50
|
+
"""A runtime dependency whose installed version is below the declared floor.
|
|
51
|
+
|
|
52
|
+
Attributes:
|
|
53
|
+
dist_name: Distribution name as passed to `importlib.metadata.version`.
|
|
54
|
+
installed: The installed version string.
|
|
55
|
+
floor: The highest declared floor version `installed` sorts below.
|
|
56
|
+
required: The requirement spec as declared in `pyproject.toml`, kept
|
|
57
|
+
for display only. `floor` is the parsed value to compare against;
|
|
58
|
+
this string is `packaging`'s rendering and may shift across
|
|
59
|
+
`packaging` releases.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
dist_name: str
|
|
63
|
+
installed: str
|
|
64
|
+
floor: str
|
|
65
|
+
required: str
|
|
66
|
+
|
|
67
|
+
def describe(self) -> str:
|
|
68
|
+
"""Return the one-line advisory row for this violation.
|
|
69
|
+
|
|
70
|
+
Both the stderr warning and the interactive prompt render violations,
|
|
71
|
+
so the sentence lives here rather than being duplicated per channel.
|
|
72
|
+
"""
|
|
73
|
+
return (
|
|
74
|
+
f"{self.dist_name} {self.installed} is installed, "
|
|
75
|
+
f"but {self.required} is required"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _load_cli_requirements() -> list[str] | None:
|
|
80
|
+
"""Read the hard dependency list from the editable source checkout.
|
|
81
|
+
|
|
82
|
+
The installed `Requires-Dist` metadata is frozen at install time, so a
|
|
83
|
+
floor bump on `main` would not reach a stale editable venv through it.
|
|
84
|
+
The checkout's own `pyproject.toml` is live, and editable installs keep
|
|
85
|
+
the console entry point importing from the checkout, so the package
|
|
86
|
+
directory's parent holds it.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
The `project.dependencies` entries, or `None` when the source
|
|
90
|
+
checkout or its dependency list cannot be read.
|
|
91
|
+
"""
|
|
92
|
+
pyproject = Path(__file__).resolve().parent.parent / "pyproject.toml"
|
|
93
|
+
try:
|
|
94
|
+
data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
|
|
95
|
+
entries = data["project"]["dependencies"]
|
|
96
|
+
except (OSError, KeyError, TypeError, tomllib.TOMLDecodeError):
|
|
97
|
+
logger.debug(
|
|
98
|
+
"Could not read dependency floors from the source checkout",
|
|
99
|
+
exc_info=True,
|
|
100
|
+
)
|
|
101
|
+
return None
|
|
102
|
+
if not isinstance(entries, list) or not all(
|
|
103
|
+
isinstance(entry, str) for entry in entries
|
|
104
|
+
):
|
|
105
|
+
return None
|
|
106
|
+
return entries
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _find_floor_violations(entries: list[str]) -> list[_FloorViolation]:
|
|
110
|
+
"""Compare each applicable requirement's floor against installed versions.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
entries: Requirement strings from `project.dependencies`.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
One `_FloorViolation` per requirement whose installed version parses
|
|
117
|
+
below its declared `>=`/`~=`/`==` floor. Requirements that fail to
|
|
118
|
+
parse, whose marker does not apply to this environment, whose only
|
|
119
|
+
equality specifier is a `==X.*` wildcard, or whose distribution is
|
|
120
|
+
not installed are skipped.
|
|
121
|
+
"""
|
|
122
|
+
# `packaging` is a runtime dependency, but this module must remain
|
|
123
|
+
# importable when an editable environment is stale enough to lack it.
|
|
124
|
+
# The caller treats failures in this best-effort check as non-fatal.
|
|
125
|
+
from packaging.requirements import InvalidRequirement, Requirement
|
|
126
|
+
from packaging.version import InvalidVersion, Version
|
|
127
|
+
|
|
128
|
+
violations: list[_FloorViolation] = []
|
|
129
|
+
for entry in entries:
|
|
130
|
+
try:
|
|
131
|
+
req = Requirement(entry)
|
|
132
|
+
except InvalidRequirement:
|
|
133
|
+
logger.debug("Unparseable dependency entry %r; skipping", entry)
|
|
134
|
+
continue
|
|
135
|
+
except Exception: # any unexpected parser failure skips the entry
|
|
136
|
+
logger.debug(
|
|
137
|
+
"Requirement parser failed on %r; skipping", entry, exc_info=True
|
|
138
|
+
)
|
|
139
|
+
continue
|
|
140
|
+
if req.marker is not None:
|
|
141
|
+
try:
|
|
142
|
+
if not req.marker.evaluate():
|
|
143
|
+
continue
|
|
144
|
+
except Exception: # an unevaluatable marker must not abort the whole check
|
|
145
|
+
logger.debug(
|
|
146
|
+
"Could not evaluate marker for %r; skipping", entry, exc_info=True
|
|
147
|
+
)
|
|
148
|
+
continue
|
|
149
|
+
# `==` pins act as floors here too: a hard pin (e.g. the SDK's
|
|
150
|
+
# `deepagents==X.Y.Z`) still means "this version or drift" in an
|
|
151
|
+
# editable venv, and an older-than-pinned install is exactly the
|
|
152
|
+
# staleness this check exists to surface. `==X.*` wildcard equality
|
|
153
|
+
# has no parseable single version, so it stays out.
|
|
154
|
+
floors = [
|
|
155
|
+
spec.version
|
|
156
|
+
for spec in req.specifier
|
|
157
|
+
if spec.operator in {">=", "~="}
|
|
158
|
+
or (spec.operator == "==" and not spec.version.endswith(".*"))
|
|
159
|
+
]
|
|
160
|
+
if not floors:
|
|
161
|
+
continue
|
|
162
|
+
try:
|
|
163
|
+
installed = importlib.metadata.version(req.name)
|
|
164
|
+
except importlib.metadata.PackageNotFoundError:
|
|
165
|
+
# Workspace `[tool.uv.sources]` path deps and not-yet-installed
|
|
166
|
+
# dists both land here; a missing dist is not a stale floor.
|
|
167
|
+
logger.debug("Distribution %r is not installed; skipping", req.name)
|
|
168
|
+
continue
|
|
169
|
+
except Exception:
|
|
170
|
+
# A corrupt or half-written `.dist-info` raises from the metadata
|
|
171
|
+
# parser. Skip just this entry: letting it escape would discard
|
|
172
|
+
# violations already found and leave the rest of the list
|
|
173
|
+
# unexamined, reporting a false all-clear for every dependency.
|
|
174
|
+
logger.debug(
|
|
175
|
+
"Could not read the installed version of %r; skipping",
|
|
176
|
+
req.name,
|
|
177
|
+
exc_info=True,
|
|
178
|
+
)
|
|
179
|
+
continue
|
|
180
|
+
try:
|
|
181
|
+
installed_version = Version(installed)
|
|
182
|
+
except InvalidVersion:
|
|
183
|
+
logger.debug("Unparseable installed version %r for %r", installed, req.name)
|
|
184
|
+
continue
|
|
185
|
+
floor = max(floors, key=_version_key)
|
|
186
|
+
try:
|
|
187
|
+
floor_version = Version(floor)
|
|
188
|
+
except InvalidVersion:
|
|
189
|
+
# `_version_key` sorts unparseable floors lowest, so this is only
|
|
190
|
+
# reachable when every floor for the entry is unparseable.
|
|
191
|
+
logger.debug("Unparseable floor %r for %r; skipping", floor, req.name)
|
|
192
|
+
continue
|
|
193
|
+
if installed_version < floor_version:
|
|
194
|
+
violations.append(
|
|
195
|
+
_FloorViolation(
|
|
196
|
+
dist_name=req.name,
|
|
197
|
+
installed=installed,
|
|
198
|
+
floor=floor,
|
|
199
|
+
required=str(req),
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
return violations
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _quote_arg(arg: str) -> str:
|
|
206
|
+
"""Quote a command argument for the platform's command-line conventions.
|
|
207
|
+
|
|
208
|
+
`shlex.quote` emits POSIX single quotes, which `cmd.exe` does not treat
|
|
209
|
+
as quoting — on Windows the quote characters would become part of the
|
|
210
|
+
path, so the printed refresh command would not work there.
|
|
211
|
+
`subprocess.list2cmdline` follows the Windows argv rules instead.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
arg: The raw argument string.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
The argument quoted for the current platform's shell conventions.
|
|
218
|
+
"""
|
|
219
|
+
if sys.platform == "win32":
|
|
220
|
+
return subprocess.list2cmdline([arg])
|
|
221
|
+
return shlex.quote(arg)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _version_key(version: str) -> tuple[int, ...]:
|
|
225
|
+
"""Return a sortable key for a floor version string.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
version: A PEP 440 version string from a `>=`/`~=` specifier.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
The release tuple when parseable, else an empty tuple so malformed
|
|
232
|
+
floors sort lowest and a parseable floor always wins the `max`.
|
|
233
|
+
"""
|
|
234
|
+
from packaging.version import InvalidVersion, Version
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
return Version(version).release
|
|
238
|
+
except InvalidVersion:
|
|
239
|
+
return ()
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
_DEBUG_VIOLATION = _FloorViolation(
|
|
243
|
+
dist_name="packaging",
|
|
244
|
+
installed="0.0.1",
|
|
245
|
+
floor="26.2",
|
|
246
|
+
required="packaging>=26.2",
|
|
247
|
+
)
|
|
248
|
+
"""Fake below-floor violation used by `DEEPAGENTS_CODE_DEBUG_DEP_FLOOR`.
|
|
249
|
+
|
|
250
|
+
Lets the warn/prompt/mute flow be exercised end to end without a genuinely
|
|
251
|
+
stale environment or monkeypatching internals. This one instance deliberately
|
|
252
|
+
misreports the environment, so "an instance describes a real installed
|
|
253
|
+
version" is not an invariant of `_FloorViolation`.
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def _checkout_root() -> Path:
|
|
258
|
+
"""Return the editable source checkout root this module runs from."""
|
|
259
|
+
return Path(__file__).resolve().parent.parent
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def refresh_command() -> str:
|
|
263
|
+
"""Return the shell command that refreshes this editable environment.
|
|
264
|
+
|
|
265
|
+
Shared by the stderr warning and the interactive prompt so the two
|
|
266
|
+
channels cannot drift apart.
|
|
267
|
+
"""
|
|
268
|
+
return (
|
|
269
|
+
"uv pip install --python "
|
|
270
|
+
f"{_quote_arg(sys.executable)} -e {_quote_arg(str(_checkout_root()))} "
|
|
271
|
+
"--upgrade"
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def _collect_violations() -> list[_FloorViolation]:
|
|
276
|
+
"""Detect below-floor dependencies for this editable install.
|
|
277
|
+
|
|
278
|
+
`DEEPAGENTS_CODE_DEBUG_DEP_FLOOR` short-circuits to a synthetic
|
|
279
|
+
violation before the editable gate and any real metadata reads.
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
The offending distributions; empty when the install is released,
|
|
283
|
+
the checkout cannot be read, or every floor is satisfied.
|
|
284
|
+
"""
|
|
285
|
+
from deepagents_code._env_vars import DEBUG_DEP_FLOOR, is_env_truthy
|
|
286
|
+
|
|
287
|
+
if is_env_truthy(DEBUG_DEP_FLOOR):
|
|
288
|
+
return [_DEBUG_VIOLATION]
|
|
289
|
+
if not _is_editable_install():
|
|
290
|
+
return []
|
|
291
|
+
entries = _load_cli_requirements()
|
|
292
|
+
if entries is None:
|
|
293
|
+
return []
|
|
294
|
+
return _find_floor_violations(entries)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def _mismatch_fingerprint(violations: list[_FloorViolation]) -> str:
|
|
298
|
+
"""Hash the mismatch so a dismissal stays valid only while it is unchanged.
|
|
299
|
+
|
|
300
|
+
Args:
|
|
301
|
+
violations: The offending distributions.
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
A hex digest over sorted `name/installed/floor` rows. Any change —
|
|
305
|
+
a refreshed dep, a moved floor, a newly stale package — produces a
|
|
306
|
+
different fingerprint and re-arms the warning.
|
|
307
|
+
|
|
308
|
+
The rows deliberately exclude `required`: it is `packaging`'s rendering
|
|
309
|
+
of the requirement, so hashing it would let a `packaging` upgrade that
|
|
310
|
+
reorders specifiers silently invalidate every stored dismissal.
|
|
311
|
+
"""
|
|
312
|
+
rows = sorted(f"{v.dist_name}/{v.installed}/{v.floor}" for v in violations)
|
|
313
|
+
return hashlib.sha256("\n".join(rows).encode()).hexdigest()
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def format_dep_floor_warning(violations: list[_FloorViolation]) -> str:
|
|
317
|
+
"""Build the full advisory: one line per violation plus the refresh command.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
violations: The offending distributions.
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
Plain-text (no Rich markup) advisory listing each violation, then the
|
|
324
|
+
refresh command, ending with a "continuing anyway" caveat.
|
|
325
|
+
"""
|
|
326
|
+
lines = [
|
|
327
|
+
(
|
|
328
|
+
"this editable dcode install is running against dependencies "
|
|
329
|
+
"older than the floors declared in the checkout's pyproject.toml:"
|
|
330
|
+
)
|
|
331
|
+
]
|
|
332
|
+
lines.extend(f" - {v.describe()}" for v in violations)
|
|
333
|
+
refresh = refresh_command()
|
|
334
|
+
lines.append(
|
|
335
|
+
"Refresh the active environment:\n"
|
|
336
|
+
f" {refresh}\n"
|
|
337
|
+
"Continuing anyway; behavior may be broken."
|
|
338
|
+
)
|
|
339
|
+
return "\n".join(lines)
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
# ---------------------------------------------------------------------------
|
|
343
|
+
# Dismissal ("mute") store — per-checkout fingerprint of a muted mismatch.
|
|
344
|
+
# Mirrors the hooks trust store's locking/atomic-write pattern, but the file
|
|
345
|
+
# records a *specific mismatch* rather than a durable grant: unlike hook
|
|
346
|
+
# trust, muting never disables the check, it only silences the exact mismatch
|
|
347
|
+
# the user already saw.
|
|
348
|
+
# ---------------------------------------------------------------------------
|
|
349
|
+
|
|
350
|
+
_DISMISSAL_STORE_LOCK_TIMEOUT_SECONDS = 5.0
|
|
351
|
+
_DISMISSAL_STORE_THREAD_LOCK = threading.Lock()
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def _default_dismissal_path() -> Path:
|
|
355
|
+
from deepagents_code.model_config import DEFAULT_STATE_DIR
|
|
356
|
+
|
|
357
|
+
return DEFAULT_STATE_DIR / "dep_floor_dismissed.json"
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def _checkout_key() -> str:
|
|
361
|
+
"""Return the canonical per-checkout key: the resolved editable source root."""
|
|
362
|
+
return str(_checkout_root())
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
@contextmanager
|
|
366
|
+
def _dismissal_store_lock(path: Path) -> Iterator[None]:
|
|
367
|
+
"""Serialize read-merge-write updates to the dismissal store.
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
path: Path to the dismissal JSON file.
|
|
371
|
+
|
|
372
|
+
Yields:
|
|
373
|
+
Control while the caller exclusively holds the mutation lock.
|
|
374
|
+
"""
|
|
375
|
+
from filelock import FileLock
|
|
376
|
+
|
|
377
|
+
path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
378
|
+
if os.name != "nt":
|
|
379
|
+
with suppress(OSError):
|
|
380
|
+
path.parent.chmod(0o700)
|
|
381
|
+
file_lock = FileLock(
|
|
382
|
+
str(path.with_name(f"{path.name}.lock")),
|
|
383
|
+
timeout=_DISMISSAL_STORE_LOCK_TIMEOUT_SECONDS,
|
|
384
|
+
thread_local=False,
|
|
385
|
+
)
|
|
386
|
+
with _DISMISSAL_STORE_THREAD_LOCK, file_lock:
|
|
387
|
+
yield
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def _read_dismissed_fingerprints(path: Path) -> dict[str, str]:
|
|
391
|
+
"""Read the dismissal store, tolerating corruption and absence.
|
|
392
|
+
|
|
393
|
+
Args:
|
|
394
|
+
path: Path to the dismissal JSON file.
|
|
395
|
+
|
|
396
|
+
Returns:
|
|
397
|
+
Map of checkout key to muted mismatch fingerprint; empty on any
|
|
398
|
+
read/parse failure (a lost dismissal simply re-arms the prompt).
|
|
399
|
+
"""
|
|
400
|
+
try:
|
|
401
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
402
|
+
except (OSError, ValueError):
|
|
403
|
+
return {}
|
|
404
|
+
if not isinstance(data, dict):
|
|
405
|
+
return {}
|
|
406
|
+
dismissed = data.get("dismissed")
|
|
407
|
+
if not isinstance(dismissed, dict):
|
|
408
|
+
return {}
|
|
409
|
+
return {k: v for k, v in dismissed.items() if isinstance(v, str)}
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def _write_dismissed_fingerprints(path: Path, dismissed: dict[str, str]) -> None:
|
|
413
|
+
"""Atomically replace the dismissal store.
|
|
414
|
+
|
|
415
|
+
Args:
|
|
416
|
+
path: Path to the dismissal JSON file.
|
|
417
|
+
dismissed: Full map of checkout key to muted mismatch fingerprint.
|
|
418
|
+
"""
|
|
419
|
+
payload = json.dumps({"dismissed": dismissed}, indent=2, sort_keys=True)
|
|
420
|
+
fd, tmp_name = tempfile.mkstemp(
|
|
421
|
+
dir=path.parent, prefix=f"{path.name}.", suffix=".tmp"
|
|
422
|
+
)
|
|
423
|
+
tmp = Path(tmp_name)
|
|
424
|
+
try:
|
|
425
|
+
# `fdopen` takes ownership of `fd`, so it is only closed by hand when
|
|
426
|
+
# the wrap itself failed; otherwise the `with` block closes it.
|
|
427
|
+
try:
|
|
428
|
+
handle = os.fdopen(fd, "w", encoding="utf-8")
|
|
429
|
+
except BaseException:
|
|
430
|
+
with suppress(OSError):
|
|
431
|
+
os.close(fd)
|
|
432
|
+
raise
|
|
433
|
+
with handle:
|
|
434
|
+
handle.write(payload)
|
|
435
|
+
if os.name != "nt":
|
|
436
|
+
with suppress(OSError):
|
|
437
|
+
tmp.chmod(0o600)
|
|
438
|
+
tmp.replace(path)
|
|
439
|
+
except BaseException:
|
|
440
|
+
with suppress(OSError):
|
|
441
|
+
tmp.unlink()
|
|
442
|
+
raise
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def is_dep_floor_mismatch_muted(fingerprint: str) -> bool:
|
|
446
|
+
"""Return whether this checkout's muted fingerprint matches *fingerprint*.
|
|
447
|
+
|
|
448
|
+
Reads without taking the store lock. Writes land via an atomic
|
|
449
|
+
`Path.replace`, so a concurrent mute is either wholly visible or wholly
|
|
450
|
+
absent — never torn. Locking here would instead put a `filelock` import
|
|
451
|
+
and a 5-second timeout on the startup path of every editable launch, and
|
|
452
|
+
a second `dcode` mid-write would stall this one for no benefit.
|
|
453
|
+
|
|
454
|
+
Args:
|
|
455
|
+
fingerprint: Fingerprint of the currently detected mismatch.
|
|
456
|
+
|
|
457
|
+
Returns:
|
|
458
|
+
`True` when the user muted this exact mismatch for this checkout.
|
|
459
|
+
Any store read failure returns `False`, re-arming the prompt.
|
|
460
|
+
"""
|
|
461
|
+
try:
|
|
462
|
+
dismissed = _read_dismissed_fingerprints(_default_dismissal_path())
|
|
463
|
+
return dismissed.get(_checkout_key()) == fingerprint
|
|
464
|
+
except Exception:
|
|
465
|
+
logger.debug("Could not read dependency floor dismissal store", exc_info=True)
|
|
466
|
+
return False
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
def mute_dep_floor_mismatch(fingerprint: str) -> bool:
|
|
470
|
+
"""Persist *fingerprint* as this checkout's muted mismatch.
|
|
471
|
+
|
|
472
|
+
Args:
|
|
473
|
+
fingerprint: Fingerprint of the mismatch the user chose to mute.
|
|
474
|
+
|
|
475
|
+
Returns:
|
|
476
|
+
`True` when the dismissal was persisted; `False` on any write
|
|
477
|
+
failure (the caller then treats the choice as session-only).
|
|
478
|
+
"""
|
|
479
|
+
path = _default_dismissal_path()
|
|
480
|
+
try:
|
|
481
|
+
with _dismissal_store_lock(path):
|
|
482
|
+
dismissed = _read_dismissed_fingerprints(path)
|
|
483
|
+
dismissed[_checkout_key()] = fingerprint
|
|
484
|
+
_write_dismissed_fingerprints(path, dismissed)
|
|
485
|
+
except Exception:
|
|
486
|
+
logger.debug("Could not persist dependency floor dismissal", exc_info=True)
|
|
487
|
+
return False
|
|
488
|
+
return True
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
def warn_if_editable_deps_stale() -> None:
|
|
492
|
+
"""Print the stale-dependency warning to stderr for non-TUI launches.
|
|
493
|
+
|
|
494
|
+
Skips silently when there are no violations or the exact mismatch was
|
|
495
|
+
muted for this checkout. This is strictly best-effort: any unexpected
|
|
496
|
+
failure degrades to a debug log and never raises. The warning goes to
|
|
497
|
+
stderr so it never contaminates the stdout these launches produce for a
|
|
498
|
+
caller to consume (a piped `-n` answer, a subcommand's output).
|
|
499
|
+
"""
|
|
500
|
+
try:
|
|
501
|
+
violations = _collect_violations()
|
|
502
|
+
if not violations:
|
|
503
|
+
return
|
|
504
|
+
if is_dep_floor_mismatch_muted(_mismatch_fingerprint(violations)):
|
|
505
|
+
return
|
|
506
|
+
from rich.console import Console
|
|
507
|
+
from rich.markup import escape
|
|
508
|
+
|
|
509
|
+
Console(stderr=True).print(
|
|
510
|
+
f"[bold yellow]Warning:[/bold yellow] "
|
|
511
|
+
f"{escape(format_dep_floor_warning(violations))}",
|
|
512
|
+
highlight=False,
|
|
513
|
+
)
|
|
514
|
+
except Exception: # strictly best-effort: a check failure must never break startup
|
|
515
|
+
logger.debug("Dependency floor check failed", exc_info=True)
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
def prompt_if_editable_deps_stale() -> _TrustPromptOutcome | None:
|
|
519
|
+
"""Block on a continue/mute/abort prompt when an interactive launch is stale.
|
|
520
|
+
|
|
521
|
+
Prompts only when violations exist and the exact mismatch was not muted
|
|
522
|
+
for this checkout. The prompt itself is implemented in `main` next to the
|
|
523
|
+
other pre-TUI trust prompts; this function handles detection, muting, and
|
|
524
|
+
the confirmation prints.
|
|
525
|
+
|
|
526
|
+
Returns:
|
|
527
|
+
`None` to continue the launch (no violation, muted, or the user
|
|
528
|
+
chose to continue), `INTERRUPTED` on Ctrl+C (caller exits 130), or
|
|
529
|
+
`CANCELLED` on Esc/abort (caller exits 0).
|
|
530
|
+
"""
|
|
531
|
+
try:
|
|
532
|
+
return _prompt_if_editable_deps_stale()
|
|
533
|
+
except Exception: # strictly best-effort: check failures must not break startup
|
|
534
|
+
logger.debug("Interactive dependency floor check failed", exc_info=True)
|
|
535
|
+
return None
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
def _prompt_if_editable_deps_stale() -> _TrustPromptOutcome | None:
|
|
539
|
+
"""Run the interactive stale-dependency check after its fail-open boundary.
|
|
540
|
+
|
|
541
|
+
Returns:
|
|
542
|
+
The abort outcome, or `None` when launch should continue.
|
|
543
|
+
"""
|
|
544
|
+
from rich.console import Console
|
|
545
|
+
|
|
546
|
+
from deepagents_code.main import (
|
|
547
|
+
_TrustAction,
|
|
548
|
+
_TrustPromptOutcome,
|
|
549
|
+
prompt_for_dep_floor_mismatch,
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
violations = _collect_violations()
|
|
553
|
+
if not violations:
|
|
554
|
+
return None
|
|
555
|
+
fingerprint = _mismatch_fingerprint(violations)
|
|
556
|
+
if is_dep_floor_mismatch_muted(fingerprint):
|
|
557
|
+
return None
|
|
558
|
+
|
|
559
|
+
console = Console(stderr=True)
|
|
560
|
+
action = prompt_for_dep_floor_mismatch(console, violations)
|
|
561
|
+
if action in {_TrustPromptOutcome.INTERRUPTED, _TrustPromptOutcome.CANCELLED}:
|
|
562
|
+
return action
|
|
563
|
+
if action is _TrustAction.REMEMBER:
|
|
564
|
+
if mute_dep_floor_mismatch(fingerprint):
|
|
565
|
+
console.print(
|
|
566
|
+
"[dim]Muted until the dependency mismatch changes.[/dim]",
|
|
567
|
+
highlight=False,
|
|
568
|
+
)
|
|
569
|
+
else:
|
|
570
|
+
console.print(
|
|
571
|
+
"[yellow]The dismissal could not be saved; you will be asked "
|
|
572
|
+
"again next launch.[/yellow]",
|
|
573
|
+
highlight=False,
|
|
574
|
+
)
|
|
575
|
+
elif action is _TrustAction.ALLOW_ONCE:
|
|
576
|
+
console.print(
|
|
577
|
+
"[dim]Continuing this session; you will be asked again next launch.[/dim]",
|
|
578
|
+
highlight=False,
|
|
579
|
+
)
|
|
580
|
+
else:
|
|
581
|
+
# `abort_on_deny` should have collapsed a refusal into `CANCELLED`
|
|
582
|
+
# already, so `DENY` (or any future outcome) only lands here if that
|
|
583
|
+
# mapping regresses. Refuse rather than continuing: matching "continue"
|
|
584
|
+
# by default is what previously turned "Abort launch" into a launch.
|
|
585
|
+
logger.debug("Unexpected dependency floor prompt outcome %r; aborting", action)
|
|
586
|
+
return _TrustPromptOutcome.CANCELLED
|
|
587
|
+
return None
|