deepagents-code 0.1.25__tar.gz → 0.1.26__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 (302) hide show
  1. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/CHANGELOG.md +6 -0
  2. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/PKG-INFO +2 -1
  3. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_build_info.py +1 -1
  4. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_version.py +1 -1
  5. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/update_check.py +26 -20
  6. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/pyproject.toml +2 -1
  7. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/scripts/install.sh +75 -41
  8. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_app.py +4 -3
  9. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_config.py +4 -2
  10. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_install_script.py +142 -4
  11. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_update_check.py +79 -60
  12. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/uv.lock +3 -1
  13. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/.gitignore +0 -0
  14. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/AGENTS.md +0 -0
  15. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/ARCHITECTURE.md +0 -0
  16. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/COMMANDS.md +0 -0
  17. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/DEVELOPMENT.md +0 -0
  18. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/Makefile +0 -0
  19. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/README.md +0 -0
  20. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/THREAT_MODEL.md +0 -0
  21. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/__init__.py +0 -0
  22. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/__main__.py +0 -0
  23. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_ask_user_types.py +0 -0
  24. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_cli_context.py +0 -0
  25. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_constants.py +0 -0
  26. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_debug.py +0 -0
  27. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_env_vars.py +0 -0
  28. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_git.py +0 -0
  29. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_paths.py +0 -0
  30. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_server_config.py +0 -0
  31. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_session_stats.py +0 -0
  32. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_startup_error.py +0 -0
  33. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_testing_models.py +0 -0
  34. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/_textual_patches.py +0 -0
  35. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/agent.py +0 -0
  36. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/app.py +0 -0
  37. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/app.tcss +0 -0
  38. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/approval_mode.py +0 -0
  39. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/ask_user.py +0 -0
  40. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/auth_commands.py +0 -0
  41. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/auth_display.py +0 -0
  42. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/auth_store.py +0 -0
  43. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/built_in_skills/__init__.py +0 -0
  44. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
  45. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
  46. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  47. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  48. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/clipboard.py +0 -0
  49. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/command_registry.py +0 -0
  50. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/config.py +0 -0
  51. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/config_commands.py +0 -0
  52. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/config_manifest.py +0 -0
  53. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/configurable_model.py +0 -0
  54. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/default_agent_prompt.md +0 -0
  55. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/doctor.py +0 -0
  56. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/editor.py +0 -0
  57. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/event_bus.py +0 -0
  58. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/extras_info.py +0 -0
  59. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/file_ops.py +0 -0
  60. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/formatting.py +0 -0
  61. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/hooks.py +0 -0
  62. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/input.py +0 -0
  63. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/integrations/__init__.py +0 -0
  64. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/integrations/openai_codex.py +0 -0
  65. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/integrations/sandbox_config.py +0 -0
  66. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/integrations/sandbox_factory.py +0 -0
  67. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/integrations/sandbox_provider.py +0 -0
  68. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/integrations/sandbox_registry.py +0 -0
  69. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/iterm_cursor_guide.py +0 -0
  70. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/local_context.py +0 -0
  71. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/main.py +0 -0
  72. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/managed_tools.py +0 -0
  73. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_auth.py +0 -0
  74. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_commands.py +0 -0
  75. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_disabled.py +0 -0
  76. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_login_service.py +0 -0
  77. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_oauth_ui.py +0 -0
  78. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_providers/__init__.py +0 -0
  79. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_providers/_registry.py +0 -0
  80. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_providers/base.py +0 -0
  81. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_providers/github.py +0 -0
  82. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_providers/slack.py +0 -0
  83. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_tools.py +0 -0
  84. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/mcp_trust.py +0 -0
  85. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/media_utils.py +0 -0
  86. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/memory_guard.py +0 -0
  87. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/model_config.py +0 -0
  88. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/non_interactive.py +0 -0
  89. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/notifications.py +0 -0
  90. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/offload.py +0 -0
  91. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/onboarding.py +0 -0
  92. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/output.py +0 -0
  93. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/project_utils.py +0 -0
  94. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/py.typed +0 -0
  95. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/remote_client.py +0 -0
  96. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/resume_state.py +0 -0
  97. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/server.py +0 -0
  98. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/server_graph.py +0 -0
  99. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/server_manager.py +0 -0
  100. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/sessions.py +0 -0
  101. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/skills/__init__.py +0 -0
  102. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/skills/commands.py +0 -0
  103. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/skills/invocation.py +0 -0
  104. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/skills/load.py +0 -0
  105. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/state_migration.py +0 -0
  106. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/subagents.py +0 -0
  107. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/system_prompt.md +0 -0
  108. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/terminal_capabilities.py +0 -0
  109. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/terminal_escape.py +0 -0
  110. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/textual_adapter.py +0 -0
  111. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/theme.py +0 -0
  112. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/tool_display.py +0 -0
  113. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/tools.py +0 -0
  114. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/tools_commands.py +0 -0
  115. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/ui.py +0 -0
  116. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/unicode_security.py +0 -0
  117. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/__init__.py +0 -0
  118. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/_js_eval_display.py +0 -0
  119. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/_links.py +0 -0
  120. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/agent_selector.py +0 -0
  121. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/approval.py +0 -0
  122. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/ask_user.py +0 -0
  123. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/auth.py +0 -0
  124. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/autocomplete.py +0 -0
  125. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/chat_input.py +0 -0
  126. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/codex_auth.py +0 -0
  127. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/cwd_switch.py +0 -0
  128. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/diff.py +0 -0
  129. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/history.py +0 -0
  130. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/install_confirm.py +0 -0
  131. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/launch_init.py +0 -0
  132. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/loading.py +0 -0
  133. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/mcp_login.py +0 -0
  134. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/mcp_reconnect.py +0 -0
  135. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/mcp_viewer.py +0 -0
  136. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/message_store.py +0 -0
  137. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/messages.py +0 -0
  138. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/model_selector.py +0 -0
  139. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/notification_center.py +0 -0
  140. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/notification_detail.py +0 -0
  141. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/notification_settings.py +0 -0
  142. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/restart_prompt.py +0 -0
  143. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/status.py +0 -0
  144. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/subagent_panel.py +0 -0
  145. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/theme_selector.py +0 -0
  146. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/thread_selector.py +0 -0
  147. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/tool_renderers.py +0 -0
  148. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/tool_widgets.py +0 -0
  149. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/update_available.py +0 -0
  150. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/update_confirm.py +0 -0
  151. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/update_progress.py +0 -0
  152. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/deepagents_code/widgets/welcome.py +0 -0
  153. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/examples/skills/arxiv-search/SKILL.md +0 -0
  154. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  155. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/examples/skills/langgraph-docs/SKILL.md +0 -0
  156. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/examples/skills/skill-creator/SKILL.md +0 -0
  157. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  158. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  159. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/examples/skills/web-research/SKILL.md +0 -0
  160. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/hatch_build.py +0 -0
  161. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/images/tui.png +0 -0
  162. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/scripts/check_imports.py +0 -0
  163. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/scripts/debug_server.sh +0 -0
  164. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/scripts/generate_commands_catalog.py +0 -0
  165. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/README.md +0 -0
  166. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/integration_tests/__init__.py +0 -0
  167. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/integration_tests/benchmarks/__init__.py +0 -0
  168. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  169. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  170. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/integration_tests/conftest.py +0 -0
  171. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/integration_tests/test_acp_mode.py +0 -0
  172. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/integration_tests/test_compact_resume.py +0 -0
  173. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/integration_tests/test_sandbox_factory.py +0 -0
  174. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/integration_tests/test_sandbox_operations.py +0 -0
  175. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/__init__.py +0 -0
  176. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/conftest.py +0 -0
  177. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/skills/__init__.py +0 -0
  178. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/skills/test_commands.py +0 -0
  179. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/skills/test_load.py +0 -0
  180. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/skills/test_skills_json.py +0 -0
  181. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_agent.py +0 -0
  182. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_agent_friendly.py +0 -0
  183. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_agent_selector.py +0 -0
  184. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_approval.py +0 -0
  185. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_approval_mode.py +0 -0
  186. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_args.py +0 -0
  187. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_ask_user.py +0 -0
  188. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  189. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_auth_commands.py +0 -0
  190. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_auth_display.py +0 -0
  191. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_auth_store.py +0 -0
  192. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_auth_widgets.py +0 -0
  193. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_autocomplete.py +0 -0
  194. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_charset.py +0 -0
  195. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_chat_input.py +0 -0
  196. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_clipboard.py +0 -0
  197. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_command_registry.py +0 -0
  198. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_compact_tool.py +0 -0
  199. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_config_manifest.py +0 -0
  200. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_configurable_model.py +0 -0
  201. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_cursor_blink.py +0 -0
  202. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_cwd_switch.py +0 -0
  203. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_debug.py +0 -0
  204. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_doctor.py +0 -0
  205. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_editor.py +0 -0
  206. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_end_to_end.py +0 -0
  207. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_env_vars.py +0 -0
  208. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_event_bus.py +0 -0
  209. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_exception_handling.py +0 -0
  210. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_extras_info.py +0 -0
  211. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_file_ops.py +0 -0
  212. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_formatting.py +0 -0
  213. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_git.py +0 -0
  214. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_hatch_build.py +0 -0
  215. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_history.py +0 -0
  216. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_hooks.py +0 -0
  217. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_imports.py +0 -0
  218. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_input_parsing.py +0 -0
  219. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_install_command.py +0 -0
  220. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_install_confirm.py +0 -0
  221. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  222. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_launch_init.py +0 -0
  223. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_links.py +0 -0
  224. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_loading.py +0 -0
  225. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_local_context.py +0 -0
  226. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_main.py +0 -0
  227. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_main_acp_mode.py +0 -0
  228. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_main_args.py +0 -0
  229. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_managed_tools.py +0 -0
  230. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_auth.py +0 -0
  231. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_commands.py +0 -0
  232. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_disabled.py +0 -0
  233. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_login_modal.py +0 -0
  234. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_login_service.py +0 -0
  235. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
  236. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_reconnect.py +0 -0
  237. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_tools.py +0 -0
  238. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_trust.py +0 -0
  239. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_mcp_viewer.py +0 -0
  240. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_media_utils.py +0 -0
  241. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_memory_guard.py +0 -0
  242. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_message_store.py +0 -0
  243. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_messages.py +0 -0
  244. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_model_config.py +0 -0
  245. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_model_selector.py +0 -0
  246. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_model_switch.py +0 -0
  247. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_non_interactive.py +0 -0
  248. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_notification_center.py +0 -0
  249. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_notification_detail.py +0 -0
  250. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_notifications.py +0 -0
  251. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_offload.py +0 -0
  252. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  253. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_onboarding.py +0 -0
  254. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_openai_codex_integration.py +0 -0
  255. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_output.py +0 -0
  256. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_paths.py +0 -0
  257. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_reload.py +0 -0
  258. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_remote_client.py +0 -0
  259. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_restart_prompt.py +0 -0
  260. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_resume_state.py +0 -0
  261. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_sandbox_config.py +0 -0
  262. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_sandbox_factory.py +0 -0
  263. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_sandbox_provider.py +0 -0
  264. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_sandbox_registry.py +0 -0
  265. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_server.py +0 -0
  266. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_server_config.py +0 -0
  267. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_server_graph.py +0 -0
  268. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_server_helpers.py +0 -0
  269. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_server_manager.py +0 -0
  270. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_session_stats.py +0 -0
  271. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_sessions.py +0 -0
  272. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_shell_allow_list.py +0 -0
  273. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_skill_invocation.py +0 -0
  274. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_startup_fast_paths.py +0 -0
  275. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_state_migration.py +0 -0
  276. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_status.py +0 -0
  277. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_subagent_panel.py +0 -0
  278. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_subagent_stream.py +0 -0
  279. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_subagents.py +0 -0
  280. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  281. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_terminal_escape.py +0 -0
  282. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
  283. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_textual_adapter.py +0 -0
  284. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_textual_patches.py +0 -0
  285. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_theme.py +0 -0
  286. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_thread_selector.py +0 -0
  287. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_tool_display.py +0 -0
  288. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_tool_renderers.py +0 -0
  289. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_tools_commands.py +0 -0
  290. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_tracing_replicas.py +0 -0
  291. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_ui.py +0 -0
  292. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_unicode_security.py +0 -0
  293. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_update_available.py +0 -0
  294. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_update_confirm.py +0 -0
  295. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_update_progress.py +0 -0
  296. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_version.py +0 -0
  297. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/test_welcome.py +0 -0
  298. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/tools/__init__.py +0 -0
  299. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/tools/test_current_thread.py +0 -0
  300. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/tools/test_fetch_url.py +0 -0
  301. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/widgets/__init__.py +0 -0
  302. {deepagents_code-0.1.25 → deepagents_code-0.1.26}/tests/unit_tests/widgets/test_diff.py +0 -0
