deepagents-code 0.1.43__tar.gz → 0.1.44__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.43 → deepagents_code-0.1.44}/CHANGELOG.md +7 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/PKG-INFO +1 -1
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_build_info.py +1 -1
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_version.py +1 -1
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/app.py +27 -11
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/auto_mode.py +2 -1
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_tools.py +27 -7
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/modals/plugin_manager/__init__.py +10 -6
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/approval.py +86 -47
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/pyproject.toml +4 -1
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_app.py +85 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_auto_mode.py +91 -2
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_mcp_tools.py +76 -1
- deepagents_code-0.1.44/tests/unit_tests/test_startup_blocking.py +72 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/modals/plugin_manager/test_structure.py +35 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_approval.py +276 -5
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/uv.lock +3 -1
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/.gitignore +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/AGENTS.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/ARCHITECTURE.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/COMMANDS.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/DEVELOPMENT.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/Makefile +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/README.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/THREAT_MODEL.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/__main__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_ask_user_types.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_cli_context.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_constants.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_debug.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_debug_buffer.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_env_vars.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_fake_models.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_git.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_paths.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_server_config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_session_stats.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_startup_error.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_testing_models.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_textual_patches.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/_tool_stream.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/agent.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/app.tcss +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/approval_mode.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/ask_user.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/auth_display.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/auth_store.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/built_in_skills/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/commands/auth.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/commands/config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/commands/mcp.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/commands/tools.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/launch/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/launch/server.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/launch/server_manager.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/non_interactive.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/client/remote_client.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/clipboard.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/command_registry.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/config_manifest.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/configurable_model.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/default_agent_prompt.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/doctor.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/editor.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/event_bus.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/extras_info.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/file_ops.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/formatting.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/goal_rubric.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/goal_tools.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/hooks.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/input.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/integrations/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/integrations/openai_codex.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/integrations/sandbox_config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/integrations/sandbox_factory.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/integrations/sandbox_provider.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/integrations/sandbox_registry.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/local_context.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/main.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/managed_tools.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_auth.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_disabled.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_login_service.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_providers/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_providers/_registry.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_providers/base.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_providers/github.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/mcp_providers/slack.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/media_utils.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/memory_guard.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/model_config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/notifications.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/offload.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/offload_middleware.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/onboarding.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/output.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/paste_collapse.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/_json.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/adapters/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/adapters/mcp.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/adapters/skills.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/adapters/skills_middleware.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/commands_cli.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/discovery.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/manifest.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/marketplace.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/models.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/store.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/plugins/substitution.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/project_utils.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/py.typed +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/reasoning_effort.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/reliable_rubric.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/resume_state.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/server_graph.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/sessions.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/skills/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/skills/commands.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/skills/invocation.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/skills/load.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/skills/merge.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/skills/trust.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/state_migration.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/subagents.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/system_prompt.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/terminal_capabilities.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/terminal_escape.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/theme.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/todo_list_prompt.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tool_catalog.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tool_display.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tools.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/modals/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/modals/plugin_manager/content.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/modals/plugin_manager/models.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/modals/plugin_manager/plugin_manager.tcss +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/modals/plugin_manager/state.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/modals/plugin_manager/tabs.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/screens/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/textual_adapter.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/_inline_prompt.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/_js_eval_display.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/_links.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/_paste_textarea.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/agent_selector.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/ask_user.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/auth.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/autocomplete.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/chat_input.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/codex_auth.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/cwd_switch.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/debug_console.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/diff.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/effort_selector.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/goal_review.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/goal_status.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/history.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/install_confirm.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/launch_init.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/loading.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/mcp_login.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/mcp_reconnect.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/mcp_viewer.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/message_store.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/messages.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/model_selector.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/notification_center.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/notification_detail.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/notification_settings.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/plugin_reload.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/restart_prompt.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/skill_trust.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/startup_tip.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/status.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/subagent_panel.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/theme_selector.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/thread_selector.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/tool_renderers.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/tool_widgets.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/update_available.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/update_confirm.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/update_progress.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/tui/widgets/welcome.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/ui.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/unicode_security.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/deepagents_code/update_check.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/examples/skills/arxiv-search/SKILL.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/examples/skills/arxiv-search/arxiv_search.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/examples/skills/langgraph-docs/SKILL.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/examples/skills/skill-creator/SKILL.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/examples/skills/web-research/SKILL.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/hatch_build.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/images/tui.png +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/scripts/check_imports.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/scripts/debug_server.sh +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/scripts/generate_commands_catalog.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/scripts/install.sh +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/README.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/benchmarks/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/conftest.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/test_acp_mode.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/test_auto_approve_remote.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/test_compact_resume.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/test_goal_criteria_remote.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/test_offload_server_side.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/integration_tests/test_sandbox_operations.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/client/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/client/commands/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/client/commands/test_auth.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/client/commands/test_mcp.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/client/commands/test_tools.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/conftest.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/plugins/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/plugins/test_marketplace.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/plugins/test_plugins_p0.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/plugins/test_store.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/skills/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/skills/test_commands.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/skills/test_load.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/skills/test_merge.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/skills/test_skill_trust.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/skills/test_skills_json.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/smoke_tests/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/smoke_tests/conftest.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/smoke_tests/test_system_prompt.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test__tool_stream.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_agent.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_agent_friendly.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_approval_mode.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_args.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_ask_user_middleware.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_auth_display.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_auth_store.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_auth_web_search_restart.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_charset.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_clipboard.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_command_registry.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_compact_tool.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_config_manifest.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_configurable_model.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_cursor_blink.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_cursor_style.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_debug.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_debug_buffer.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_debug_console.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_doctor.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_editor.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_end_to_end.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_env_vars.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_event_bus.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_exception_handling.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_extras_info.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_file_ops.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_formatting.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_git.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_goal_criteria_client.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_goal_rubric.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_goal_tools.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_hatch_build.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_hooks.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_imports.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_input_parsing.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_install_command.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_install_script.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_local_context.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_main.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_main_acp_mode.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_main_args.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_managed_tools.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_mcp_auth.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_mcp_config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_mcp_disabled.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_mcp_login_service.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_media_utils.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_memory_guard.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_model_config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_model_switch.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_non_interactive.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_notifications.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_offload.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_onboarding.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_openai_codex_integration.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_output.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_paths.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_reasoning_effort.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_reliable_rubric.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_reload.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_remote_client.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_resume_state.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_rubric_cli.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_sandbox_config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_sandbox_factory.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_sandbox_provider.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_sandbox_registry.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_server.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_server_config.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_server_graph.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_server_helpers.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_server_manager.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_session_stats.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_sessions.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_shell_allow_list.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_skill_invocation.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_startup_fast_paths.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_state_migration.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_subagents.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_terminal_capabilities.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_terminal_escape.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_textual_patches.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_theme.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_threads_resume.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_tool_catalog.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_tool_display.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_tracing_replicas.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_transcript_virtualization.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_ui.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_unicode_security.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_update_check.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/test_version.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tools/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tools/test_current_thread.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tools/test_fetch_url.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/modals/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/modals/plugin_manager/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/test_subagent_stream.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/test_textual_adapter.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/__init__.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_agent_selector.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_ask_user.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_auth_widgets.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_autocomplete.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_chat_input.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_cwd_switch.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_diff.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_goal_review.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_history.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_inline_prompt.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_install_confirm.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_launch_init.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_links.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_loading.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_mcp_login_modal.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_mcp_reconnect.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_mcp_viewer.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_message_store.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_messages.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_model_selector.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_notification_center.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_notification_detail.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_plugin_reload.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_restart_prompt.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_skill_trust_screen.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_startup_tip.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_status.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_subagent_panel.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_thread_selector.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_tool_renderers.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_update_available.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_update_confirm.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_update_progress.py +0 -0
- {deepagents_code-0.1.43 → deepagents_code-0.1.44}/tests/unit_tests/tui/widgets/test_welcome.py +0 -0
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
# Deep Agents Code Changelog
|
|
4
4
|
|
|
5
|
+
## [0.1.44](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.43...deepagents-code==0.1.44) (2026-07-20)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- Improved approval handling by hiding the `Auto` option when it isn't eligible and moving Auto mode path checks off the event loop. ([#4839](https://github.com/langchain-ai/deepagents/issues/4839), [#4856](https://github.com/langchain-ai/deepagents/issues/4856))
|
|
10
|
+
- Warmed MCP auth imports off the event loop to avoid blocking runtime work. ([#4855](https://github.com/langchain-ai/deepagents/issues/4855))
|
|
11
|
+
|
|
5
12
|
## [0.1.43](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.42...deepagents-code==0.1.43) (2026-07-17)
|
|
6
13
|
|
|
7
14
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepagents-code
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.44
|
|
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/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Keep the `x-release-please-version` annotation — release-please uses it to
|
|
4
4
|
# bump `__version__` in sync with `pyproject.toml` on every release PR.
|
|
5
|
-
__version__ = "0.1.
|
|
5
|
+
__version__ = "0.1.44" # x-release-please-version
|
|
6
6
|
|
|
7
7
|
DOCS_URL = "https://docs.langchain.com/oss/python/deepagents/code"
|
|
8
8
|
"""URL for `deepagents-code` documentation."""
|
|
@@ -119,6 +119,10 @@ _DEFERRED_START_NOTICE = (
|
|
|
119
119
|
"Deep Agents will ask for credentials for the selected provider."
|
|
120
120
|
)
|
|
121
121
|
|
|
122
|
+
_AUTO_MODE_ENABLED_WARNING = (
|
|
123
|
+
"Auto beta enabled. It classifies gated actions but is not sandbox containment."
|
|
124
|
+
)
|
|
125
|
+
|
|
122
126
|
_BLOCKED_GOAL_RETRY_CONTEXT = (
|
|
123
127
|
"<dcode_blocked_goal_retry_context>\n"
|
|
124
128
|
"The active goal was previously marked blocked.\n\n"
|
|
@@ -2447,10 +2451,10 @@ class DeepAgentsApp(App):
|
|
|
2447
2451
|
Binding("j", "approval_down", "Down", show=False),
|
|
2448
2452
|
Binding("enter", "approval_select", "Select", show=False),
|
|
2449
2453
|
Binding("y", "approval_yes", "Yes", show=False),
|
|
2450
|
-
Binding("1", "
|
|
2451
|
-
Binding("2", "
|
|
2454
|
+
Binding("1", "approval_position(0)", "Select first", show=False),
|
|
2455
|
+
Binding("2", "approval_position(1)", "Select second", show=False),
|
|
2456
|
+
Binding("3", "approval_position(2)", "Select third", show=False),
|
|
2452
2457
|
Binding("a", "approval_auto", "Auto", show=False),
|
|
2453
|
-
Binding("3", "approval_no", "No", show=False),
|
|
2454
2458
|
Binding("n", "approval_no", "No", show=False),
|
|
2455
2459
|
]
|
|
2456
2460
|
"""App-level keybindings for interrupt, quit, toggles, and approval menu
|
|
@@ -3596,8 +3600,7 @@ class DeepAgentsApp(App):
|
|
|
3596
3600
|
self._status_bar.set_approval_mode(self._approval_mode.value)
|
|
3597
3601
|
if self._approval_mode.value == "auto":
|
|
3598
3602
|
self.notify(
|
|
3599
|
-
|
|
3600
|
-
"PTC and delegated subagent internals remain bypasses.",
|
|
3603
|
+
_AUTO_MODE_ENABLED_WARNING,
|
|
3601
3604
|
severity="warning",
|
|
3602
3605
|
timeout=10,
|
|
3603
3606
|
markup=False,
|
|
@@ -7073,7 +7076,12 @@ class DeepAgentsApp(App):
|
|
|
7073
7076
|
from deepagents_code.tui.widgets.approval import ApprovalMenu
|
|
7074
7077
|
|
|
7075
7078
|
unique_id = f"approval-menu-{uuid.uuid4().hex[:8]}"
|
|
7076
|
-
menu = ApprovalMenu(
|
|
7079
|
+
menu = ApprovalMenu(
|
|
7080
|
+
action_requests,
|
|
7081
|
+
assistant_id,
|
|
7082
|
+
id=unique_id,
|
|
7083
|
+
auto_mode_eligible=self._auto_mode_eligible,
|
|
7084
|
+
)
|
|
7077
7085
|
menu.set_future(result_future)
|
|
7078
7086
|
|
|
7079
7087
|
self._pending_approval_widget = menu
|
|
@@ -7264,8 +7272,7 @@ class DeepAgentsApp(App):
|
|
|
7264
7272
|
if self._session_state:
|
|
7265
7273
|
self._session_state.approval_mode = ApprovalMode.AUTO
|
|
7266
7274
|
self.notify(
|
|
7267
|
-
|
|
7268
|
-
"containment.",
|
|
7275
|
+
_AUTO_MODE_ENABLED_WARNING,
|
|
7269
7276
|
severity="warning",
|
|
7270
7277
|
timeout=8,
|
|
7271
7278
|
markup=False,
|
|
@@ -15934,17 +15941,26 @@ class DeepAgentsApp(App):
|
|
|
15934
15941
|
return focused.id == "chat-input" or focused in self._chat_input.walk_children()
|
|
15935
15942
|
|
|
15936
15943
|
def action_approval_yes(self) -> None:
|
|
15937
|
-
"""Handle
|
|
15944
|
+
"""Handle the semantic approve key in the approval menu."""
|
|
15938
15945
|
if self._pending_approval_widget:
|
|
15939
15946
|
self._pending_approval_widget.action_select_approve()
|
|
15940
15947
|
|
|
15948
|
+
def action_approval_position(self, position: int) -> None:
|
|
15949
|
+
"""Select an approval option by its visible position.
|
|
15950
|
+
|
|
15951
|
+
Args:
|
|
15952
|
+
position: Zero-based position of the displayed option.
|
|
15953
|
+
"""
|
|
15954
|
+
if self._pending_approval_widget:
|
|
15955
|
+
self._pending_approval_widget.action_select_position(position)
|
|
15956
|
+
|
|
15941
15957
|
def action_approval_auto(self) -> None:
|
|
15942
|
-
"""Handle
|
|
15958
|
+
"""Handle the semantic Auto key in the approval menu."""
|
|
15943
15959
|
if self._pending_approval_widget:
|
|
15944
15960
|
self._pending_approval_widget.action_select_auto()
|
|
15945
15961
|
|
|
15946
15962
|
def action_approval_no(self) -> None:
|
|
15947
|
-
"""Handle
|
|
15963
|
+
"""Handle the semantic reject key in the approval menu."""
|
|
15948
15964
|
if self._pending_approval_widget:
|
|
15949
15965
|
self._pending_approval_widget.action_select_reject()
|
|
15950
15966
|
|
|
@@ -1179,7 +1179,8 @@ class AutoModeHITLMiddleware(HumanInTheLoopMiddleware[AutoModeState, Any, Any]):
|
|
|
1179
1179
|
review_calls: list[ToolCall] = []
|
|
1180
1180
|
deterministic_dispositions: dict[str, str] = {}
|
|
1181
1181
|
for call in gated_calls:
|
|
1182
|
-
if
|
|
1182
|
+
if await asyncio.to_thread(
|
|
1183
|
+
_deterministic_allow,
|
|
1183
1184
|
self._worktree_root,
|
|
1184
1185
|
call,
|
|
1185
1186
|
tools.get(call["name"]),
|
|
@@ -1767,19 +1767,39 @@ spawn an unbounded number of simultaneous socket/subprocess handshakes (or
|
|
|
1767
1767
|
|
|
1768
1768
|
|
|
1769
1769
|
def _warm_mcp_adapter_imports() -> None:
|
|
1770
|
-
"""Eagerly import MCP
|
|
1771
|
-
|
|
1772
|
-
Run via `asyncio.to_thread` before adapter symbols are used, so
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1770
|
+
"""Eagerly import MCP modules whose first import may block.
|
|
1771
|
+
|
|
1772
|
+
Run via `asyncio.to_thread` before adapter/auth symbols are used, so any
|
|
1773
|
+
blocking side effect of a first import happens off the server event loop
|
|
1774
|
+
rather than where Blockbuster would reject it. Two known offenders:
|
|
1775
|
+
|
|
1776
|
+
- `langchain_mcp_adapters` runs a package-resource scan on first import.
|
|
1777
|
+
- `mcp_auth` imports `httpx`, which transitively imports `rich`; `rich`
|
|
1778
|
+
calls `os.getcwd()` in its module body (verified against the pinned
|
|
1779
|
+
versions — the exact culprit may shift as dependencies change, but the
|
|
1780
|
+
general risk of import-time I/O in this subtree does not).
|
|
1781
|
+
|
|
1782
|
+
Warming `mcp_auth` is best-effort: it is only *used* on per-server paths
|
|
1783
|
+
(remote-server preflight and the per-tool call path), where an import
|
|
1784
|
+
failure is captured and reported per server. A failure to warm it must not
|
|
1785
|
+
abort loading for every server — notably stdio-only configs, which never
|
|
1786
|
+
import `mcp_auth` otherwise — so it is swallowed here and left to re-raise
|
|
1787
|
+
at the real use site. Runs only when at least one active MCP server exists.
|
|
1777
1788
|
"""
|
|
1778
1789
|
from langchain_mcp_adapters import (
|
|
1779
1790
|
sessions as _sessions, # noqa: F401
|
|
1780
1791
|
tools as _tools, # noqa: F401
|
|
1781
1792
|
)
|
|
1782
1793
|
|
|
1794
|
+
try:
|
|
1795
|
+
from deepagents_code import mcp_auth as _mcp_auth # noqa: F401
|
|
1796
|
+
except Exception: # warmup is a best-effort optimization; never abort load
|
|
1797
|
+
logger.warning(
|
|
1798
|
+
"Failed to warm mcp_auth import off the event loop; "
|
|
1799
|
+
"deferring to per-server use",
|
|
1800
|
+
exc_info=True,
|
|
1801
|
+
)
|
|
1802
|
+
|
|
1783
1803
|
|
|
1784
1804
|
async def _gather_bounded(
|
|
1785
1805
|
factories: Sequence[Callable[[], Awaitable[_T]]],
|
|
@@ -304,13 +304,17 @@ class PluginManagerScreen(ModalScreen[None]): # noqa: RUF067
|
|
|
304
304
|
disabled=True,
|
|
305
305
|
)
|
|
306
306
|
)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
307
|
+
for index, row in enumerate(self._state.marketplaces):
|
|
308
|
+
if index > 0:
|
|
309
|
+
options.append(
|
|
310
|
+
Option(" ", id=f"marketplace-spacer:{index}", disabled=True)
|
|
311
|
+
)
|
|
312
|
+
options.append(
|
|
313
|
+
Option(
|
|
314
|
+
_marketplace_label(row),
|
|
315
|
+
id=f"marketplace:{row.name}",
|
|
316
|
+
)
|
|
311
317
|
)
|
|
312
|
-
for row in self._state.marketplaces
|
|
313
|
-
)
|
|
314
318
|
return options
|
|
315
319
|
if not self._state.errors:
|
|
316
320
|
return [Option("No plugin errors.", id="empty")]
|
|
@@ -42,8 +42,6 @@ _SHELL_COMMAND_TRUNCATE_LENGTH: int = 120
|
|
|
42
42
|
_SHELL_COMMAND_TRUNCATE_LINES: int = 5
|
|
43
43
|
_WARNING_PREVIEW_LIMIT: int = 3
|
|
44
44
|
_WARNING_TEXT_TRUNCATE_LENGTH: int = 220
|
|
45
|
-
# Must match the "reject" entry in `_handle_selection`'s decision map.
|
|
46
|
-
_REJECT_OPTION_INDEX: int = 2
|
|
47
45
|
|
|
48
46
|
|
|
49
47
|
def _is_command_too_long(command: str) -> bool:
|
|
@@ -109,11 +107,11 @@ class ApprovalMenu(Container):
|
|
|
109
107
|
Binding("down", "move_down", "Down", show=False),
|
|
110
108
|
Binding("j", "move_down", "Down", show=False),
|
|
111
109
|
Binding("enter", "select", "Select", show=False),
|
|
112
|
-
Binding("1", "
|
|
110
|
+
Binding("1", "select_position(0)", "Select first", show=False),
|
|
111
|
+
Binding("2", "select_position(1)", "Select second", show=False),
|
|
112
|
+
Binding("3", "select_position(2)", "Select third", show=False),
|
|
113
113
|
Binding("y", "select_approve", "Approve", show=False),
|
|
114
|
-
Binding("2", "select_auto", "Auto-approve", show=False),
|
|
115
114
|
Binding("a", "select_auto", "Auto-approve", show=False),
|
|
116
|
-
Binding("3", "select_reject", "Reject", show=False),
|
|
117
115
|
Binding("n", "select_reject", "Reject", show=False),
|
|
118
116
|
Binding("e", "toggle_expand", "Expand command", show=False),
|
|
119
117
|
Binding("tab", "reject_with_reason", "Reject with reason", show=False),
|
|
@@ -140,6 +138,8 @@ class ApprovalMenu(Container):
|
|
|
140
138
|
action_requests: list[dict[str, Any]] | dict[str, Any],
|
|
141
139
|
assistant_id: str | None = None,
|
|
142
140
|
id: str | None = None, # noqa: A002 # Textual widget constructor uses `id` parameter
|
|
141
|
+
*,
|
|
142
|
+
auto_mode_eligible: bool = True,
|
|
143
143
|
**kwargs: Any,
|
|
144
144
|
) -> None:
|
|
145
145
|
"""Initialize the ApprovalMenu widget.
|
|
@@ -151,6 +151,9 @@ class ApprovalMenu(Container):
|
|
|
151
151
|
assistant_id: Optional assistant ID for resolving virtual paths in
|
|
152
152
|
file-operation previews.
|
|
153
153
|
id: Optional widget ID. Defaults to 'approval-menu'.
|
|
154
|
+
auto_mode_eligible: Whether Auto mode can be enabled in this session.
|
|
155
|
+
When `False` (e.g. the experimental opt-in is off), the "Enable
|
|
156
|
+
Auto for this thread" option is not offered.
|
|
154
157
|
**kwargs: Additional keyword arguments passed to the Container base class.
|
|
155
158
|
"""
|
|
156
159
|
super().__init__(id=id or "approval-menu", classes="approval-menu", **kwargs)
|
|
@@ -168,6 +171,16 @@ class ApprovalMenu(Container):
|
|
|
168
171
|
and request["description"].startswith("Auto human fallback ")
|
|
169
172
|
for request in self._action_requests
|
|
170
173
|
)
|
|
174
|
+
# Only offer the Auto option when it can actually be enabled. A live
|
|
175
|
+
# Auto fallback implies Auto is already active, so its "Switch to
|
|
176
|
+
# Manual" affordance is always shown regardless of eligibility.
|
|
177
|
+
self._show_auto_option = self._is_auto_fallback or auto_mode_eligible
|
|
178
|
+
# Built once: every input to `_build_options` is fixed for the widget's
|
|
179
|
+
# lifetime, so caching keeps `_num_options`/`_reject_index` from ever
|
|
180
|
+
# disagreeing with the option list they describe.
|
|
181
|
+
self._options = self._build_options()
|
|
182
|
+
self._num_options = len(self._options)
|
|
183
|
+
self._reject_index = self._num_options - 1
|
|
171
184
|
self._selected = 0
|
|
172
185
|
self._future: asyncio.Future[dict[str, str]] | None = None
|
|
173
186
|
self._option_widgets: list[Static] = []
|
|
@@ -312,8 +325,8 @@ class ApprovalMenu(Container):
|
|
|
312
325
|
|
|
313
326
|
# Options container at bottom
|
|
314
327
|
with Container(classes="approval-options-container"):
|
|
315
|
-
# Options -
|
|
316
|
-
for i in range(
|
|
328
|
+
# Options - one Static widget per visible option
|
|
329
|
+
for i in range(self._num_options): # noqa: B007 # Loop variable unused - iterating for count only
|
|
317
330
|
widget = Static("", classes="approval-option")
|
|
318
331
|
self._option_widgets.append(widget)
|
|
319
332
|
yield widget
|
|
@@ -343,13 +356,14 @@ class ApprovalMenu(Container):
|
|
|
343
356
|
f"Enter submit {glyphs.bullet} Esc cancel {glyphs.bullet} "
|
|
344
357
|
"leave blank to reject without a reason"
|
|
345
358
|
)
|
|
359
|
+
quick_keys = "y/a/n" if self._show_auto_option else "y/n"
|
|
346
360
|
help_parts = [
|
|
347
361
|
(
|
|
348
362
|
f"{glyphs.arrow_up}/{glyphs.arrow_down} navigate "
|
|
349
|
-
f"{glyphs.bullet} Enter select {glyphs.bullet}
|
|
363
|
+
f"{glyphs.bullet} Enter select {glyphs.bullet} {quick_keys} quick keys"
|
|
350
364
|
),
|
|
351
365
|
]
|
|
352
|
-
if self._selected ==
|
|
366
|
+
if self._selected == self._reject_index:
|
|
353
367
|
help_parts.append("Tab amend")
|
|
354
368
|
help_parts.append("Esc reject")
|
|
355
369
|
help_text = f" {glyphs.bullet} ".join(help_parts)
|
|
@@ -409,32 +423,36 @@ class ApprovalMenu(Container):
|
|
|
409
423
|
approval_widget = widget_class(data)
|
|
410
424
|
await self._tool_info_container.mount(approval_widget)
|
|
411
425
|
|
|
412
|
-
def
|
|
413
|
-
"""
|
|
426
|
+
def _build_options(self) -> list[tuple[str, str]]:
|
|
427
|
+
"""Build the visible options as `(label, decision_type)` pairs.
|
|
428
|
+
|
|
429
|
+
The Auto option is omitted unless Auto can actually be enabled
|
|
430
|
+
(`_show_auto_option`), so it is never suggested outside the
|
|
431
|
+
experimental opt-in. Labels are unnumbered; `_update_options`
|
|
432
|
+
prefixes the display number.
|
|
433
|
+
|
|
434
|
+
Returns:
|
|
435
|
+
Ordered `(label, decision_type)` pairs for the visible options.
|
|
436
|
+
"""
|
|
414
437
|
count = len(self._action_requests)
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
"
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
]
|
|
426
|
-
else:
|
|
427
|
-
options = [
|
|
428
|
-
f"1. Approve all {count} (y)",
|
|
429
|
-
middle,
|
|
430
|
-
f"3. Reject all {count} (n)",
|
|
431
|
-
]
|
|
438
|
+
approve = "Approve (y)" if count == 1 else f"Approve all {count} (y)"
|
|
439
|
+
reject = "Reject (n)" if count == 1 else f"Reject all {count} (n)"
|
|
440
|
+
options: list[tuple[str, str]] = [(approve, "approve")]
|
|
441
|
+
if self._show_auto_option:
|
|
442
|
+
if self._is_auto_fallback:
|
|
443
|
+
options.append(("Switch to Manual (a)", "switch_manual"))
|
|
444
|
+
else:
|
|
445
|
+
options.append(("Enable Auto for this thread (a)", "auto_approve_all"))
|
|
446
|
+
options.append((reject, "reject"))
|
|
447
|
+
return options
|
|
432
448
|
|
|
433
|
-
|
|
434
|
-
|
|
449
|
+
def _update_options(self) -> None:
|
|
450
|
+
"""Update option widgets based on selection."""
|
|
451
|
+
for i, ((text, _decision), widget) in enumerate(
|
|
452
|
+
zip(self._options, self._option_widgets, strict=True)
|
|
435
453
|
):
|
|
436
454
|
cursor = f"{get_glyphs().cursor} " if i == self._selected else " "
|
|
437
|
-
widget.update(f"{cursor}{text}")
|
|
455
|
+
widget.update(f"{cursor}{i + 1}. {text}")
|
|
438
456
|
|
|
439
457
|
# Update classes
|
|
440
458
|
widget.remove_class("approval-option-selected")
|
|
@@ -447,26 +465,49 @@ class ApprovalMenu(Container):
|
|
|
447
465
|
"""Move selection up."""
|
|
448
466
|
if self._reason_input_active:
|
|
449
467
|
return
|
|
450
|
-
self._selected = (self._selected - 1) %
|
|
468
|
+
self._selected = (self._selected - 1) % self._num_options
|
|
451
469
|
self._update_options()
|
|
452
470
|
|
|
453
471
|
def action_move_down(self) -> None:
|
|
454
472
|
"""Move selection down."""
|
|
455
473
|
if self._reason_input_active:
|
|
456
474
|
return
|
|
457
|
-
self._selected = (self._selected + 1) %
|
|
475
|
+
self._selected = (self._selected + 1) % self._num_options
|
|
458
476
|
self._update_options()
|
|
459
477
|
|
|
460
478
|
def action_select(self) -> None:
|
|
461
479
|
"""Select current option."""
|
|
462
480
|
self._handle_selection(self._selected)
|
|
463
481
|
|
|
482
|
+
def action_select_position(self, position: int) -> None:
|
|
483
|
+
"""Submit the option at a display position (0-indexed).
|
|
484
|
+
|
|
485
|
+
Backs the numeric quick keys, which map key `1`/`2`/`3` to position
|
|
486
|
+
`0`/`1`/`2`. Positions outside the visible options are ignored, so
|
|
487
|
+
when the Auto option is hidden (only positions 0-1 exist) the `3` key
|
|
488
|
+
(position 2) is a no-op and key `2` (position 1) selects Reject rather
|
|
489
|
+
than Auto.
|
|
490
|
+
|
|
491
|
+
Args:
|
|
492
|
+
position: Zero-based index of the visible option to submit.
|
|
493
|
+
"""
|
|
494
|
+
if not 0 <= position < self._num_options:
|
|
495
|
+
return
|
|
496
|
+
self._handle_selection(position)
|
|
497
|
+
|
|
464
498
|
def action_select_approve(self) -> None:
|
|
465
499
|
"""Submit approve option."""
|
|
466
500
|
self._handle_selection(0)
|
|
467
501
|
|
|
468
502
|
def action_select_auto(self) -> None:
|
|
469
|
-
"""Submit
|
|
503
|
+
"""Submit the middle option (Auto, or Switch to Manual in a fallback).
|
|
504
|
+
|
|
505
|
+
No-op when the option is hidden, since Auto cannot be enabled. When
|
|
506
|
+
shown it is always the second option (index 1): "Enable Auto" normally,
|
|
507
|
+
or "Switch to Manual" during a live Auto fallback.
|
|
508
|
+
"""
|
|
509
|
+
if not self._show_auto_option:
|
|
510
|
+
return
|
|
470
511
|
self._handle_selection(1)
|
|
471
512
|
|
|
472
513
|
def action_select_reject(self) -> None:
|
|
@@ -479,7 +520,7 @@ class ApprovalMenu(Container):
|
|
|
479
520
|
if self._reason_input_active:
|
|
480
521
|
self._exit_reason_input_mode()
|
|
481
522
|
return
|
|
482
|
-
self._handle_selection(
|
|
523
|
+
self._handle_selection(self._reject_index)
|
|
483
524
|
|
|
484
525
|
def action_toggle_expand(self) -> None:
|
|
485
526
|
"""Toggle shell command expansion."""
|
|
@@ -496,17 +537,15 @@ class ApprovalMenu(Container):
|
|
|
496
537
|
"""Handle the selected option.
|
|
497
538
|
|
|
498
539
|
Args:
|
|
499
|
-
option: Index of the chosen option
|
|
500
|
-
|
|
501
|
-
|
|
540
|
+
option: Index of the chosen visible option. Maps to a decision type
|
|
541
|
+
via the current option layout (which omits Auto when hidden).
|
|
542
|
+
reject_message: Optional free-text reason. Only attached when a
|
|
543
|
+
non-empty reason is submitted via `on_input_submitted` (the
|
|
544
|
+
free-text reject flow opened by `action_reject_with_reason`).
|
|
502
545
|
"""
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
2: "reject",
|
|
507
|
-
}
|
|
508
|
-
decision: dict[str, str] = {"type": decision_map[option]}
|
|
509
|
-
if option == _REJECT_OPTION_INDEX and reject_message:
|
|
546
|
+
decision_type = self._options[option][1]
|
|
547
|
+
decision: dict[str, str] = {"type": decision_type}
|
|
548
|
+
if decision_type == "reject" and reject_message:
|
|
510
549
|
decision["message"] = reject_message
|
|
511
550
|
|
|
512
551
|
self.display = False
|
|
@@ -526,7 +565,7 @@ class ApprovalMenu(Container):
|
|
|
526
565
|
"""
|
|
527
566
|
if self._reason_input_active:
|
|
528
567
|
return
|
|
529
|
-
if self._selected !=
|
|
568
|
+
if self._selected != self._reject_index:
|
|
530
569
|
return
|
|
531
570
|
if self._reason_input is None:
|
|
532
571
|
# Lifecycle bug: Tab fired before `compose()` populated the Input ref.
|
|
@@ -568,7 +607,7 @@ class ApprovalMenu(Container):
|
|
|
568
607
|
return
|
|
569
608
|
reason = event.value.strip()
|
|
570
609
|
self._reason_input_active = False
|
|
571
|
-
self._handle_selection(
|
|
610
|
+
self._handle_selection(self._reject_index, reject_message=reason or None)
|
|
572
611
|
|
|
573
612
|
def _collect_security_warnings(self) -> list[str]:
|
|
574
613
|
"""Collect warning strings for suspicious Unicode and URL values.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "deepagents-code"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.44"
|
|
8
8
|
description = "Terminal coding agent built on the Deep Agents SDK - works with any model, with persistent memory, customizable skills, subagents, and approval controls."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -172,6 +172,9 @@ test = [
|
|
|
172
172
|
"pytest-xdist>=3.8.0,<4.0.0",
|
|
173
173
|
"responses>=0.26.1,<1.0.0",
|
|
174
174
|
"twine>=6.2.0,<7.0.0",
|
|
175
|
+
# Detect blocking calls on the event loop in startup smoke tests; mirrors the
|
|
176
|
+
# Blockbuster instance langgraph-runtime-inmem activates at runtime.
|
|
177
|
+
"blockbuster>=1.5.26,<1.6",
|
|
175
178
|
]
|
|
176
179
|
|
|
177
180
|
[tool.hatch.build.hooks.custom]
|
|
@@ -13420,6 +13420,52 @@ class TestInterruptApprovalPriority:
|
|
|
13420
13420
|
assert app._quit_pending is False
|
|
13421
13421
|
|
|
13422
13422
|
|
|
13423
|
+
class TestApprovalPositionBindings:
|
|
13424
|
+
"""Tests for app-level approval fallback shortcuts."""
|
|
13425
|
+
|
|
13426
|
+
@pytest.mark.parametrize(
|
|
13427
|
+
("key", "action"),
|
|
13428
|
+
[
|
|
13429
|
+
("1", "approval_position(0)"),
|
|
13430
|
+
("2", "approval_position(1)"),
|
|
13431
|
+
("3", "approval_position(2)"),
|
|
13432
|
+
],
|
|
13433
|
+
)
|
|
13434
|
+
def test_numeric_bindings_route_by_visible_position(
|
|
13435
|
+
self, key: str, action: str
|
|
13436
|
+
) -> None:
|
|
13437
|
+
"""Each app fallback number maps to the matching display position."""
|
|
13438
|
+
bindings = [
|
|
13439
|
+
binding
|
|
13440
|
+
for binding in DeepAgentsApp.BINDINGS
|
|
13441
|
+
if isinstance(binding, Binding) and binding.key == key
|
|
13442
|
+
]
|
|
13443
|
+
|
|
13444
|
+
assert len(bindings) == 1
|
|
13445
|
+
assert bindings[0].action == action
|
|
13446
|
+
|
|
13447
|
+
@pytest.mark.parametrize("position", [0, 1, 2])
|
|
13448
|
+
def test_numeric_position_delegates_to_visible_option(self, position: int) -> None:
|
|
13449
|
+
"""Fallback number actions use the widget's visible option positions."""
|
|
13450
|
+
app = DeepAgentsApp()
|
|
13451
|
+
approval = MagicMock()
|
|
13452
|
+
app._pending_approval_widget = approval
|
|
13453
|
+
|
|
13454
|
+
app.action_approval_position(position)
|
|
13455
|
+
|
|
13456
|
+
approval.action_select_position.assert_called_once_with(position)
|
|
13457
|
+
|
|
13458
|
+
def test_numeric_position_is_no_op_without_pending_approval(self) -> None:
|
|
13459
|
+
"""Fallback number actions do nothing outside an approval prompt."""
|
|
13460
|
+
app = DeepAgentsApp()
|
|
13461
|
+
assert app._pending_approval_widget is None
|
|
13462
|
+
|
|
13463
|
+
# Must not raise despite there being no widget to delegate to.
|
|
13464
|
+
app.action_approval_position(1)
|
|
13465
|
+
|
|
13466
|
+
assert app._pending_approval_widget is None
|
|
13467
|
+
|
|
13468
|
+
|
|
13423
13469
|
class TestIsUserTyping:
|
|
13424
13470
|
"""Unit tests for `_is_user_typing()` threshold logic."""
|
|
13425
13471
|
|
|
@@ -13580,6 +13626,45 @@ class TestRequestApprovalBranching:
|
|
|
13580
13626
|
f"Expected ApprovalMenu to be mounted, got {mounted_types}"
|
|
13581
13627
|
)
|
|
13582
13628
|
|
|
13629
|
+
@pytest.mark.parametrize("eligible", [True, False])
|
|
13630
|
+
async def test_menu_receives_auto_mode_eligibility(self, *, eligible: bool) -> None:
|
|
13631
|
+
"""The app forwards `_auto_mode_eligible` into the mounted ApprovalMenu.
|
|
13632
|
+
|
|
13633
|
+
Guards the load-bearing seam: if this kwarg were dropped or hardcoded,
|
|
13634
|
+
the Auto option would (dis)appear regardless of session eligibility, and
|
|
13635
|
+
the widget-level tests — which pass the flag themselves — would not catch
|
|
13636
|
+
it.
|
|
13637
|
+
"""
|
|
13638
|
+
app = DeepAgentsApp(agent=MagicMock())
|
|
13639
|
+
app._last_typed_at = None
|
|
13640
|
+
app._auto_mode_eligible = eligible
|
|
13641
|
+
|
|
13642
|
+
async def fake_mount_before_queued( # noqa: RUF029
|
|
13643
|
+
_container: object, _widget: object
|
|
13644
|
+
) -> None:
|
|
13645
|
+
return None
|
|
13646
|
+
|
|
13647
|
+
app._mount_before_queued = fake_mount_before_queued # ty: ignore
|
|
13648
|
+
app.call_after_refresh = MagicMock() # ty: ignore
|
|
13649
|
+
app.query_one = MagicMock(return_value=MagicMock()) # ty: ignore
|
|
13650
|
+
|
|
13651
|
+
action_requests = [
|
|
13652
|
+
{"name": "write_file", "args": {"path": "/tmp/e.txt", "content": "hi"}}
|
|
13653
|
+
]
|
|
13654
|
+
future = asyncio.get_running_loop().create_future()
|
|
13655
|
+
|
|
13656
|
+
with (
|
|
13657
|
+
patch.object(asyncio, "get_running_loop") as mock_loop,
|
|
13658
|
+
patch.object(app, "_reveal_pending_tool_calls"),
|
|
13659
|
+
):
|
|
13660
|
+
mock_loop.return_value.create_future.return_value = future
|
|
13661
|
+
await app._request_approval(action_requests, None)
|
|
13662
|
+
|
|
13663
|
+
# For a non-fallback request `_show_auto_option` equals the eligibility
|
|
13664
|
+
# flag, so this asserts the value actually crossed the app→widget seam.
|
|
13665
|
+
assert app._pending_approval_widget is not None
|
|
13666
|
+
assert app._pending_approval_widget._show_auto_option is eligible
|
|
13667
|
+
|
|
13583
13668
|
|
|
13584
13669
|
class TestDeferredShowApproval:
|
|
13585
13670
|
"""_deferred_show_approval should swap placeholder once idle."""
|