deepagents-code 0.1.33__tar.gz → 0.1.35__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 (341) hide show
  1. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/AGENTS.md +3 -3
  2. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/CHANGELOG.md +29 -0
  3. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/COMMANDS.md +1 -1
  4. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/PKG-INFO +3 -2
  5. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/THREAT_MODEL.md +21 -21
  6. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_build_info.py +1 -1
  7. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_env_vars.py +3 -0
  8. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_session_stats.py +86 -3
  9. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_tool_stream.py +42 -4
  10. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_version.py +1 -1
  11. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/app.py +895 -188
  12. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/auth_store.py +41 -6
  13. deepagents_code-0.1.35/deepagents_code/client/__init__.py +1 -0
  14. deepagents_code-0.1.35/deepagents_code/client/commands/__init__.py +1 -0
  15. deepagents_code-0.1.33/deepagents_code/auth_commands.py → deepagents_code-0.1.35/deepagents_code/client/commands/auth.py +7 -4
  16. deepagents_code-0.1.33/deepagents_code/tools_commands.py → deepagents_code-0.1.35/deepagents_code/client/commands/tools.py +10 -2
  17. deepagents_code-0.1.35/deepagents_code/client/launch/__init__.py +1 -0
  18. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/client/launch}/server.py +1 -1
  19. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/client/launch}/server_manager.py +40 -21
  20. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/client}/non_interactive.py +2 -2
  21. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/command_registry.py +1 -1
  22. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/config.py +2 -2
  23. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/config_manifest.py +52 -6
  24. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/input.py +21 -1
  25. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/main.py +61 -20
  26. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/managed_tools.py +116 -15
  27. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_auth.py +193 -1
  28. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_tools.py +3 -1
  29. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/model_config.py +86 -18
  30. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/offload.py +1 -1
  31. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/system_prompt.md +1 -1
  32. deepagents_code-0.1.35/deepagents_code/tui/__init__.py +1 -0
  33. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/textual_adapter.py +36 -80
  34. deepagents_code-0.1.35/deepagents_code/tui/widgets/__init__.py +9 -0
  35. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/agent_selector.py +1 -1
  36. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/approval.py +1 -1
  37. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/auth.py +231 -60
  38. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/chat_input.py +13 -5
  39. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/codex_auth.py +1 -1
  40. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/goal_review.py +1 -1
  41. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/install_confirm.py +4 -4
  42. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/mcp_login.py +2 -2
  43. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/mcp_reconnect.py +1 -1
  44. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/message_store.py +239 -21
  45. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/messages.py +30 -5
  46. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/model_selector.py +8 -8
  47. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/notification_center.py +65 -7
  48. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/restart_prompt.py +35 -12
  49. deepagents_code-0.1.35/deepagents_code/tui/widgets/startup_tip.py +97 -0
  50. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/status.py +1 -1
  51. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/subagent_panel.py +1 -1
  52. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/thread_selector.py +1 -1
  53. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/tool_renderers.py +6 -5
  54. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/tool_widgets.py +21 -3
  55. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/update_available.py +1 -1
  56. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/update_progress.py +3 -4
  57. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/welcome.py +20 -37
  58. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/update_check.py +6 -6
  59. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/pyproject.toml +11 -3
  60. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/scripts/install.sh +523 -28
  61. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +1 -1
  62. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +1 -1
  63. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/test_auto_approve_remote.py +5 -2
  64. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/test_compact_resume.py +2 -2
  65. deepagents_code-0.1.35/tests/unit_tests/client/__init__.py +1 -0
  66. deepagents_code-0.1.35/tests/unit_tests/client/commands/__init__.py +1 -0
  67. deepagents_code-0.1.33/tests/unit_tests/test_auth_commands.py → deepagents_code-0.1.35/tests/unit_tests/client/commands/test_auth.py +24 -1
  68. deepagents_code-0.1.33/tests/unit_tests/test_mcp_commands.py → deepagents_code-0.1.35/tests/unit_tests/client/commands/test_mcp.py +11 -11
  69. deepagents_code-0.1.33/tests/unit_tests/test_tools_commands.py → deepagents_code-0.1.35/tests/unit_tests/client/commands/test_tools.py +17 -1
  70. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/conftest.py +1 -1
  71. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/smoke_tests/snapshots/system_prompt_interactive_local.md +1 -1
  72. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_app.py +1038 -170
  73. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_args.py +5 -5
  74. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_auth_store.py +43 -4
  75. deepagents_code-0.1.35/tests/unit_tests/test_auth_web_search_restart.py +609 -0
  76. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_config_manifest.py +40 -4
  77. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_install_command.py +6 -6
  78. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_install_script.py +1007 -2
  79. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_main.py +29 -2
  80. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_main_args.py +75 -13
  81. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_managed_tools.py +173 -10
  82. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_mcp_auth.py +337 -0
  83. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_mcp_tools.py +33 -0
  84. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_model_config.py +101 -0
  85. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_model_switch.py +3 -3
  86. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_non_interactive.py +239 -215
  87. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_offload.py +5 -5
  88. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_reasoning_effort.py +2 -2
  89. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_reload.py +2 -2
  90. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_remote_client.py +5 -3
  91. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_rubric_cli.py +2 -2
  92. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_server.py +138 -56
  93. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_server_helpers.py +2 -2
  94. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_server_manager.py +99 -29
  95. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_session_stats.py +95 -0
  96. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_skill_invocation.py +3 -3
  97. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_theme.py +28 -28
  98. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_version.py +34 -34
  99. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui}/test_subagent_stream.py +1 -1
  100. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui}/test_textual_adapter.py +101 -319
  101. deepagents_code-0.1.35/tests/unit_tests/tui/widgets/__init__.py +0 -0
  102. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_agent_selector.py +9 -9
  103. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_approval.py +1 -1
  104. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_ask_user.py +4 -3
  105. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_auth_widgets.py +603 -44
  106. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_autocomplete.py +2 -2
  107. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_chat_input.py +5 -5
  108. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_cwd_switch.py +4 -1
  109. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui}/widgets/test_diff.py +1 -1
  110. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_goal_review.py +4 -3
  111. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_history.py +1 -1
  112. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_install_confirm.py +1 -1
  113. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_launch_init.py +1 -1
  114. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_links.py +17 -14
  115. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_loading.py +4 -4
  116. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_mcp_login_modal.py +1 -1
  117. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_mcp_reconnect.py +1 -1
  118. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_mcp_viewer.py +22 -22
  119. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_message_store.py +214 -3
  120. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_messages.py +31 -29
  121. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_model_selector.py +39 -39
  122. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_notification_center.py +52 -3
  123. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_notification_detail.py +1 -1
  124. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_restart_prompt.py +44 -5
  125. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_skill_trust_screen.py +1 -1
  126. deepagents_code-0.1.35/tests/unit_tests/tui/widgets/test_startup_tip.py +89 -0
  127. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_status.py +4 -4
  128. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_subagent_panel.py +1 -1
  129. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_thread_selector.py +56 -56
  130. deepagents_code-0.1.35/tests/unit_tests/tui/widgets/test_tool_renderers.py +102 -0
  131. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_update_available.py +1 -1
  132. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_update_confirm.py +1 -1
  133. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_update_progress.py +1 -1
  134. {deepagents_code-0.1.33/tests/unit_tests → deepagents_code-0.1.35/tests/unit_tests/tui/widgets}/test_welcome.py +32 -9
  135. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/uv.lock +3 -1
  136. deepagents_code-0.1.33/deepagents_code/widgets/__init__.py +0 -9
  137. deepagents_code-0.1.33/tests/unit_tests/test_tool_renderers.py +0 -43
  138. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/.gitignore +0 -0
  139. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/ARCHITECTURE.md +0 -0
  140. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/DEVELOPMENT.md +0 -0
  141. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/Makefile +0 -0
  142. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/README.md +0 -0
  143. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/__init__.py +0 -0
  144. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/__main__.py +0 -0
  145. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_ask_user_types.py +0 -0
  146. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_cli_context.py +0 -0
  147. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_constants.py +0 -0
  148. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_debug.py +0 -0
  149. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_fake_models.py +0 -0
  150. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_git.py +0 -0
  151. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_paths.py +0 -0
  152. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_server_config.py +0 -0
  153. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_startup_error.py +0 -0
  154. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_testing_models.py +0 -0
  155. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/_textual_patches.py +0 -0
  156. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/agent.py +0 -0
  157. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/app.tcss +0 -0
  158. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/approval_mode.py +0 -0
  159. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/ask_user.py +0 -0
  160. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/auth_display.py +0 -0
  161. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/built_in_skills/__init__.py +0 -0
  162. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/built_in_skills/remember/SKILL.md +0 -0
  163. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/built_in_skills/skill-creator/SKILL.md +0 -0
  164. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  165. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  166. /deepagents_code-0.1.33/deepagents_code/config_commands.py → /deepagents_code-0.1.35/deepagents_code/client/commands/config.py +0 -0
  167. /deepagents_code-0.1.33/deepagents_code/mcp_commands.py → /deepagents_code-0.1.35/deepagents_code/client/commands/mcp.py +0 -0
  168. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/client}/remote_client.py +0 -0
  169. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/clipboard.py +0 -0
  170. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/configurable_model.py +0 -0
  171. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/default_agent_prompt.md +0 -0
  172. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/doctor.py +0 -0
  173. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/editor.py +0 -0
  174. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/event_bus.py +0 -0
  175. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/extras_info.py +0 -0
  176. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/file_ops.py +0 -0
  177. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/formatting.py +0 -0
  178. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/goal_rubric.py +0 -0
  179. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/goal_tools.py +0 -0
  180. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/hooks.py +0 -0
  181. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/integrations/__init__.py +0 -0
  182. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/integrations/openai_codex.py +0 -0
  183. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/integrations/sandbox_config.py +0 -0
  184. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/integrations/sandbox_factory.py +0 -0
  185. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/integrations/sandbox_provider.py +0 -0
  186. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/integrations/sandbox_registry.py +0 -0
  187. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/iterm_cursor_guide.py +0 -0
  188. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/local_context.py +0 -0
  189. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_disabled.py +0 -0
  190. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_login_service.py +0 -0
  191. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_oauth_ui.py +0 -0
  192. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_providers/__init__.py +0 -0
  193. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_providers/_registry.py +0 -0
  194. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_providers/base.py +0 -0
  195. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_providers/github.py +0 -0
  196. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_providers/slack.py +0 -0
  197. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/mcp_trust.py +0 -0
  198. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/media_utils.py +0 -0
  199. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/memory_guard.py +0 -0
  200. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/notifications.py +0 -0
  201. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/onboarding.py +0 -0
  202. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/output.py +0 -0
  203. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/paste_collapse.py +0 -0
  204. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/project_utils.py +0 -0
  205. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/py.typed +0 -0
  206. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/reasoning_effort.py +0 -0
  207. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/resume_state.py +0 -0
  208. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/server_graph.py +0 -0
  209. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/sessions.py +0 -0
  210. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/skills/__init__.py +0 -0
  211. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/skills/commands.py +0 -0
  212. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/skills/invocation.py +0 -0
  213. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/skills/load.py +0 -0
  214. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/skills/trust.py +0 -0
  215. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/state_migration.py +0 -0
  216. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/subagents.py +0 -0
  217. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/terminal_capabilities.py +0 -0
  218. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/terminal_escape.py +0 -0
  219. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/theme.py +0 -0
  220. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/tool_catalog.py +0 -0
  221. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/tool_display.py +0 -0
  222. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/tools.py +0 -0
  223. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/_js_eval_display.py +0 -0
  224. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/_links.py +0 -0
  225. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/ask_user.py +0 -0
  226. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/autocomplete.py +0 -0
  227. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/cwd_switch.py +0 -0
  228. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/diff.py +0 -0
  229. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/effort_selector.py +0 -0
  230. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/history.py +0 -0
  231. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/launch_init.py +0 -0
  232. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/loading.py +0 -0
  233. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/mcp_viewer.py +0 -0
  234. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/notification_detail.py +0 -0
  235. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/notification_settings.py +0 -0
  236. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/skill_trust.py +0 -0
  237. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/theme_selector.py +0 -0
  238. {deepagents_code-0.1.33/deepagents_code → deepagents_code-0.1.35/deepagents_code/tui}/widgets/update_confirm.py +0 -0
  239. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/ui.py +0 -0
  240. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/deepagents_code/unicode_security.py +0 -0
  241. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/examples/skills/arxiv-search/SKILL.md +0 -0
  242. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  243. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/examples/skills/langgraph-docs/SKILL.md +0 -0
  244. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/examples/skills/skill-creator/SKILL.md +0 -0
  245. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  246. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  247. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/examples/skills/web-research/SKILL.md +0 -0
  248. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/hatch_build.py +0 -0
  249. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/images/tui.png +0 -0
  250. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/scripts/check_imports.py +0 -0
  251. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/scripts/debug_server.sh +0 -0
  252. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/scripts/generate_commands_catalog.py +0 -0
  253. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/README.md +0 -0
  254. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/__init__.py +0 -0
  255. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/benchmarks/__init__.py +0 -0
  256. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/conftest.py +0 -0
  257. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/test_acp_mode.py +0 -0
  258. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/test_sandbox_factory.py +0 -0
  259. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/integration_tests/test_sandbox_operations.py +0 -0
  260. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/__init__.py +0 -0
  261. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/data/coding_agent_v1_validator.json +0 -0
  262. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/skills/__init__.py +0 -0
  263. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/skills/test_commands.py +0 -0
  264. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/skills/test_load.py +0 -0
  265. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/skills/test_skill_trust.py +0 -0
  266. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/skills/test_skills_json.py +0 -0
  267. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/smoke_tests/__init__.py +0 -0
  268. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/smoke_tests/conftest.py +0 -0
  269. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/smoke_tests/test_system_prompt.py +0 -0
  270. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test__tool_stream.py +0 -0
  271. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_agent.py +0 -0
  272. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_agent_friendly.py +0 -0
  273. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_approval_mode.py +0 -0
  274. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  275. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_auth_display.py +0 -0
  276. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_charset.py +0 -0
  277. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_clipboard.py +0 -0
  278. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_coding_agent_metadata.py +0 -0
  279. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_command_registry.py +0 -0
  280. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_compact_tool.py +0 -0
  281. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_config.py +0 -0
  282. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_configurable_model.py +0 -0
  283. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_cursor_blink.py +0 -0
  284. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_debug.py +0 -0
  285. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_doctor.py +0 -0
  286. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_editor.py +0 -0
  287. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_end_to_end.py +0 -0
  288. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_env_vars.py +0 -0
  289. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_event_bus.py +0 -0
  290. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_exception_handling.py +0 -0
  291. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_extras_info.py +0 -0
  292. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_file_ops.py +0 -0
  293. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_formatting.py +0 -0
  294. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_git.py +0 -0
  295. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_goal_rubric.py +0 -0
  296. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_goal_tools.py +0 -0
  297. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_hatch_build.py +0 -0
  298. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_hooks.py +0 -0
  299. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_imports.py +0 -0
  300. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_input_parsing.py +0 -0
  301. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  302. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_local_context.py +0 -0
  303. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_main_acp_mode.py +0 -0
  304. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_mcp_disabled.py +0 -0
  305. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_mcp_login_service.py +0 -0
  306. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_mcp_oauth_ui.py +0 -0
  307. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_mcp_trust.py +0 -0
  308. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_media_utils.py +0 -0
  309. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_memory_guard.py +0 -0
  310. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_notifications.py +0 -0
  311. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  312. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_onboarding.py +0 -0
  313. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_openai_codex_integration.py +0 -0
  314. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_output.py +0 -0
  315. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_paths.py +0 -0
  316. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_resume_state.py +0 -0
  317. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_sandbox_config.py +0 -0
  318. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_sandbox_factory.py +0 -0
  319. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_sandbox_provider.py +0 -0
  320. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_sandbox_registry.py +0 -0
  321. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_server_config.py +0 -0
  322. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_server_graph.py +0 -0
  323. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_sessions.py +0 -0
  324. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_shell_allow_list.py +0 -0
  325. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_startup_fast_paths.py +0 -0
  326. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_state_migration.py +0 -0
  327. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_subagents.py +0 -0
  328. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  329. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_terminal_escape.py +0 -0
  330. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_terminal_progress_preference.py +0 -0
  331. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_textual_patches.py +0 -0
  332. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_tool_catalog.py +0 -0
  333. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_tool_display.py +0 -0
  334. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_tracing_replicas.py +0 -0
  335. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_ui.py +0 -0
  336. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_unicode_security.py +0 -0
  337. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/test_update_check.py +0 -0
  338. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/tools/__init__.py +0 -0
  339. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/tools/test_current_thread.py +0 -0
  340. {deepagents_code-0.1.33 → deepagents_code-0.1.35}/tests/unit_tests/tools/test_fetch_url.py +0 -0
  341. {deepagents_code-0.1.33/tests/unit_tests/widgets → deepagents_code-0.1.35/tests/unit_tests/tui}/__init__.py +0 -0
