deepagents-code 0.1.61__tar.gz → 0.1.63__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 (531) hide show
  1. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/AGENTS.md +4 -4
  2. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/CHANGELOG.md +41 -0
  3. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/COMMANDS.md +4 -3
  4. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/PKG-INFO +3 -3
  5. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/THREAT_MODEL.md +26 -9
  6. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/__init__.py +19 -1
  7. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/__main__.py +1 -1
  8. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_build_info.py +1 -1
  9. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_constants.py +15 -0
  10. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_env_vars.py +19 -4
  11. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_git.py +71 -18
  12. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_glm_5p2_profile.py +5 -0
  13. deepagents_code-0.1.63/deepagents_code/_home_error.py +21 -0
  14. deepagents_code-0.1.63/deepagents_code/_paths.py +801 -0
  15. deepagents_code-0.1.63/deepagents_code/_reserved_names.py +126 -0
  16. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_server_config.py +16 -0
  17. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_session_stats.py +109 -11
  18. deepagents_code-0.1.63/deepagents_code/_terminal_stderr.py +194 -0
  19. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_version.py +1 -1
  20. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/agent.py +208 -102
  21. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/app.py +978 -206
  22. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/ask_user.py +5 -0
  23. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/auth_store.py +1 -1
  24. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/auto_mode.py +82 -32
  25. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/built_in_skills/deepagents-thread-inspector/SKILL.md +2 -2
  26. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/built_in_skills/deepagents-thread-inspector/scripts/inspect_sessions.py +32 -1
  27. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/built_in_skills/remember/SKILL.md +2 -2
  28. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/built_in_skills/skill-creator/SKILL.md +3 -3
  29. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +3 -2
  30. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +2 -2
  31. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/commands/config.py +16 -4
  32. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/commands/mcp.py +26 -24
  33. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/commands/tools.py +12 -7
  34. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/launch/server.py +155 -31
  35. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/launch/server_manager.py +6 -0
  36. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/non_interactive.py +39 -3
  37. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/command_registry.py +8 -2
  38. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/config.py +692 -290
  39. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/config_manifest.py +348 -132
  40. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/configurable_model.py +43 -14
  41. deepagents_code-0.1.63/deepagents_code/configuration/provider.py +233 -0
  42. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/configuration/providers.py +764 -1
  43. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/configuration/resolver.py +225 -47
  44. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/configuration/service.py +228 -43
  45. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/configuration/types.py +87 -1
  46. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/configuration/writer.py +8 -7
  47. deepagents_code-0.1.63/deepagents_code/context_doctor.py +274 -0
  48. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/cost_tracking.py +88 -9
  49. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/doctor.py +161 -25
  50. deepagents_code-0.1.63/deepagents_code/extensions/__init__.py +5 -0
  51. deepagents_code-0.1.63/deepagents_code/extensions/api.py +188 -0
  52. deepagents_code-0.1.63/deepagents_code/extensions/discovery.py +205 -0
  53. deepagents_code-0.1.63/deepagents_code/extensions/registry.py +228 -0
  54. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/goal_rubric.py +47 -2
  55. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/goal_state_notice.py +38 -10
  56. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/goal_tools.py +34 -47
  57. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/server_middleware.py +5 -0
  58. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/transcript.py +21 -2
  59. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/local_context.py +110 -68
  60. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/main.py +628 -180
  61. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/managed_tools.py +356 -53
  62. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_auth.py +9 -7
  63. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_login_service.py +14 -12
  64. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_tools.py +238 -69
  65. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/memory_guard.py +4 -1
  66. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/model_config.py +92 -52
  67. deepagents_code-0.1.63/deepagents_code/model_retry.py +886 -0
  68. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/offload.py +20 -14
  69. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/offload_api.py +90 -2
  70. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/offload_middleware.py +94 -2
  71. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/onboarding.py +11 -1
  72. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/manifest.py +56 -6
  73. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/models.py +3 -0
  74. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/store.py +1 -7
  75. deepagents_code-0.1.63/deepagents_code/reliable_rubric.py +136 -0
  76. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/resume_state.py +5 -0
  77. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/server_graph.py +7 -1
  78. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/sessions.py +5 -1
  79. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/skills/commands.py +14 -6
  80. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/skills/load.py +2 -1
  81. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/state_migration.py +2 -4
  82. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tool_catalog.py +14 -1
  83. deepagents_code-0.1.63/deepagents_code/tui/modals/model_switch.py +125 -0
  84. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/prompt_clipboard.py +3 -21
  85. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/textual_adapter.py +98 -42
  86. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/agent_selector.py +4 -1
  87. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/approval.py +2 -6
  88. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/auth.py +22 -5
  89. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/chat_input.py +4 -29
  90. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/diff.py +433 -11
  91. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/launch_init.py +4 -1
  92. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/model_selector.py +10 -8
  93. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/notification_center.py +3 -1
  94. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/prompt_search.py +2 -31
  95. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/startup_tip.py +1 -0
  96. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/ui.py +34 -7
  97. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/update_check.py +96 -26
  98. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/pyproject.toml +7 -4
  99. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/scripts/install.sh +367 -39
  100. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/test_offload_server_side.py +87 -0
  101. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/client/commands/test_mcp.py +77 -19
  102. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/conftest.py +103 -5
  103. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/test_transcript.py +50 -2
  104. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/plugins/test_plugins_p0.py +0 -32
  105. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/skills/test_load.py +9 -0
  106. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/skills/test_thread_inspector.py +32 -1
  107. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +3 -3
  108. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/smoke_tests/test_system_prompt.py +2 -0
  109. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_agent.py +396 -27
  110. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_agent_friendly.py +9 -28
  111. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_app.py +1410 -79
  112. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_args.py +88 -13
  113. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_auto_mode.py +137 -14
  114. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_charset.py +22 -16
  115. deepagents_code-0.1.63/tests/unit_tests/test_cli_provider.py +351 -0
  116. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_compact_tool.py +101 -13
  117. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_config.py +827 -272
  118. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_config_manifest.py +69 -3
  119. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_configurable_model.py +65 -0
  120. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_configuration.py +5225 -2278
  121. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_configuration_resolution.py +1 -1
  122. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_configuration_resolver.py +322 -2
  123. deepagents_code-0.1.63/tests/unit_tests/test_context_doctor.py +160 -0
  124. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_cost_tracking.py +98 -2
  125. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_debug_console.py +35 -6
  126. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_doctor.py +108 -0
  127. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_exception_handling.py +0 -27
  128. deepagents_code-0.1.63/tests/unit_tests/test_extension_api.py +198 -0
  129. deepagents_code-0.1.63/tests/unit_tests/test_extension_discovery.py +180 -0
  130. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_git.py +80 -1
  131. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_goal_rubric.py +29 -0
  132. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_goal_state_notice.py +119 -0
  133. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_goal_tools.py +93 -77
  134. deepagents_code-0.1.63/tests/unit_tests/test_imports.py +8 -0
  135. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_input_parsing.py +0 -16
  136. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_install_script.py +762 -21
  137. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_local_context.py +109 -123
  138. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_main.py +358 -207
  139. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_main_acp_mode.py +107 -2
  140. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_main_args.py +724 -65
  141. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_managed_tools.py +430 -7
  142. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_mcp_auth.py +1 -1
  143. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_mcp_login_service.py +49 -35
  144. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_mcp_tools.py +408 -115
  145. deepagents_code-0.1.63/tests/unit_tests/test_middleware_trace_policy.py +55 -0
  146. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_model_config.py +29 -3
  147. deepagents_code-0.1.63/tests/unit_tests/test_model_retry.py +1482 -0
  148. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_model_switch.py +119 -4
  149. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_non_interactive.py +58 -0
  150. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_notifications.py +0 -8
  151. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_offload.py +31 -16
  152. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_offload_api.py +190 -1
  153. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_onboarding.py +17 -0
  154. deepagents_code-0.1.63/tests/unit_tests/test_paths.py +1263 -0
  155. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_reasoning_effort.py +2 -74
  156. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_reliable_rubric.py +202 -101
  157. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_reload.py +198 -3
  158. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_server.py +125 -19
  159. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_server_config.py +40 -0
  160. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_server_graph.py +38 -0
  161. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_server_helpers.py +30 -0
  162. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_session_stats.py +115 -0
  163. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_sessions.py +32 -5
  164. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_startup_fast_paths.py +23 -0
  165. deepagents_code-0.1.63/tests/unit_tests/test_terminal_stderr.py +149 -0
  166. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_tool_catalog.py +7 -2
  167. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_tool_display.py +39 -18
  168. deepagents_code-0.1.63/tests/unit_tests/test_ui.py +72 -0
  169. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_update_check.py +210 -6
  170. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_version.py +156 -30
  171. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tools/test_current_thread.py +0 -5
  172. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/modals/plugin_manager/test_structure.py +0 -8
  173. deepagents_code-0.1.63/tests/unit_tests/tui/modals/test_model_switch.py +64 -0
  174. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/modals/test_prompt_clipboard.py +5 -47
  175. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/test_key_hints.py +0 -9
  176. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/test_textual_adapter.py +284 -9
  177. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_ask_user.py +0 -43
  178. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_auth_widgets.py +115 -1
  179. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_auto_mode_notice.py +1 -10
  180. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_autocomplete.py +3 -3
  181. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_chat_input.py +7 -11
  182. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_diff.py +360 -17
  183. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_launch_init.py +2 -1
  184. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_model_selector.py +6 -4
  185. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_thread_selector.py +1 -0
  186. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/uv.lock +7 -7
  187. deepagents_code-0.1.61/deepagents_code/_paths.py +0 -69
  188. deepagents_code-0.1.61/deepagents_code/configuration/provider.py +0 -42
  189. deepagents_code-0.1.61/deepagents_code/reliable_rubric.py +0 -345
  190. deepagents_code-0.1.61/tests/unit_tests/test_config_recursion_limit.py +0 -21
  191. deepagents_code-0.1.61/tests/unit_tests/test_imports.py +0 -29
  192. deepagents_code-0.1.61/tests/unit_tests/test_paths.py +0 -44
  193. deepagents_code-0.1.61/tests/unit_tests/test_ui.py +0 -421
  194. deepagents_code-0.1.61/tests/unit_tests/tui/widgets/test_yolo_mode_notice.py +0 -8
  195. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/.gitignore +0 -0
  196. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/ARCHITECTURE.md +0 -0
  197. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/DEVELOPMENT.md +0 -0
  198. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/HOOKS.md +0 -0
  199. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/LICENSE +0 -0
  200. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/Makefile +0 -0
  201. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/PRICING.md +0 -0
  202. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/README.md +0 -0
  203. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_ask_user_types.py +0 -0
  204. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_cli_context.py +0 -0
  205. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_debug.py +0 -0
  206. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_debug_buffer.py +0 -0
  207. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_dep_floor_check.py +0 -0
  208. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_fake_models.py +0 -0
  209. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_invocation.py +0 -0
  210. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_markdown.py +0 -0
  211. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_repository_bounds.py +0 -0
  212. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_startup_error.py +0 -0
  213. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_testing_models.py +0 -0
  214. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_textual_patches.py +0 -0
  215. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_tool_stream.py +0 -0
  216. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/_tracing.py +0 -0
  217. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/acp.py +0 -0
  218. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/app.tcss +0 -0
  219. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/approval_mode.py +0 -0
  220. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/auth_display.py +0 -0
  221. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/built_in_skills/__init__.py +0 -0
  222. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/bundled_prices.README.md +0 -0
  223. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/bundled_prices.json +0 -0
  224. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/__init__.py +0 -0
  225. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/commands/__init__.py +0 -0
  226. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/commands/auth.py +0 -0
  227. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/commands/extras.py +0 -0
  228. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/launch/__init__.py +0 -0
  229. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/client/remote_client.py +0 -0
  230. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/clipboard.py +0 -0
  231. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/cold_cache.py +0 -0
  232. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/configuration/__init__.py +0 -0
  233. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/configuration/paths.py +0 -0
  234. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/configuration/theme_resolution.py +0 -0
  235. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/default_agent_prompt.md +0 -0
  236. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/diff_utils.py +0 -0
  237. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/editor.py +0 -0
  238. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/event_bus.py +0 -0
  239. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/extras_info.py +0 -0
  240. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/file_ops.py +0 -0
  241. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/formatting.py +0 -0
  242. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/goal_state_limits.py +0 -0
  243. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/__init__.py +0 -0
  244. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/capabilities.py +0 -0
  245. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/client.py +0 -0
  246. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/client_lifecycle.py +0 -0
  247. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/context.py +0 -0
  248. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/engine.py +0 -0
  249. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/env.py +0 -0
  250. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/envelope.py +0 -0
  251. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/interrupt.py +0 -0
  252. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/legacy.py +0 -0
  253. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/loading.py +0 -0
  254. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/manager.py +0 -0
  255. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/migration.py +0 -0
  256. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/models/__init__.py +0 -0
  257. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/models/adapters.py +0 -0
  258. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/models/config.py +0 -0
  259. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/models/domain.py +0 -0
  260. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/models/transport.py +0 -0
  261. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/models/wire.py +0 -0
  262. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/permissions.py +0 -0
  263. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/presenter.py +0 -0
  264. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/projection.py +0 -0
  265. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/reducer.py +0 -0
  266. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/runner.py +0 -0
  267. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/runtime.py +0 -0
  268. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/snapshot.py +0 -0
  269. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/tools.py +0 -0
  270. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/trust.py +0 -0
  271. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/hooks/validate_terminal_sequence.py +0 -0
  272. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/input.py +0 -0
  273. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/integrations/__init__.py +0 -0
  274. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/integrations/openai_codex.py +0 -0
  275. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/integrations/sandbox_config.py +0 -0
  276. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/integrations/sandbox_factory.py +0 -0
  277. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/integrations/sandbox_provider.py +0 -0
  278. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/integrations/sandbox_registry.py +0 -0
  279. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/iterm_cursor_guide.py +0 -0
  280. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/json_types.py +0 -0
  281. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_config.py +0 -0
  282. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_disabled.py +0 -0
  283. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_oauth_ui.py +0 -0
  284. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_providers/__init__.py +0 -0
  285. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_providers/_registry.py +0 -0
  286. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_providers/base.py +0 -0
  287. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_providers/github.py +0 -0
  288. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/mcp_providers/slack.py +0 -0
  289. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/media_utils.py +0 -0
  290. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/notifications.py +0 -0
  291. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/output.py +0 -0
  292. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/paste_collapse.py +0 -0
  293. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/__init__.py +0 -0
  294. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/_json.py +0 -0
  295. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/adapters/__init__.py +0 -0
  296. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/adapters/hooks.py +0 -0
  297. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/adapters/mcp.py +0 -0
  298. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/adapters/skills.py +0 -0
  299. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/adapters/skills_middleware.py +0 -0
  300. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/commands_cli.py +0 -0
  301. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/discovery.py +0 -0
  302. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/marketplace.py +0 -0
  303. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/plugins/substitution.py +0 -0
  304. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/project_utils.py +0 -0
  305. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/py.typed +0 -0
  306. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/reasoning_effort.py +0 -0
  307. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/skills/__init__.py +0 -0
  308. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/skills/invocation.py +0 -0
  309. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/skills/merge.py +0 -0
  310. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/skills/trust.py +0 -0
  311. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/subagents.py +0 -0
  312. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/system_prompt.md +0 -0
  313. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/terminal_capabilities.py +0 -0
  314. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/terminal_escape.py +0 -0
  315. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/theme.py +0 -0
  316. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tool_display.py +0 -0
  317. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tools.py +0 -0
  318. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/__init__.py +0 -0
  319. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/key_hints.py +0 -0
  320. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/__init__.py +0 -0
  321. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/cold_cache.py +0 -0
  322. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/plugin_manager/__init__.py +0 -0
  323. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/plugin_manager/content.py +0 -0
  324. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/plugin_manager/models.py +0 -0
  325. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/plugin_manager/plugin_manager.tcss +0 -0
  326. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/plugin_manager/state.py +0 -0
  327. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/plugin_manager/tabs.py +0 -0
  328. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/prompt_clipboard.tcss +0 -0
  329. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/modals/resume_compact.py +0 -0
  330. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/screens/__init__.py +0 -0
  331. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/__init__.py +0 -0
  332. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/_copy_spans.py +0 -0
  333. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/_inline_prompt.py +0 -0
  334. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/_js_eval_display.py +0 -0
  335. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/_links.py +0 -0
  336. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/_paste_textarea.py +0 -0
  337. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/ask_user.py +0 -0
  338. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/auto_mode_notice.py +0 -0
  339. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/autocomplete.py +0 -0
  340. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/codex_auth.py +0 -0
  341. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/context_usage.py +0 -0
  342. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/cwd_switch.py +0 -0
  343. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/debug_console.py +0 -0
  344. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/effort_selector.py +0 -0
  345. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/goal_review.py +0 -0
  346. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/goal_status.py +0 -0
  347. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/history.py +0 -0
  348. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/install_confirm.py +0 -0
  349. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/loading.py +0 -0
  350. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/mcp_login.py +0 -0
  351. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/mcp_reconnect.py +0 -0
  352. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/mcp_viewer.py +0 -0
  353. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/message_store.py +0 -0
  354. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/messages.py +0 -0
  355. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/notification_detail.py +0 -0
  356. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/notification_settings.py +0 -0
  357. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/restart_prompt.py +0 -0
  358. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/skill_trust.py +0 -0
  359. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/status.py +0 -0
  360. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/subagent_panel.py +0 -0
  361. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/theme_selector.py +0 -0
  362. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/thread_agent_switch.py +0 -0
  363. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/thread_selector.py +0 -0
  364. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/tool_renderers.py +0 -0
  365. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/tool_widgets.py +0 -0
  366. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/update_available.py +0 -0
  367. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/update_confirm.py +0 -0
  368. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/update_progress.py +0 -0
  369. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/welcome.py +0 -0
  370. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/tui/widgets/yolo_mode_notice.py +0 -0
  371. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/deepagents_code/unicode_security.py +0 -0
  372. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/examples/skills/arxiv-search/SKILL.md +0 -0
  373. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  374. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/examples/skills/langgraph-docs/SKILL.md +0 -0
  375. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/examples/skills/skill-creator/SKILL.md +0 -0
  376. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  377. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  378. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/examples/skills/web-research/SKILL.md +0 -0
  379. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/hatch_build.py +0 -0
  380. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/images/tui.png +0 -0
  381. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/scripts/check_imports.py +0 -0
  382. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/scripts/debug_server.sh +0 -0
  383. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/scripts/generate_commands_catalog.py +0 -0
  384. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/README.md +0 -0
  385. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/__init__.py +0 -0
  386. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/benchmarks/__init__.py +0 -0
  387. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  388. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/benchmarks/test_local_context_benchmarks.py +0 -0
  389. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  390. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/conftest.py +0 -0
  391. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/test_acp_mode.py +0 -0
  392. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/test_auto_approve_remote.py +0 -0
  393. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/test_compact_resume.py +0 -0
  394. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/test_goal_criteria_remote.py +0 -0
  395. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/test_sandbox_factory.py +0 -0
  396. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/integration_tests/test_sandbox_operations.py +0 -0
  397. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/__init__.py +0 -0
  398. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/client/__init__.py +0 -0
  399. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/client/commands/__init__.py +0 -0
  400. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/client/commands/test_auth.py +0 -0
  401. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/client/commands/test_extras.py +0 -0
  402. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/client/commands/test_tools.py +0 -0
  403. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
  404. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/__init__.py +0 -0
  405. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/models/__init__.py +0 -0
  406. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/models/test_models.py +0 -0
  407. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/test_client_lifecycle.py +0 -0
  408. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/test_configuration.py +0 -0
  409. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/test_engine.py +0 -0
  410. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/test_execution.py +0 -0
  411. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/test_manager.py +0 -0
  412. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/test_presenter.py +0 -0
  413. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/test_server_lifecycle.py +0 -0
  414. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/hooks/test_trust.py +0 -0
  415. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/plugins/__init__.py +0 -0
  416. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/plugins/test_marketplace.py +0 -0
  417. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/plugins/test_plugin_hooks.py +0 -0
  418. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/plugins/test_store.py +0 -0
  419. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/skills/__init__.py +0 -0
  420. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/skills/test_commands.py +0 -0
  421. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/skills/test_merge.py +0 -0
  422. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/skills/test_skill_trust.py +0 -0
  423. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/skills/test_skills_json.py +0 -0
  424. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/smoke_tests/__init__.py +0 -0
  425. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/smoke_tests/conftest.py +0 -0
  426. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test__tool_stream.py +0 -0
  427. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_acp.py +0 -0
  428. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_approval_mode.py +0 -0
  429. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  430. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_ask_user_types.py +0 -0
  431. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_auth_display.py +0 -0
  432. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_auth_store.py +0 -0
  433. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_auth_web_search_restart.py +0 -0
  434. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_clipboard.py +0 -0
  435. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
  436. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_cold_cache.py +0 -0
  437. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_command_registry.py +0 -0
  438. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_cursor_blink.py +0 -0
  439. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_cursor_style.py +0 -0
  440. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_debug.py +0 -0
  441. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_debug_buffer.py +0 -0
  442. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_dep_floor_check.py +0 -0
  443. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_diff_utils.py +0 -0
  444. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_editor.py +0 -0
  445. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_end_to_end.py +0 -0
  446. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_env_vars.py +0 -0
  447. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_event_bus.py +0 -0
  448. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_extras_info.py +0 -0
  449. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_file_ops.py +0 -0
  450. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_formatting.py +0 -0
  451. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_glm_5p2_profile.py +0 -0
  452. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_goal_criteria_client.py +0 -0
  453. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_goal_state_limits.py +0 -0
  454. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_goal_state_persistence.py +0 -0
  455. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_hatch_build.py +0 -0
  456. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_hooks.py +0 -0
  457. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_install_command.py +0 -0
  458. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_invocation.py +0 -0
  459. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  460. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_json_types.py +0 -0
  461. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_mcp_config.py +0 -0
  462. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_mcp_disabled.py +0 -0
  463. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
  464. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_media_utils.py +0 -0
  465. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_memory_guard.py +0 -0
  466. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_openai_codex_integration.py +0 -0
  467. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_output.py +0 -0
  468. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_remote_client.py +0 -0
  469. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_repository_bounds.py +0 -0
  470. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_resume_state.py +0 -0
  471. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_rubric_cli.py +0 -0
  472. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_sandbox_config.py +0 -0
  473. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_sandbox_factory.py +0 -0
  474. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_sandbox_provider.py +0 -0
  475. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_sandbox_registry.py +0 -0
  476. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_server_manager.py +0 -0
  477. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_shell_allow_list.py +0 -0
  478. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_skill_invocation.py +0 -0
  479. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_startup_blocking.py +0 -0
  480. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_state_migration.py +0 -0
  481. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_subagents.py +0 -0
  482. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  483. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_terminal_escape.py +0 -0
  484. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
  485. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_textual_patches.py +0 -0
  486. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_theme.py +0 -0
  487. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_threads_resume.py +0 -0
  488. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_tracing.py +0 -0
  489. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_tracing_replicas.py +0 -0
  490. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_transcript_virtualization.py +0 -0
  491. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/test_unicode_security.py +0 -0
  492. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tools/__init__.py +0 -0
  493. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tools/test_fetch_url.py +0 -0
  494. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tools/test_tool_arg_schemas.py +0 -0
  495. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/__init__.py +0 -0
  496. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/modals/__init__.py +0 -0
  497. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/modals/plugin_manager/__init__.py +0 -0
  498. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/modals/test_cold_cache.py +0 -0
  499. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/test_modal_footer_layout.py +0 -0
  500. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/test_subagent_stream.py +0 -0
  501. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/__init__.py +0 -0
  502. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_agent_selector.py +0 -0
  503. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_approval.py +0 -0
  504. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_copy_spans.py +0 -0
  505. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_cwd_switch.py +0 -0
  506. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_goal_review.py +0 -0
  507. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_history.py +0 -0
  508. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_inline_prompt.py +0 -0
  509. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_install_confirm.py +0 -0
  510. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_links.py +0 -0
  511. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_loading.py +0 -0
  512. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_mcp_login_modal.py +0 -0
  513. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_mcp_reconnect.py +0 -0
  514. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_mcp_viewer.py +0 -0
  515. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_message_store.py +0 -0
  516. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_messages.py +0 -0
  517. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_notification_center.py +0 -0
  518. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_notification_detail.py +0 -0
  519. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_notification_settings.py +0 -0
  520. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_prompt_search.py +0 -0
  521. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_restart_prompt.py +0 -0
  522. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_skill_trust_screen.py +0 -0
  523. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_startup_tip.py +0 -0
  524. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_status.py +0 -0
  525. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_subagent_panel.py +0 -0
  526. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_thread_agent_switch.py +0 -0
  527. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_tool_renderers.py +0 -0
  528. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_update_available.py +0 -0
  529. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_update_confirm.py +0 -0
  530. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_update_progress.py +0 -0
  531. {deepagents_code-0.1.61 → deepagents_code-0.1.63}/tests/unit_tests/tui/widgets/test_welcome.py +0 -0
