deepagents-code 0.1.16__tar.gz → 0.1.18__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/AGENTS.md +3 -2
  2. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/CHANGELOG.md +23 -0
  3. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/PKG-INFO +2 -2
  4. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_env_vars.py +2 -1
  5. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_version.py +1 -1
  6. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/app.py +163 -74
  7. deepagents_code-0.1.18/deepagents_code/auth_commands.py +450 -0
  8. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/auth_display.py +3 -3
  9. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/auth_store.py +41 -10
  10. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/config.py +177 -55
  11. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/config_manifest.py +1 -1
  12. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/input.py +0 -13
  13. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/integrations/sandbox_factory.py +0 -9
  14. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/main.py +154 -8
  15. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_tools.py +0 -4
  16. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_trust.py +1 -1
  17. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/model_config.py +63 -0
  18. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/sessions.py +0 -94
  19. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/ui.py +49 -1
  20. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/update_check.py +226 -22
  21. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/auth.py +422 -53
  22. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/codex_auth.py +11 -2
  23. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/mcp_login.py +13 -0
  24. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/message_store.py +0 -13
  25. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/messages.py +9 -0
  26. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/thread_selector.py +249 -37
  27. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/pyproject.toml +3 -3
  28. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/scripts/install.sh +180 -12
  29. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/conftest.py +10 -3
  30. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_app.py +186 -0
  31. deepagents_code-0.1.18/tests/unit_tests/test_auth_commands.py +747 -0
  32. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_auth_display.py +4 -2
  33. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_auth_store.py +4 -1
  34. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_auth_widgets.py +478 -11
  35. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_config.py +226 -0
  36. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_install_command.py +76 -0
  37. deepagents_code-0.1.18/tests/unit_tests/test_install_script.py +562 -0
  38. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_main.py +298 -0
  39. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_main_args.py +247 -4
  40. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_login_modal.py +41 -0
  41. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_messages.py +19 -0
  42. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_model_config.py +67 -0
  43. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_startup_fast_paths.py +2 -0
  44. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_thread_selector.py +577 -1
  45. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_update_check.py +336 -4
  46. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_version.py +145 -6
  47. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/uv.lock +164 -164
  48. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/.gitignore +0 -0
  49. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/COMMANDS.md +0 -0
  50. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/DEV.md +0 -0
  51. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/Makefile +0 -0
  52. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/README.md +0 -0
  53. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/THREAT_MODEL.md +0 -0
  54. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/__init__.py +0 -0
  55. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/__main__.py +0 -0
  56. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_ask_user_types.py +0 -0
  57. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_cli_context.py +0 -0
  58. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_constants.py +0 -0
  59. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_debug.py +0 -0
  60. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_git.py +0 -0
  61. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_server_config.py +0 -0
  62. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_session_stats.py +0 -0
  63. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_startup_error.py +0 -0
  64. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_testing_models.py +0 -0
  65. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/_textual_patches.py +0 -0
  66. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/agent.py +0 -0
  67. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/app.tcss +0 -0
  68. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/ask_user.py +0 -0
  69. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/built_in_skills/__init__.py +0 -0
  70. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
  71. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
  72. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  73. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  74. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/clipboard.py +0 -0
  75. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/command_registry.py +0 -0
  76. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/config_commands.py +0 -0
  77. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/configurable_model.py +0 -0
  78. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/default_agent_prompt.md +0 -0
  79. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/editor.py +0 -0
  80. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/event_bus.py +0 -0
  81. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/extras_info.py +0 -0
  82. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/file_ops.py +0 -0
  83. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/filesystem_empty_result.py +0 -0
  84. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/formatting.py +0 -0
  85. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/hooks.py +0 -0
  86. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/integrations/__init__.py +0 -0
  87. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/integrations/openai_codex.py +0 -0
  88. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/integrations/sandbox_config.py +0 -0
  89. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/integrations/sandbox_provider.py +0 -0
  90. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/integrations/sandbox_registry.py +0 -0
  91. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/iterm_cursor_guide.py +0 -0
  92. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/local_context.py +0 -0
  93. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/managed_tools.py +0 -0
  94. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_auth.py +0 -0
  95. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_commands.py +0 -0
  96. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_disabled.py +0 -0
  97. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_login_service.py +0 -0
  98. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_oauth_ui.py +0 -0
  99. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_providers/__init__.py +0 -0
  100. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_providers/_registry.py +0 -0
  101. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_providers/base.py +0 -0
  102. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_providers/github.py +0 -0
  103. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/mcp_providers/slack.py +0 -0
  104. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/media_utils.py +0 -0
  105. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/memory_guard.py +0 -0
  106. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/non_interactive.py +0 -0
  107. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/notifications.py +0 -0
  108. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/offload.py +0 -0
  109. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/onboarding.py +0 -0
  110. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/output.py +0 -0
  111. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/project_utils.py +0 -0
  112. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/py.typed +0 -0
  113. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/remote_client.py +0 -0
  114. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/resume_state.py +0 -0
  115. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/server.py +0 -0
  116. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/server_graph.py +0 -0
  117. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/server_manager.py +0 -0
  118. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/skills/__init__.py +0 -0
  119. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/skills/commands.py +0 -0
  120. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/skills/invocation.py +0 -0
  121. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/skills/load.py +0 -0
  122. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/state_migration.py +0 -0
  123. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/subagents.py +0 -0
  124. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/system_prompt.md +0 -0
  125. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/terminal_capabilities.py +0 -0
  126. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/terminal_escape.py +0 -0
  127. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/textual_adapter.py +0 -0
  128. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/theme.py +0 -0
  129. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/tool_display.py +0 -0
  130. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/tools.py +0 -0
  131. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/unicode_security.py +0 -0
  132. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/__init__.py +0 -0
  133. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/_links.py +0 -0
  134. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/agent_selector.py +0 -0
  135. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/approval.py +0 -0
  136. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/ask_user.py +0 -0
  137. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/autocomplete.py +0 -0
  138. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/chat_input.py +0 -0
  139. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/cwd_switch.py +0 -0
  140. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/diff.py +0 -0
  141. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/history.py +0 -0
  142. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/install_confirm.py +0 -0
  143. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/launch_init.py +0 -0
  144. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/loading.py +0 -0
  145. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/mcp_reconnect.py +0 -0
  146. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/mcp_viewer.py +0 -0
  147. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/model_selector.py +0 -0
  148. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/notification_center.py +0 -0
  149. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/notification_detail.py +0 -0
  150. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/notification_settings.py +0 -0
  151. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/restart_prompt.py +0 -0
  152. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/status.py +0 -0
  153. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/theme_selector.py +0 -0
  154. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/tool_renderers.py +0 -0
  155. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/tool_widgets.py +0 -0
  156. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/update_available.py +0 -0
  157. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/update_progress.py +0 -0
  158. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/deepagents_code/widgets/welcome.py +0 -0
  159. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/examples/skills/arxiv-search/SKILL.md +0 -0
  160. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  161. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/examples/skills/langgraph-docs/SKILL.md +0 -0
  162. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/examples/skills/skill-creator/SKILL.md +0 -0
  163. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  164. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  165. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/examples/skills/web-research/SKILL.md +0 -0
  166. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/images/tui.png +0 -0
  167. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/scripts/check_imports.py +0 -0
  168. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/scripts/debug_server.sh +0 -0
  169. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/scripts/generate_commands_catalog.py +0 -0
  170. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/README.md +0 -0
  171. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/integration_tests/__init__.py +0 -0
  172. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/integration_tests/benchmarks/__init__.py +0 -0
  173. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  174. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  175. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/integration_tests/conftest.py +0 -0
  176. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/integration_tests/test_acp_mode.py +0 -0
  177. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/integration_tests/test_compact_resume.py +0 -0
  178. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/integration_tests/test_sandbox_factory.py +0 -0
  179. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/integration_tests/test_sandbox_operations.py +0 -0
  180. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/__init__.py +0 -0
  181. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/skills/__init__.py +0 -0
  182. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/skills/test_commands.py +0 -0
  183. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/skills/test_load.py +0 -0
  184. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/skills/test_skills_json.py +0 -0
  185. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_agent.py +0 -0
  186. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_agent_friendly.py +0 -0
  187. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_agent_selector.py +0 -0
  188. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_approval.py +0 -0
  189. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_args.py +0 -0
  190. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_ask_user.py +0 -0
  191. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  192. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_autocomplete.py +0 -0
  193. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_charset.py +0 -0
  194. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_chat_input.py +0 -0
  195. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_clipboard.py +0 -0
  196. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_command_registry.py +0 -0
  197. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_compact_tool.py +0 -0
  198. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_config_manifest.py +0 -0
  199. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_configurable_model.py +0 -0
  200. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_cursor_blink.py +0 -0
  201. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_cwd_switch.py +0 -0
  202. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_debug.py +0 -0
  203. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_editor.py +0 -0
  204. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_end_to_end.py +0 -0
  205. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_env_vars.py +0 -0
  206. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_event_bus.py +0 -0
  207. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_exception_handling.py +0 -0
  208. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_extras_info.py +0 -0
  209. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_file_ops.py +0 -0
  210. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_filesystem_empty_result.py +0 -0
  211. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_formatting.py +0 -0
  212. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_git.py +0 -0
  213. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_history.py +0 -0
  214. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_hooks.py +0 -0
  215. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_imports.py +0 -0
  216. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_input_parsing.py +0 -0
  217. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_install_confirm.py +0 -0
  218. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  219. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_launch_init.py +0 -0
  220. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_links.py +0 -0
  221. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_loading.py +0 -0
  222. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_local_context.py +0 -0
  223. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_main_acp_mode.py +0 -0
  224. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_managed_tools.py +0 -0
  225. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_auth.py +0 -0
  226. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_commands.py +0 -0
  227. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_disabled.py +0 -0
  228. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_login_service.py +0 -0
  229. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
  230. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_reconnect.py +0 -0
  231. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_tools.py +0 -0
  232. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_trust.py +0 -0
  233. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_mcp_viewer.py +0 -0
  234. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_media_utils.py +0 -0
  235. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_memory_guard.py +0 -0
  236. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_message_store.py +0 -0
  237. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_model_selector.py +0 -0
  238. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_model_switch.py +0 -0
  239. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_non_interactive.py +0 -0
  240. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_notification_center.py +0 -0
  241. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_notification_detail.py +0 -0
  242. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_notifications.py +0 -0
  243. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_offload.py +0 -0
  244. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  245. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_onboarding.py +0 -0
  246. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_openai_codex_integration.py +0 -0
  247. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_output.py +0 -0
  248. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_reload.py +0 -0
  249. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_remote_client.py +0 -0
  250. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_restart_prompt.py +0 -0
  251. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_resume_state.py +0 -0
  252. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_sandbox_config.py +0 -0
  253. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_sandbox_factory.py +0 -0
  254. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_sandbox_provider.py +0 -0
  255. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_sandbox_registry.py +0 -0
  256. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_server.py +0 -0
  257. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_server_config.py +0 -0
  258. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_server_graph.py +0 -0
  259. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_server_helpers.py +0 -0
  260. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_server_manager.py +0 -0
  261. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_session_stats.py +0 -0
  262. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_sessions.py +0 -0
  263. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_shell_allow_list.py +0 -0
  264. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_skill_invocation.py +0 -0
  265. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_state_migration.py +0 -0
  266. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_status.py +0 -0
  267. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_subagents.py +0 -0
  268. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  269. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_terminal_escape.py +0 -0
  270. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
  271. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_textual_adapter.py +0 -0
  272. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_textual_patches.py +0 -0
  273. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_theme.py +0 -0
  274. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_tool_display.py +0 -0
  275. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_ui.py +0 -0
  276. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_unicode_security.py +0 -0
  277. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_update_available.py +0 -0
  278. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_update_progress.py +0 -0
  279. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/test_welcome.py +0 -0
  280. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/tools/__init__.py +0 -0
  281. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/tools/test_current_thread.py +0 -0
  282. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/tools/test_fetch_url.py +0 -0
  283. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/widgets/__init__.py +0 -0
  284. {deepagents_code-0.1.16 → deepagents_code-0.1.18}/tests/unit_tests/widgets/test_diff.py +0 -0
