deepagents-cli 0.0.56__tar.gz → 0.0.57__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.57}/CHANGELOG.md +10 -0
  2. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/PKG-INFO +1 -1
  3. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_env_vars.py +3 -0
  4. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_version.py +1 -1
  5. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/app.py +53 -0
  6. deepagents_cli-0.0.57/deepagents_cli/terminal_escape.py +287 -0
  7. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/textual_adapter.py +10 -1
  8. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/theme_selector.py +17 -1
  9. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/pyproject.toml +1 -1
  10. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_app.py +252 -0
  11. deepagents_cli-0.0.57/tests/unit_tests/test_terminal_escape.py +377 -0
  12. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_theme.py +145 -0
  13. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_token_tracker.py +25 -0
  14. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/uv.lock +1 -1
  15. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/.gitignore +0 -0
  16. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/DEV.md +0 -0
  17. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/Makefile +0 -0
  18. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/README.md +0 -0
  19. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/THREAT_MODEL.md +0 -0
  20. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/__init__.py +0 -0
  21. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/__main__.py +0 -0
  22. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_ask_user_types.py +0 -0
  23. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_cli_context.py +0 -0
  24. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_constants.py +0 -0
  25. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_debug.py +0 -0
  26. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_git.py +0 -0
  27. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_server_config.py +0 -0
  28. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_session_stats.py +0 -0
  29. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_testing_models.py +0 -0
  30. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/_textual_patches.py +0 -0
  31. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/agent.py +0 -0
  32. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/app.tcss +0 -0
  33. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/ask_user.py +0 -0
  34. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/auth_store.py +0 -0
  35. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/built_in_skills/__init__.py +0 -0
  36. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/built_in_skills/remember/SKILL.md +0 -0
  37. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/built_in_skills/skill-creator/SKILL.md +0 -0
  38. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  39. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  40. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/clipboard.py +0 -0
  41. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/command_registry.py +0 -0
  42. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/config.py +0 -0
  43. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/configurable_model.py +0 -0
  44. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/default_agent_prompt.md +0 -0
  45. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/__init__.py +0 -0
  46. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/bundler.py +0 -0
  47. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/commands.py +0 -0
  48. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/config.py +0 -0
  49. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/context_hub.py +0 -0
  50. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/frontend_dist/assets/anonymous-B9UzAXQd.js +0 -0
  51. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/frontend_dist/assets/clerk-5xHgyQyG.js +0 -0
  52. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/frontend_dist/assets/highlighted-body-OFNGDK62-rX-7qT8o.js +0 -0
  53. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/frontend_dist/assets/index-DM3gptpu.js +0 -0
  54. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/frontend_dist/assets/index-Ddy7F6KI.css +0 -0
  55. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/frontend_dist/assets/supabase-S6NACDgm.js +0 -0
  56. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/frontend_dist/index.html +0 -0
  57. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/frontend_dist/logo-dark.svg +0 -0
  58. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/frontend_dist/logo-light.svg +0 -0
  59. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/deploy/templates.py +0 -0
  60. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/editor.py +0 -0
  61. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/event_bus.py +0 -0
  62. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/extras_info.py +0 -0
  63. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/file_ops.py +0 -0
  64. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/formatting.py +0 -0
  65. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/hooks.py +0 -0
  66. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/input.py +0 -0
  67. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/integrations/__init__.py +0 -0
  68. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/integrations/sandbox_factory.py +0 -0
  69. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/integrations/sandbox_provider.py +0 -0
  70. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/iterm_cursor_guide.py +0 -0
  71. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/local_context.py +0 -0
  72. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/main.py +0 -0
  73. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/mcp_auth.py +0 -0
  74. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/mcp_commands.py +0 -0
  75. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/mcp_providers/__init__.py +0 -0
  76. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/mcp_providers/_registry.py +0 -0
  77. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/mcp_providers/base.py +0 -0
  78. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/mcp_providers/github.py +0 -0
  79. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/mcp_providers/slack.py +0 -0
  80. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/mcp_tools.py +0 -0
  81. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/mcp_trust.py +0 -0
  82. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/media_utils.py +0 -0
  83. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/model_config.py +0 -0
  84. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/non_interactive.py +0 -0
  85. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/notifications.py +0 -0
  86. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/offload.py +0 -0
  87. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/onboarding.py +0 -0
  88. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/output.py +0 -0
  89. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/project_utils.py +0 -0
  90. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/py.typed +0 -0
  91. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/remote_client.py +0 -0
  92. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/server.py +0 -0
  93. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/server_graph.py +0 -0
  94. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/server_manager.py +0 -0
  95. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/sessions.py +0 -0
  96. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/skills/__init__.py +0 -0
  97. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/skills/commands.py +0 -0
  98. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/skills/invocation.py +0 -0
  99. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/skills/load.py +0 -0
  100. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/state_migration.py +0 -0
  101. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/subagents.py +0 -0
  102. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/system_prompt.md +0 -0
  103. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/terminal_capabilities.py +0 -0
  104. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/theme.py +0 -0
  105. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/token_state.py +0 -0
  106. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/tool_display.py +0 -0
  107. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/tools.py +0 -0
  108. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/ui.py +0 -0
  109. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/unicode_security.py +0 -0
  110. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/update_check.py +0 -0
  111. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/__init__.py +0 -0
  112. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/_links.py +0 -0
  113. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/agent_selector.py +0 -0
  114. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/approval.py +0 -0
  115. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/ask_user.py +0 -0
  116. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/auth.py +0 -0
  117. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/autocomplete.py +0 -0
  118. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/chat_input.py +0 -0
  119. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/diff.py +0 -0
  120. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/history.py +0 -0
  121. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/launch_init.py +0 -0
  122. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/loading.py +0 -0
  123. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/mcp_viewer.py +0 -0
  124. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/message_store.py +0 -0
  125. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/messages.py +0 -0
  126. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/model_selector.py +0 -0
  127. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/notification_center.py +0 -0
  128. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/notification_detail.py +0 -0
  129. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/notification_settings.py +0 -0
  130. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/status.py +0 -0
  131. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/thread_selector.py +0 -0
  132. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/tool_renderers.py +0 -0
  133. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/tool_widgets.py +0 -0
  134. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/update_available.py +0 -0
  135. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/update_progress.py +0 -0
  136. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/deepagents_cli/widgets/welcome.py +0 -0
  137. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/deploy-content-writer/.env.example +0 -0
  138. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/deploy-content-writer/skills/blog-post/SKILL.md +0 -0
  139. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/deploy-content-writer/skills/social-media/SKILL.md +0 -0
  140. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/deploy-content-writer/user/context.md +0 -0
  141. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/deploy-content-writer/user/preferences.md +0 -0
  142. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/skills/arxiv-search/SKILL.md +0 -0
  143. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  144. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/skills/langgraph-docs/SKILL.md +0 -0
  145. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/skills/skill-creator/SKILL.md +0 -0
  146. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  147. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  148. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/examples/skills/web-research/SKILL.md +0 -0
  149. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/.nvmrc +0 -0
  150. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/index.html +0 -0
  151. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/package-lock.json +0 -0
  152. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/package.json +0 -0
  153. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/postcss.config.js +0 -0
  154. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/public/logo-dark.svg +0 -0
  155. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/public/logo-light.svg +0 -0
  156. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/App.tsx +0 -0
  157. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/ThemeProvider.tsx +0 -0
  158. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/auth/anonymous.tsx +0 -0
  159. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/auth/clerk.tsx +0 -0
  160. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/auth/loader.tsx +0 -0
  161. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/auth/supabase.tsx +0 -0
  162. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/auth/types.ts +0 -0
  163. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/AppHeader.tsx +0 -0
  164. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/FilePanels.tsx +0 -0
  165. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/MessageList.tsx +0 -0
  166. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/SubagentActivity.tsx +0 -0
  167. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/ThreadPicker.tsx +0 -0
  168. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/TodosPanel.tsx +0 -0
  169. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/ToolCallCard.tsx +0 -0
  170. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/toolcalls/FileToolCard.tsx +0 -0
  171. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/toolcalls/SearchCard.tsx +0 -0
  172. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/toolcalls/ThinkCard.tsx +0 -0
  173. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/toolcalls/TodosCard.tsx +0 -0
  174. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/components/toolcalls/index.ts +0 -0
  175. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/constants.ts +0 -0
  176. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/index.css +0 -0
  177. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/main.tsx +0 -0
  178. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/runtimeConfig.ts +0 -0
  179. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/types.ts +0 -0
  180. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/src/vite-env.d.ts +0 -0
  181. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/tsconfig.json +0 -0
  182. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/frontend/vite.config.ts +0 -0
  183. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/images/cli.png +0 -0
  184. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/scripts/check_imports.py +0 -0
  185. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/scripts/debug_server.sh +0 -0
  186. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/scripts/install.sh +0 -0
  187. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/README.md +0 -0
  188. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/__init__.py +0 -0
  189. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/benchmarks/__init__.py +0 -0
  190. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  191. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  192. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/conftest.py +0 -0
  193. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/test_acp_mode.py +0 -0
  194. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/test_compact_resume.py +0 -0
  195. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/test_context_hub.py +0 -0
  196. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/test_deploy_hub.py +0 -0
  197. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/test_sandbox_factory.py +0 -0
  198. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/integration_tests/test_sandbox_operations.py +0 -0
  199. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/__init__.py +0 -0
  200. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/conftest.py +0 -0
  201. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/deploy/__init__.py +0 -0
  202. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/deploy/test_bundler.py +0 -0
  203. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/deploy/test_commands.py +0 -0
  204. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/deploy/test_config.py +0 -0
  205. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/deploy/test_context_hub.py +0 -0
  206. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/deploy/test_frontend_bundle.py +0 -0
  207. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/deploy/test_frontend_config.py +0 -0
  208. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/skills/__init__.py +0 -0
  209. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/skills/test_commands.py +0 -0
  210. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/skills/test_load.py +0 -0
  211. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/skills/test_skills_json.py +0 -0
  212. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_agent.py +0 -0
  213. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_agent_friendly.py +0 -0
  214. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_agent_selector.py +0 -0
  215. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_approval.py +0 -0
  216. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_args.py +0 -0
  217. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_ask_user.py +0 -0
  218. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  219. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_auth_store.py +0 -0
  220. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_auth_widgets.py +0 -0
  221. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_autocomplete.py +0 -0
  222. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_charset.py +0 -0
  223. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_chat_input.py +0 -0
  224. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_clipboard.py +0 -0
  225. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_command_registry.py +0 -0
  226. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_compact_tool.py +0 -0
  227. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_config.py +0 -0
  228. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_configurable_model.py +0 -0
  229. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_debug.py +0 -0
  230. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_editor.py +0 -0
  231. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_end_to_end.py +0 -0
  232. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_env_vars.py +0 -0
  233. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_event_bus.py +0 -0
  234. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_exception_handling.py +0 -0
  235. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_extras_info.py +0 -0
  236. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_file_ops.py +0 -0
  237. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_formatting.py +0 -0
  238. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_git.py +0 -0
  239. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_history.py +0 -0
  240. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_hooks.py +0 -0
  241. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_imports.py +0 -0
  242. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_input_parsing.py +0 -0
  243. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_iterm_cursor_guide.py +0 -0
  244. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_launch_init.py +0 -0
  245. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_links.py +0 -0
  246. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_loading.py +0 -0
  247. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_local_context.py +0 -0
  248. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_main.py +0 -0
  249. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_main_acp_mode.py +0 -0
  250. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_main_args.py +0 -0
  251. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_mcp_auth.py +0 -0
  252. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_mcp_commands.py +0 -0
  253. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_mcp_tools.py +0 -0
  254. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_mcp_trust.py +0 -0
  255. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_mcp_viewer.py +0 -0
  256. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_media_utils.py +0 -0
  257. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_message_store.py +0 -0
  258. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_messages.py +0 -0
  259. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_model_config.py +0 -0
  260. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_model_selector.py +0 -0
  261. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_model_switch.py +0 -0
  262. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_non_interactive.py +0 -0
  263. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_notification_center.py +0 -0
  264. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_notification_detail.py +0 -0
  265. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_notifications.py +0 -0
  266. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_offload.py +0 -0
  267. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  268. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_onboarding.py +0 -0
  269. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_output.py +0 -0
  270. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_reload.py +0 -0
  271. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_remote_client.py +0 -0
  272. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_sandbox_factory.py +0 -0
  273. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_server.py +0 -0
  274. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_server_config.py +0 -0
  275. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_server_graph.py +0 -0
  276. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_server_helpers.py +0 -0
  277. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_server_manager.py +0 -0
  278. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_session_stats.py +0 -0
  279. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_sessions.py +0 -0
  280. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_shell_allow_list.py +0 -0
  281. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_skill_invocation.py +0 -0
  282. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_startup_fast_paths.py +0 -0
  283. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_state_migration.py +0 -0
  284. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_status.py +0 -0
  285. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_subagents.py +0 -0
  286. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  287. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_textual_adapter.py +0 -0
  288. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_textual_patches.py +0 -0
  289. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_thread_selector.py +0 -0
  290. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_tool_display.py +0 -0
  291. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_ui.py +0 -0
  292. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_unicode_security.py +0 -0
  293. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_update_available.py +0 -0
  294. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_update_check.py +0 -0
  295. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_update_progress.py +0 -0
  296. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_version.py +0 -0
  297. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/test_welcome.py +0 -0
  298. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/tools/__init__.py +0 -0
  299. {deepagents_cli-0.0.56 → deepagents_cli-0.0.57}/tests/unit_tests/tools/test_fetch_url.py +0 -0
@@ -1,5 +1,15 @@
1
1
  # Deep Agents CLI Changelog
2
2
 
3
+ ## [0.0.57](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.56...deepagents-cli==0.0.57) (2026-05-12)
4
+
5
+ ### Features
6
+
7
+ * OSC 9;4 progress & escape helper ([#3347](https://github.com/langchain-ai/deepagents/issues/3347)) ([75d60cd](https://github.com/langchain-ai/deepagents/commit/75d60cd82f559b2944b78a348d16b0a10a00d663))
8
+
9
+ ### Bug Fixes
10
+
11
+ * 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))
12
+
3
13
  ## [0.0.56](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.55...deepagents-cli==0.0.56) (2026-05-11)
4
14
 
5
15
  ### 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.57
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/
@@ -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.57" # 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
@@ -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:
@@ -6582,6 +6625,15 @@ class DeepAgentsApp(App):
6582
6625
  ).encode()
6583
6626
  _dispatch_hook_sync("session.end", payload, hooks)
6584
6627
 
6628
+ from deepagents_cli.terminal_escape import reset_terminal_background
6629
+
6630
+ try:
6631
+ reset_terminal_background()
6632
+ except Exception:
6633
+ # Cosmetic only: must never raise during shutdown.
6634
+ logger.warning(
6635
+ "reset_terminal_background raised unexpectedly", exc_info=True
6636
+ )
6585
6637
  restore_iterm_cursor_guide()
6586
6638
  super().exit(result=result, return_code=return_code, message=message)
6587
6639
 
@@ -6986,6 +7038,7 @@ class DeepAgentsApp(App):
6986
7038
  """Handle the theme selector result."""
6987
7039
  if result is not None:
6988
7040
  self.theme = result
7041
+ self.sync_terminal_background()
6989
7042
  self.refresh_css(animate=False)
6990
7043
 
6991
7044
  async def _persist() -> None:
@@ -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)
@@ -1432,13 +1432,22 @@ async def _persist_context_tokens(
1432
1432
  ) -> None:
1433
1433
  """Best-effort persist of the context token count into graph state.
1434
1434
 
1435
+ The `aupdate_state` call is wrapped in `tracing_context(enabled=False)` so
1436
+ this purely-internal bookkeeping write does not surface as a separate
1437
+ `UpdateState` run in LangSmith. `_context_tokens` is already marked
1438
+ `PrivateStateAttr`, but `aupdate_state` itself creates its own traced run
1439
+ that would otherwise clutter the project's traces.
1440
+
1435
1441
  Args:
1436
1442
  agent: The LangGraph agent (must support `aupdate_state`).
1437
1443
  config: Runnable config with `thread_id`.
1438
1444
  tokens: Total context tokens to persist.
1439
1445
  """
1446
+ from langsmith import tracing_context
1447
+
1440
1448
  try:
1441
- await agent.aupdate_state(config, {"_context_tokens": tokens})
1449
+ with tracing_context(enabled=False):
1450
+ await agent.aupdate_state(config, {"_context_tokens": tokens})
1442
1451
  except (httpx.TransportError, httpx.TimeoutException) as e:
1443
1452
  logger.warning(
1444
1453
  "Could not persist _context_tokens=%d (network): %s; "
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import asyncio
6
6
  import logging
7
7
  import os
8
- from typing import TYPE_CHECKING, ClassVar
8
+ from typing import TYPE_CHECKING, ClassVar, Protocol, runtime_checkable
9
9
 
10
10
  from textual.binding import Binding, BindingType
11
11
  from textual.containers import Vertical
@@ -22,6 +22,14 @@ from deepagents_cli.config import get_glyphs, is_ascii_mode
22
22
  logger = logging.getLogger(__name__)
23
23
 
24
24
 
25
+ @runtime_checkable
26
+ class _TerminalBackgroundSyncApp(Protocol):
27
+ """App protocol for terminal background sync after theme preview changes."""
28
+
29
+ def sync_terminal_background(self) -> None:
30
+ """Sync the terminal background to the active theme."""
31
+
32
+
25
33
  class ThemeSelectorScreen(ModalScreen[str | None]):
26
34
  """Modal dialog for theme selection with live preview.
27
35
 
@@ -103,6 +111,11 @@ class ThemeSelectorScreen(ModalScreen[str | None]):
103
111
  self._terminal_default = terminal_default
104
112
  self._show_keys = False
105
113
 
114
+ def _sync_terminal_background(self) -> None:
115
+ """Ask the app to sync terminal background after preview changes."""
116
+ if isinstance(self.app, _TerminalBackgroundSyncApp):
117
+ self.app.sync_terminal_background()
118
+
106
119
  def _format_option(self, name: str, entry: theme.ThemeEntry) -> str:
107
120
  """Render the option text for a theme entry.
108
121
 
@@ -172,6 +185,7 @@ class ThemeSelectorScreen(ModalScreen[str | None]):
172
185
  if name is not None and name in theme.get_registry():
173
186
  try:
174
187
  self.app.theme = name
188
+ self._sync_terminal_background()
175
189
  # refresh_css only repaints the active (modal) screen's layout;
176
190
  # force the screen beneath us to repaint so the user sees the
177
191
  # preview through the transparent scrim.
@@ -182,6 +196,7 @@ class ThemeSelectorScreen(ModalScreen[str | None]):
182
196
  logger.warning("Failed to preview theme '%s'", name, exc_info=True)
183
197
  try:
184
198
  self.app.theme = self._original_theme
199
+ self._sync_terminal_background()
185
200
  except Exception:
186
201
  logger.warning(
187
202
  "Failed to restore original theme '%s'",
@@ -205,6 +220,7 @@ class ThemeSelectorScreen(ModalScreen[str | None]):
205
220
  def action_cancel(self) -> None:
206
221
  """Restore the original theme and dismiss."""
207
222
  self.app.theme = self._original_theme
223
+ self._sync_terminal_background()
208
224
  self.dismiss(None)
209
225
 
210
226
  def action_cursor_down(self) -> None:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "deepagents-cli"
7
- version = "0.0.56"
7
+ version = "0.0.57"
8
8
  description = "Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }