deepagents-cli 0.0.56__tar.gz → 0.0.58__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 (299) hide show
  1. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/CHANGELOG.md +16 -0
  2. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/PKG-INFO +6 -6
  3. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/THREAT_MODEL.md +2 -1
  4. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_env_vars.py +3 -0
  5. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_version.py +1 -1
  6. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/app.py +69 -83
  7. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/integrations/sandbox_factory.py +1 -1
  8. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/local_context.py +1 -0
  9. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/remote_client.py +18 -2
  10. deepagents_cli-0.0.58/deepagents_cli/terminal_escape.py +287 -0
  11. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/textual_adapter.py +10 -1
  12. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/theme_selector.py +17 -1
  13. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/pyproject.toml +6 -6
  14. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/test_compact_resume.py +14 -35
  15. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_app.py +281 -36
  16. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_offload.py +16 -24
  17. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_offload_dict_messages.py +3 -4
  18. deepagents_cli-0.0.58/tests/unit_tests/test_terminal_escape.py +377 -0
  19. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_theme.py +145 -0
  20. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_token_tracker.py +25 -0
  21. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/uv.lock +127 -52
  22. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/.gitignore +0 -0
  23. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/DEV.md +0 -0
  24. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/Makefile +0 -0
  25. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/README.md +0 -0
  26. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/__init__.py +0 -0
  27. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/__main__.py +0 -0
  28. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_ask_user_types.py +0 -0
  29. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_cli_context.py +0 -0
  30. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_constants.py +0 -0
  31. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_debug.py +0 -0
  32. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_git.py +0 -0
  33. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_server_config.py +0 -0
  34. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_session_stats.py +0 -0
  35. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_testing_models.py +0 -0
  36. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/_textual_patches.py +0 -0
  37. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/agent.py +0 -0
  38. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/app.tcss +0 -0
  39. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/ask_user.py +0 -0
  40. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/auth_store.py +0 -0
  41. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/built_in_skills/__init__.py +0 -0
  42. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/built_in_skills/remember/SKILL.md +0 -0
  43. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/built_in_skills/skill-creator/SKILL.md +0 -0
  44. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  45. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  46. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/clipboard.py +0 -0
  47. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/command_registry.py +0 -0
  48. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/config.py +0 -0
  49. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/configurable_model.py +0 -0
  50. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/default_agent_prompt.md +0 -0
  51. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/__init__.py +0 -0
  52. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/bundler.py +0 -0
  53. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/commands.py +0 -0
  54. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/config.py +0 -0
  55. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/context_hub.py +0 -0
  56. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/frontend_dist/assets/anonymous-B9UzAXQd.js +0 -0
  57. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/frontend_dist/assets/clerk-5xHgyQyG.js +0 -0
  58. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/frontend_dist/assets/highlighted-body-OFNGDK62-rX-7qT8o.js +0 -0
  59. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/frontend_dist/assets/index-DM3gptpu.js +0 -0
  60. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/frontend_dist/assets/index-Ddy7F6KI.css +0 -0
  61. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/frontend_dist/assets/supabase-S6NACDgm.js +0 -0
  62. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/frontend_dist/index.html +0 -0
  63. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/frontend_dist/logo-dark.svg +0 -0
  64. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/frontend_dist/logo-light.svg +0 -0
  65. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/deploy/templates.py +0 -0
  66. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/editor.py +0 -0
  67. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/event_bus.py +0 -0
  68. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/extras_info.py +0 -0
  69. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/file_ops.py +0 -0
  70. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/formatting.py +0 -0
  71. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/hooks.py +0 -0
  72. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/input.py +0 -0
  73. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/integrations/__init__.py +0 -0
  74. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/integrations/sandbox_provider.py +0 -0
  75. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/iterm_cursor_guide.py +0 -0
  76. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/main.py +0 -0
  77. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/mcp_auth.py +0 -0
  78. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/mcp_commands.py +0 -0
  79. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/mcp_providers/__init__.py +0 -0
  80. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/mcp_providers/_registry.py +0 -0
  81. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/mcp_providers/base.py +0 -0
  82. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/mcp_providers/github.py +0 -0
  83. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/mcp_providers/slack.py +0 -0
  84. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/mcp_tools.py +0 -0
  85. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/mcp_trust.py +0 -0
  86. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/media_utils.py +0 -0
  87. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/model_config.py +0 -0
  88. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/non_interactive.py +0 -0
  89. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/notifications.py +0 -0
  90. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/offload.py +0 -0
  91. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/onboarding.py +0 -0
  92. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/output.py +0 -0
  93. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/project_utils.py +0 -0
  94. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/py.typed +0 -0
  95. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/server.py +0 -0
  96. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/server_graph.py +0 -0
  97. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/server_manager.py +0 -0
  98. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/sessions.py +0 -0
  99. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/skills/__init__.py +0 -0
  100. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/skills/commands.py +0 -0
  101. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/skills/invocation.py +0 -0
  102. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/skills/load.py +0 -0
  103. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/state_migration.py +0 -0
  104. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/subagents.py +0 -0
  105. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/system_prompt.md +0 -0
  106. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/terminal_capabilities.py +0 -0
  107. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/theme.py +0 -0
  108. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/token_state.py +0 -0
  109. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/tool_display.py +0 -0
  110. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/tools.py +0 -0
  111. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/ui.py +0 -0
  112. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/unicode_security.py +0 -0
  113. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/update_check.py +0 -0
  114. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/__init__.py +0 -0
  115. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/_links.py +0 -0
  116. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/agent_selector.py +0 -0
  117. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/approval.py +0 -0
  118. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/ask_user.py +0 -0
  119. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/auth.py +0 -0
  120. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/autocomplete.py +0 -0
  121. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/chat_input.py +0 -0
  122. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/diff.py +0 -0
  123. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/history.py +0 -0
  124. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/launch_init.py +0 -0
  125. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/loading.py +0 -0
  126. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/mcp_viewer.py +0 -0
  127. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/message_store.py +0 -0
  128. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/messages.py +0 -0
  129. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/model_selector.py +0 -0
  130. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/notification_center.py +0 -0
  131. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/notification_detail.py +0 -0
  132. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/notification_settings.py +0 -0
  133. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/status.py +0 -0
  134. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/thread_selector.py +0 -0
  135. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/tool_renderers.py +0 -0
  136. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/tool_widgets.py +0 -0
  137. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/update_available.py +0 -0
  138. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/update_progress.py +0 -0
  139. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/deepagents_cli/widgets/welcome.py +0 -0
  140. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/deploy-content-writer/.env.example +0 -0
  141. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/deploy-content-writer/skills/blog-post/SKILL.md +0 -0
  142. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/deploy-content-writer/skills/social-media/SKILL.md +0 -0
  143. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/deploy-content-writer/user/context.md +0 -0
  144. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/deploy-content-writer/user/preferences.md +0 -0
  145. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/skills/arxiv-search/SKILL.md +0 -0
  146. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  147. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/skills/langgraph-docs/SKILL.md +0 -0
  148. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/skills/skill-creator/SKILL.md +0 -0
  149. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  150. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  151. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/examples/skills/web-research/SKILL.md +0 -0
  152. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/.nvmrc +0 -0
  153. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/index.html +0 -0
  154. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/package-lock.json +0 -0
  155. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/package.json +0 -0
  156. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/postcss.config.js +0 -0
  157. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/public/logo-dark.svg +0 -0
  158. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/public/logo-light.svg +0 -0
  159. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/App.tsx +0 -0
  160. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/ThemeProvider.tsx +0 -0
  161. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/auth/anonymous.tsx +0 -0
  162. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/auth/clerk.tsx +0 -0
  163. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/auth/loader.tsx +0 -0
  164. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/auth/supabase.tsx +0 -0
  165. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/auth/types.ts +0 -0
  166. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/AppHeader.tsx +0 -0
  167. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/FilePanels.tsx +0 -0
  168. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/MessageList.tsx +0 -0
  169. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/SubagentActivity.tsx +0 -0
  170. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/ThreadPicker.tsx +0 -0
  171. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/TodosPanel.tsx +0 -0
  172. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/ToolCallCard.tsx +0 -0
  173. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/toolcalls/FileToolCard.tsx +0 -0
  174. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/toolcalls/SearchCard.tsx +0 -0
  175. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/toolcalls/ThinkCard.tsx +0 -0
  176. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/toolcalls/TodosCard.tsx +0 -0
  177. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/components/toolcalls/index.ts +0 -0
  178. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/constants.ts +0 -0
  179. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/index.css +0 -0
  180. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/main.tsx +0 -0
  181. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/runtimeConfig.ts +0 -0
  182. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/types.ts +0 -0
  183. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/src/vite-env.d.ts +0 -0
  184. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/tsconfig.json +0 -0
  185. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/frontend/vite.config.ts +0 -0
  186. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/images/cli.png +0 -0
  187. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/scripts/check_imports.py +0 -0
  188. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/scripts/debug_server.sh +0 -0
  189. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/scripts/install.sh +0 -0
  190. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/README.md +0 -0
  191. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/__init__.py +0 -0
  192. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/benchmarks/__init__.py +0 -0
  193. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  194. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  195. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/conftest.py +0 -0
  196. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/test_acp_mode.py +0 -0
  197. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/test_context_hub.py +0 -0
  198. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/test_deploy_hub.py +0 -0
  199. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/test_sandbox_factory.py +0 -0
  200. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/integration_tests/test_sandbox_operations.py +0 -0
  201. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/__init__.py +0 -0
  202. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/conftest.py +0 -0
  203. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/deploy/__init__.py +0 -0
  204. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/deploy/test_bundler.py +0 -0
  205. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/deploy/test_commands.py +0 -0
  206. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/deploy/test_config.py +0 -0
  207. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/deploy/test_context_hub.py +0 -0
  208. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/deploy/test_frontend_bundle.py +0 -0
  209. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/deploy/test_frontend_config.py +0 -0
  210. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/skills/__init__.py +0 -0
  211. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/skills/test_commands.py +0 -0
  212. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/skills/test_load.py +0 -0
  213. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/skills/test_skills_json.py +0 -0
  214. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_agent.py +0 -0
  215. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_agent_friendly.py +0 -0
  216. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_agent_selector.py +0 -0
  217. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_approval.py +0 -0
  218. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_args.py +0 -0
  219. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_ask_user.py +0 -0
  220. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  221. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_auth_store.py +0 -0
  222. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_auth_widgets.py +0 -0
  223. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_autocomplete.py +0 -0
  224. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_charset.py +0 -0
  225. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_chat_input.py +0 -0
  226. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_clipboard.py +0 -0
  227. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_command_registry.py +0 -0
  228. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_compact_tool.py +0 -0
  229. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_config.py +0 -0
  230. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_configurable_model.py +0 -0
  231. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_debug.py +0 -0
  232. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_editor.py +0 -0
  233. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_end_to_end.py +0 -0
  234. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_env_vars.py +0 -0
  235. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_event_bus.py +0 -0
  236. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_exception_handling.py +0 -0
  237. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_extras_info.py +0 -0
  238. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_file_ops.py +0 -0
  239. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_formatting.py +0 -0
  240. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_git.py +0 -0
  241. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_history.py +0 -0
  242. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_hooks.py +0 -0
  243. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_imports.py +0 -0
  244. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_input_parsing.py +0 -0
  245. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  246. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_launch_init.py +0 -0
  247. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_links.py +0 -0
  248. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_loading.py +0 -0
  249. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_local_context.py +0 -0
  250. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_main.py +0 -0
  251. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_main_acp_mode.py +0 -0
  252. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_main_args.py +0 -0
  253. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_mcp_auth.py +0 -0
  254. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_mcp_commands.py +0 -0
  255. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_mcp_tools.py +0 -0
  256. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_mcp_trust.py +0 -0
  257. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_mcp_viewer.py +0 -0
  258. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_media_utils.py +0 -0
  259. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_message_store.py +0 -0
  260. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_messages.py +0 -0
  261. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_model_config.py +0 -0
  262. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_model_selector.py +0 -0
  263. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_model_switch.py +0 -0
  264. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_non_interactive.py +0 -0
  265. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_notification_center.py +0 -0
  266. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_notification_detail.py +0 -0
  267. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_notifications.py +0 -0
  268. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_onboarding.py +0 -0
  269. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_output.py +0 -0
  270. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_reload.py +0 -0
  271. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_remote_client.py +0 -0
  272. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_sandbox_factory.py +0 -0
  273. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_server.py +0 -0
  274. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_server_config.py +0 -0
  275. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_server_graph.py +0 -0
  276. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_server_helpers.py +0 -0
  277. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_server_manager.py +0 -0
  278. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_session_stats.py +0 -0
  279. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_sessions.py +0 -0
  280. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_shell_allow_list.py +0 -0
  281. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_skill_invocation.py +0 -0
  282. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_startup_fast_paths.py +0 -0
  283. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_state_migration.py +0 -0
  284. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_status.py +0 -0
  285. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_subagents.py +0 -0
  286. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  287. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_textual_adapter.py +0 -0
  288. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_textual_patches.py +0 -0
  289. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_thread_selector.py +0 -0
  290. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_tool_display.py +0 -0
  291. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_ui.py +0 -0
  292. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_unicode_security.py +0 -0
  293. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_update_available.py +0 -0
  294. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_update_check.py +0 -0
  295. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_update_progress.py +0 -0
  296. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_version.py +0 -0
  297. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/test_welcome.py +0 -0
  298. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/tools/__init__.py +0 -0
  299. {deepagents_cli-0.0.56 → deepagents_cli-0.0.58}/tests/unit_tests/tools/test_fetch_url.py +0 -0
@@ -1,5 +1,21 @@
1
1
  # Deep Agents CLI Changelog
2
2
 
3
+ ## [0.0.58](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.57...deepagents-cli==0.0.58) (2026-05-12)
4
+
5
+ ### Features
6
+
7
+ * Pin v0.6 and fix import race ([4db09ac](https://github.com/langchain-ai/deepagents/commit/4db09acba34b38521192b8f278723524be560779))
8
+
9
+ ## [0.0.57](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.56...deepagents-cli==0.0.57) (2026-05-12)
10
+
11
+ ### Features
12
+
13
+ * OSC 9;4 progress & escape helper ([#3347](https://github.com/langchain-ai/deepagents/issues/3347)) ([75d60cd](https://github.com/langchain-ai/deepagents/commit/75d60cd82f559b2944b78a348d16b0a10a00d663))
14
+
15
+ ### Bug Fixes
16
+
17
+ * Suppress LangSmith trace for `_context_tokens` state writes ([#3317](https://github.com/langchain-ai/deepagents/issues/3317)) ([63db13e](https://github.com/langchain-ai/deepagents/commit/63db13ee262d19a1a87fbe4df1271a2e958deed6))
18
+
3
19
  ## [0.0.56](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.55...deepagents-cli==0.0.56) (2026-05-11)
4
20
 
5
21
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-cli
3
- Version: 0.0.56
3
+ Version: 0.0.58
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,18 +27,18 @@ Classifier: Topic :: Terminals
27
27
  Requires-Python: <4.0,>=3.11
28
28
  Requires-Dist: aiosqlite<1.0.0,>=0.19.0
29
29
  Requires-Dist: deepagents-acp>=0.0.4
30
- Requires-Dist: deepagents==0.5.9
30
+ Requires-Dist: deepagents==0.6.1
31
31
  Requires-Dist: httpx<1.0.0,>=0.28.1
32
32
  Requires-Dist: langchain-anthropic<2.0.0,>=1.4.3
33
33
  Requires-Dist: langchain-google-genai<5.0.0,>=4.2.2
34
34
  Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.2.2
35
35
  Requires-Dist: langchain-openai<2.0.0,>=1.2.1
36
- Requires-Dist: langchain<2.0.0,>=1.2.17
37
- Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.0.3
36
+ Requires-Dist: langchain<2.0.0,>=1.3.0
37
+ Requires-Dist: langgraph-checkpoint-sqlite<4.0.0,>=3.1.0
38
38
  Requires-Dist: langgraph-cli[inmem]<1.0.0,>=0.4.24
39
- Requires-Dist: langgraph-prebuilt<2.0.0,>=1.0.13
39
+ Requires-Dist: langgraph-runtime-inmem<1.0.0,>=0.28.1
40
40
  Requires-Dist: langgraph-sdk<1.0.0,>=0.3.13
41
- Requires-Dist: langgraph<2.0.0,>=1.1.10
41
+ Requires-Dist: langgraph<2.0.0,>=1.2.0
42
42
  Requires-Dist: langsmith[sandbox]>=0.8.0
43
43
  Requires-Dist: markdownify<2.0.0,>=0.13.0
44
44
  Requires-Dist: packaging>=23.0
@@ -57,7 +57,7 @@
57
57
 
58
58
  ### Architecture Diagram
59
59
 
60
- ```
60
+ ```txt
61
61
  ┌──────────────────────────────────────────────────────────────────────┐
62
62
  │ User (local machine) │
63
63
  │ │
@@ -138,6 +138,7 @@
138
138
  | C17 | Model Config Loader | Resolves model provider, supports `class_path` for arbitrary `BaseChatModel` instantiation via `importlib` | user-controlled | N/A | `config.create_model`, `config._create_model_from_class`, `model_config.ModelConfig.load` |
139
139
 
140
140
  **Notes:**
141
+
141
142
  1. `http_request` and `fetch_url` enabled by default; `web_search` requires `TAVILY_API_KEY`.
142
143
  2. MCP servers only load if `.mcp.json` config files are present.
143
144
  3. Hooks only execute if `~/.deepagents/hooks.json` exists.
@@ -110,6 +110,9 @@ KITTY_KEYBOARD = "DEEPAGENTS_CLI_KITTY_KEYBOARD"
110
110
  LANGSMITH_PROJECT = "DEEPAGENTS_CLI_LANGSMITH_PROJECT"
111
111
  """Override LangSmith project name for agent traces."""
112
112
 
113
+ NO_TERMINAL_ESCAPE = "DEEPAGENTS_CLI_NO_TERMINAL_ESCAPE"
114
+ """Disable all terminal escape/control sequence output when enabled."""
115
+
113
116
  NO_UPDATE_CHECK = "DEEPAGENTS_CLI_NO_UPDATE_CHECK"
114
117
  """Disable automatic update checking when set."""
115
118
 
@@ -1,6 +1,6 @@
1
1
  """Version information and lightweight constants for `deepagents-cli`."""
2
2
 
3
- __version__ = "0.0.56" # x-release-please-version
3
+ __version__ = "0.0.58" # x-release-please-version
4
4
 
5
5
  DOCS_URL = "https://docs.langchain.com/oss/python/deepagents/cli"
6
6
  """URL for `deepagents-cli` documentation."""
@@ -1151,6 +1151,7 @@ class DeepAgentsApp(App):
1151
1151
  Loaded from the user's saved preference (or the default) so the app
1152
1152
  boots with consistent colors before `/theme` runs.
1153
1153
  """
1154
+ self.sync_terminal_background()
1154
1155
 
1155
1156
  # Injected session config
1156
1157
  self._agent = agent
@@ -1590,7 +1591,7 @@ class DeepAgentsApp(App):
1590
1591
  - The agent is a local `Pregel` graph (e.g. ACP mode, test harnesses).
1591
1592
 
1592
1593
  Used to gate features that require a server-backed agent (e.g. model
1593
- switching via `ConfigurableModelMiddleware`, checkpointer fallback).
1594
+ switching via `ConfigurableModelMiddleware`, thread registration).
1594
1595
  Checks the agent type rather than server ownership so this works for
1595
1596
  both CLI-spawned servers and externally managed ones.
1596
1597
 
@@ -3290,19 +3291,61 @@ class DeepAgentsApp(App):
3290
3291
 
3291
3292
  return children[-1] == self._loading_widget
3292
3293
 
3294
+ def sync_terminal_background(self) -> None:
3295
+ """Best-effort sync of terminal default background to the active theme.
3296
+
3297
+ Custom themes use their stored registry colors; built-in Textual themes
3298
+ resolve colors from the active app theme. Terminal write failures are
3299
+ logged and swallowed because the OSC background sync is cosmetic.
3300
+ """
3301
+ from deepagents_cli.terminal_escape import set_terminal_background
3302
+
3303
+ entry = theme.get_registry().get(self.theme)
3304
+ colors = (
3305
+ entry.colors
3306
+ if entry is not None and entry.custom
3307
+ else theme.get_theme_colors(self)
3308
+ )
3309
+ try:
3310
+ set_terminal_background(colors.background)
3311
+ except Exception:
3312
+ # Cosmetic only: must never break app startup or theme changes.
3313
+ logger.warning("set_terminal_background raised unexpectedly", exc_info=True)
3314
+
3293
3315
  async def _set_spinner(self, status: SpinnerStatus) -> None:
3294
3316
  """Show, update, or hide the loading spinner.
3295
3317
 
3318
+ Also drives the terminal's `OSC 9;4` progress indicator, when
3319
+ supported, so taskbar / dock / tab badges reflect agent activity while
3320
+ the user is in another window.
3321
+
3296
3322
  Args:
3297
3323
  status: The spinner status to display, or `None` to hide.
3298
3324
  """
3325
+ from deepagents_cli.terminal_escape import (
3326
+ TerminalProgressState,
3327
+ clear_terminal_progress,
3328
+ set_terminal_progress,
3329
+ )
3330
+
3299
3331
  if status is None:
3300
3332
  # Hide
3301
3333
  if self._loading_widget:
3302
3334
  await self._loading_widget.remove()
3303
3335
  self._loading_widget = None
3336
+ try:
3337
+ clear_terminal_progress()
3338
+ except Exception:
3339
+ # Cosmetic only — must never break spinner lifecycle.
3340
+ logger.exception("clear_terminal_progress raised unexpectedly")
3304
3341
  return
3305
3342
 
3343
+ try:
3344
+ set_terminal_progress(state=TerminalProgressState.INDETERMINATE)
3345
+ except Exception:
3346
+ # Cosmetic only — must never break spinner lifecycle.
3347
+ logger.exception("set_terminal_progress raised unexpectedly")
3348
+
3306
3349
  try:
3307
3350
  messages = self.query_one("#messages", Container)
3308
3351
  except NoMatches:
@@ -5443,9 +5486,6 @@ class DeepAgentsApp(App):
5443
5486
  if result.offload_warning:
5444
5487
  await self._mount_message(ErrorMessage(result.offload_warning))
5445
5488
 
5446
- if remote := self._remote_agent():
5447
- await remote.aensure_thread(config) # ty: ignore[invalid-argument-type]
5448
-
5449
5489
  await self._agent.aupdate_state(
5450
5490
  config, {"_summarization_event": result.new_event}
5451
5491
  )
@@ -5792,12 +5832,14 @@ class DeepAgentsApp(App):
5792
5832
  return result
5793
5833
 
5794
5834
  async def _get_thread_state_values(self, thread_id: str) -> dict[str, Any]:
5795
- """Fetch thread state values, with remote checkpointer fallback.
5835
+ """Fetch thread state values for a thread.
5796
5836
 
5797
- In server mode the LangGraph dev server can report an empty thread state
5798
- after a restart even when checkpoints exist on disk. When that happens,
5799
- read the latest checkpoint directly so resumed threads can still load
5800
- history and offload correctly.
5837
+ In server mode the LangGraph dev server starts with an empty in-memory
5838
+ thread store, so `aget_state` returns empty state for any thread that
5839
+ was not registered in the current server session. Calling
5840
+ `aensure_thread` first registers the thread idempotently so the
5841
+ subsequent `aget_state` call can read from the checkpointer correctly,
5842
+ including proper reconstruction of delta channels.
5801
5843
 
5802
5844
  Args:
5803
5845
  thread_id: Thread ID to fetch from checkpoint storage.
@@ -5810,46 +5852,20 @@ class DeepAgentsApp(App):
5810
5852
  return {}
5811
5853
 
5812
5854
  config: RunnableConfig = {"configurable": {"thread_id": thread_id}}
5813
- state = await self._agent.aget_state(config)
5855
+ remote_config: dict[str, Any] = {"configurable": {"thread_id": thread_id}}
5814
5856
 
5815
- values: dict[str, Any] = {}
5816
- if state and state.values:
5817
- values = dict(state.values)
5857
+ if remote := self._remote_agent():
5858
+ await remote.aensure_thread(remote_config)
5818
5859
 
5819
- messages = values.get("messages")
5820
- if isinstance(messages, list) and messages:
5821
- return values
5822
- if not self._remote_agent():
5823
- return values
5860
+ state = await self._agent.aget_state(config)
5824
5861
 
5825
- logger.debug(
5826
- "Remote state empty for thread %s; falling back to local checkpointer",
5827
- thread_id,
5828
- )
5829
- fallback_values = await self._read_channel_values_from_checkpointer(thread_id)
5830
- fallback_messages = fallback_values.get("messages")
5831
- if isinstance(fallback_messages, list) and fallback_messages:
5832
- values["messages"] = fallback_messages
5833
- if (
5834
- values.get("_summarization_event") is None
5835
- and "_summarization_event" in fallback_values
5836
- ):
5837
- values["_summarization_event"] = fallback_values["_summarization_event"]
5838
- if (
5839
- values.get("_context_tokens") is None
5840
- and "_context_tokens" in fallback_values
5841
- ):
5842
- values["_context_tokens"] = fallback_values["_context_tokens"]
5843
- return values
5862
+ if state and state.values:
5863
+ return dict(state.values)
5864
+ return {}
5844
5865
 
5845
5866
  async def _fetch_thread_history_data(self, thread_id: str) -> _ThreadHistoryPayload:
5846
5867
  """Fetch and convert stored messages for a thread.
5847
5868
 
5848
- In server mode the LangGraph dev server starts with an empty thread
5849
- store, so `aget_state` via the HTTP API returns no messages even when
5850
- checkpoints exist on disk. We fall back to reading the SQLite
5851
- checkpointer directly to guarantee resumed threads load their history.
5852
-
5853
5869
  Args:
5854
5870
  thread_id: Thread ID to fetch from checkpoint storage.
5855
5871
 
@@ -5867,10 +5883,8 @@ class DeepAgentsApp(App):
5867
5883
  if not messages:
5868
5884
  return _ThreadHistoryPayload([], context_tokens)
5869
5885
 
5870
- # Server mode / direct checkpointer may return dicts; convert to
5886
+ # RemoteGraph.aget_state returns values as raw JSON dicts; convert to
5871
5887
  # LangChain message objects so _convert_messages_to_data works.
5872
- # `any(...)` guards against heterogeneous lists where only some
5873
- # elements are serialized.
5874
5888
  if any(isinstance(m, dict) for m in messages):
5875
5889
  from langchain_core.messages.utils import convert_to_messages
5876
5890
 
@@ -5880,44 +5894,6 @@ class DeepAgentsApp(App):
5880
5894
  data = await asyncio.to_thread(self._convert_messages_to_data, messages)
5881
5895
  return _ThreadHistoryPayload(data, context_tokens)
5882
5896
 
5883
- @staticmethod
5884
- async def _read_channel_values_from_checkpointer(thread_id: str) -> dict[str, Any]:
5885
- """Read checkpoint channel values directly from the SQLite checkpointer.
5886
-
5887
- Args:
5888
- thread_id: Thread ID to look up.
5889
-
5890
- Returns:
5891
- Channel values from the latest checkpoint, or an empty dict on
5892
- failure.
5893
- """
5894
- try:
5895
- from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
5896
-
5897
- from deepagents_cli.sessions import get_db_path
5898
-
5899
- db_path = str(get_db_path())
5900
- config: RunnableConfig = {"configurable": {"thread_id": thread_id}}
5901
- async with AsyncSqliteSaver.from_conn_string(db_path) as saver:
5902
- tup = await saver.aget_tuple(config)
5903
- if tup and tup.checkpoint:
5904
- channel_values = tup.checkpoint.get("channel_values", {})
5905
- if isinstance(channel_values, dict):
5906
- return dict(channel_values)
5907
- except (ImportError, OSError) as exc:
5908
- logger.warning(
5909
- "Failed to read checkpointer directly for %s: %s",
5910
- thread_id,
5911
- exc,
5912
- )
5913
- except Exception:
5914
- logger.warning(
5915
- "Unexpected error reading checkpointer for %s",
5916
- thread_id,
5917
- exc_info=True,
5918
- )
5919
- return {}
5920
-
5921
5897
  async def _upgrade_thread_message_link(
5922
5898
  self,
5923
5899
  widget: AppMessage,
@@ -6582,6 +6558,15 @@ class DeepAgentsApp(App):
6582
6558
  ).encode()
6583
6559
  _dispatch_hook_sync("session.end", payload, hooks)
6584
6560
 
6561
+ from deepagents_cli.terminal_escape import reset_terminal_background
6562
+
6563
+ try:
6564
+ reset_terminal_background()
6565
+ except Exception:
6566
+ # Cosmetic only: must never raise during shutdown.
6567
+ logger.warning(
6568
+ "reset_terminal_background raised unexpectedly", exc_info=True
6569
+ )
6585
6570
  restore_iterm_cursor_guide()
6586
6571
  super().exit(result=result, return_code=return_code, message=message)
6587
6572
 
@@ -6986,6 +6971,7 @@ class DeepAgentsApp(App):
6986
6971
  """Handle the theme selector result."""
6987
6972
  if result is not None:
6988
6973
  self.theme = result
6974
+ self.sync_terminal_background()
6989
6975
  self.refresh_css(animate=False)
6990
6976
 
6991
6977
  async def _persist() -> None:
@@ -710,7 +710,7 @@ class _AgentCoreProvider(SandboxProvider):
710
710
 
711
711
  # Validate AWS credentials early for a clear error message.
712
712
  try:
713
- import boto3 # ty: ignore[unresolved-import, unused-ignore-comment]
713
+ import boto3 # ty: ignore[unresolved-import]
714
714
 
715
715
  session = boto3.Session()
716
716
  credentials = session.get_credentials()
@@ -104,6 +104,7 @@ class _AsyncExecutableBackend(Protocol):
104
104
 
105
105
  logger = logging.getLogger(__name__)
106
106
 
107
+
107
108
  # ---------------------------------------------------------------------------
108
109
  # Context detection script
109
110
  #
@@ -183,7 +183,8 @@ class RemoteAgent:
183
183
  ) -> Any: # noqa: ANN401
184
184
  """Get the current state of a thread.
185
185
 
186
- Returns `None` when the thread does not exist on the server (404).
186
+ Returns `None` when the thread does not exist on the server (404) or
187
+ when the thread exists but has no checkpoint yet (new/empty thread).
187
188
  All other errors (network, auth, 500) are logged at WARNING and
188
189
  re-raised so callers can handle them.
189
190
 
@@ -196,10 +197,11 @@ class RemoteAgent:
196
197
 
197
198
  Returns:
198
199
  Thread state object with `values` and `next` attributes, or `None`
199
- if the thread is not found.
200
+ if the thread is not found or has no checkpoint.
200
201
 
201
202
  Raises:
202
203
  ValueError: If `thread_id` is not present in `config`.
204
+ TypeError: If the server returns an unexpected state shape.
203
205
  """ # noqa: DOC502 — raised by _require_thread_id
204
206
  from langgraph_sdk.errors import NotFoundError
205
207
 
@@ -211,6 +213,20 @@ class RemoteAgent:
211
213
  except NotFoundError:
212
214
  logger.debug("Thread %s not found on server", thread_id)
213
215
  return None
216
+ except TypeError as e:
217
+ # langgraph SDK bug: _create_state_snapshot does
218
+ # state["checkpoint"]["thread_id"], but the server returns
219
+ # checkpoint=null for threads with no checkpoint yet (new threads,
220
+ # or threads registered via aensure_thread before any run).
221
+ if "subscriptable" in str(e).lower():
222
+ logger.debug(
223
+ "Thread %s has no checkpoint yet; treating as empty", thread_id
224
+ )
225
+ return None
226
+ logger.warning(
227
+ "Failed to get state for thread %s", thread_id, exc_info=True
228
+ )
229
+ raise
214
230
  except Exception:
215
231
  logger.warning(
216
232
  "Failed to get state for thread %s", thread_id, exc_info=True
@@ -0,0 +1,287 @@
1
+ """Best-effort writer for terminal escape/control sequences.
2
+
3
+ Centralizes the "fire and forget" pattern the CLI uses for cosmetic terminal
4
+ control (OSC 9;4 taskbar progress today; eventually OSC 52 clipboard and the
5
+ iTerm2 cursor guide). Writes prefer `/dev/tty` so output reaches the terminal
6
+ even when stdout/stderr are redirected, fall back to `sys.__stderr__`, and
7
+ never raise — cosmetic control output must not crash the app.
8
+
9
+ Set `DEEPAGENTS_CLI_NO_TERMINAL_ESCAPE=1` to disable all output (useful for
10
+ unsupported terminals or noisy logs).
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import atexit
16
+ import logging
17
+ import pathlib
18
+ import sys
19
+ import threading
20
+ from enum import StrEnum
21
+ from typing import TYPE_CHECKING
22
+
23
+ from deepagents_cli._env_vars import NO_TERMINAL_ESCAPE, is_env_truthy
24
+
25
+ if TYPE_CHECKING:
26
+ from typing import TextIO
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+ _PROGRESS_MIN = 0
31
+ """Lower clamp bound for determinate `OSC 9;4` progress percentages."""
32
+
33
+ _PROGRESS_MAX = 100
34
+ """Upper clamp bound for determinate `OSC 9;4` progress percentages."""
35
+
36
+
37
+ class TerminalProgressState(StrEnum):
38
+ """`OSC 9;4` progress states.
39
+
40
+ See https://learn.microsoft.com/en-us/windows/terminal/tutorials/progress-bar-sequences.
41
+ """
42
+
43
+ CLEAR = "0"
44
+ """Remove any progress indicator. Percentage is ignored."""
45
+
46
+ NORMAL = "1"
47
+ """Determinate progress shown with the default (success) color."""
48
+
49
+ ERROR = "2"
50
+ """Determinate progress shown with the error/red color."""
51
+
52
+ INDETERMINATE = "3"
53
+ """Activity in progress with no known percentage; renders as a pulse."""
54
+
55
+ WARNING = "4"
56
+ """Determinate progress shown with the warning/yellow color."""
57
+
58
+
59
+ def _is_disabled() -> bool:
60
+ """Return whether terminal-escape output is opt-out disabled."""
61
+ return is_env_truthy(NO_TERMINAL_ESCAPE)
62
+
63
+
64
+ def _open_tty() -> TextIO | None:
65
+ """Return an open `/dev/tty` handle, or `None` if unavailable."""
66
+ try:
67
+ return pathlib.Path("/dev/tty").open("w", encoding="utf-8")
68
+ except OSError:
69
+ return None
70
+
71
+
72
+ def _is_stream_tty(stream: TextIO | None) -> bool:
73
+ """Return whether `stream` is a real TTY."""
74
+ if stream is None:
75
+ return False
76
+ try:
77
+ return bool(stream.isatty())
78
+ except (ValueError, OSError):
79
+ return False
80
+
81
+
82
+ def write_terminal_escape(sequence: str) -> bool:
83
+ r"""Best-effort write of a terminal control sequence.
84
+
85
+ Prefers `/dev/tty` so the sequence reaches the terminal even when stdout
86
+ or stderr are redirected. Falls back to `sys.__stderr__` only if it is a
87
+ TTY.
88
+
89
+ Returns `False` (no-op) when output is disabled or no TTY is reachable.
90
+
91
+ Args:
92
+ sequence: Raw escape sequence to write, including leading `\x1b`/`ESC`
93
+ and terminator.
94
+
95
+ Returns:
96
+ `True` if the sequence was written and flushed without error.
97
+ """
98
+ if _is_disabled() or not sequence:
99
+ return False
100
+ tty = _open_tty()
101
+ if tty is not None:
102
+ try:
103
+ with tty:
104
+ tty.write(sequence)
105
+ tty.flush()
106
+ except (OSError, UnicodeError) as exc:
107
+ logger.debug("terminal_escape /dev/tty write failed: %s", exc)
108
+ else:
109
+ return True
110
+ stderr = sys.__stderr__
111
+ if stderr is not None and _is_stream_tty(stderr):
112
+ try:
113
+ stderr.write(sequence)
114
+ stderr.flush()
115
+ except (OSError, ValueError) as exc:
116
+ logger.debug("terminal_escape stderr write failed: %s", exc)
117
+ return False
118
+ return True
119
+ return False
120
+
121
+
122
+ def write_osc(command: str, payload: str = "", *, st: bool = False) -> bool:
123
+ r"""Write an `OSC <command>;<payload>` sequence.
124
+
125
+ Args:
126
+ command: The numeric OSC command (e.g. ``"9;4"`` for taskbar progress).
127
+ payload: Optional semicolon-joined payload appended after the command.
128
+ st: When `True`, terminate with String Terminator (`ESC \`) instead of
129
+ the default BEL (`\a`).
130
+
131
+ BEL matches the Windows Terminal docs and works on most terminals;
132
+ VTE-derived terminals may prefer ST.
133
+
134
+ Returns:
135
+ `True` if the sequence was written.
136
+ """
137
+ body = f"{command};{payload}" if payload else command
138
+ terminator = "\x1b\\" if st else "\a"
139
+ return write_terminal_escape(f"\x1b]{body}{terminator}")
140
+
141
+
142
+ _progress_active = False
143
+ _terminal_background_active = False
144
+ _atexit_registered = False
145
+ _atexit_lock = threading.Lock()
146
+
147
+
148
+ def _ensure_atexit_registered() -> None:
149
+ """Register terminal-state cleanup exactly once."""
150
+ global _atexit_registered # noqa: PLW0603
151
+
152
+ with _atexit_lock:
153
+ if not _atexit_registered:
154
+ atexit.register(_atexit_clear)
155
+ _atexit_registered = True
156
+
157
+
158
+ def _validate_progress(progress: int | None, state: TerminalProgressState) -> int:
159
+ """Clamp/normalize `progress` for a given `state`.
160
+
161
+ Determinate states (`NORMAL`, `ERROR`, `WARNING`) clamp to `[0, 100]`;
162
+ `INDETERMINATE` and `CLEAR` always emit `0`. A non-`None` `progress`
163
+ supplied with `CLEAR`/`INDETERMINATE` is dropped with a debug log so
164
+ misuse stays observable without raising on a cosmetic write path. A
165
+ `progress` that can't be coerced to `int` is treated the same way.
166
+
167
+ Args:
168
+ progress: Raw percentage, or `None`.
169
+ state: The OSC 9;4 progress state.
170
+
171
+ Returns:
172
+ The normalized progress integer to emit.
173
+ """
174
+ if state in {TerminalProgressState.CLEAR, TerminalProgressState.INDETERMINATE}:
175
+ if progress is not None and progress != 0:
176
+ logger.debug(
177
+ "terminal_progress: ignoring progress=%r for state=%s",
178
+ progress,
179
+ state.name,
180
+ )
181
+ return 0
182
+ if progress is None:
183
+ return 0
184
+ try:
185
+ coerced = int(progress)
186
+ except (TypeError, ValueError) as exc:
187
+ logger.debug(
188
+ "terminal_progress: non-numeric progress=%r ignored (%s)", progress, exc
189
+ )
190
+ return 0
191
+ return max(_PROGRESS_MIN, min(_PROGRESS_MAX, coerced))
192
+
193
+
194
+ def set_terminal_progress(
195
+ progress: int | None = None,
196
+ *,
197
+ state: TerminalProgressState = TerminalProgressState.NORMAL,
198
+ ) -> bool:
199
+ """Set the terminal's `OSC 9;4` progress indicator.
200
+
201
+ Fires unconditionally — terminals that don't recognize `OSC 9;4` silently
202
+ ignore the sequence. Set `DEEPAGENTS_CLI_NO_TERMINAL_ESCAPE=1` to opt out
203
+ entirely.
204
+
205
+ Args:
206
+ progress: Percentage `0-100` for determinate states. Ignored for
207
+ `INDETERMINATE` and `CLEAR`.
208
+ state: One of `TerminalProgressState`.
209
+
210
+ Returns:
211
+ `True` if the sequence was written.
212
+ """
213
+ global _progress_active # noqa: PLW0603
214
+
215
+ value = _validate_progress(progress, state)
216
+ payload = f"{state.value};{value}"
217
+ written = write_osc("9;4", payload)
218
+ if written and state is not TerminalProgressState.CLEAR:
219
+ _ensure_atexit_registered()
220
+ _progress_active = True
221
+ elif state is TerminalProgressState.CLEAR:
222
+ _progress_active = False
223
+ return written
224
+
225
+
226
+ def clear_terminal_progress() -> bool:
227
+ """Clear the terminal's progress indicator.
228
+
229
+ Emits `OSC 9;4;0;0`.
230
+
231
+ Returns:
232
+ `True` if the sequence was written.
233
+ """
234
+ return set_terminal_progress(state=TerminalProgressState.CLEAR)
235
+
236
+
237
+ def set_terminal_background(color: str) -> bool:
238
+ """Set the terminal's dynamic default background color with `OSC 11`.
239
+
240
+ This is cosmetic and intentionally best-effort. Terminals that don't
241
+ support `OSC 11` ignore it; `OSC 111` is emitted from `atexit` to restore
242
+ the default background when this call succeeds.
243
+
244
+ Args:
245
+ color: Terminal color payload, usually a CSS-style hex color such as
246
+ `#11121D`.
247
+
248
+ Returns:
249
+ `True` if the sequence was written.
250
+ """
251
+ global _terminal_background_active # noqa: PLW0603
252
+
253
+ if not color:
254
+ return False
255
+ written = write_osc("11", color, st=True)
256
+ if written:
257
+ _ensure_atexit_registered()
258
+ _terminal_background_active = True
259
+ return written
260
+
261
+
262
+ def reset_terminal_background() -> bool:
263
+ """Reset the terminal's dynamic default background color with `OSC 111`.
264
+
265
+ Returns:
266
+ `True` if the sequence was written.
267
+ """
268
+ global _terminal_background_active # noqa: PLW0603
269
+
270
+ written = write_osc("111", st=True)
271
+ if written:
272
+ _terminal_background_active = False
273
+ return written
274
+
275
+
276
+ def _atexit_clear() -> None:
277
+ """`atexit` hook that clears any leftover terminal state."""
278
+ if _progress_active:
279
+ try:
280
+ clear_terminal_progress()
281
+ except Exception:
282
+ logger.warning("Failed to clear terminal progress at exit", exc_info=True)
283
+ if _terminal_background_active:
284
+ try:
285
+ reset_terminal_background()
286
+ except Exception:
287
+ logger.warning("Failed to reset terminal background at exit", exc_info=True)