@@ -1,6 +1,6 @@
1
1
  # `libs/code` agent guide
2
2
 
3
- `deepagents-code` is the interactive coding agent — the Textual REPL, headless `-x` mode, MCP integration, skills, sandbox bootstrap, and slash-command surface. Forked from `deepagents-cli` at the 0.1.0 split.
3
+ `deepagents-code` is the interactive coding agent — the Textual REPL, headless `-x` mode, MCP integration, skills, sandbox bootstrap, and slash-command surface.
4
4
 
5
5
  For monorepo-wide conventions (commit titles, lint, testing, docs, CI, benchmarks), see the root `AGENTS.md`. For a high-level map of the package (client/server processes, request lifecycle, module map), see `ARCHITECTURE.md`.
6
6
 
@@ -78,7 +78,7 @@ Apply these rules to new UI; do not treat them as a mandate to refactor existing
78
78
  - Use `textual.pilot` for async UI testing - see [Testing guide](https://textual.textualize.io/guide/testing/)
79
79
  - Snapshot testing available for visual regression - see repo `notes/snapshot_testing.md`
80
80
  - For modal flows, test the real interaction path with keypresses when possible. Unit tests that call action methods or resume handlers directly can miss focus and modal-stack bugs.
81
- - A modal test that pushes the screen onto a bare `App` host cannot catch app-level key interception. The app owns a priority `shift+tab -> toggle_auto_approve` binding (`app.py`) that wins dispatch over any screen binding; `action_toggle_auto_approve` routes the key to the active screen. Cursor-style modals (highlighted rows, no focusable children) just implement `action_move_up` — the router's `_SupportsReverseNav` protocol branch picks them up automatically. The protocol matches on method *presence*, so enrollment is opt-out, not opt-in: a screen that defines `action_move_up` for its own arrow keys gets `shift+tab` reverse-nav whether or not it was written with that key in mind. Screens needing different behavior (`focus_previous`, tab bars) — or none — need an explicit branch *above* the protocol check in `action_toggle_auto_approve`. Either way, add an app-level regression test in `test_app.py` that presses `shift+tab` through the real `DeepAgentsApp` dispatch, or the modal will silently swallow the key.
81
+ - A modal test that pushes the screen onto a bare `App` host cannot catch app-level key interception. The app owns a priority `shift+tab -> toggle_auto_approve` binding (`app.py`) that wins dispatch over any screen binding; `action_toggle_auto_approve` routes the key to the active screen. Cursor-style modals (highlighted rows, no focusable children) just implement `action_move_up` — the router's `_SupportsReverseNav` protocol branch picks them up automatically. The protocol matches on method *presence*, so enrollment is opt-out, not opt-in: a screen that defines `action_move_up` for its own arrow keys gets `shift+tab` reverse-nav whether or not it was written with that key in mind. Screens needing different behavior (`focus_previous`, tab bars) — or none — need an explicit branch *above* the protocol check in `action_toggle_auto_approve`. Add an app-level regression test in `test_app.py` when a screen needs behavior other than swallowing the key.
82
82
  - Do not open another modal or refocus the base chat input directly inside a modal dismiss callback. Preserve the non-blocking `push_screen(..., callback)` flow and schedule follow-up UI work with `call_after_refresh` so the dismissing modal fully unwinds first.
83
83
  - Be cautious replacing `push_screen(..., callback)` with an awaited modal result inside slash-command handlers; awaiting can block the Textual message pump and break keyboard navigation in the active modal. Slash commands are dispatched from `on_chat_input_submitted`, which is awaited inline on that pump, so a modal awaited anywhere in the call chain never receives the keys that would resolve it and looks frozen.
84
84
  - When a command genuinely needs an awaited modal result, hand the continuation to `_schedule_off_message_pump` so the handler returns first. A detached continuation runs outside the handler's `try/except` and is cancelled at app exit, so it must catch its own exceptions and mount its own failure message — otherwise the failure reaches only `_log_task_exception` and the user sees no outcome at all — and it must tolerate cancellation part-way through, including mid-subprocess. Anything that mutates the running tool environment must also take `_environment_mutation_lock`, since the handler no longer serializes commands by blocking.
@@ -153,8 +153,8 @@ To add a new slash command: (1) add a `SlashCommand` entry to `COMMANDS`, (2) se
153
153
 
154
154
  1. `deepagents_code/model_config.py` — add `"provider_name": "ENV_VAR_NAME"` to `PROVIDER_API_KEY_ENV`
155
155
  2. `deepagents_code/model_config.py` — if the provider reads a *dedicated* endpoint env var, add `"provider_name": ("CANONICAL_BASE_URL", "ALTERNATE", ...)` to `PROVIDER_BASE_URL_ENV` (see guidelines below); omit the provider entirely when it has no provider-specific endpoint variable
156
- 3. `pyproject.toml` — add `provider = ["langchain-provider>=X.Y.Z,<N.0.0"]` to `[project.optional-dependencies]` and include it in the `all-providers` composite extra
157
- 4. `deepagents_code/model_config.py` — add `"provider_name"` to `RETRY_PARAM_BY_PROVIDER` if the provider's chat model accepts `max_retries`
156
+ 3. `deepagents_code/model_config.py` — add `"provider_name": "max_retries"` (or the provider's actual retry-count constructor kwarg) to `RETRY_PARAM_BY_PROVIDER`. dcode's model-node middleware owns the retry budget, so this entry is the disable-list that forces the provider's own SDK retry loop off; omitting it lets the SDK retries multiply the middleware's attempts. Verify the kwarg name against the integration's constructor — leave the provider out only when it exposes no integer retry-count kwarg. Check what the kwarg counts: retries are disabled with the default zero, but a kwarg counting *total attempts* needs an entry in `RETRY_DISABLE_VALUE_BY_PROVIDER` (see `google_genai`), because zero attempts either restores the SDK default or is coerced back to one
157
+ 4. `pyproject.toml` — add `provider = ["langchain-provider>=X.Y.Z,<N.0.0"]` to `[project.optional-dependencies]` and include it in the `all-providers` composite extra
158
158
  5. `deepagents_code/tui/widgets/auth.py` — add `"provider_name": "Display Name"` to `PROVIDER_DISPLAY_NAMES` so the `/auth` UI shows a branded label instead of the title-cased key, and (if the provider issues API keys from a self-serve page) `"provider_name": "https://…"` to `PROVIDER_API_KEY_URLS` so the prompt links straight to the key page
159
159
  6. `tests/unit_tests/test_model_config.py` — add `assert PROVIDER_API_KEY_ENV["provider_name"] == "ENV_VAR_NAME"` to `TestProviderApiKeyEnv.test_contains_major_providers`, and pin any `PROVIDER_BASE_URL_ENV` entry with a matching assertion
160
160
 
@@ -2,6 +2,47 @@
2
2
 
3
3
  # Deep Agents Code Changelog
4
4
 
5
+ ## [0.1.63](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.62...deepagents-code==0.1.63) (2026-08-26)
6
+
7
+ ### Features
8
+
9
+ - Added Baseten `zai-org/GLM-5.3-Flash` to the model switcher ([#5844](https://github.com/langchain-ai/deepagents/issues/5844)).
10
+ - Added support for loading managed config from a remote source ([#5776](https://github.com/langchain-ai/deepagents/issues/5776)).
11
+ - Added retry middleware for transient model errors in model nodes ([#4569](https://github.com/langchain-ai/deepagents/issues/4569)).
12
+
13
+ ### Fixes
14
+
15
+ - Fixed live cost tracking for dynamic subagents ([#5833](https://github.com/langchain-ai/deepagents/issues/5833)).
16
+ - Improved `clear` command descriptions ([#5841](https://github.com/langchain-ai/deepagents/issues/5841)).
17
+ - Allowed instrumental Auto actions ([#5832](https://github.com/langchain-ai/deepagents/issues/5832)).
18
+ - Ensured traces are flushed before server shutdown ([#5837](https://github.com/langchain-ai/deepagents/issues/5837)).
19
+ - Made the debug log path click-to-copy ([#5845](https://github.com/langchain-ai/deepagents/issues/5845)).
20
+
21
+ ## [0.1.62](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.61...deepagents-code==0.1.62) (2026-08-26)
22
+
23
+ ### Features
24
+
25
+ - Added `/context-doctor` for inspecting and troubleshooting context issues ([#5830](https://github.com/langchain-ai/deepagents/issues/5830)).
26
+ - Added warning when switching models mid-session ([#5829](https://github.com/langchain-ai/deepagents/issues/5829)).
27
+ - Added support for `DEEPAGENTS_HOME` ([#5773](https://github.com/langchain-ai/deepagents/issues/5773)).
28
+ - (Re-)Enabled secret redaction by default ([#5816](https://github.com/langchain-ai/deepagents/issues/5816)).
29
+ - Improved update visibility by showing cached updates in version output ([#5817](https://github.com/langchain-ai/deepagents/issues/5817)).
30
+ - Improved prompts and pickers: the stale editable-deps prompt now defaults to `Refresh environment now`, and the model picker shows an Escape hint ([#5810](https://github.com/langchain-ai/deepagents/issues/5810), [#5775](https://github.com/langchain-ai/deepagents/issues/5775)).
31
+ - Added CLI config provider support ([#5774](https://github.com/langchain-ai/deepagents/issues/5774)).
32
+
33
+ ### Bug Fixes
34
+
35
+ - Fixed refreshed local context handling after compaction to reduce cache busts ([#5828](https://github.com/langchain-ai/deepagents/issues/5828)).
36
+ - Preserved goal notice history for prompt caching ([#5823](https://github.com/langchain-ai/deepagents/issues/5823)).
37
+ - Improved rubric coverage checks ([#5369](https://github.com/langchain-ai/deepagents/issues/5369)).
38
+ - Protected the TUI from native stderr writes ([#5813](https://github.com/langchain-ai/deepagents/issues/5813)).
39
+ - Fixed Git origin resolution from worktree common Git directories ([#5818](https://github.com/langchain-ai/deepagents/issues/5818)).
40
+ - Fixed prompt clipboard behavior so Tab inserts instead of pages ([#5820](https://github.com/langchain-ai/deepagents/issues/5820)).
41
+
42
+ ### Performance Improvements
43
+
44
+ - Reduced tracing overhead by omitting middleware trace inputs ([#5815](https://github.com/langchain-ai/deepagents/issues/5815)).
45
+
5
46
  ## [0.1.61](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.60...deepagents-code==0.1.61) (2026-08-24)
6
47
 
7
48
  ### Features
@@ -8,7 +8,7 @@ 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 (41)
11
+ ## Public (42)
12
12
 
13
13
  | Command | Aliases | Description |
14
14
  | --- | --- | --- |
@@ -17,15 +17,16 @@ aliases, descriptions, visibility, or hidden-command metadata.
17
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
- | `/clear` | | Clear the chat and start a new thread |
20
+ | `/clear` | | Start a fresh thread |
21
21
  | `/context` | | Show current context window usage |
22
+ | `/context-doctor` | | Audit what a session injects and its estimated token cost |
22
23
  | `/copy` | | Copy the latest assistant message to clipboard |
23
24
  | `/cost` | | Show estimated thread cost |
24
25
  | `/docs` | | Open the docs |
25
26
  | `/editor` | | Open prompt in an external editor ($EDITOR) |
26
27
  | `/effort` | | Set reasoning effort for the current model |
27
28
  | `/feedback` | | Send feedback or report an issue |
28
- | `/force-clear` | | Stop active work, clear the chat, and start a new thread |
29
+ | `/force-clear` | | Recover a stuck session with a fresh thread |
29
30
  | `/goal` | | Set and manage a persistent objective with acceptance criteria |
30
31
  | `/help` | | Show help and available commands |
31
32
  | `/install` | | Install an optional integration |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: deepagents-code
3
- Version: 0.1.61
3
+ Version: 0.1.63
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://www.langchain.com/dcode
6
6
  Project-URL: Documentation, https://docs.langchain.com/oss/deepagents/code/overview
@@ -30,7 +30,7 @@ Requires-Python: <4.0,>=3.12
30
30
  Requires-Dist: aiosqlite<1.0.0,>=0.22.1
31
31
  Requires-Dist: anyio<5.0.0,>=4.14.2
32
32
  Requires-Dist: deepagents-acp<1.0.0,>=0.0.10
33
- Requires-Dist: deepagents==0.7.8
33
+ Requires-Dist: deepagents==0.7.9
34
34
  Requires-Dist: filelock<3.30,>=3.29.7
35
35
  Requires-Dist: genai-prices<0.2.0,>=0.1.4
36
36
  Requires-Dist: httpx<1.0.0,>=0.28.1
@@ -39,7 +39,7 @@ Requires-Dist: langchain-google-genai<5.0.0,>=4.3.5
39
39
  Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.3.2
40
40
  Requires-Dist: langchain-openai<2.0.0,>=1.6.0
41
41
  Requires-Dist: langchain-quickjs<0.4.0,>=0.3.4
42
- Requires-Dist: langchain<2.0.0,>=1.3.16
42
+ Requires-Dist: langchain<2.0.0,>=1.3.17
43
43
  Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.1.1
44
44
  Requires-Dist: langgraph-cli[inmem]<1.0.0,>=0.4.31
45
45
  Requires-Dist: langgraph-runtime-inmem<1.0.0,>=0.33.0
@@ -44,9 +44,11 @@
44
44
 
45
45
  ### Assumptions
46
46
 
47
+ > Throughout this document `~/.deepagents/` names the *effective* user profile directory. That is the default location; `DEEPAGENTS_HOME` selects a different one (TB14), and every claim about profile-owned files applies to whichever directory is selected at launch.
48
+
47
49
  1. The CLI runs locally on the user's machine; the user is a developer who invoked `deepagents` themselves.
48
50
  2. The project provides the HITL approval framework. Users control model selection, API keys, and whether to disable approval gates. Managed policy can narrow each of these; `[models].allowed` narrows model selection.
49
- 3. `~/.deepagents/` is only writable by the authenticated local user — no multi-user shared home directories.
51
+ 3. The user profile directory is only writable by the authenticated local user — no multi-user shared home directories. `DEEPAGENTS_HOME` (see TB14) can relocate that directory outside `$HOME`; keeping the selected location single-user is then the operator's responsibility.
50
52
  4. Sandbox backends are trusted third-party services. CLI responsibility ends at correctly constructing and dispatching requests to them.
51
53
  5. LangSmith tracing, if enabled, is user-opted-in via environment variables.
52
54
  6. The LangGraph dev server subprocess binds to `127.0.0.1` by default (`client/launch/server.py:_DEFAULT_HOST`) and is ephemeral — started and stopped per CLI session.
@@ -226,6 +228,7 @@
226
228
  | TB11 | Config File → Code Execution | `class_path` in `config.toml` triggers `importlib.import_module()`; project/global `.env` values are loaded into the process environment and can reach Bash startup hooks | Format validation (`module:ClassName`); `issubclass(BaseChatModel)` check; dotenv loading denies shell startup / environment-hijack keys (`BASH_ENV`, `ENV`) | Module-level side effects execute during import; user controls config file; project files in the working directory influence execution |
227
229
  | TB12 | Goal/Rubric State → Model Context | Persisted user- and agent-controlled goal state becomes a synthetic `HumanMessage` in a primary-model request | State projection, lifecycle filtering, notice fingerprinting, raw-character limits, HTML escaping of boundary tags | Natural-language instructions, sensitivity, post-escape size, and provider-specific byte/token budgets |
228
230
  | TB13 | Managed Config → Runtime | A fixed administrator-deployed TOML file overrides CLI, environment, and user preferences | Fixed non-redirectable path; the CLI never writes the file; fail-closed startup for every command except diagnostics; typed resolution; model-policy checks before credentials/imports/construction; diagnostics remain available | Filesystem ownership/mode and privileged deployment are outside the CLI; a host administrator can weaken or strengthen policy |
231
+ | TB14 | Launch Env → User Trust Root | Inherited `DEEPAGENTS_HOME` selects the profile whose config, credentials, and user MCP file are trusted | Captured and normalized once before dotenv loading; absolute/`~/` validation; denied from every dotenv layer; propagated unchanged to the server | A user can deliberately select a profile inside or above a checkout; only the exact profile `.mcp.json` receives user provenance |
229
232
 
230
233
  ### Boundary Details
231
234
 
@@ -257,7 +260,7 @@
257
260
 
258
261
  #### TB4: MCP Config → Process / Network
259
262
 
260
- - **Inside**: `mcp_tools._validate_server_config` validates JSON structure and field types. Project-level servers (stdio and remote) require approval: an interactive prompt (`main._check_mcp_project_trust`) that offers allow-for-this-session ("y"), remember a chosen subset of servers ("r"), or deny ("N") — unless `--trust-project-mcp` is set, which trusts the whole config for the run. Whole-config trust is never persisted; it exists only as in-memory run state, set by `--trust-project-mcp` or by an interactive allow-once/remember decision. The remembered subset governs only what is persisted for future runs — both allow-once and remember load every prompted server for the current session. Persistent "remember" (a.k.a. "always allow") decisions are stored in `[mcp].enabled_project_server_approvals` with a local-project identity, server name, and server definition fingerprint. Remote server approvals with fixed URLs are shared by main checkouts and linked worktrees only through validated reciprocal Git common-directory metadata; independent clones remain separate, and non-Git or malformed/forged metadata falls back to the exact resolved root. Remote definitions with interpolated URLs remain exact-worktree scoped because project `.env` files can resolve the same template to different endpoints. Local stdio server approvals always use the exact resolved worktree root because the same command can execute different files in another checkout. A changed command, URL, or transport under the same name requires re-approval. Users can reject individual project server names via `[mcp].disabled_project_servers` (or `DEEPAGENTS_CODE_DISABLED_PROJECT_MCP_SERVERS`). There is also an explicit process-wide escape hatch, `DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS`, that approves matching names globally and intentionally bypasses the project/fingerprint binding. Reject wins over approval and over full trust, with one documented exception: if the user's `config.toml` is unreadable (see below), any deny defined *only* there is lost, so a name that is both TOML-`disabled` and exported in `DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS` survives — an accepted footgun (`load_mcp_server_trust_lists` documents it inline) that requires a self-contradicting config plus the explicit dangerous opt-in, and the read error is surfaced to the user. These policies are read by `model_config.load_mcp_server_trust_lists` only from user-controlled sources — the user-level `~/.deepagents/config.toml`, the global `~/.deepagents/.env`, and shell-exported env — never from `.mcp.json` or any repo-committed file, so a committed config cannot self-approve its own servers. In particular, the env forms (`DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS` / `..._DISABLED_...`) are added to `config._PROJECT_DOTENV_DENIED_ENV_KEYS`, so a committed *project* `.env` cannot inject them into `os.environ` even though it is loaded at bootstrap. The dangerous enable env var and scoped TOML approvals are independent grants: setting the env var, including to an empty value, does not suppress remembered approvals. Disabled *unions* TOML and env so a deny can never be silently emptied by the other source. If the user's `config.toml` exists but cannot be read or parsed, the loader fails closed (project configs are treated as untrusted and the error is surfaced) rather than proceeding with an empty deny list. Only scoped-approved, dangerously env-enabled, or fully trusted names survive into the merged config, so a non-approved remote entry is never preflighted and its interpolated headers are never resolved.
263
+ - **Inside**: `mcp_tools._validate_server_config` validates JSON structure and field types. Discovery emits typed `(path, scope, project_root)` records; runtime and login preserve that provenance instead of inferring trust from path containment. Only the exact configured profile `.mcp.json` is a user candidate. Standard project-root and `.deepagents/.mcp.json` candidates remain project-scoped when `DEEPAGENTS_HOME` is an ancestor of, inside, or equal to the checkout; a user/project path or symlink collision fails closed to project scope. Project-level servers (stdio and remote) require approval: an interactive prompt (`main._check_mcp_project_trust`) that offers allow-for-this-session ("y"), remember a chosen subset of servers ("r"), or deny ("N") — unless `--trust-project-mcp` is set, which trusts the whole config for the run. Whole-config trust is never persisted; it exists only as in-memory run state, set by `--trust-project-mcp` or by an interactive allow-once/remember decision. The remembered subset governs only what is persisted for future runs — both allow-once and remember load every prompted server for the current session. Persistent "remember" (a.k.a. "always allow") decisions are stored in `[mcp].enabled_project_server_approvals` with a local-project identity, server name, and server definition fingerprint. Remote server approvals with fixed URLs are shared by main checkouts and linked worktrees only through validated reciprocal Git common-directory metadata; independent clones remain separate, and non-Git or malformed/forged metadata falls back to the exact resolved root. Remote definitions with interpolated URLs remain exact-worktree scoped because project `.env` files can resolve the same template to different endpoints. Local stdio server approvals always use the exact resolved worktree root because the same command can execute different files in another checkout. A changed command, URL, or transport under the same name requires re-approval. Users can reject individual project server names via `[mcp].disabled_project_servers` (or `DEEPAGENTS_CODE_DISABLED_PROJECT_MCP_SERVERS`). There is also an explicit process-wide escape hatch, `DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS`, that approves matching names globally and intentionally bypasses the project/fingerprint binding. Reject wins over approval and over full trust, with one documented exception: if the user's `config.toml` is unreadable (see below), any deny defined *only* there is lost, so a name that is both TOML-`disabled` and exported in `DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS` survives — an accepted footgun (`load_mcp_server_trust_lists` documents it inline) that requires a self-contradicting config plus the explicit dangerous opt-in, and the read error is surfaced to the user. These policies are read by `model_config.load_mcp_server_trust_lists` only from user-controlled sources — the user-level profile `config.toml`, its global `.env`, and shell-exported env — never from `.mcp.json` or any repo-committed file, so a committed config cannot self-approve its own servers. In particular, the trust-list env forms are denied from project dotenv, while `DEEPAGENTS_HOME` is denied from every dotenv source under TB14. The dangerous enable env var and scoped TOML approvals are independent grants: setting the env var, including to an empty value, does not suppress remembered approvals. Disabled *unions* TOML and env so a deny can never be silently emptied by the other source. If the user's `config.toml` exists but cannot be read or parsed, the loader fails closed (project configs are treated as untrusted and the error is surfaced) rather than proceeding with an empty deny list. Only scoped-approved, dangerously env-enabled, or fully trusted names survive into the merged config, so a non-approved remote entry is never preflighted and its interpolated headers are never resolved.
261
264
  - **Outside**: Stdio server `command`, `args`, and `env` fields are user-controlled strings passed directly to `StdioConnection`. The `env` dict from MCP config is forwarded without filtering — users can set arbitrary environment variables (including `PATH`, `LD_PRELOAD`, `PYTHONPATH`) for the MCP subprocess.
262
265
  - **Crossing mechanism**: `subprocess.Popen` (via `langchain_mcp_adapters`) for stdio; HTTP/SSE for remote servers.
263
266
 
@@ -290,12 +293,12 @@
290
293
  - **Inside**: `config._create_model_from_class` validates `class_path` format (`module:ClassName`), imports the module via `importlib.import_module()`, and checks `issubclass(cls, BaseChatModel)` before instantiation.
291
294
  - **Outside**: Module-level code in the imported module executes unconditionally during `import_module()`. The `issubclass` check only runs after import. Any side effects (file I/O, network calls, subprocess spawning) in the module's top-level scope execute before the type check.
292
295
  - **Crossing mechanism**: `importlib.import_module(module_path)` in `config._create_model_from_class`.
293
- - **Inside (dotenv)**: `config._load_dotenv` loads project and global `.env` values with `override=False` and drops shell startup / environment-hijack keys (`BASH_ENV`, `ENV`, and related) so a project `.env` cannot register a script that Bash would source at startup. The denylist is best-effort: it enumerates environment variables known to reach a code-execution consumer (a shell's startup hook, the dynamic linker, an interpreter's startup path) and cannot claim completeness — any tool `dcode` spawns that honors an environment-driven execution hook not yet in the list remains a live vector until the key is added. The preview path (`_preview_dotenv_environ`) applies the same denylist so a dry-run config change cannot report a value a real reload would reject.
296
+ - **Inside (dotenv)**: `config._load_dotenv` loads project and global `.env` values with `override=False` and drops shell startup / environment-hijack keys (`BASH_ENV`, `ENV`, and related) so a project `.env` cannot register a script that Bash would source at startup. `DEEPAGENTS_HOME` is also denied from both layers because profile selection has already crossed TB14. The denylist is best-effort for execution-hook variables: it enumerates variables known to reach a code-execution consumer (a shell's startup hook, the dynamic linker, an interpreter's startup path) and cannot claim completeness — any tool `dcode` spawns that honors an environment-driven execution hook not yet in the list remains a live vector until the key is added. The preview path (`_preview_dotenv_environ`) applies the same denylist so a dry-run config change cannot report a value a real reload would reject.
294
297
  - **Outside (dotenv)**: All other `.env` keys are applied to the process environment, and any project file in the working directory (`.env`, `Makefile`, build scripts) can still influence execution. See T12.
295
298
 
296
299
  #### TB12: Goal/Rubric State → Model Context
297
300
 
298
- - **Inside**: `goal_state_notice.project_goal_state` only exposes an objective and status note while the goal is actionable, and `build_goal_state_notice` HTML-escapes embedded text before wrapping it in boundary tags. `GoalToolsMiddleware` fingerprints notices, writes a replacement when state is stale or compacted, and re-pins the notice into model requests when necessary.
301
+ - **Inside**: `goal_state_notice.project_goal_state` only exposes an objective and status note while the goal is actionable, and `build_goal_state_notice` HTML-escapes embedded text before wrapping it in boundary tags. `GoalToolsMiddleware` fingerprints notices, appends a fresh notice when state is stale or compacted, and re-pins the notice into model requests when necessary. Earlier bounded notices remain unchanged for prompt-cache stability; oversized legacy notices are replaced transiently with bounded same-index stand-ins, and each fresh notice explicitly supersedes them.
299
302
  - **Outside**: Goal objectives and criteria originate from user input. `/rubric file` reads the selected local text file. Status notes can be model-authored through `update_goal`. `goal_state_limits` rejects raw text above these limits:
300
303
 
301
304
  | Value | Limit (characters) |
@@ -330,11 +333,24 @@
330
333
  - A missing file is accepted and applies no policy.
331
334
  - A present unreadable, undecodable, or syntactically corrupt file blocks every command except `--help`, `--version`, `help`, `config`, `doctor`, and `auth path`. It also blocks `/reload`.
332
335
  - On Windows, a ProgramData directory that cannot be read from the registry blocks the same commands. The path would be a guess, and an empty read at a guessed path does not prove that no policy is deployed. Reporting it as a missing file made every managed setting silently inert on a host whose ProgramData is relocated.
333
- - A failed `/reload` keeps the last snapshot that parsed cleanly, so policy is never dropped mid-session.
336
+ - A failed `/reload` keeps the last enforceable snapshot, so policy is never dropped mid-session. A snapshot that parses but cannot be enforced is not cached either, so a rejected edit cannot become the generation later readers observe.
334
337
  - An unusable user `config.toml` drops only the user layer, so managed policy still applies.
335
338
  - A deny list that cannot be read is treated as denying everything, never as empty. This covers a managed `[mcp].disabled_servers` that is neither an array of names nor a comma-separated string, and a `[mcp]` section that is not a table. A managed `[mcp].enabled_project_server_approvals` that is not an array is treated the same way: the key is present, so policy means to narrow access, and reading its presence as absence would keep both the user's approvals and the `DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS` bypass in force.
336
339
  - **Outside**: Ownership, permission-mode validation, privileged installation, and `sudo` policy are deployment responsibilities. Anyone who can replace the administrator-managed file can control model, sandbox, interpreter, MCP trust, and other supported runtime settings. Model policy constrains official dcode selection and construction paths; it does not stop a hostile local user from replacing the package, modifying the process, or calling a provider SDK directly. On macOS, note that stock `/Library/Application Support` is group-writable by `admin`, so any admin-group member can create the file and grant themselves policy. Deployments that rely on this boundary must tighten ownership and mode on the `dcode` directory.
337
- - **Crossing mechanism**: Synchronous local file read through `configuration.TomlFileProvider`, followed by typed resolution and CLI/server startup gates.
340
+ - **Remote source**: The fixed local file may contain only `[managed_config].source`. Its administrator-owned HTTPS URL is then the explicit destination allowlist. The remote document becomes the whole managed policy. It cannot chain to another source. URLs with userinfo, query strings, or fragments are rejected. So are URLs carrying whitespace, control characters, or any non-ASCII character: confusable host text must not reach operator output, and `urllib` does not encode a non-ASCII request target consistently.
341
+ - Requests validate the certificate against Python's default TLS trust store, bypass environment proxies, and refuse redirects. One five-second budget covers the whole fetch: the connection, the TLS handshake, the headers, and the body. The fetch is abandoned once that budget is spent. At most 1 MiB is accepted.
342
+ - Only a complete document is accepted. The status must be 200. The media type must be `application/toml`, `text/plain`, or `application/octet-stream`, and the body must not be compressed. A captive portal or gateway error page that answers 200 with `text/html` is rejected before it is parsed. This is not a complete guard, and it is not relied on as one: a response with no `Content-Type`, or one claiming `application/octet-stream`, is read, because a bare object store answers that way. Such a body still has to parse as TOML and satisfy every rule below. Framing must show the body arrived whole: one matching `Content-Length`, or chunked encoding. A response that sends both, or that repeats `Content-Length` with different values, is rejected — the first value wins in `http.client`, so a duplicate header would otherwise let a prefix pass as a whole document. A keyless document is rejected as a failed publish. Truncated TOML often still parses, so a partial document would otherwise enforce a policy with entries silently missing, and would replace the last enforceable generation.
343
+ - The proxy bypass stops a local user redirecting the fetch through `HTTPS_PROXY`. The trust store itself is not pinned. `SSL_CERT_FILE` and `SSL_CERT_DIR` still select the certificate authorities, so the same actor can substitute the CA set for this request. This is the same deployment responsibility as the local file ownership in the **Outside** bullet above. This boundary does not apply on a host where an unprivileged user controls the `dcode` process environment.
344
+ - No disk cache or authentication material is stored. Private enterprise hosts remain reachable because the local trust anchor, not user input, selects the host. A fetch failure stops startup. A failed reload keeps the process's last enforceable snapshot, and `dcode doctor` reports that the refresh failed so a host that stopped answering is not silent.
345
+
346
+ - **Crossing mechanism**: Synchronous local file read through `configuration.TomlFileProvider`, optionally followed by one bounded HTTPS fetch through `configuration.RemoteTomlProvider`, then typed resolution and CLI/server startup gates.
347
+
348
+ #### TB14: Launch Environment → User Trust Root
349
+
350
+ - **Inside**: `_paths.PATHS` captures `DEEPAGENTS_HOME` before either dotenv layer is inspected. Empty/unset selects the launch user's `~/.deepagents`; absolute paths and a leading `~/` are normalized without requiring the target to exist. Other relative paths and `~user` forms stop startup, as do a dangling symlink and a root that exists but denies traversal. The unreadable case is rejected explicitly: `Path.is_symlink` reports `False` under EACCES, so it would otherwise pass every guard and fail one file at a time later. The normalized absolute value is frozen for the client and explicitly copied into every server subprocess environment, so reloads, cwd changes, and server cwd differences cannot move the profile.
351
+ - **Trust invariant**: Project-controlled input cannot relocate the user trust root. `DEEPAGENTS_HOME` is in the deny set shared by project and global dotenv loading. MCP discovery separately records user/project provenance and gives project scope precedence when standard discovery locations collide. `$HOME` itself is rejected at startup, in any spelling: the comparison uses device and inode, so a symlink or a case variant on a case-insensitive filesystem is caught too. The home comparison fails closed: when identity cannot be determined at all, startup stops rather than accepting the path. For the roots that are accepted — an ancestor of a checkout, the checkout root, or a directory inside it — collision handling keeps the checkout's standard MCP files project-scoped. `PATH` is treated the same way: the installation-scoped managed bin may be prepended directly, but a verified `rg` in the profile fallback is exposed through a process-private shim containing only that entrypoint. A repository-controlled `<profile>/bin` and every sibling executable in it stay off `PATH` for agent subprocesses.
352
+ - **Outside**: A shell or process supervisor can deliberately select any accepted absolute profile path at launch. Protecting ownership and permissions on that selected directory is the operator's responsibility.
353
+ - **Crossing mechanism**: Inherited process environment → immutable standard-library-only path snapshot → normalized child environment.
338
354
 
339
355
  ---
340
356
 
@@ -451,7 +467,7 @@
451
467
  #### T15: Stored Prompt Injection Through Goal/Rubric State
452
468
 
453
469
  - **Flow**: DF28/DF29 (user or local-file content → checkpointed notice → primary-model context)
454
- - **Description**: The goal-state notice embeds the full actionable objective, active criteria, and status note in a synthetic `HumanMessage`. A rubric loaded from an untrusted repository file, or a crafted status note, can therefore persist instructions that influence later model behavior. HTML escaping and boundary labels prevent literal tag forgery. They do not stop natural-language prompt injection. Interactive HITL still gates side-effecting tool calls. Auto and non-interactive configurations can reduce that protection.
470
+ - **Description**: The goal-state notice embeds the full actionable objective, active criteria, and status note in a synthetic `HumanMessage`. A rubric loaded from an untrusted repository file, or a crafted status note, can therefore persist instructions that influence later model behavior. Bounded superseded notices remain in the append-only request history until compaction; the latest notice identifies itself as authoritative, but a model can still attend to older text. Oversized legacy notices are replaced only in the transient model request. HTML escaping and boundary labels prevent literal tag forgery. They do not stop natural-language prompt injection. Interactive HITL still gates side-effecting tool calls. Auto and non-interactive configurations can reduce that protection.
455
471
  - **Preconditions**: (1) The user accepts a goal/rubric or loads a file containing attacker-controlled instructions; (2) the state is actionable or the rubric remains active; (3) the primary model follows the injected content; (4) for side effects, the resulting tool call is approved or an approval-bypassing mode is active.
456
472
 
457
473
  #### T16: Automatic Disclosure of File-Loaded Rubrics
@@ -523,8 +539,8 @@
523
539
  #### T11: Auto-Installed ripgrep Binary from Upstream Release
524
540
 
525
541
  - **Flow**: Download performed by `managed_tools.ensure_ripgrep` when `rg` is not on `PATH` — either on first run, or eagerly at install time via `dcode tools install` (invoked by `scripts/install.sh`).
526
- - **Description**: Without a system `rg`, Deep Agents Code fetches the pinned ripgrep release tarball from `github.com/BurntSushi/ripgrep/releases/...`, verifies it against an in-tree SHA-256 (`RIPGREP_ASSETS`), extracts it under a `TemporaryDirectory`, and atomically moves the binary into `~/.deepagents/bin/rg`. The binary then runs unsandboxed, inheriting the same trust as a user-installed `rg` (the SDK invokes it via `subprocess.run(["rg", ...])`). The same verified path backs the `dcode tools install` verb, so the install script reuses it rather than re-encoding the version + checksum table in bash.
527
- - **Mitigations**: (1) SHA-256 verified against the pinned hash table before move — a mismatch aborts the install and leaves `BIN_DIR` clean. (2) Network egress is limited to `github.com`. (3) Opt-out via `DEEPAGENTS_CODE_OFFLINE` for air-gapped environments, or `DEEPAGENTS_CODE_RIPGREP_INSTALLER=system` to defer to the OS package manager instead of the managed binary. (4) Pinned version + checksums are bumped in-tree, so a compromised upstream release is detected on the next Deep Agents Code release rather than silently propagating. (5) Atomic move-into-place avoids partial installs when concurrent CLI invocations race. (6) The eager install-script path is non-`sudo` (no system package manager is invoked in the default `managed` mode).
542
+ - **Description**: Without a system `rg`, Deep Agents Code fetches the pinned ripgrep release tarball from `github.com/BurntSushi/ripgrep/releases/...`, verifies it against an in-tree SHA-256 (`RIPGREP_ASSETS`), extracts it under a `TemporaryDirectory`, and atomically moves the binary into `managed_tools.BIN_DIR` (`<sys.prefix>/share/deepagents-code/bin/rg`, shared by every profile), or into the profile-scoped `managed_tools.FALLBACK_BIN_DIR` when that directory is not writable. The binary then runs unsandboxed, inheriting the same trust as a user-installed `rg` (the SDK invokes it via `subprocess.run(["rg", ...])`). The same verified path backs the `dcode tools install` verb, so the install script reuses it rather than re-encoding the version + checksum table in bash.
543
+ - **Mitigations**: (1) SHA-256 verified against the pinned hash table before move — a mismatch aborts the install and leaves the chosen bin directory clean. (2) Network egress is limited to `github.com`. (3) Opt-out via `DEEPAGENTS_CODE_OFFLINE` for air-gapped environments, or `DEEPAGENTS_CODE_RIPGREP_INSTALLER=system` to defer to the OS package manager instead of the managed binary. (4) Pinned version + checksums are bumped in-tree, so a compromised upstream release is detected on the next Deep Agents Code release rather than silently propagating. (5) Atomic move-into-place avoids partial installs when concurrent CLI invocations race. (6) The eager install-script path is non-`sudo` (no system package manager is invoked in the default `managed` mode).
528
544
  - **Preconditions**: User has not installed `rg` via their package manager, `DEEPAGENTS_CODE_OFFLINE` is unset, `DEEPAGENTS_CODE_RIPGREP_INSTALLER` is not `system`, and the host can reach `github.com`. The pinned SHA-256 in `RIPGREP_ASSETS` would need to be incorrect (a supply-chain compromise of the deepagents-code release) for a tampered binary to be installed.
529
545
 
530
546
  #### T11b: Unpinned Pricing Catalog Fetched Hourly from a Mutable Upstream Ref
@@ -648,3 +664,4 @@ Threats that appear valid in isolation but fall outside project responsibility b
648
664
  | 2026-08-21 | manual update | Clarified that the dotenv execution-hook denylist (`config._DOTENV_DENIED_ENV_KEYS`) is a best-effort enumeration of known code-execution consumers, not a closed set: TB11's inside-detail and T12's description now state this explicitly, and the Configuration input-coverage gap was reworded from the stale "project `.env` can set shell startup-hook vars" (denylisted since #4288) to the actual residual — execution-hook keys consumed by not-yet-enumerated tools still reach subprocesses |
649
665
  | 2026-08-24 | langster-threat-model (diff) | Removed the client-seeded `/offload` fallback. `/offload` is now available only through C18 on built-in servers; local in-process and ACP agents do not support it, and custom or older servers without the route fail at the HTTP boundary. Updated DC5, TB2, TB10, and T6 to remove the client self-approval and synthetic-message attack surface. The server route, hook behavior, archive guard, and state-only persistence controls are unchanged; no new threat was identified. |
650
666
  | 2026-08-24 | manual update | The C18 boundary now strips endpoint/proxy/transport keys (`base_url`, `openai_proxy`, `http_client`, and similar) from client-supplied `model_params` before they reach `config.create_model` (`offload_api._strip_transport_model_params`), closing the credential-redirection consequence of T6 for this route. Client-supplied `model` and behavioral params still flow through; in-process `CLIContextSchema` model params remain trusted and unfiltered |
667
+ | 2026-08-25 | manual update | Stopped replacing bounded superseded goal-state notices in model requests while retaining bounded same-index stand-ins for oversized legacy notices. Goal/rubric history now remains append-only for prompt-cache stability where safe, and the latest notice explicitly supersedes earlier notices. Updated T15 to record the residual risk that a model can still attend to older bounded goal text until compaction. |
@@ -3,10 +3,12 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import logging
6
+ import sys
6
7
  from typing import TYPE_CHECKING
7
8
 
8
9
  from deepagents_code._debug import configure_debug_logging
9
10
  from deepagents_code._debug_buffer import install_log_buffer
11
+ from deepagents_code._home_error import DeepAgentsHomeError
10
12
  from deepagents_code._version import __version__
11
13
 
12
14
  if TYPE_CHECKING:
@@ -33,9 +35,25 @@ def __getattr__(name: str) -> Callable[[], None]:
33
35
 
34
36
  Raises:
35
37
  AttributeError: If *name* is not a lazily-provided attribute.
38
+
39
+ Note:
40
+ Any import error other than an unresolvable profile location
41
+ propagates unchanged; `DeepAgentsHomeError` is reported as a message
42
+ plus exit 2 instead of a traceback.
36
43
  """
37
44
  if name == "cli_main":
38
- from deepagents_code.main import cli_main
45
+ try:
46
+ from deepagents_code.main import cli_main
47
+ except DeepAgentsHomeError as exc:
48
+ # `_paths` resolves the profile at import, so a bad DEEPAGENTS_HOME
49
+ # or an unresolvable home surfaces here. Report it as a message
50
+ # rather than a traceback: the user has a value to fix, and every
51
+ # module that imports `_paths` would fail the same way.
52
+ message = str(exc)
53
+
54
+ def cli_main() -> None:
55
+ print(f"dcode: {message}", file=sys.stderr) # noqa: T201
56
+ raise SystemExit(2)
39
57
 
40
58
  return cli_main
41
59
  msg = f"module {__name__!r} has no attribute {name!r}"
@@ -1,6 +1,6 @@
1
1
  """Allow running the CLI as: `python -m deepagents_code`."""
2
2
 
3
- from deepagents_code.main import cli_main
3
+ from deepagents_code import cli_main
4
4
 
5
5
  if __name__ == "__main__":
6
6
  cli_main()
@@ -1,3 +1,3 @@
1
1
  """Generated at build time. Do not edit or commit."""
2
2
 
3
- BUILD_COMMIT = "23a80f4"
3
+ BUILD_COMMIT = "970003e"
@@ -77,3 +77,18 @@ resume but are not user-authored, so they are filtered out of both the rendered
77
77
  transcript and a thread's initial prompt. Shared here so the single producer
78
78
  (`textual_adapter`) and its consumers (`app`, `sessions`) agree on one literal.
79
79
  """
80
+
81
+ LOCAL_CONTEXT_MESSAGE_SOURCE: Final[str] = "local_context"
82
+ """Source for model-only local-context refresh messages."""
83
+
84
+ DEFAULT_PLUGIN_DIRNAME: Final[str] = "plugins"
85
+ """Directory name for plugin storage under the profile root.
86
+
87
+ Not an agent profile. The `/agent` picker reserves this name in addition to
88
+ requiring an `AGENTS.md` marker, so it is never listed as a selectable agent.
89
+
90
+ Defined here rather than in `plugins.store` because `_reserved_names` reads it
91
+ on the CLI startup path, and importing `plugins.store` pulls in the `plugins`
92
+ package `__init__`, which loads pydantic through `plugins.models` (see AGENTS.md
93
+ "Startup performance"). `plugins.store` re-exports it for its own callers.
94
+ """
@@ -199,6 +199,21 @@ persist trust decisions.
199
199
  Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` as enabled.
200
200
  """
201
201
 
202
+ DEBUG_MODEL_SWITCH = "DEEPAGENTS_CODE_DEBUG_MODEL_SWITCH"
203
+ """Force the model-switch confirmation modal on every model change.
204
+
205
+ Set to a truthy value when launching the interactive TUI to make
206
+ `_confirm_and_switch_model` show `ModelSwitchWarningScreen` for every switch
207
+ to a different model, bypassing the `warnings.model_switch_token_threshold`
208
+ gate. Lets the modal — including the deferred path that queues behind an
209
+ active turn — be exercised without growing a thread past the token threshold.
210
+ The modal shows the real current/target models and the live context-token
211
+ count, which may be 0.
212
+
213
+ Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` (case-insensitive)
214
+ as enabled, and `0`, `false`, `no`, `off`, empty string, or unset as disabled.
215
+ """
216
+
202
217
  DEBUG_NOTIFICATIONS = "DEEPAGENTS_CODE_DEBUG_NOTIFICATIONS"
203
218
  """Inject sample missing-dependency notifications at launch so the notification
204
219
  center UI can be exercised without waiting for real conditions.
@@ -314,7 +329,7 @@ LANGSMITH_PROJECT = "DEEPAGENTS_CODE_LANGSMITH_PROJECT"
314
329
  """Override LangSmith project name for agent traces."""
315
330
 
316
331
  LANGSMITH_REDACT = "DEEPAGENTS_CODE_LANGSMITH_REDACT"
317
- """Toggle LangSmith secret redaction for agent traces (defaults to off)."""
332
+ """Toggle LangSmith secret redaction for agent traces (defaults to on)."""
318
333
 
319
334
  LANGSMITH_REPLICA_PROJECTS = "DEEPAGENTS_CODE_LANGSMITH_REPLICA_PROJECTS"
320
335
  """Comma-separated LangSmith project names to *also* write agent traces to.
@@ -500,9 +515,9 @@ settable as `[features].resume_term_program` in config.toml.
500
515
  RIPGREP_INSTALLER = "DEEPAGENTS_CODE_RIPGREP_INSTALLER"
501
516
  """Select how ripgrep is provisioned: `managed` (default) or `system`.
502
517
 
503
- `managed` downloads the pinned, SHA-256-verified upstream binary into
504
- `~/.deepagents/bin` (no sudo). `system` skips that download so power users can
505
- rely on their distro package / existing toolchain instead; the install script's
518
+ `managed` downloads the pinned, SHA-256-verified upstream binary into the dcode
519
+ installation (no sudo). `system` skips that download so power users can rely on
520
+ their distro package / existing toolchain instead; the install script's
506
521
  `system` mode keeps the brew/apt/cargo path. A system `rg` already on `PATH` is
507
522
  reused under either setting. Unrecognized values fall back to `managed`. See
508
523
  `managed_tools.ripgrep_installer`."""
@@ -336,6 +336,72 @@ def find_git_common_dir(path: str | Path) -> Path | None:
336
336
  return common_dir
337
337
 
338
338
 
339
+ def _read_git_config_value(raw: str, section: str, key: str) -> str | None:
340
+ """Read one value from a Git config section.
341
+
342
+ Returns:
343
+ The configured value, or `None` when it is absent.
344
+ """
345
+ in_section = False
346
+ expected = section.replace(" ", "").lower()
347
+ for line in raw.splitlines():
348
+ stripped = line.strip()
349
+ if stripped.startswith("[") and stripped.endswith("]"):
350
+ in_section = stripped.replace(" ", "").lower() == expected
351
+ continue
352
+ name, separator, value = stripped.partition("=")
353
+ if in_section and separator and name.strip().lower() == key:
354
+ return value.strip() or None
355
+ return None
356
+
357
+
358
+ def _submodule_git_dir(root: Path, parent_config_dir: Path) -> Path | None:
359
+ """Resolve a validated submodule administration directory.
360
+
361
+ Returns:
362
+ The administration directory, or `None` when validation fails.
363
+ """
364
+ git_entry = root / ".git"
365
+ if git_entry.is_symlink() or not git_entry.is_file():
366
+ return None
367
+ git_dir = _parse_trusted_git_dir_pointer(git_entry)
368
+ if git_dir is None or not _is_valid_git_common_dir(git_dir):
369
+ return None
370
+ try:
371
+ git_dir.relative_to(parent_config_dir / "modules")
372
+ raw = (git_dir / "config").read_text(encoding="utf-8")
373
+ worktree = _read_git_config_value(raw, "[core]", "worktree")
374
+ if worktree is None:
375
+ return None
376
+ candidate = Path(worktree)
377
+ if not candidate.is_absolute():
378
+ candidate = git_dir / candidate
379
+ return git_dir if candidate.resolve(strict=True) == root else None
380
+ except (OSError, RuntimeError, ValueError):
381
+ logger.debug("Failed to validate submodule Git metadata")
382
+ return None
383
+
384
+
385
+ def _find_git_config_dir(path: str | Path) -> Path | None:
386
+ """Locate a validated repository config directory.
387
+
388
+ Returns:
389
+ The config directory, or `None` when validation fails.
390
+ """
391
+ root = find_git_root(path)
392
+ if root is None:
393
+ return None
394
+ common_dir = find_git_common_dir(root)
395
+ if common_dir is not None:
396
+ return common_dir
397
+ parent_config_dir = _find_git_config_dir(root.parent)
398
+ return (
399
+ _submodule_git_dir(root, parent_config_dir)
400
+ if parent_config_dir is not None
401
+ else None
402
+ )
403
+
404
+
339
405
  def read_git_branch_from_filesystem(path: str | Path) -> str | None:
340
406
  """Read the current git branch from repository metadata.
341
407
 
@@ -556,32 +622,19 @@ def read_git_remote_url_from_filesystem(path: str | Path) -> str | None:
556
622
  The `origin` remote URL, an empty string when `path` is not inside a
557
623
  git repository, or `None` when no `origin` URL is configured.
558
624
  """
559
- git_dir = find_git_dir(path)
560
- if git_dir is None:
625
+ config_dir = _find_git_config_dir(path)
626
+ if config_dir is None:
561
627
  return ""
562
628
 
563
629
  try:
564
- raw = (git_dir / "config").read_text(encoding="utf-8")
630
+ raw = (config_dir / "config").read_text(encoding="utf-8")
565
631
  except FileNotFoundError:
566
632
  return None
567
633
  except OSError:
568
- logger.debug("Failed to read git config in %s", git_dir, exc_info=True)
634
+ logger.debug("Failed to read Git config")
569
635
  return None
570
636
 
571
- in_origin = False
572
- for line in raw.splitlines():
573
- stripped = line.strip()
574
- if stripped.startswith("[") and stripped.endswith("]"):
575
- # Section header, e.g. [remote "origin"]. Match case-insensitively
576
- # on the remote name to mirror git's own behavior.
577
- in_origin = stripped.replace(" ", "").lower() == '[remote"origin"]'
578
- continue
579
- if in_origin and stripped.lower().startswith("url"):
580
- _, _, value = stripped.partition("=")
581
- url = value.strip()
582
- if url:
583
- return url
584
- return None
637
+ return _read_git_config_value(raw, '[remote "origin"]', "url")
585
638
 
586
639
 
587
640
  def read_git_remote_url_via_subprocess(path: str | Path) -> str:
@@ -21,6 +21,8 @@ from langchain.agents.middleware.types import (
21
21
  AgentMiddleware,
22
22
  ModelRequest,
23
23
  ModelResponse,
24
+ TracePolicy,
25
+ omit_payload,
24
26
  )
25
27
  from langchain_core.messages import AIMessage
26
28
 
@@ -155,6 +157,9 @@ class _GlmTerminalStallRecovery(AgentMiddleware):
155
157
  the stall was measured only there; OpenRouter and Baseten are excluded.
156
158
  """
157
159
 
160
+ trace_policy = TracePolicy(process_inputs=omit_payload)
161
+ """Omit hook inputs from traces by default; set a `TracePolicy` to override."""
162
+
158
163
  @staticmethod
159
164
  def _is_terminal_stall(response: ModelResponse) -> bool:
160
165
  """Return whether a turn was truncated by the output cap without acting."""
@@ -0,0 +1,21 @@
1
+ """The `DEEPAGENTS_HOME` resolution error, isolated from path capture.
2
+
3
+ `_paths` resolves `DEEPAGENTS_HOME` at import time, so a failure there raises
4
+ while `_paths` itself is still initializing. Any handler that wants to catch it
5
+ therefore cannot import it from `_paths`. This module holds nothing but the
6
+ exception class and runs no code at import, so `__init__` can import it, catch
7
+ the error by type, and print a friendly message instead of a traceback.
8
+
9
+ Keep this module free of imports and side effects.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+
15
+ class DeepAgentsHomeError(ValueError):
16
+ """Raised when the launch-time profile location cannot be resolved.
17
+
18
+ Covers an unsupported `DEEPAGENTS_HOME` value and a launch home that
19
+ cannot be determined or is itself unusable. It is a `ValueError` subclass
20
+ so existing handlers that expect a bad-value error keep working.
21
+ """