@@ -43,7 +43,7 @@ Textual's `App.notify(message)` parses the message string as Rich markup by defa
43
43
  Charset-dependent characters and animations have **single sources of truth**. Reuse them instead of hand-rolling new ones — copies drift, and (more subtly) a hardcoded Unicode literal won't degrade to ASCII on terminals that need it.
44
44
 
45
45
  - **Glyphs** (checkmarks, arrows, ellipsis, cursor, box-drawing, branch icon, etc.): pull from `get_glyphs()` (`config.Glyphs`). Each glyph has a Unicode and an ASCII variant; `get_glyphs()` returns the right set for the active terminal. Never inline `"✓"`, `"…"`, `"›"`, and friends.
46
- - **Animated spinners**: reuse the `Spinner` class in `widgets/loading.py`, which wraps `get_glyphs().spinner_frames` (braille on Unicode, `(-) (\) (|) (/)` on ASCII) and exposes `next_frame()`/`current_frame()`. Do **not** define your own frame tuples or interval constants for a spinner — drive a `Spinner` on a `set_interval`. The status-bar reconnect indicator (`widgets/status.py`) is the reference example; it ticks at the same 0.1s cadence as `LoadingWidget`. All connection/queue progress lives in the status bar — the welcome banner deliberately stays out of it, so there are currently no bespoke spinners to carve an exception for.
46
+ - **Animated spinners**: reuse the `Spinner` class in `tui/widgets/loading.py`, which wraps `get_glyphs().spinner_frames` (braille on Unicode, `(-) (\) (|) (/)` on ASCII) and exposes `next_frame()`/`current_frame()`. Do **not** define your own frame tuples or interval constants for a spinner — drive a `Spinner` on a `set_interval`. The status-bar reconnect indicator (`tui/widgets/status.py`) is the reference example; it ticks at the same 0.1s cadence as `LoadingWidget`. All connection/queue progress lives in the status bar — the welcome banner deliberately stays out of it, so there are currently no bespoke spinners to carve an exception for.
47
47
 
48
48
  ### Textual patterns used in this codebase
49
49
 
@@ -99,7 +99,7 @@ The `deepagents-code --help` screen is hand-maintained in `ui.show_help()`, sepa
99
99
 
100
100
  ## Splash screen tips
101
101
 
102
- When adding a user-facing CLI feature (new slash command, keybinding, workflow), add a corresponding tip to the `_TIPS` list in `deepagents_code/widgets/welcome.py`. Tips are shown randomly on startup to help users discover features. Keep tips short and action-oriented (e.g., `"Press ctrl+x to compose prompts in your external editor"`).
102
+ When adding a user-facing CLI feature (new slash command, keybinding, workflow), add a corresponding entry to the `_TIPS` dict in `deepagents_code/tui/widgets/startup_tip.py`, mapping the tip text to a relative selection weight (higher = shown more often). One tip is chosen at random above the input on startup to help users discover features. Keep tips short and action-oriented (e.g., `"Press ctrl+x to compose prompts in your external editor"`).
103
103
 
104
104
  ## Slash commands
105
105
 
@@ -115,7 +115,7 @@ To add a new slash command: (1) add a `SlashCommand` entry to `COMMANDS`, (2) se
115
115
  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
116
116
  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
117
117
  4. `deepagents_code/model_config.py` — add `"provider_name"` to `RETRY_PARAM_BY_PROVIDER` if the provider's chat model accepts `max_retries`
118
- 5. `deepagents_code/widgets/auth.py` — add `"provider_name": "Display Name"` to `PROVIDER_DISPLAY_NAMES` so the `/auth` UI shows a branded label instead of the title-cased key, and (if the provider issues API keys from a self-serve page) `"provider_name": "https://…"` to `PROVIDER_API_KEY_URLS` so the prompt links straight to the key page
118
+ 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
119
119
  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
120
120
 
121
121
  ### `PROVIDER_BASE_URL_ENV` guidelines
@@ -2,6 +2,35 @@
2
2
 
3
3
  # Deep Agents Code Changelog
4
4
 
5
+ ## [0.1.35](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.34...deepagents-code==0.1.35) (2026-07-09)
6
+
7
+ ### Features
8
+
9
+ * Restore interrupted prompt to input on ESC ([#4544](https://github.com/langchain-ai/deepagents/issues/4544)) ([fccf037](https://github.com/langchain-ai/deepagents/commit/fccf03732140d39749e70e8fc6cb7d73124a1d70))
10
+ * Add `[startup].mode` default approval mode ([#4573](https://github.com/langchain-ai/deepagents/issues/4573)) ([7c5bf54](https://github.com/langchain-ai/deepagents/commit/7c5bf542c2f58fa46ecd708c66cd1817a0ebdc41))
11
+ * Offer restart after saving Tavily key via `/auth` ([#4560](https://github.com/langchain-ai/deepagents/issues/4560)) ([12df81a](https://github.com/langchain-ai/deepagents/commit/12df81ad00d814c570b4d24a2b06de9b18d51abd))
12
+ * Reload env from `/auth` modal via Ctrl+R ([#4566](https://github.com/langchain-ai/deepagents/issues/4566)) ([f07d638](https://github.com/langchain-ai/deepagents/commit/f07d6387b7dc1f0e880f77784905c2aa94143adb))
13
+ * Toast on saved `/auth` API key ([#4558](https://github.com/langchain-ai/deepagents/issues/4558)) ([ee3c264](https://github.com/langchain-ai/deepagents/commit/ee3c26415be84e369b829fefb21461c8ec210a5e))
14
+
15
+ ### Bug Fixes
16
+
17
+ * Harden approval content rendering ([#4581](https://github.com/langchain-ai/deepagents/issues/4581)) ([38446fd](https://github.com/langchain-ai/deepagents/commit/38446fda649b891dd8604e788701eabe739c1dd0))
18
+ * Preserve transcript order during virtualization ([#4549](https://github.com/langchain-ai/deepagents/issues/4549)) ([f6ee70c](https://github.com/langchain-ai/deepagents/commit/f6ee70c00ac6ad7b1b180155018b794308a18361))
19
+ * Run stdio MCP server pre-flight check off the event loop ([#4434](https://github.com/langchain-ai/deepagents/issues/4434)) ([c9636e2](https://github.com/langchain-ai/deepagents/commit/c9636e22725a5bd32c1f8b9e739b02b4aa7c3dc7))
20
+ * Avoid duplicate "criteria ready" message on `/goal` revisions ([#4559](https://github.com/langchain-ai/deepagents/issues/4559)) ([1110497](https://github.com/langchain-ai/deepagents/commit/1110497e17fac6deceb9d1d6e530f9197bfc0d4a))
21
+ * Restore welcome banner tips ([#4528](https://github.com/langchain-ai/deepagents/issues/4528)) ([3f1e55e](https://github.com/langchain-ai/deepagents/commit/3f1e55eafbc1fde79cb75f631561cf35d4b8ff4c))
22
+ * Clarify managed `rg` install failures ([#4578](https://github.com/langchain-ai/deepagents/issues/4578)) ([434c84a](https://github.com/langchain-ai/deepagents/commit/434c84ae144b0319afe37d6f2dbadfd7f5fc9f70))
23
+ * Dedupe update/install log path output ([#4553](https://github.com/langchain-ai/deepagents/issues/4553)) ([1398fee](https://github.com/langchain-ai/deepagents/commit/1398feeca507cab9ec51a66604d46c747f7fcd2f))
24
+ * Keep notification center open for API-key entry ([#4568](https://github.com/langchain-ai/deepagents/issues/4568)) ([6e89417](https://github.com/langchain-ai/deepagents/commit/6e8941776cdcc35909da305f3bb39500c0f479cb))
25
+ * Queue `/mcp login` sent before the server connects ([#4533](https://github.com/langchain-ai/deepagents/issues/4533)) ([edac82c](https://github.com/langchain-ai/deepagents/commit/edac82c837de8e12b58b97ac25acc31f743d4c5d))
26
+ * Serialize MCP OAuth token refreshes to prevent reuse revocation ([#4565](https://github.com/langchain-ai/deepagents/issues/4565)) ([c37100d](https://github.com/langchain-ai/deepagents/commit/c37100d4763e527fce12fa4451794ca25ded7640))
27
+
28
+ ## [0.1.34](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.33...deepagents-code==0.1.34) (2026-07-07)
29
+
30
+ ### Bug Fixes
31
+
32
+ * **code:** show `(local)` tag under ANSI themes ([#4534](https://github.com/langchain-ai/deepagents/issues/4534)) ([699e439](https://github.com/langchain-ai/deepagents/commit/699e439699723e477a621f95eef87a7d76aac5f5))
33
+
5
34
  ## [0.1.33](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.32...deepagents-code==0.1.33) (2026-07-06)
6
35
 
7
36
  ### Features
@@ -29,7 +29,7 @@ aliases, descriptions, visibility, or hidden-command metadata.
29
29
  | `/mcp` | | Manage MCP servers and authentication |
30
30
  | `/model` | | Switch models or edit model settings |
31
31
  | `/notifications` | | Configure startup warnings |
32
- | `/offload` | `/compact` | Offload older messages to free context |
32
+ | `/offload` | `/compact` | Summarize and offload older messages to free context |
33
33
  | `/quit` | `/q` | Exit app |
34
34
  | `/reload` | | Reload environment and config |
35
35
  | `/remember` | | Save useful context to memory or skills |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-code
3
- Version: 0.1.33
3
+ Version: 0.1.35
4
4
  Summary: Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities.
5
5
  Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
6
6
  Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
@@ -27,7 +27,8 @@ Classifier: Topic :: Terminals
27
27
  Requires-Python: <4.0,>=3.11
28
28
  Requires-Dist: aiosqlite<1.0.0,>=0.22.1
29
29
  Requires-Dist: deepagents-acp<1.0.0,>=0.0.8
30
- Requires-Dist: deepagents==0.7.0a4
30
+ Requires-Dist: deepagents==0.7.0a6
31
+ Requires-Dist: filelock<4.0.0,>=3.12
31
32
  Requires-Dist: httpx<1.0.0,>=0.28.1
32
33
  Requires-Dist: langchain-anthropic<2.0.0,>=1.4.7
33
34
  Requires-Dist: langchain-google-genai<5.0.0,>=4.2.7
@@ -12,8 +12,8 @@
12
12
 
13
13
  - `deepagents_code/` — all Python source modules shipped as the `deepagents-code` package
14
14
  - CLI entry point (`main.py`, `__init__.py`)
15
- - Interactive TUI (`app.py`, `textual_adapter.py`, `widgets/`)
16
- - Non-interactive pipeline runner (`non_interactive.py`)
15
+ - Interactive TUI (`app.py`, `tui/textual_adapter.py`, `tui/widgets/`)
16
+ - Non-interactive pipeline runner (`client/non_interactive.py`)
17
17
  - Agent creation (`agent.py`)
18
18
  - Built-in tools (`tools.py`: `http_request`, `web_search`, `fetch_url`)
19
19
  - MCP config loader and trust store (`mcp_tools.py`, `mcp_trust.py`)
@@ -22,8 +22,8 @@
22
22
  - Session persistence (`sessions.py`)
23
23
  - Configuration system (`config.py`, `model_config.py`)
24
24
  - Unicode/URL safety helpers (`unicode_security.py`)
25
- - LangGraph dev server subprocess management (`server.py`, `server_manager.py`, `server_graph.py`)
26
- - Remote agent client (`remote_client.py`)
25
+ - LangGraph dev server subprocess management (`client/launch/server.py`, `client/launch/server_manager.py`, `server_graph.py`)
26
+ - Remote agent client (`client/remote_client.py`)
27
27
  - Local context middleware (`local_context.py`)
28
28
  - Custom subagent loader (`subagents.py`, `agent.py:load_async_subagents`)
29
29
  - Conversation offload (`offload.py`)
@@ -47,7 +47,7 @@
47
47
  3. `~/.deepagents/` is only writable by the authenticated local user — no multi-user shared home directories.
48
48
  4. Sandbox backends are trusted third-party services. CLI responsibility ends at correctly constructing and dispatching requests to them.
49
49
  5. LangSmith tracing, if enabled, is user-opted-in via environment variables.
50
- 6. The LangGraph dev server subprocess binds to `127.0.0.1` by default (`server.py:_DEFAULT_HOST`) and is ephemeral — started and stopped per CLI session.
50
+ 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.
51
51
  7. `DA_SERVER_*` environment variables are readable only by the CLI process and its child server subprocess (OS process isolation assumption).
52
52
  8. Users who set `class_path` in `config.toml` accept the same trust model as `pyproject.toml` build scripts — they control their own machine.
53
53
 
@@ -68,19 +68,19 @@
68
68
  │ ┌────────────────┼─────────────────────┐ │
69
69
  │ ▼ ▼ ▼ │
70
70
  │ C2: TUI (app.py) C2b: Non-interactive C13: Config Channel │
71
- │ │ (non_interactive.py) (DA_SERVER_* env vars)│
71
+ │ │ (client/non_interactive.py) (DA_SERVER_* vars)
72
72
  │ - - - - - - - - - - TB8: CLI / Server IPC - - - - - │ - - - - - - - │
73
73
  │ │ ▼ │
74
- │ │ C11: Server Manager (server_manager)
74
+ │ │ C11: Server Manager (client/launch)
75
75
  │ │ │ spawns │
76
76
  │ │ ▼ │
77
77
  │ │ C11b: LangGraph Dev Server │
78
- │ │ (server.py:ServerProcess)
78
+ │ │ (client/launch/server.py:ServerProcess)
79
79
  │ │ LANGGRAPH_AUTH_TYPE=noop │
80
80
  │ - - - - - - - - │ - - - - - TB10: RemoteAgent / Dev Server - - - - │
81
81
  │ │ ▲ │
82
82
  │ └─►C12: RemoteAgent────┘ (HTTP+SSE on 127.0.0.1) │
83
- │ (remote_client.py)
83
+ │ (client/remote_client.py)
84
84
  │ │ │
85
85
  │ C3: Agent Engine (server_graph.py) │
86
86
  │ (create_cli_agent, deepagents SDK) │
@@ -122,7 +122,7 @@
122
122
  | ID | Component | Description | Trust Level | Default? | Entry Points |
123
123
  |-----|-----------------------------|---------------------------------------------------------------------------------------------------------------------|----------------------|----------|---------------------------------------------------------------------------------------------------|
124
124
  | C1 | CLI Entry Point | Parses argv, loads config/env, bootstraps session | framework-controlled | Yes | `main.cli_main`, `main.parse_args` |
125
- | C2 | TUI / Non-interactive | Textual UI for interactive chat; `non_interactive.py` for headless pipelines (both use `RemoteAgent`) | framework-controlled | Yes | `app.DeepAgentsApp.run`, `non_interactive.run_non_interactive` |
125
+ | C2 | TUI / Non-interactive | Textual UI for interactive chat; `client/non_interactive.py` for headless pipelines (both use `RemoteAgent`) | framework-controlled | Yes | `app.DeepAgentsApp.run`, `client.non_interactive.run_non_interactive` |
126
126
  | C3 | Agent Engine | LangGraph agent graph running inside `langgraph dev` server, assembled by `create_cli_agent` | framework-controlled | Yes | `agent.create_cli_agent`, `agent._add_interrupt_on`, `server_graph.make_graph` |
127
127
  | C4 | Built-in Tools | `http_request`, `web_search` (Tavily), `fetch_url` (HTML→markdown) | framework-controlled | Partial¹ | `tools.http_request`, `tools.web_search`, `tools.fetch_url` |
128
128
  | C5 | MCP Loader & Trust | Discovers/loads `.mcp.json`, validates server configs, manages trust store | framework-controlled | No² | `mcp_tools.resolve_and_load_mcp_tools`, `mcp_trust.compute_config_fingerprint` |
@@ -131,8 +131,8 @@
131
131
  | C8 | Session Persistence | SQLite checkpoint store for LangGraph thread state | framework-controlled | Yes | `sessions.get_db_path`, `sessions.generate_thread_id` |
132
132
  | C9 | Configuration System | TOML config, env vars, `AGENTS.md` system prompts, model config | user-controlled | N/A | `config.settings`, `model_config.ModelConfig`, `~/.deepagents/config.toml` |
133
133
  | C10 | Unicode/URL Safety | Detects hidden Unicode, checks URL domain spoofing for approval UI warnings | framework-controlled | Yes | `unicode_security.detect_dangerous_unicode`, `unicode_security.check_url_safety` |
134
- | C11 | LangGraph Dev Server | Subprocess running `langgraph dev` with `LANGGRAPH_AUTH_TYPE=noop`; managed by `ServerProcess` | framework-controlled | Yes⁵ | `server.ServerProcess.start`, `server.generate_langgraph_json`, `server_manager.start_server_and_get_agent` |
135
- | C12 | Remote Agent Client | HTTP+SSE client wrapping `RemoteGraph`; connects to C11 on localhost | framework-controlled | Yes⁵ | `remote_client.RemoteAgent.astream`, `remote_client.RemoteAgent.aget_state` |
134
+ | C11 | LangGraph Dev Server | Subprocess running `langgraph dev` with `LANGGRAPH_AUTH_TYPE=noop`; managed by `ServerProcess` | framework-controlled | Yes⁵ | `client.launch.server.ServerProcess.start`, `client.launch.server.generate_langgraph_json`, `client.launch.server_manager.start_server_and_get_agent` |
135
+ | C12 | Remote Agent Client | HTTP+SSE client wrapping `RemoteGraph`; connects to C11 on localhost | framework-controlled | Yes⁵ | `client.remote_client.RemoteAgent.astream`, `client.remote_client.RemoteAgent.aget_state` |
136
136
  | C13 | Server Config Channel | Passes CLI config to server subprocess via `DA_SERVER_*` environment variables | framework-controlled | Yes | `_server_config.ServerConfig.to_env`, `_server_config.ServerConfig.from_env` |
137
137
  | C14 | Async Subagent Config | Loads remote LangGraph deployment specs from `[async_subagents]` in `config.toml` | user-controlled | No | `agent.load_async_subagents` |
138
138
  | C15 | LocalContext Middleware | Runs a bash detection script via backend; injects git/project/env context into system prompt each turn | framework-controlled | Yes⁶ | `local_context.LocalContextMiddleware.before_agent`, `local_context.build_detect_script` |
@@ -164,7 +164,7 @@
164
164
  #### DC1: API Keys / Credentials
165
165
 
166
166
  - **Fields**: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `TAVILY_API_KEY`, `LANGSMITH_API_KEY`, `LANGGRAPH_API_KEY`, and any provider-specific keys in the user's environment.
167
- - **Storage**: Loaded from environment at process start (`config.py`). The CLI explicitly strips `LANGGRAPH_CLOUD_LICENSE_KEY` and related auth vars from the server subprocess environment (`server.py:_build_server_env`) but passes the remaining env vars (including provider API keys) to the server subprocess via `os.environ.copy()`.
167
+ - **Storage**: Loaded from environment at process start (`config.py`). The CLI explicitly strips `LANGGRAPH_CLOUD_LICENSE_KEY` and related auth vars from the server subprocess environment (`client/launch/server.py:_build_server_env`) but passes the remaining env vars (including provider API keys) to the server subprocess via `os.environ.copy()`.
168
168
  - **Access**: Available to both the CLI process and the server subprocess (which inherits the full environment minus stripped vars).
169
169
  - **Encryption**: Not encrypted — in-memory process environment only.
170
170
  - **Retention**: Process lifetime; cleared on CLI exit.
@@ -206,20 +206,20 @@
206
206
  | TB7 | External LLM API → Agent State | LLM API responses drive tool call decisions | LLM client configuration, model selection, request params | LLM output content; provider-side safety |
207
207
  | TB8 | CLI → Server Subprocess IPC | Config passed from CLI to `langgraph dev` subprocess via `DA_SERVER_*` env vars | `ServerConfig.to_env()` serialization; env var scoping to parent+child process | Subprocess environment post-fork; /proc visibility to same-uid processes |
208
208
  | TB9 | LocalContextMiddleware → Host Env | Bash detect script output (git info, project files, Makefile) injected into system prompt | Script is framework-generated static code; 30s timeout; exit-code check | Content of Makefile, pyproject.toml, git branch names, directory listing |
209
- | TB10 | RemoteAgent → LangGraph Dev Server | CLI communicates with agent via HTTP+SSE on localhost | Server bound to `127.0.0.1` (`server.py:_DEFAULT_HOST`); ephemeral per session | No authentication (`LANGGRAPH_AUTH_TYPE=noop`); any localhost process can reach the API |
209
+ | TB10 | RemoteAgent → LangGraph Dev Server | CLI communicates with agent via HTTP+SSE on localhost | Server bound to `127.0.0.1` (`client/launch/server.py:_DEFAULT_HOST`); ephemeral per session | No authentication (`LANGGRAPH_AUTH_TYPE=noop`); any localhost process can reach the API |
210
210
  | 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 |
211
211
 
212
212
  ### Boundary Details
213
213
 
214
214
  #### TB1: User Input → Agent Engine
215
215
 
216
- - **Inside**: `app.DeepAgentsApp` routes keystrokes to message queue; `non_interactive.run_non_interactive` reads from stdin/argv. Both paths now go through `RemoteAgent.astream` to the server. Session ID assigned per thread (`sessions.generate_thread_id`).
216
+ - **Inside**: `app.DeepAgentsApp` routes keystrokes to message queue; `client.non_interactive.run_non_interactive` reads from stdin/argv. Both paths now go through `RemoteAgent.astream` to the server. Session ID assigned per thread (`sessions.generate_thread_id`).
217
217
  - **Outside**: Prompt content — the agent accepts any text the user types. No content filtering at this layer (HITL handles downstream tool calls, not prompt intent).
218
- - **Crossing mechanism**: HTTP POST to `127.0.0.1:{port}` via `remote_client.RemoteAgent.astream`.
218
+ - **Crossing mechanism**: HTTP POST to `127.0.0.1:{port}` via `client.remote_client.RemoteAgent.astream`.
219
219
 
220
220
  #### TB2: LLM Decision → Tool Execution Gate (HITL)
221
221
 
222
- - **Inside**: `agent._add_interrupt_on` registers interrupt configs for `execute`, `write_file`, `edit_file`, `web_search`, `fetch_url`, `task`, `compact_conversation`, `launch_async_subagent`, `update_async_subagent`, `cancel_async_subagent`. In non-interactive mode, `non_interactive._handle_action_request` enforces the shell allow-list via `config.is_shell_command_allowed`.
222
+ - **Inside**: `agent._add_interrupt_on` registers interrupt configs for `execute`, `write_file`, `edit_file`, `web_search`, `fetch_url`, `task`, `compact_conversation`, `launch_async_subagent`, `update_async_subagent`, `cancel_async_subagent`. In non-interactive mode, `client.non_interactive._handle_action_request` enforces the shell allow-list via `config.is_shell_command_allowed`.
223
223
  - **Outside**: Once the user clicks "approve" (interactive) or a command passes the allow-list check (non-interactive), the tool executes with no further framework-level gating.
224
224
  - **Crossing mechanism**: LangGraph HITL interrupt routed through `RemoteAgent` SSE stream.
225
225
  - **Key note**: `auto_approve` mode bypasses all HITL approval prompts while still displaying Unicode/URL warnings.
@@ -238,7 +238,7 @@
238
238
 
239
239
  #### TB8: CLI → Server Subprocess IPC
240
240
 
241
- - **Inside**: `ServerConfig.to_env()` serializes all config (model, assistant_id, system_prompt, sandbox settings, cwd, MCP config path, shell-enable flags) to `DA_SERVER_*` env vars. `server_manager._apply_server_config` writes these to `os.environ` before `subprocess.Popen`. `server.py:_build_server_env` strips cloud auth vars (`LANGGRAPH_CLOUD_LICENSE_KEY`, `LANGSMITH_CONTROL_PLANE_API_KEY`, `LANGSMITH_TENANT_ID`, `LANGGRAPH_AUTH`).
241
+ - **Inside**: `ServerConfig.to_env()` serializes all config (model, assistant_id, system_prompt, sandbox settings, cwd, MCP config path, shell-enable flags) to `DA_SERVER_*` env vars. `client.launch.server_manager._apply_server_config` writes these to `os.environ` before `subprocess.Popen`. `client/launch/server.py:_build_server_env` strips cloud auth vars (`LANGGRAPH_CLOUD_LICENSE_KEY`, `LANGSMITH_CONTROL_PLANE_API_KEY`, `LANGSMITH_TENANT_ID`, `LANGGRAPH_AUTH`).
242
242
  - **Outside**: The full parent environment including provider API keys flows to the child via `os.environ.copy()`. The system prompt string becomes `DA_SERVER_SYSTEM_PROMPT`. After process start, the env is fixed — no runtime mutation across processes.
243
243
  - **Crossing mechanism**: `subprocess.Popen` env kwarg; subsequent `os.environ` reads in `_server_config.ServerConfig.from_env`.
244
244
 
@@ -250,7 +250,7 @@
250
250
 
251
251
  #### TB10: RemoteAgent → LangGraph Dev Server
252
252
 
253
- - **Inside**: Server bound to `127.0.0.1` by default; `server.py:_DEFAULT_HOST = "127.0.0.1"`. `RemoteAgent` only connects to the URL returned by `ServerProcess.url`. Server is ephemeral — started at session start, stopped at session end. Binds a free ephemeral port by default (`server.py:_EPHEMERAL_PORT`); an explicit port is honored but still falls back to a free port if occupied.
253
+ - **Inside**: Server bound to `127.0.0.1` by default; `client/launch/server.py:_DEFAULT_HOST = "127.0.0.1"`. `RemoteAgent` only connects to the URL returned by `ServerProcess.url`. Server is ephemeral — started at session start, stopped at session end. Binds a free ephemeral port by default (`client/launch/server.py:_EPHEMERAL_PORT`); an explicit port is honored but still falls back to a free port if occupied.
254
254
  - **Outside**: `LANGGRAPH_AUTH_TYPE=noop` disables all LangGraph server authentication. Any process on localhost that discovers the port can submit requests, read thread state, or inject messages.
255
255
  - **Crossing mechanism**: HTTP POST/GET to `http://127.0.0.1:{port}` using `langgraph.pregel.remote.RemoteGraph`.
256
256
 
@@ -339,7 +339,7 @@
339
339
  | ID | Data Flow | Classification | Threat | Boundary | Severity | Validation | Code Reference |
340
340
  |-----|-----------|----------------|---------------------------------------------------------------------------------------------|----------|----------|------------|------------------------------------------------------------------------|
341
341
  | T1 | DF8, DF9 | — | Prompt injection via fetched web content causes LLM to request harmful actions | TB3 | Medium | Likely | `tools.fetch_url`, `agent._add_interrupt_on` |
342
- | T2 | DF7 | — | `--shell-allow-list all` removes pattern checks; LLM-injected shell commands execute without approval in non-interactive mode | TB2 | Medium | Verified | `config.is_shell_command_allowed`, `non_interactive._handle_action_request` |
342
+ | T2 | DF7 | — | `--shell-allow-list all` removes pattern checks; LLM-injected shell commands execute without approval in non-interactive mode | TB2 | Medium | Verified | `config.is_shell_command_allowed`, `client.non_interactive._handle_action_request` |
343
343
  | T3 | DF7 | — | Unicode-homoglyph URL in LLM-generated tool args deceives user during approval | TB2 | Low | Disproven | `unicode_security.check_url_safety`, `agent._format_fetch_url_description` |
344
344
  | T4 | DF5, DF9 | — | Auto-approve mode bypasses all HITL gates; any LLM-initiated tool call executes | TB2 | Low | Verified | `agent.create_cli_agent` (`auto_approve` param), `agent._add_interrupt_on` |
345
345
  | T5 | DF13, DF14| DC2 | Local SQLite checkpoint file tampered with to inject adversarial content into future LLM context | None | Low | Unverified | `sessions.get_db_path` |
@@ -385,7 +385,7 @@
385
385
  #### T6: Unauthenticated LangGraph Dev Server on Localhost
386
386
 
387
387
  - **Flow**: DF3/DF4 (CLI ↔ LangGraph dev server)
388
- - **Description**: The CLI spawns a `langgraph dev` server subprocess with `LANGGRAPH_AUTH_TYPE=noop` (`server.py:_build_server_env`). This disables all server-side authentication. The server binds to `127.0.0.1:{port}` (a free ephemeral port by default, so it no longer squats the well-known `langgraph dev` port 2024). Any local process that discovers the port can: send arbitrary inputs to the running agent thread, read the agent's conversation state (including tool results that may contain file contents or secrets), inject messages into the conversation history, or trigger state updates. The server is ephemeral — it lives only for the duration of the CLI session — but this is the entire attack window. Port discovery is feasible via localhost port scanning or by reading `/proc/{pid}/cmdline` which contains the `--port` argument.
388
+ - **Description**: The CLI spawns a `langgraph dev` server subprocess with `LANGGRAPH_AUTH_TYPE=noop` (`client/launch/server.py:_build_server_env`). This disables all server-side authentication. The server binds to `127.0.0.1:{port}` (a free ephemeral port by default, so it no longer squats the well-known `langgraph dev` port 2024). Any local process that discovers the port can: send arbitrary inputs to the running agent thread, read the agent's conversation state (including tool results that may contain file contents or secrets), inject messages into the conversation history, or trigger state updates. The server is ephemeral — it lives only for the duration of the CLI session — but this is the entire attack window. Port discovery is feasible via localhost port scanning or by reading `/proc/{pid}/cmdline` which contains the `--port` argument.
389
389
  - **Preconditions**: (1) Attacker has a local process running as the same user (or as root); (2) Attacker discovers the server port (port scan on localhost, or reads process arguments).
390
390
 
391
391
  #### T7: LocalContextMiddleware Injects Host File Contents into System Prompt
@@ -1,3 +1,3 @@
1
1
  """Generated at build time. Do not edit or commit."""
2
2
 
3
- BUILD_COMMIT = "0199007"
3
+ BUILD_COMMIT = "09daab5"
@@ -156,6 +156,9 @@ HIDE_GIT_BRANCH = "DEEPAGENTS_CODE_HIDE_GIT_BRANCH"
156
156
  HIDE_LANGSMITH_TRACING = "DEEPAGENTS_CODE_HIDE_LANGSMITH_TRACING"
157
157
  """Hide LangSmith tracing project/thread info in the startup splash when enabled."""
158
158
 
159
+ HIDE_SPLASH_TIPS = "DEEPAGENTS_CODE_HIDE_SPLASH_TIPS"
160
+ """Hide the startup tip shown above the chat input when enabled."""
161
+
159
162
  HIDE_SPLASH_VERSION = "DEEPAGENTS_CODE_HIDE_SPLASH_VERSION"
160
163
  """Hide version and local-install details in the splash screen when enabled."""
161
164
 
@@ -1,6 +1,8 @@
1
- """Lightweight session statistics and token formatting utilities.
1
+ """Lightweight session statistics, token formatting, and usage-table rendering.
2
2
 
3
- This module is intentionally kept free of heavy dependencies (no pydantic, no
3
+ Holds `SessionStats`/`ModelStats`, the `format_token_count` formatter, and
4
+ `print_usage_table` (which imports `rich.table` lazily). The module is
5
+ intentionally kept free of heavy top-level dependencies (no pydantic, no
4
6
  config, no widget imports) so that `app.py` can import `SessionStats` and
5
7
  `format_token_count` at module level without pulling in the full
6
8
  `textual_adapter` dependency tree.
@@ -9,7 +11,12 @@ config, no widget imports) so that `app.py` can import `SessionStats` and
9
11
  from __future__ import annotations
10
12
 
11
13
  from dataclasses import dataclass, field
12
- from typing import Literal
14
+ from typing import TYPE_CHECKING, Literal
15
+
16
+ from deepagents_code.formatting import format_duration
17
+
18
+ if TYPE_CHECKING:
19
+ from rich.console import Console
13
20
 
14
21
  SpinnerStatus = (
15
22
  Literal[
@@ -150,3 +157,79 @@ def format_token_count(count: int) -> str:
150
157
  if count >= 1000: # noqa: PLR2004
151
158
  return f"{count / 1000:.1f}K"
152
159
  return str(count)
160
+
161
+
162
+ def print_usage_table(
163
+ stats: SessionStats,
164
+ wall_time: float,
165
+ console: Console,
166
+ ) -> None:
167
+ """Print a model-usage stats table to a Rich console.
168
+
169
+ Each row shows the serving provider alongside the model name. When the
170
+ session spans multiple models each gets its own row with a totals row
171
+ appended; single-model sessions show one row.
172
+
173
+ Args:
174
+ stats: Cumulative session stats.
175
+ wall_time: Total wall-clock time in seconds.
176
+ console: Rich console for output.
177
+ """
178
+ from rich.table import Table
179
+
180
+ has_time = wall_time >= 0.1 # noqa: PLR2004
181
+ if not (stats.request_count or stats.input_tokens or has_time):
182
+ return
183
+
184
+ if stats.per_model:
185
+ multi_model = len(stats.per_model) > 1
186
+
187
+ table = Table(
188
+ show_header=True,
189
+ header_style="bold",
190
+ box=None,
191
+ padding=(0, 2, 0, 0),
192
+ show_edge=False,
193
+ )
194
+ table.add_column("Provider", style="dim")
195
+ table.add_column("Model", style="dim")
196
+ table.add_column("Reqs", justify="right", style="dim")
197
+ table.add_column("InputTok", justify="right", style="dim")
198
+ table.add_column("OutputTok", justify="right", style="dim")
199
+
200
+ if multi_model:
201
+ for ms in stats.per_model.values():
202
+ table.add_row(
203
+ ms.provider,
204
+ ms.model_name,
205
+ str(ms.request_count),
206
+ format_token_count(ms.input_tokens),
207
+ format_token_count(ms.output_tokens),
208
+ )
209
+ table.add_row(
210
+ "",
211
+ "Total",
212
+ str(stats.request_count),
213
+ format_token_count(stats.input_tokens),
214
+ format_token_count(stats.output_tokens),
215
+ )
216
+ else:
217
+ ms = next(iter(stats.per_model.values()))
218
+ table.add_row(
219
+ ms.provider,
220
+ ms.model_name,
221
+ str(stats.request_count),
222
+ format_token_count(stats.input_tokens),
223
+ format_token_count(stats.output_tokens),
224
+ )
225
+
226
+ console.print()
227
+ console.print("[bold]Usage Stats[/bold]")
228
+ console.print(table)
229
+ if has_time:
230
+ console.print()
231
+ console.print(
232
+ f"Agent active {format_duration(wall_time)}",
233
+ style="dim",
234
+ highlight=False,
235
+ )
@@ -3,8 +3,8 @@
3
3
  Both execution surfaces reassemble the same streamed tool-call state and fire
4
4
  the same `tool.use` / `tool.result` / `tool.error` hook payloads:
5
5
 
6
- - the interactive Textual TUI (`deepagents_code.textual_adapter`), and
7
- - the headless runner (`deepagents_code.non_interactive`).
6
+ - the interactive Textual TUI (`deepagents_code.tui.textual_adapter`), and
7
+ - the headless runner (`deepagents_code.client.non_interactive`).
8
8
 
9
9
  This module holds the single implementation of the buffering, argument parsing,
10
10
  and payload-shape logic, so the two surfaces cannot drift *in those layers*. The
@@ -102,6 +102,7 @@ from __future__ import annotations
102
102
 
103
103
  import json
104
104
  import logging
105
+ import sys
105
106
  from dataclasses import dataclass, field
106
107
  from typing import TYPE_CHECKING, Any, Literal, NamedTuple, TypedDict
107
108
 
@@ -146,6 +147,9 @@ Lets both surfaces keep the terminal `tool.result` dispatch unconditional
146
147
  without re-touching the offending content (whose `__str__`/`__repr__` may itself
147
148
  raise), so a hook consumer still sees the result rather than a dropped event."""
148
149
 
150
+ MAX_JSON_CONTAINER_DEPTH = sys.getrecursionlimit()
151
+ """Maximum JSON container nesting accepted for streamed tool-call args."""
152
+
149
153
 
150
154
  def normalize_tool_status(raw_status: object, tool_name: str) -> ToolStatus:
151
155
  """Map a raw `ToolMessage.status` to the two-value hook domain, fail-closed.
@@ -247,6 +251,31 @@ def tool_call_buffer_key(
247
251
  return f"unknown-{count}"
248
252
 
249
253
 
254
+ def _exceeds_json_container_depth(s: str) -> bool:
255
+ """Return whether `s` exceeds the safe nesting depth for JSON args."""
256
+ depth = 0
257
+ in_string = False
258
+ escaped = False
259
+ for ch in s:
260
+ if in_string:
261
+ if escaped:
262
+ escaped = False
263
+ elif ch == "\\":
264
+ escaped = True
265
+ elif ch == '"':
266
+ in_string = False
267
+ continue
268
+ if ch == '"':
269
+ in_string = True
270
+ elif ch in "{[":
271
+ depth += 1
272
+ if depth > MAX_JSON_CONTAINER_DEPTH:
273
+ return True
274
+ elif ch in "}]":
275
+ depth -= 1
276
+ return False
277
+
278
+
250
279
  def _looks_structurally_complete(s: str) -> bool:
251
280
  """Return whether `s` is a balanced JSON container, string-state aware.
252
281
 
@@ -493,8 +522,17 @@ class ToolCallBuffer:
493
522
  # this method. Real provider arg streams are pure JSON, so this shape
494
523
  # does not occur in practice; if such a call still executes, its
495
524
  # `tool.result` logs the correlation miss.
496
- if stripped[0] in "{[" and not stripped.endswith(("}", "]")):
497
- return None
525
+ if stripped[0] in "{[":
526
+ if not stripped.endswith(("}", "]")):
527
+ return None
528
+ if _exceeds_json_container_depth(stripped):
529
+ if not self.warned:
530
+ self.warned = True
531
+ logger.warning(
532
+ "Tool-call args look complete but failed to parse: %r",
533
+ joined[:200],
534
+ )
535
+ return None
498
536
  try:
499
537
  parsed = json.loads(joined)
500
538
  except (json.JSONDecodeError, RecursionError):
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Keep the `x-release-please-version` annotation — release-please uses it to
4
4
  # bump `__version__` in sync with `pyproject.toml` on every release PR.
5
- __version__ = "0.1.33" # x-release-please-version
5
+ __version__ = "0.1.35" # x-release-please-version
6
6
 
7
7
  DOCS_URL = "https://docs.langchain.com/oss/python/deepagents/code"
8
8
  """URL for `deepagents-code` documentation."""