@@ -115,7 +115,7 @@ dcode-dev --version
115
115
  - To read another package's version without importing it, use `importlib.metadata.version("package-name")`.
116
116
  - Feature-gate checks on the startup hot path (before background workers fire) must be lightweight — env var lookups, small file reads. Never pull in expensive modules just to decide whether to skip a feature.
117
117
  - When adding logic that already exists elsewhere (e.g., editable-install detection), import the existing cached implementation rather than duplicating it.
118
- - Features that run shell commands silently must be opt-in, never default-enabled. Gate behind an explicit env var or config key.
118
+ - Features that run shell commands must never do so *silently* by default. Either gate them behind an explicit env var or config key (opt-in), or — if default-enabled — announce the action before running it and offer a documented opt-out. Auto-update is the sole default-enabled exception: it shows a one-time migration notice and skips the first install when enabled only by the opt-out default, prints the upgrade it is about to perform, is overridable via `DEEPAGENTS_CODE_AUTO_UPDATE` / `[update].auto_update`, and is always disabled for editable installs.
119
119
  - Background workers that spawn subprocesses must set a timeout to avoid blocking indefinitely.
120
120
 
121
121
  ## Logging
@@ -148,7 +148,8 @@ To add a new slash command: (1) add a `SlashCommand` entry to `COMMANDS`, (2) se
148
148
  2. `deepagents_code/model_config.py` — if the provider reads a *dedicated* endpoint env var, add `"provider_name": ("CANONICAL_BASE_URL", "ALTERNATE", ...)` to `PROVIDER_BASE_URL_ENV` (see guidelines below); omit the provider entirely when it has no provider-specific endpoint variable
149
149
  3. `pyproject.toml` — add `provider = ["langchain-provider>=X.Y.Z,<N.0.0"]` to `[project.optional-dependencies]` and include it in the `all-providers` composite extra
150
150
  4. `deepagents_code/model_config.py` — add `"provider_name"` to `RETRY_PARAM_BY_PROVIDER` if the provider's chat model accepts `max_retries`
151
- 5. `tests/unit_tests/test_model_config.py` — add `assert PROVIDER_API_KEY_ENV["provider_name"] == "ENV_VAR_NAME"` to `TestProviderApiKeyEnv.test_contains_major_providers`, and pin any `PROVIDER_BASE_URL_ENV` entry with a matching assertion
151
+ 5. `deepagents_code/widgets/auth.py` — add `"provider_name": "Display Name"` to `PROVIDER_DISPLAY_NAMES` so the `/auth` UI shows a branded label instead of the title-cased key, and (if the provider issues API keys from a self-serve page) `"provider_name": "https://…"` to `PROVIDER_API_KEY_URLS` so the prompt links straight to the key page
152
+ 6. `tests/unit_tests/test_model_config.py` — add `assert PROVIDER_API_KEY_ENV["provider_name"] == "ENV_VAR_NAME"` to `TestProviderApiKeyEnv.test_contains_major_providers`, and pin any `PROVIDER_BASE_URL_ENV` entry with a matching assertion
152
153
 
153
154
  ### `PROVIDER_BASE_URL_ENV` guidelines
154
155
 
@@ -2,6 +2,29 @@
2
2
 
3
3
  # Deep Agents Code Changelog
4
4
 
5
+ ## [0.1.18](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.17...deepagents-code==0.1.18) (2026-06-16)
6
+
7
+ ### Features
8
+
9
+ * Add provider-specific auth guidance ([#4004](https://github.com/langchain-ai/deepagents/issues/4004)) ([6a39247](https://github.com/langchain-ai/deepagents/commit/6a392471ba30089b1a63135494873d55209bb081))
10
+
11
+ ## [0.1.17](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.16...deepagents-code==0.1.17) (2026-06-16)
12
+
13
+ ### Features
14
+
15
+ * Make auto-update opt-out by default ([#3994](https://github.com/langchain-ai/deepagents/issues/3994)) ([7ff6e22](https://github.com/langchain-ai/deepagents/commit/7ff6e2224d7ba8462c073333da937c35831f9b34))
16
+ * Warn on `--interpreter-tools` without `--interpreter` ([#3976](https://github.com/langchain-ai/deepagents/issues/3976)) ([e68e720](https://github.com/langchain-ai/deepagents/commit/e68e720e2c3caa4e4e7c5e937faf718db7ad2e98))
17
+ * Add pre-release update support ([#3960](https://github.com/langchain-ai/deepagents/issues/3960)) ([341a5cc](https://github.com/langchain-ai/deepagents/commit/341a5cc55a30d808dbb366b396923c7801c431d2))
18
+ * Add agent filter dropdown to `/threads` picker ([#3677](https://github.com/langchain-ai/deepagents/issues/3677)) ([f8193df](https://github.com/langchain-ai/deepagents/commit/f8193df41d7c47626d94252039217f4079d117cd))
19
+ * Non-interactive `deepagents auth` subcommands ([#3910](https://github.com/langchain-ai/deepagents/issues/3910)) ([11a71bb](https://github.com/langchain-ai/deepagents/commit/11a71bbf00c4e6c1f989e70fb3472a65c8d39662))
20
+ * Prompt before updating an out-of-date dcode install ([#3995](https://github.com/langchain-ai/deepagents/issues/3995)) ([a5ec6dd](https://github.com/langchain-ai/deepagents/commit/a5ec6dd0fec66ad321c1cc0f5e2f990c9026e03f))
21
+
22
+ ### Bug Fixes
23
+
24
+ * Guard against misconfigured LangSmith tracing ([#3993](https://github.com/langchain-ai/deepagents/issues/3993)) ([81acc2e](https://github.com/langchain-ai/deepagents/commit/81acc2ecdada55a98e512f96b0caf8cb0f2c6d29))
25
+ * Guard restart-prompt import against in-place self-upgrade ([#3980](https://github.com/langchain-ai/deepagents/issues/3980)) ([7af13f6](https://github.com/langchain-ai/deepagents/commit/7af13f6ec2440c2e3eb63bad2ff31e809f772804))
26
+ * Skip startup auto-update when already updated in-session ([#3915](https://github.com/langchain-ai/deepagents/issues/3915)) ([3ba3471](https://github.com/langchain-ai/deepagents/commit/3ba347138ac61a474bad58365fdeaa0d00cc1a42))
27
+
5
28
  ## [0.1.16](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.15...deepagents-code==0.1.16) (2026-06-13)
6
29
 
7
30
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-code
3
- Version: 0.1.16
3
+ Version: 0.1.18
4
4
  Summary: Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities.
5
5
  Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
6
6
  Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
@@ -122,7 +122,7 @@ Requires-Dist: langchain-openrouter<2.0.0,>=0.2.3; extra == 'openrouter'
122
122
  Provides-Extra: perplexity
123
123
  Requires-Dist: langchain-perplexity<2.0.0,>=1.4.0; extra == 'perplexity'
124
124
  Provides-Extra: quickjs
125
- Requires-Dist: langchain-quickjs<0.2.0,>=0.1.4; extra == 'quickjs'
125
+ Requires-Dist: langchain-quickjs<0.3.0,>=0.2.0; extra == 'quickjs'
126
126
  Provides-Extra: runloop
127
127
  Requires-Dist: langchain-runloop>=0.0.6; extra == 'runloop'
128
128
  Provides-Extra: together
@@ -31,7 +31,8 @@ import os
31
31
  # ---------------------------------------------------------------------------
32
32
 
33
33
  AUTO_UPDATE = "DEEPAGENTS_CODE_AUTO_UPDATE"
34
- """Enable automatic app updates ('1', 'true', or 'yes')."""
34
+ """Toggle automatic app updates. Enabled by default; set to a falsy value
35
+ ('0', 'false', 'no', 'off', or empty) to opt out."""
35
36
 
36
37
  DANGEROUSLY_OVERRIDE_STARTUP_SUBHEADER = (
37
38
  "DEEPAGENTS_CODE_DANGEROUSLY_OVERRIDE_STARTUP_SUBHEADER"
@@ -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.16" # x-release-please-version
5
+ __version__ = "0.1.18" # 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."""
@@ -205,6 +205,7 @@ if TYPE_CHECKING:
205
205
  from deepagents_code.widgets.notification_center import (
206
206
  NotificationSuppressRequested,
207
207
  )
208
+ from deepagents_code.widgets.restart_prompt import RestartChoice
208
209
  from deepagents_code.widgets.update_progress import UpdateProgressScreen
209
210
 
210
211
  _LAUNCH_INIT_CONNECTION_TIMEOUT_SECONDS = 60.0
@@ -1877,6 +1878,10 @@ class DeepAgentsApp(App):
1877
1878
  self._agent_running = False
1878
1879
  """True while the agent worker is streaming a response."""
1879
1880
 
1881
+ self._active_user_message: UserMessage | None = None
1882
+ """The `UserMessage` widget that started the in-flight turn, tracked so
1883
+ it can be dimmed if the turn is interrupted."""
1884
+
1880
1885
  self._shell_process: asyncio.subprocess.Process | None = None
1881
1886
  """Shell command process tracking for interruption (! commands)."""
1882
1887
 
@@ -2352,6 +2357,52 @@ class DeepAgentsApp(App):
2352
2357
  )
2353
2358
  self._maybe_start_external_event_source()
2354
2359
 
2360
+ # Non-essential advisory: defer past first paint so it never delays
2361
+ # the initial frame.
2362
+ self.call_after_refresh(self._notify_interpreter_tools_without_interpreter)
2363
+ self.call_after_refresh(self._notify_orphaned_tracing_disabled)
2364
+
2365
+ def _notify_orphaned_tracing_disabled(self) -> None:
2366
+ """Toast if startup disabled tracing because credentials were missing."""
2367
+ from deepagents_code.config import consume_orphaned_tracing_disabled_notice
2368
+
2369
+ notice = consume_orphaned_tracing_disabled_notice()
2370
+ if notice is None:
2371
+ return
2372
+ # The notice is already consumed (cleared) above, so a failed render
2373
+ # would drop the toast. The durable channel is the `logger.warning`
2374
+ # emitted at the mutation site in `_disable_orphaned_tracing`; this
2375
+ # toast is best-effort, so swallow-and-log rather than letting the
2376
+ # exception escape this deferred callback unlogged.
2377
+ try:
2378
+ self.notify(notice, severity="warning", timeout=8, markup=False)
2379
+ except Exception:
2380
+ logger.exception("Failed to surface orphaned-tracing disabled notice")
2381
+
2382
+ def _notify_interpreter_tools_without_interpreter(self) -> None:
2383
+ """Toast when `--interpreter-tools` was set without `--interpreter`.
2384
+
2385
+ The PTC allowlist applies only when the interpreter middleware is
2386
+ enabled, so the flag is a no-op on its own. This is the TUI counterpart
2387
+ of the non-interactive stderr warning emitted in
2388
+ `main._warn_if_interpreter_tools_without_interpreter`: a stderr line is
2389
+ invisible behind the alternate screen, so the same advisory is surfaced
2390
+ as a startup notification here.
2391
+
2392
+ Reads the values from `self._server_kwargs` (which already carries them
2393
+ for server startup); no extra plumbing is required.
2394
+ """
2395
+ server_kwargs = self._server_kwargs or {}
2396
+ if server_kwargs.get("interpreter_ptc") is None:
2397
+ return
2398
+ if server_kwargs.get("enable_interpreter"):
2399
+ return
2400
+ self.notify(
2401
+ "--interpreter-tools has no effect unless --interpreter is set.",
2402
+ severity="warning",
2403
+ markup=False,
2404
+ )
2405
+
2355
2406
  def _maybe_start_external_event_source(self) -> None:
2356
2407
  """Start the external event listener when explicitly enabled."""
2357
2408
  from deepagents_code._env_vars import (
@@ -3759,19 +3810,44 @@ class DeepAgentsApp(App):
3759
3810
  except Exception:
3760
3811
  logger.warning("Failed to persist seen-version marker", exc_info=True)
3761
3812
 
3762
- async def _handle_update_command(self) -> None:
3763
- """Handle the `/update` slash command — check for and install updates."""
3764
- await self._mount_message(UserMessage("/update"))
3813
+ async def _handle_update_command(self, command: str = "/update") -> None:
3814
+ """Handle the `/update` slash command — check for and install updates.
3815
+
3816
+ Parses an optional `--prerelease` flag from the raw command line; any
3817
+ other option is rejected with a usage message.
3818
+
3819
+ Args:
3820
+ command: The raw slash-command line as typed, including any options.
3821
+ """
3822
+ parts = command.split()
3823
+ await self._mount_message(UserMessage(command))
3824
+ # Reject typo'd/miscased options (e.g. `--prereleases`, `--PRERELEASE`)
3825
+ # loudly instead of silently downgrading to a stable update — mirroring
3826
+ # the headless path, which also refuses unknown options rather than
3827
+ # silently ignoring them.
3828
+ unknown = [opt for opt in parts[1:] if opt != "--prerelease"]
3829
+ if unknown:
3830
+ await self._mount_message(
3831
+ AppMessage(
3832
+ f"Unknown option(s) for /update: {' '.join(unknown)}. "
3833
+ "Usage: /update [--prerelease]",
3834
+ ),
3835
+ )
3836
+ return
3837
+ prerelease_requested = "--prerelease" in parts[1:]
3838
+ include_prereleases = True if prerelease_requested else None
3765
3839
  try:
3766
3840
  from deepagents_code._env_vars import DEBUG_UPDATE
3767
3841
  from deepagents_code._version import __version__ as cli_version
3768
3842
  from deepagents_code.config import _is_editable_install
3769
3843
  from deepagents_code.update_check import (
3844
+ _PRERELEASE_UNSUPPORTED_MESSAGE,
3770
3845
  format_age_suffix,
3771
3846
  format_installed_age_suffix,
3772
3847
  format_release_age_parenthetical,
3773
3848
  is_update_available,
3774
3849
  perform_upgrade,
3850
+ prerelease_upgrade_supported,
3775
3851
  upgrade_command,
3776
3852
  )
3777
3853
 
@@ -3785,10 +3861,23 @@ class DeepAgentsApp(App):
3785
3861
  )
3786
3862
  return
3787
3863
 
3864
+ # Refuse pre-release upgrades the install method can't honor before
3865
+ # promising an upgrade or hitting PyPI.
3866
+ if prerelease_requested:
3867
+ supported, reason = await asyncio.to_thread(
3868
+ prerelease_upgrade_supported,
3869
+ )
3870
+ if not supported:
3871
+ await self._mount_message(
3872
+ AppMessage(reason or _PRERELEASE_UNSUPPORTED_MESSAGE),
3873
+ )
3874
+ return
3875
+
3788
3876
  await self._mount_message(AppMessage("Checking for updates..."))
3789
3877
  available, latest = await asyncio.to_thread(
3790
3878
  is_update_available,
3791
3879
  bypass_cache=True,
3880
+ include_prereleases=include_prereleases,
3792
3881
  )
3793
3882
  if latest is None:
3794
3883
  await self._mount_message(
@@ -3827,7 +3916,9 @@ class DeepAgentsApp(App):
3827
3916
  AppMessage("Skipped update install (debug mode)."),
3828
3917
  )
3829
3918
  return
3830
- success, output = await perform_upgrade()
3919
+ success, output = await perform_upgrade(
3920
+ include_prereleases=include_prereleases,
3921
+ )
3831
3922
  if success:
3832
3923
  self._update_available = (False, None)
3833
3924
  await self._mount_message(
@@ -3836,7 +3927,7 @@ class DeepAgentsApp(App):
3836
3927
  ),
3837
3928
  )
3838
3929
  else:
3839
- cmd = upgrade_command()
3930
+ cmd = upgrade_command(include_prereleases=include_prereleases)
3840
3931
  detail = f": {output[:200]}" if output else ""
3841
3932
  await self._mount_message(
3842
3933
  AppMessage(f"Auto-update failed{detail}\nRun manually: {cmd}"),
@@ -3959,6 +4050,9 @@ class DeepAgentsApp(App):
3959
4050
  return
3960
4051
 
3961
4052
  log_path = create_update_log_path()
4053
+ # Load the restart modal before the upgrade rewrites our own package
4054
+ # tree; the post-install import then hits the in-memory cache.
4055
+ self._ensure_restart_prompt_loaded()
3962
4056
  await self._mount_message(
3963
4057
  AppMessage(f"Installing extra '{extra}'..."),
3964
4058
  )
@@ -4070,6 +4164,9 @@ class DeepAgentsApp(App):
4070
4164
  return
4071
4165
 
4072
4166
  log_path = create_update_log_path()
4167
+ # Load the restart modal before the upgrade rewrites our own package
4168
+ # tree; the post-install import then hits the in-memory cache.
4169
+ self._ensure_restart_prompt_loaded()
4073
4170
  await self._mount_message(
4074
4171
  AppMessage(f"Installing package '{package}'..."),
4075
4172
  )
@@ -5617,15 +5714,6 @@ class DeepAgentsApp(App):
5617
5714
 
5618
5715
  return LaunchDependenciesScreen(continue_screen=continue_screen)
5619
5716
 
5620
- async def _prompt_launch_dependencies(self) -> bool | None:
5621
- """Show the onboarding dependency summary and wait for a choice.
5622
-
5623
- Returns:
5624
- `True` when the user continues, or `None` when setup is skipped.
5625
- """
5626
- result = await self._push_screen_wait(self._build_launch_dependencies_screen())
5627
- return result if result is None or isinstance(result, bool) else None
5628
-
5629
5717
  async def _prompt_launch_dependencies_then_model(
5630
5718
  self,
5631
5719
  ) -> tuple[bool, tuple[str, str] | None]:
@@ -6500,8 +6588,8 @@ class DeepAgentsApp(App):
6500
6588
  await self._show_thread_selector()
6501
6589
  elif cmd == "/trace":
6502
6590
  await self._handle_trace_command(command)
6503
- elif cmd == "/update":
6504
- await self._handle_update_command()
6591
+ elif cmd == "/update" or cmd.startswith("/update "):
6592
+ await self._handle_update_command(command)
6505
6593
  elif cmd == "/auto-update":
6506
6594
  await self._handle_auto_update_toggle()
6507
6595
  elif cmd == "/install" or cmd.startswith("/install "):
@@ -6951,41 +7039,6 @@ class DeepAgentsApp(App):
6951
7039
  logger.debug("Failed to retrieve conversation token count", exc_info=True)
6952
7040
  return None
6953
7041
 
6954
- def _resolve_offload_budget_str(self) -> str | None:
6955
- """Resolve the offload retention budget as a human-readable string.
6956
-
6957
- Instantiates a model and computes summarization defaults, so this is
6958
- not a trivial accessor. Call only from a worker thread; cold imports
6959
- and model construction run under the process-wide import lock.
6960
-
6961
- Returns:
6962
- A string like `"20.0K (10% of 200.0K)"` or
6963
- `"last 6 messages"`, or `None` if the budget cannot be determined.
6964
- """
6965
- from deepagents_code.config import settings
6966
-
6967
- try:
6968
- with _DEEPAGENTS_IMPORT_LOCK:
6969
- from deepagents.middleware.summarization import (
6970
- compute_summarization_defaults,
6971
- )
6972
-
6973
- model_spec = f"{settings.model_provider}:{settings.model_name}"
6974
- result = _create_model_with_deepagents_import_lock(
6975
- model_spec,
6976
- profile_overrides=self._profile_override,
6977
- )
6978
- defaults = compute_summarization_defaults(result.model)
6979
- from deepagents_code.offload import format_offload_limit
6980
-
6981
- return format_offload_limit(
6982
- defaults["keep"],
6983
- settings.model_context_limit,
6984
- )
6985
- except Exception: # best-effort for /tokens display
6986
- logger.debug("Failed to compute offload budget string", exc_info=True)
6987
- return None
6988
-
6989
7042
  async def _handle_offload(self) -> None:
6990
7043
  """Offload older messages to free context window space."""
6991
7044
  from deepagents_code.config import settings
@@ -7124,8 +7177,10 @@ class DeepAgentsApp(App):
7124
7177
  Args:
7125
7178
  message: The user's message
7126
7179
  """
7127
- # Mount the user message
7128
- await self._mount_message(UserMessage(message))
7180
+ # Mount the user message, tracking it so it can be dimmed on interrupt.
7181
+ user_message = UserMessage(message)
7182
+ await self._mount_message(user_message)
7183
+ self._active_user_message = user_message
7129
7184
  await self._send_to_agent(message)
7130
7185
 
7131
7186
  async def _send_to_agent(
@@ -7342,6 +7397,7 @@ class DeepAgentsApp(App):
7342
7397
  """Clean up after agent task completes or is cancelled."""
7343
7398
  self._agent_running = False
7344
7399
  self._agent_worker = None
7400
+ self._active_user_message = None
7345
7401
 
7346
7402
  # Remove spinner if present
7347
7403
  await self._set_spinner(None)
@@ -8001,6 +8057,10 @@ class DeepAgentsApp(App):
8001
8057
  self._pending_shell_messages.clear()
8002
8058
  # Clear the message store first
8003
8059
  self._message_store.clear()
8060
+ # Drop the tracked in-flight prompt: its widget is about to leave the
8061
+ # DOM, so the pointer must not outlive it. Keeps the "cleared screen ⇒
8062
+ # nothing to dim" invariant self-enforcing regardless of caller timing.
8063
+ self._active_user_message = None
8004
8064
  try:
8005
8065
  messages = self.query_one("#messages", Container)
8006
8066
  await messages.remove_children()
@@ -8218,6 +8278,8 @@ class DeepAgentsApp(App):
8218
8278
 
8219
8279
  # If agent is running, interrupt it and discard queued messages
8220
8280
  if self._agent_running and self._agent_worker:
8281
+ if self._active_user_message is not None:
8282
+ self._active_user_message.set_cancelled()
8221
8283
  self._cancel_worker(self._agent_worker)
8222
8284
  self._quit_pending = False
8223
8285
  return
@@ -8348,6 +8410,8 @@ class DeepAgentsApp(App):
8348
8410
 
8349
8411
  # If agent is running, interrupt it and discard queued messages
8350
8412
  if self._agent_running and self._agent_worker:
8413
+ if self._active_user_message is not None:
8414
+ self._active_user_message.set_cancelled()
8351
8415
  self._cancel_worker(self._agent_worker)
8352
8416
  return
8353
8417
 
@@ -8750,23 +8814,6 @@ class DeepAgentsApp(App):
8750
8814
  result_callback=result_callback,
8751
8815
  )
8752
8816
 
8753
- async def _prompt_model_selector(
8754
- self,
8755
- *,
8756
- curated: bool = False,
8757
- ) -> tuple[str, str] | None:
8758
- """Show the model selector and wait for a choice.
8759
-
8760
- Args:
8761
- curated: Whether to use the shorter onboarding model list.
8762
-
8763
- Returns:
8764
- `(model_spec, provider)` on selection, or `None` on cancel.
8765
- """
8766
- screen = self._build_model_selector_screen(curated=curated)
8767
- result = await self._push_screen_wait(screen)
8768
- return result if result is None or isinstance(result, tuple) else None
8769
-
8770
8817
  async def _show_model_selector(
8771
8818
  self,
8772
8819
  *,
@@ -10675,6 +10722,34 @@ class DeepAgentsApp(App):
10675
10722
  ),
10676
10723
  )
10677
10724
 
10725
+ @staticmethod
10726
+ def _ensure_restart_prompt_loaded() -> None:
10727
+ """Load the restart-prompt modal before any in-place self-upgrade.
10728
+
10729
+ `/install` runs `uv tool install -U 'deepagents-code[...]'`, which
10730
+ rewrites deepagents-code's own on-disk package tree while this process
10731
+ is running. Modules already in `sys.modules` keep working from memory,
10732
+ but a *first* import after the rewrite reads the mutated (or
10733
+ partially-written) tree and raises `ModuleNotFoundError`.
10734
+ `restart_prompt` is imported only on the post-install path, so import
10735
+ it now — before the mutation — so the later import in
10736
+ `_offer_restart_after_install` resolves from `sys.modules` without
10737
+ re-reading disk. That import is still defended there for the genuine
10738
+ upgrade case where the on-disk module legitimately differs from what is
10739
+ resident.
10740
+
10741
+ Catches only `ModuleNotFoundError` (the missing-tree failure), not the
10742
+ broader `ImportError`, so a genuine name-binding bug in `restart_prompt`
10743
+ still surfaces instead of being mistaken for an upgrade race.
10744
+
10745
+ Best-effort: a failure here just means the post-install import falls
10746
+ back to its own guard, so swallow it rather than crash the install.
10747
+ """
10748
+ try:
10749
+ import deepagents_code.widgets.restart_prompt # noqa: F401
10750
+ except ModuleNotFoundError:
10751
+ logger.warning("Could not preload restart_prompt modal", exc_info=True)
10752
+
10678
10753
  async def _offer_restart_after_install(self, label: str) -> None:
10679
10754
  """Offer a one-keypress restart after a restart-capable install.
10680
10755
 
@@ -10696,10 +10771,24 @@ class DeepAgentsApp(App):
10696
10771
  if self._agent_running or self._connecting:
10697
10772
  return
10698
10773
 
10699
- from deepagents_code.widgets.restart_prompt import (
10700
- RestartChoice,
10701
- RestartPromptScreen,
10702
- )
10774
+ try:
10775
+ from deepagents_code.widgets.restart_prompt import RestartPromptScreen
10776
+ except ModuleNotFoundError:
10777
+ # `/install` runs `uv tool install -U 'deepagents-code[...]'`, which
10778
+ # can rewrite deepagents-code's own on-disk package tree mid-session
10779
+ # (see `_ensure_restart_prompt_loaded`). A first import of the modal
10780
+ # here may then fail with `ModuleNotFoundError`. The manual
10781
+ # `/restart` hint was already mounted by the caller, so degrade to
10782
+ # that instead of crashing the TUI. The catch is deliberately
10783
+ # narrow — a genuine `ImportError` from a broken modal still
10784
+ # propagates rather than being mistaken for an upgrade race.
10785
+ logger.warning(
10786
+ "restart_prompt unavailable after installing %r; leaving the "
10787
+ "manual /restart hint in place",
10788
+ label,
10789
+ exc_info=True,
10790
+ )
10791
+ return
10703
10792
 
10704
10793
  choice: RestartChoice | None
10705
10794
  try: