deepagents-code 0.1.54__tar.gz → 0.1.55__tar.gz

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