@@ -2,6 +2,12 @@
2
2
 
3
3
  # Deep Agents Code Changelog
4
4
 
5
+ ## [0.1.26](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.25...deepagents-code==0.1.26) (2026-06-26)
6
+
7
+ ### Bug Fixes
8
+
9
+ * Pin app version when installing extras ([#4313](https://github.com/langchain-ai/deepagents/issues/4313)) ([c20c8e2](https://github.com/langchain-ai/deepagents/commit/c20c8e2fc138f72f1444107d2a936305a591807b))
10
+
5
11
  ## [0.1.25](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.24...deepagents-code==0.1.25) (2026-06-26)
6
12
 
7
13
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-code
3
- Version: 0.1.25
3
+ Version: 0.1.26
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/
@@ -45,6 +45,7 @@ Requires-Dist: mcp<2.0.0,>=1.9.2
45
45
  Requires-Dist: packaging>=26.2
46
46
  Requires-Dist: pillow<13.0.0,>=12.2.0
47
47
  Requires-Dist: prompt-toolkit<4.0.0,>=3.0.52
48
+ Requires-Dist: pydantic<2.14.0a0,>=2.7.4
48
49
  Requires-Dist: pyperclip<2.0.0,>=1.11.0
49
50
  Requires-Dist: python-dotenv<2.0.0,>=1.2.2
50
51
  Requires-Dist: pyyaml>=6.0.3
@@ -1,3 +1,3 @@
1
1
  """Generated at build time. Do not edit or commit."""
2
2
 
3
- BUILD_COMMIT = "9f2622d"
3
+ BUILD_COMMIT = "de6e341"
@@ -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.25" # x-release-please-version
5
+ __version__ = "0.1.26" # 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."""
@@ -2123,6 +2123,7 @@ def _uv_tool_install_command(
2123
2123
  Raises:
2124
2124
  ExtrasIntrospectionError: If a metadata-sourced extra name fails PEP 508
2125
2125
  validation.
2126
+ ValueError: If `version` is not PEP 440 compliant.
2126
2127
 
2127
2128
  Propagates `ToolRequirementIntrospectionError` if the uv tool receipt's
2128
2129
  interpreter or `--with` packages cannot be determined safely from the tool
@@ -2138,6 +2139,8 @@ def _uv_tool_install_command(
2138
2139
  try:
2139
2140
  requirement = _dcode_extras_requirement(extras, version=version)
2140
2141
  except ValueError as exc:
2142
+ if str(exc).startswith("Invalid deepagents-code version"):
2143
+ raise
2141
2144
  msg = f"Distribution metadata yielded an invalid extra name: {exc}"
2142
2145
  raise ExtrasIntrospectionError(msg) from exc
2143
2146
  cmd = "uv tool install --reinstall -U" if reinstall else "uv tool install -U"
@@ -2298,13 +2301,13 @@ def install_package_command(
2298
2301
 
2299
2302
  Delegates to `_uv_tool_install_command` (the same builder the extras path
2300
2303
  uses), passing the new package as a `--with` requirement. That builder folds
2301
- already-installed extras into the `deepagents-code[...]` requirement, and
2302
- preserves the uv-managed Python interpreter, the receipt's existing `--with`
2303
- packages, and the installed pre-release channel. Without this, reinstalling
2304
- to add a second package would replace the tool with a plain `deepagents-code`
2305
- (dropping extras the user added through `/install <extra>`), rebuild with
2306
- only the newest `--with` package (dropping previously configured custom
2307
- providers), or silently downgrade a pre-release install to the latest stable.
2304
+ already-installed extras into the pinned `deepagents-code[...]` requirement,
2305
+ and preserves the uv-managed Python interpreter and the receipt's existing
2306
+ `--with` packages. Without this, reinstalling to add a second package would
2307
+ replace the tool with a plain `deepagents-code` (dropping extras the user
2308
+ added through `/install <extra>`), rebuild with only the newest `--with`
2309
+ package (dropping previously configured custom providers), or silently
2310
+ downgrade when the latest stable app depends on prerelease packages.
2308
2311
 
2309
2312
  Like the extras path (`_install_extra_uv_tool_command`), passes
2310
2313
  `reinstall=True` so the upgrade rebuilds the tool environment cleanly; see
@@ -2335,8 +2338,8 @@ def install_package_command(
2335
2338
  )
2336
2339
  raise ValueError(msg)
2337
2340
  return _uv_tool_install_command(
2338
- version=None,
2339
- include_prereleases=None,
2341
+ version=__version__,
2342
+ include_prereleases=True,
2340
2343
  distribution_name=distribution_name,
2341
2344
  with_packages_to_add=(package,),
2342
2345
  reinstall=True,
@@ -2434,6 +2437,8 @@ def _install_extra_uv_tool_command(
2434
2437
  ) -> str:
2435
2438
  """Return the receipt-preserving uv command that installs one dcode extra.
2436
2439
 
2440
+ Pins the running `deepagents-code` version and allows prerelease dependency
2441
+ resolution so adding an extra cannot make uv backtrack to an older app release.
2437
2442
  Passes `reinstall=True` so the upgrade rebuilds the tool environment from
2438
2443
  scratch rather than patching it in place; see `_uv_tool_install_command`'s
2439
2444
  `reinstall` parameter for why an in-place upgrade is unsafe.
@@ -2459,8 +2464,8 @@ def _install_extra_uv_tool_command(
2459
2464
  )
2460
2465
  raise ValueError(msg)
2461
2466
  return _uv_tool_install_command(
2462
- version=None,
2463
- include_prereleases=None,
2467
+ version=__version__,
2468
+ include_prereleases=True,
2464
2469
  distribution_name=distribution_name,
2465
2470
  extras_to_add=(extra,),
2466
2471
  reinstall=True,
@@ -2504,11 +2509,11 @@ async def perform_install_extra(
2504
2509
  ) -> tuple[bool, str]:
2505
2510
  """Add `extra` to the installed dcode tool environment.
2506
2511
 
2507
- Runs `uv tool install --reinstall -U 'deepagents-code[<extras>]'`,
2508
- preserving any extras that are already installed. Editable installs are
2509
- refused — the caller should rerun their `uv tool install --editable` command
2510
- with `--with 'deepagents-code[<extra>]'` added so the extra is resolved
2511
- against the editable source.
2512
+ Runs `uv tool install --reinstall -U 'deepagents-code[<extras>]==<current>'
2513
+ --prerelease allow`, preserving any extras that are already installed.
2514
+ Editable installs are refused — the caller should rerun their
2515
+ `uv tool install --editable` command with `--with 'deepagents-code[<extra>]'`
2516
+ added so the extra is resolved against the editable source.
2512
2517
 
2513
2518
  Args:
2514
2519
  extra: The extra name to install. Must satisfy `is_valid_extra_name`;
@@ -2575,10 +2580,11 @@ async def perform_install_package(
2575
2580
  ) -> tuple[bool, str]:
2576
2581
  """Add an arbitrary `package` to the installed dcode tool environment.
2577
2582
 
2578
- Runs `uv tool install --reinstall -U 'deepagents-code[<extras>]' --with
2579
- <package>`, the escape hatch for a provider whose package is not a
2580
- `deepagents-code` extra (e.g. a custom or in-house `class_path` model).
2581
- Already-installed extras are preserved so the reinstall does not drop them.
2583
+ Runs `uv tool install --reinstall -U 'deepagents-code[<extras>]==<current>'
2584
+ --with <package> --prerelease allow`, the escape hatch for a provider whose
2585
+ package is not a `deepagents-code` extra (e.g. a custom or in-house
2586
+ `class_path` model). Already-installed extras are preserved so the reinstall
2587
+ does not drop them.
2582
2588
  Editable installs are refused
2583
2589
  — the caller should rerun their `uv tool install --editable` command with
2584
2590
  `--with <package>` added so it resolves against the editable source.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "deepagents-code"
7
- version = "0.1.25"
7
+ version = "0.1.26"
8
8
  description = "Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -40,6 +40,7 @@ dependencies = [
40
40
  "langchain-anthropic>=1.4.7,<2.0.0",
41
41
  "langchain-google-genai>=4.2.5,<5.0.0",
42
42
  "langchain-openai>=1.3.3,<2.0.0",
43
+ "pydantic>=2.7.4,<2.14.0a0",
43
44
 
44
45
  # UI/Terminal
45
46
  # Workaround for Textualize/textual#6378 lives in `_textual_patches.py`.
@@ -7,11 +7,14 @@
7
7
  # Install an exact pre-release version:
8
8
  # curl -LsSf https://langch.in/dcode | DEEPAGENTS_CODE_VERSION="0.1.0rc1" bash
9
9
  #
10
- # Allow uv to consider alpha/beta/rc releases when resolving the latest version:
10
+ # Override uv's pre-release strategy when resolving the latest version:
11
11
  # curl -LsSf https://langch.in/dcode | DEEPAGENTS_CODE_PRERELEASE="allow" bash
12
12
  #
13
- # DEEPAGENTS_CODE_VERSION and DEEPAGENTS_CODE_PRERELEASE are mutually exclusive:
14
- # an exact pin already selects a single version, so setting both is an error.
13
+ # By default, the installer uses uv's `allow` pre-release strategy so stable
14
+ # deepagents-code releases that pin a pre-release dependency can resolve.
15
+ # DEEPAGENTS_CODE_VERSION and an explicit DEEPAGENTS_CODE_PRERELEASE are mutually
16
+ # exclusive: an exact pin already selects a single version, so setting both is an
17
+ # error.
15
18
  #
16
19
  # Already installed?
17
20
  # Safe to re-run. If a newer version exists, it asks before upgrading — or
@@ -47,8 +50,8 @@
47
50
  # (mutually exclusive with DEEPAGENTS_CODE_PRERELEASE)
48
51
  # DEEPAGENTS_CODE_PRERELEASE — uv pre-release strategy applied when
49
52
  # resolving the latest version: disallow, allow, if-necessary, explicit,
50
- # or if-necessary-or-explicit (mutually exclusive with
51
- # DEEPAGENTS_CODE_VERSION)
53
+ # or if-necessary-or-explicit (default: allow; explicitly setting it is
54
+ # mutually exclusive with DEEPAGENTS_CODE_VERSION)
52
55
  # DEEPAGENTS_CODE_PYTHON — Python version to use (default: 3.13)
53
56
  # DEEPAGENTS_CODE_YES — set to 1 to accept an available update without
54
57
  # prompting (assume "yes"). Exists so automated runs that still attach a
@@ -341,7 +344,8 @@ copy_install_log() {
341
344
  # ---------------------------------------------------------------------------
342
345
  EXTRAS="${DEEPAGENTS_CODE_EXTRAS:-}"
343
346
  VERSION="${DEEPAGENTS_CODE_VERSION:-}"
344
- PRERELEASE="${DEEPAGENTS_CODE_PRERELEASE:-}"
347
+ PRERELEASE_REQUESTED="${DEEPAGENTS_CODE_PRERELEASE:-}"
348
+ PRERELEASE="${PRERELEASE_REQUESTED:-allow}"
345
349
  PYTHON_REQUESTED=false
346
350
  if [[ -n "${DEEPAGENTS_CODE_PYTHON:-}" ]]; then
347
351
  PYTHON_REQUESTED=true
@@ -383,11 +387,12 @@ if [[ -n "$EXTRAS" ]]; then
383
387
  EXTRAS="[${EXTRAS}]"
384
388
  fi
385
389
 
386
- # An exact pin already selects a single version, so a pre-release strategy
387
- # (which only affects how a range resolves) is redundant at best and
388
- # contradictory at worst (e.g. an rc pin with "disallow"). Reject the combo
389
- # up front rather than forwarding an ambiguous request to uv.
390
- if [[ -n "$VERSION" && -n "$PRERELEASE" ]]; then
390
+ # An exact pin already selects a single version, so an explicitly requested
391
+ # pre-release strategy (which only affects how a range resolves) is redundant at
392
+ # best and contradictory at worst (e.g. an rc pin with "disallow"). Reject only
393
+ # user-provided combinations; the installer's default `if-necessary` strategy is
394
+ # not forwarded when a version is pinned.
395
+ if [[ -n "$VERSION" && -n "$PRERELEASE_REQUESTED" ]]; then
391
396
  log_error "DEEPAGENTS_CODE_VERSION and DEEPAGENTS_CODE_PRERELEASE are mutually exclusive."
392
397
  log_error "Pin an exact version, or set a pre-release strategy — not both."
393
398
  exit 1
@@ -453,29 +458,54 @@ install_uv() {
453
458
  fi
454
459
  }
455
460
 
456
- if ! command -v uv >/dev/null 2>&1; then
457
- log_info "uv not found installing..."
458
- install_uv
459
- fix_owner "${HOME}/.local/bin" # root installs: restore user ownership
460
- fi
461
+ # Resolve uv binary: honor UV_BIN override, then PATH, the env file written by
462
+ # uv's installer, then the default install location (~/.local/bin). MDM and cron
463
+ # jobs often run with a minimal PATH, so an existing uv in ~/.local/bin must
464
+ # count as installed before we invoke the upstream installer.
465
+ resolve_uv_bin() {
466
+ if [ -n "${UV_BIN:-}" ]; then
467
+ case "$UV_BIN" in
468
+ */*) [ -f "$UV_BIN" ] && [ -x "$UV_BIN" ] ;;
469
+ *) command -v "$UV_BIN" >/dev/null 2>&1 ;;
470
+ esac
471
+ return $?
472
+ fi
461
473
 
462
- # Resolve uv binary: honor UV_BIN override, then PATH, then the default
463
- # install location (~/.local/bin). A fresh install may not have updated PATH
464
- # in the current session, so we source the env file the installer creates.
465
- if [ -z "${UV_BIN:-}" ]; then
466
- UV_BIN="uv"
467
- if ! command -v "$UV_BIN" >/dev/null 2>&1; then
468
- if [ -f "${HOME}/.local/bin/env" ]; then
469
- # shellcheck source=/dev/null
470
- . "${HOME}/.local/bin/env"
474
+ if command -v uv >/dev/null 2>&1; then
475
+ UV_BIN="uv"
476
+ return 0
477
+ fi
478
+
479
+ if [ -f "${HOME}/.local/bin/env" ]; then
480
+ set +e +u
481
+ # shellcheck source=/dev/null
482
+ . "${HOME}/.local/bin/env"
483
+ set -e -u
484
+ if command -v uv >/dev/null 2>&1; then
485
+ UV_BIN="uv"
486
+ return 0
471
487
  fi
472
488
  fi
473
- if ! command -v uv >/dev/null 2>&1; then
489
+
490
+ if [ -x "${HOME}/.local/bin/uv" ]; then
474
491
  UV_BIN="${HOME}/.local/bin/uv"
475
- if [ ! -x "$UV_BIN" ]; then
476
- log_error "uv not found after installation. Restart your shell or add ~/.local/bin to PATH."
477
- exit 1
478
- fi
492
+ return 0
493
+ fi
494
+
495
+ return 1
496
+ }
497
+
498
+ if ! resolve_uv_bin; then
499
+ if [ -n "${UV_BIN:-}" ]; then
500
+ log_error "UV_BIN is set but does not point to an executable uv: ${UV_BIN}"
501
+ exit 1
502
+ fi
503
+ log_info "uv not found — installing..."
504
+ install_uv
505
+ fix_owner "${HOME}/.local/bin" # root installs: restore user ownership
506
+ if ! resolve_uv_bin; then
507
+ log_error "uv not found after installation. Restart your shell or add ~/.local/bin to PATH."
508
+ exit 1
479
509
  fi
480
510
  fi
481
511
 
@@ -555,7 +585,7 @@ if [ "$IS_EDITABLE" = true ]; then
555
585
  log_info "deepagents-code ${pre_label} found (editable install from local source)."
556
586
  fi
557
587
  log_info " Replacing with a standard install from PyPI — the existing environment will be rebuilt."
558
- elif [ -n "$PRE_VERSION" ] && [ -z "$VERSION" ] && [ -z "$PRERELEASE" ]; then
588
+ elif [ -n "$PRE_VERSION" ] && [ -z "$VERSION" ] && [ -z "$PRERELEASE_REQUESTED" ]; then
559
589
  # Default path with an existing install: probe PyPI and prompt before
560
590
  # upgrading, rather than silently pulling the latest version every run.
561
591
  # A pinned version or pre-release strategy (handled by the branches above and
@@ -609,8 +639,8 @@ fi
609
639
  # instead of upgrading in place (e.g., Python interpreter mismatch, or
610
640
  # editable↔regular install swap).
611
641
  # 2. Drop uv's per-step timing lines ("Resolved N packages in...", etc.)
612
- # and the trailing "Installed N executables:" line — we already show
613
- # a Verified line with the binary name and version.
642
+ # download/build progress, and the trailing "Installed N executables:" line
643
+ # we already show a concise install/update summary.
614
644
  # 3. Reformat the `- pkg==X` / `+ pkg==Y` diff into an aligned
615
645
  # "pkg X → Y" table under a single header.
616
646
  # 4. Detect whether uv actually moved any packages (those same
@@ -652,7 +682,7 @@ if [ -n "$cache_root" ]; then
652
682
  fi
653
683
  fi
654
684
  fi
655
- if [[ -n "$PRERELEASE" ]]; then
685
+ if [[ -z "$VERSION" ]]; then
656
686
  "$UV_BIN" tool install -U --python "$PYTHON_VERSION" \
657
687
  --prerelease "$PRERELEASE" "$PACKAGE" 2>"$uv_stderr" || uv_rc=$?
658
688
  else
@@ -665,12 +695,16 @@ if [ "$VERBOSE" != "1" ] && command -v awk >/dev/null 2>&1; then
665
695
  print "⚠ Existing environment uses a different Python — rebuilding from scratch (this is normal)."
666
696
  next
667
697
  }
668
- /^Resolved [0-9]+ packages? in / { next }
669
- /^Prepared [0-9]+ packages? in / { next }
670
- /^Uninstalled [0-9]+ packages? in / { next }
671
- /^Installed [0-9]+ packages? in / { next }
672
- /^Audited [0-9]+ packages? in / { next }
673
- /^Checked [0-9]+ packages? in / { next }
698
+ /^Resolved( [0-9]+ packages?)? in / { next }
699
+ /^Prepared [0-9]+ packages?( |$)/ { next }
700
+ /^Uninstalled [0-9]+ packages? in / { next }
701
+ /^Installed [0-9]+ packages? in / { next }
702
+ /^Audited( [0-9]+ packages?)? in / { next }
703
+ /^Checked( [0-9]+ packages?)? in / { next }
704
+ /^[[:space:]]*Downloading / { next }
705
+ /^[[:space:]]*Downloaded / { next }
706
+ /^[[:space:]]*Building / { next }
707
+ /^[[:space:]]*Built / { next }
674
708
  /^Installed [0-9]+ executables?:/ { next }
675
709
  /^ - / {
676
710
  s = $0; sub(/^ - /, "", s); n = index(s, "==")
@@ -968,7 +1002,7 @@ if [ "$SKIP_OPTIONAL" != "1" ]; then
968
1002
  # PATH and honors DEEPAGENTS_CODE_OFFLINE and
969
1003
  # DEEPAGENTS_CODE_RIPGREP_INSTALLER=system, reporting what it did.
970
1004
  echo ""
971
- log_info "Setting up ripgrep (managed; opt out with DEEPAGENTS_CODE_RIPGREP_INSTALLER=system)..."
1005
+ log_info "Setting up ripgrep..."
972
1006
  if "$DCODE_BIN" tools install; then
973
1007
  fix_owner "${HOME}/.deepagents/bin"
974
1008
  else
@@ -33,7 +33,7 @@ from textual.screen import ModalScreen
33
33
  from textual.widget import Widget
34
34
  from textual.widgets import Checkbox, Input, Static
35
35
 
36
- from deepagents_code._version import CHANGELOG_URL
36
+ from deepagents_code._version import CHANGELOG_URL, __version__
37
37
  from deepagents_code.app import (
38
38
  _DEEPAGENTS_IMPORT_LOCK,
39
39
  _TYPING_IDLE_THRESHOLD_SECONDS,
@@ -9161,8 +9161,9 @@ class TestDeferredActions:
9161
9161
  assert isinstance(widget, ErrorMessage)
9162
9162
  rendered = str(widget._content)
9163
9163
  assert (
9164
- "uv tool install --reinstall -U deepagents-code "
9165
- "--with langchain-custom_provider" in rendered
9164
+ "uv tool install --reinstall -U "
9165
+ f"deepagents-code=={__version__} "
9166
+ "--with langchain-custom_provider --prerelease allow" in rendered
9166
9167
  )
9167
9168
  assert "/model custom_provider:<model>" in rendered
9168
9169
 
@@ -12,6 +12,7 @@ import pytest
12
12
 
13
13
  from deepagents_code import _git as git_module, model_config
14
14
  from deepagents_code._env_vars import SERVER_ENV_PREFIX
15
+ from deepagents_code._version import __version__
15
16
  from deepagents_code.config import (
16
17
  CLI_MAX_RETRIES_KEY,
17
18
  RECOMMENDED_SAFE_SHELL_COMMANDS,
@@ -3929,8 +3930,9 @@ class TestCreateModelViaInitImportError:
3929
3930
  pytest.raises(
3930
3931
  ModelConfigError,
3931
3932
  match=(
3932
- "Install with: uv tool install --reinstall -U deepagents-code "
3933
- "--with langchain-custom_provider"
3933
+ "Install with: uv tool install --reinstall -U "
3934
+ f"deepagents-code=={__version__} "
3935
+ "--with langchain-custom_provider --prerelease allow"
3934
3936
  ),
3935
3937
  ),
3936
3938
  ):
@@ -292,13 +292,13 @@ def test_install_script_default_invocation_installs_plain_package(
292
292
  """A fresh machine installs the bare package with no prompt.
293
293
 
294
294
  Guards the most common `curl ... | bash` path against accidentally
295
- appending a version pin, extras, or a `--prerelease` flag.
295
+ appending a version pin or extras, while allowing stable releases that pin
296
+ pre-release dependencies to resolve.
296
297
  """
297
298
  args = _run_install_script(tmp_path, {}, installed_version=None)
298
299
 
299
300
  assert args[:3] == ["tool", "install", "-U"]
300
- assert args[-1] == "deepagents-code"
301
- assert "--prerelease" not in args
301
+ assert args[-3:] == ["--prerelease", "allow", "deepagents-code"]
302
302
 
303
303
 
304
304
  def test_install_script_supports_exact_version_with_extras(tmp_path: Path) -> None:
@@ -583,7 +583,21 @@ _DEPENDENCY_UPDATE_DIFF = " - boto3==1.43.33\n + boto3==1.43.34"
583
583
  _DEPENDENCY_ADDITION_DIFF = " + brand-new-dep==1.0.0"
584
584
 
585
585
  # uv ran but moved nothing — only timing/summary noise, no `± pkg==ver` lines.
586
- _NO_PACKAGE_CHANGE_STDERR = "Resolved 5 packages in 12ms\nAudited 5 packages in 1ms"
586
+ _NO_PACKAGE_CHANGE_STDERR = (
587
+ "Resolved 5 packages in 12ms\n"
588
+ "Resolved in 12ms\n"
589
+ "Prepared 1 package for build in 20ms\n"
590
+ "Checked in 1ms\n"
591
+ "Audited 5 packages in 1ms"
592
+ )
593
+
594
+ _UV_PROGRESS_STDERR = (
595
+ "Downloading uvloop (1.3MiB)\n"
596
+ " Downloading pygments (1.2MiB)\n"
597
+ "Downloaded uvloop\n"
598
+ "Building forbiddenfruit==0.1.4\n"
599
+ "Built forbiddenfruit==0.1.4"
600
+ )
587
601
 
588
602
 
589
603
  def test_install_script_fresh_install_hides_packages(tmp_path: Path) -> None:
@@ -614,6 +628,41 @@ def test_install_script_verbose_lists_every_package(tmp_path: Path) -> None:
614
628
  assert "Installed 3 packages" not in proc.stderr
615
629
 
616
630
 
631
+ def test_install_script_hides_uv_download_and_build_progress(tmp_path: Path) -> None:
632
+ """Non-verbose installs hide uv's download and build progress lines."""
633
+ proc, _ = _invoke(
634
+ tmp_path,
635
+ {"FAKE_UV_INSTALL_STDERR": _UV_PROGRESS_STDERR},
636
+ installed_version=None,
637
+ )
638
+
639
+ assert proc.returncode == 0
640
+ assert "Downloading uvloop" not in proc.stderr
641
+ assert "Downloaded uvloop" not in proc.stderr
642
+ assert "Building forbiddenfruit" not in proc.stderr
643
+ assert "Built forbiddenfruit" not in proc.stderr
644
+
645
+
646
+ def test_install_script_verbose_shows_uv_download_and_build_progress(
647
+ tmp_path: Path,
648
+ ) -> None:
649
+ """Verbose installs preserve uv's raw download and build progress lines."""
650
+ proc, _ = _invoke(
651
+ tmp_path,
652
+ {
653
+ "FAKE_UV_INSTALL_STDERR": _UV_PROGRESS_STDERR,
654
+ "DEEPAGENTS_CODE_VERBOSE": "1",
655
+ },
656
+ installed_version=None,
657
+ )
658
+
659
+ assert proc.returncode == 0
660
+ assert "Downloading uvloop" in proc.stderr
661
+ assert "Downloaded uvloop" in proc.stderr
662
+ assert "Building forbiddenfruit" in proc.stderr
663
+ assert "Built forbiddenfruit" in proc.stderr
664
+
665
+
617
666
  def test_install_script_upgrade_still_shows_diff(tmp_path: Path) -> None:
618
667
  """An upgrade keeps its compact changed-package diff."""
619
668
  proc, _ = _invoke(
@@ -1182,6 +1231,92 @@ def test_install_script_linux_skips_clt_check(tmp_path: Path) -> None:
1182
1231
  assert uv_args.exists()
1183
1232
 
1184
1233
 
1234
+ def _invoke_with_local_uv_not_on_path(
1235
+ tmp_path: Path, *, env_file_content: str | None = None
1236
+ ) -> tuple[subprocess.CompletedProcess[str], Path]:
1237
+ """Run with uv present only in ~/.local/bin, absent from PATH."""
1238
+ bin_dir, home, uv = _write_fake_tools(
1239
+ tmp_path, installed_version=None, latest_version="0.2.0"
1240
+ )
1241
+
1242
+ local_bin = home / ".local" / "bin"
1243
+ local_bin.mkdir(parents=True)
1244
+ local_uv = local_bin / "uv"
1245
+ local_uv.write_text(uv.read_text())
1246
+ _make_executable(local_uv)
1247
+ uv.unlink()
1248
+ if env_file_content is not None:
1249
+ (local_bin / "env").write_text(env_file_content)
1250
+
1251
+ path_without_uv = os.pathsep.join(
1252
+ entry
1253
+ for entry in _path_without_dcode().split(os.pathsep)
1254
+ if entry and not (Path(entry) / "uv").exists()
1255
+ )
1256
+ env = {
1257
+ **os.environ,
1258
+ "HOME": str(home),
1259
+ "XDG_CACHE_HOME": str(home / ".cache"),
1260
+ "PATH": f"{bin_dir}{os.pathsep}{path_without_uv}",
1261
+ "DEEPAGENTS_CODE_SKIP_OPTIONAL": "1",
1262
+ }
1263
+ proc = subprocess.run(
1264
+ ["bash", str(SCRIPT)],
1265
+ env=env,
1266
+ check=False,
1267
+ capture_output=True,
1268
+ text=True,
1269
+ stdin=subprocess.DEVNULL,
1270
+ start_new_session=True,
1271
+ )
1272
+ return proc, tmp_path / "uv-args.txt"
1273
+
1274
+
1275
+ def test_install_script_uses_local_uv_when_not_on_path(tmp_path: Path) -> None:
1276
+ """A minimal MDM PATH must not reinstall uv when ~/.local/bin/uv exists."""
1277
+ proc, uv_args = _invoke_with_local_uv_not_on_path(tmp_path)
1278
+
1279
+ assert proc.returncode == 0
1280
+ assert uv_args.exists()
1281
+ assert "uv not found — installing" not in proc.stdout + proc.stderr
1282
+ assert uv_args.read_text().splitlines()[:3] == ["tool", "install", "-U"]
1283
+
1284
+
1285
+ def test_install_script_sources_uv_env_file_defensively(tmp_path: Path) -> None:
1286
+ """A non-zero command in uv's env file must not abort the installer."""
1287
+ proc, uv_args = _invoke_with_local_uv_not_on_path(
1288
+ tmp_path,
1289
+ env_file_content='export PATH="$HOME/.local/bin:$PATH"\nfalse\n',
1290
+ )
1291
+
1292
+ assert proc.returncode == 0
1293
+ assert uv_args.exists()
1294
+ assert "uv not found — installing" not in proc.stdout + proc.stderr
1295
+ assert uv_args.read_text().splitlines()[:3] == ["tool", "install", "-U"]
1296
+
1297
+
1298
+ def test_install_script_rejects_invalid_uv_bin_without_installing(
1299
+ tmp_path: Path,
1300
+ ) -> None:
1301
+ """A bad `UV_BIN` should fail clearly instead of reinstalling uv."""
1302
+ cases = [
1303
+ (tmp_path / "missing", tmp_path / "missing" / "uv"),
1304
+ (tmp_path / "directory", tmp_path / "directory" / "uv"),
1305
+ ]
1306
+ cases[1][1].mkdir(parents=True)
1307
+
1308
+ for root, uv_bin in cases:
1309
+ root.mkdir(exist_ok=True)
1310
+ proc, uv_args = _invoke(root, {"UV_BIN": str(uv_bin)})
1311
+
1312
+ assert proc.returncode != 0
1313
+ assert not uv_args.exists()
1314
+ assert (
1315
+ f"UV_BIN is set but does not point to an executable uv: {uv_bin}"
1316
+ in proc.stderr
1317
+ )
1318
+
1319
+
1185
1320
  def _invoke_with_local_dcode_not_on_path(
1186
1321
  tmp_path: Path, *, create_env_file: bool = False
1187
1322
  ) -> subprocess.CompletedProcess[str]:
@@ -1273,6 +1408,9 @@ def test_install_script_managed_ripgrep_calls_tools_install(tmp_path: Path) -> N
1273
1408
  tools_log = tmp_path / "dcode-tools.txt"
1274
1409
  assert tools_log.exists(), proc.stdout + proc.stderr
1275
1410
  assert "tools install" in tools_log.read_text()
1411
+ combined = proc.stdout + proc.stderr
1412
+ assert "Setting up ripgrep..." in combined
1413
+ assert "opt out with DEEPAGENTS_CODE_RIPGREP_INSTALLER=system" not in combined
1276
1414
 
1277
1415
 
1278
1416
  def test_install_script_system_ripgrep_skips_tools_install(tmp_path: Path) -> None: