deepagents-cli 0.0.41__tar.gz → 0.0.43__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 (265) hide show
  1. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/.gitignore +6 -0
  2. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/CHANGELOG.md +26 -10
  3. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/PKG-INFO +5 -5
  4. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_env_vars.py +3 -0
  5. deepagents_cli-0.0.43/deepagents_cli/_textual_patches.py +66 -0
  6. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_version.py +1 -1
  7. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/agent.py +34 -7
  8. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/app.py +23 -1
  9. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/config.py +82 -35
  10. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/bundler.py +135 -9
  11. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/commands.py +45 -0
  12. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/config.py +116 -7
  13. deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/anonymous-B9UzAXQd.js +1 -0
  14. deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/clerk-5xHgyQyG.js +23 -0
  15. deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/highlighted-body-OFNGDK62-rX-7qT8o.js +1 -0
  16. deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/index-DM3gptpu.js +205 -0
  17. deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/index-Ddy7F6KI.css +1 -0
  18. deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/assets/supabase-S6NACDgm.js +44 -0
  19. deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/index.html +16 -0
  20. deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/logo-dark.svg +12 -0
  21. deepagents_cli-0.0.43/deepagents_cli/deploy/frontend_dist/logo-light.svg +12 -0
  22. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/templates.py +112 -0
  23. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/local_context.py +21 -7
  24. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/system_prompt.md +1 -1
  25. deepagents_cli-0.0.43/deepagents_cli/terminal_capabilities.py +115 -0
  26. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/model_selector.py +23 -2
  27. deepagents_cli-0.0.43/frontend/.nvmrc +1 -0
  28. deepagents_cli-0.0.43/frontend/index.html +15 -0
  29. deepagents_cli-0.0.43/frontend/package-lock.json +6207 -0
  30. deepagents_cli-0.0.43/frontend/package.json +34 -0
  31. deepagents_cli-0.0.43/frontend/postcss.config.js +5 -0
  32. deepagents_cli-0.0.43/frontend/public/logo-dark.svg +12 -0
  33. deepagents_cli-0.0.43/frontend/public/logo-light.svg +12 -0
  34. deepagents_cli-0.0.43/frontend/src/App.tsx +342 -0
  35. deepagents_cli-0.0.43/frontend/src/ThemeProvider.tsx +66 -0
  36. deepagents_cli-0.0.43/frontend/src/auth/anonymous.tsx +45 -0
  37. deepagents_cli-0.0.43/frontend/src/auth/clerk.tsx +138 -0
  38. deepagents_cli-0.0.43/frontend/src/auth/loader.tsx +26 -0
  39. deepagents_cli-0.0.43/frontend/src/auth/supabase.tsx +236 -0
  40. deepagents_cli-0.0.43/frontend/src/auth/types.ts +22 -0
  41. deepagents_cli-0.0.43/frontend/src/components/AppHeader.tsx +70 -0
  42. deepagents_cli-0.0.43/frontend/src/components/FilePanels.tsx +148 -0
  43. deepagents_cli-0.0.43/frontend/src/components/MessageList.tsx +177 -0
  44. deepagents_cli-0.0.43/frontend/src/components/SubagentActivity.tsx +262 -0
  45. deepagents_cli-0.0.43/frontend/src/components/ThreadPicker.tsx +162 -0
  46. deepagents_cli-0.0.43/frontend/src/components/TodosPanel.tsx +54 -0
  47. deepagents_cli-0.0.43/frontend/src/components/ToolCallCard.tsx +136 -0
  48. deepagents_cli-0.0.43/frontend/src/components/toolcalls/FileToolCard.tsx +126 -0
  49. deepagents_cli-0.0.43/frontend/src/components/toolcalls/SearchCard.tsx +107 -0
  50. deepagents_cli-0.0.43/frontend/src/components/toolcalls/ThinkCard.tsx +60 -0
  51. deepagents_cli-0.0.43/frontend/src/components/toolcalls/TodosCard.tsx +63 -0
  52. deepagents_cli-0.0.43/frontend/src/components/toolcalls/index.ts +51 -0
  53. deepagents_cli-0.0.43/frontend/src/constants.ts +15 -0
  54. deepagents_cli-0.0.43/frontend/src/index.css +220 -0
  55. deepagents_cli-0.0.43/frontend/src/main.tsx +20 -0
  56. deepagents_cli-0.0.43/frontend/src/runtimeConfig.ts +75 -0
  57. deepagents_cli-0.0.43/frontend/src/types.ts +22 -0
  58. deepagents_cli-0.0.43/frontend/src/vite-env.d.ts +1 -0
  59. deepagents_cli-0.0.43/frontend/tsconfig.json +19 -0
  60. deepagents_cli-0.0.43/frontend/vite.config.ts +25 -0
  61. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/pyproject.toml +13 -4
  62. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/conftest.py +15 -0
  63. deepagents_cli-0.0.43/tests/unit_tests/deploy/test_frontend_bundle.py +427 -0
  64. deepagents_cli-0.0.43/tests/unit_tests/deploy/test_frontend_config.py +181 -0
  65. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_agent.py +110 -6
  66. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_config.py +372 -45
  67. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_local_context.py +39 -10
  68. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_model_switch.py +80 -0
  69. deepagents_cli-0.0.43/tests/unit_tests/test_terminal_capabilities.py +203 -0
  70. deepagents_cli-0.0.43/tests/unit_tests/test_textual_patches.py +92 -0
  71. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_version.py +11 -1
  72. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/uv.lock +34 -21
  73. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/DEV.md +0 -0
  74. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/Makefile +0 -0
  75. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/README.md +0 -0
  76. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/THREAT_MODEL.md +0 -0
  77. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/__init__.py +0 -0
  78. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/__main__.py +0 -0
  79. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_ask_user_types.py +0 -0
  80. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_cli_context.py +0 -0
  81. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_debug.py +0 -0
  82. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_git.py +0 -0
  83. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_server_config.py +0 -0
  84. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_session_stats.py +0 -0
  85. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/_testing_models.py +0 -0
  86. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/app.tcss +0 -0
  87. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/ask_user.py +0 -0
  88. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/__init__.py +0 -0
  89. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/remember/SKILL.md +0 -0
  90. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/skill-creator/SKILL.md +0 -0
  91. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  92. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  93. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/clipboard.py +0 -0
  94. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/command_registry.py +0 -0
  95. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/configurable_model.py +0 -0
  96. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/default_agent_prompt.md +0 -0
  97. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/deploy/__init__.py +0 -0
  98. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/editor.py +0 -0
  99. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/extras_info.py +0 -0
  100. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/file_ops.py +0 -0
  101. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/formatting.py +0 -0
  102. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/hooks.py +0 -0
  103. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/input.py +0 -0
  104. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/integrations/__init__.py +0 -0
  105. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/integrations/sandbox_factory.py +0 -0
  106. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/integrations/sandbox_provider.py +0 -0
  107. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/main.py +0 -0
  108. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/mcp_tools.py +0 -0
  109. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/mcp_trust.py +0 -0
  110. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/media_utils.py +0 -0
  111. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/model_config.py +0 -0
  112. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/non_interactive.py +0 -0
  113. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/notifications.py +0 -0
  114. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/offload.py +0 -0
  115. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/output.py +0 -0
  116. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/project_utils.py +0 -0
  117. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/py.typed +0 -0
  118. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/remote_client.py +0 -0
  119. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/server.py +0 -0
  120. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/server_graph.py +0 -0
  121. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/server_manager.py +0 -0
  122. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/sessions.py +0 -0
  123. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/skills/__init__.py +0 -0
  124. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/skills/commands.py +0 -0
  125. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/skills/invocation.py +0 -0
  126. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/skills/load.py +0 -0
  127. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/subagents.py +0 -0
  128. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/textual_adapter.py +0 -0
  129. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/theme.py +0 -0
  130. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/token_state.py +0 -0
  131. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/tool_display.py +0 -0
  132. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/tools.py +0 -0
  133. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/ui.py +0 -0
  134. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/unicode_security.py +0 -0
  135. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/update_check.py +0 -0
  136. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/__init__.py +0 -0
  137. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/_links.py +0 -0
  138. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/agent_selector.py +0 -0
  139. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/approval.py +0 -0
  140. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/ask_user.py +0 -0
  141. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/autocomplete.py +0 -0
  142. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/chat_input.py +0 -0
  143. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/diff.py +0 -0
  144. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/history.py +0 -0
  145. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/loading.py +0 -0
  146. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/mcp_viewer.py +0 -0
  147. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/message_store.py +0 -0
  148. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/messages.py +0 -0
  149. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/notification_center.py +0 -0
  150. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/notification_detail.py +0 -0
  151. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/notification_settings.py +0 -0
  152. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/status.py +0 -0
  153. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/theme_selector.py +0 -0
  154. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/thread_selector.py +0 -0
  155. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/tool_renderers.py +0 -0
  156. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/tool_widgets.py +0 -0
  157. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/update_available.py +0 -0
  158. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/deepagents_cli/widgets/welcome.py +0 -0
  159. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/.env.example +0 -0
  160. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/skills/blog-post/SKILL.md +0 -0
  161. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/skills/social-media/SKILL.md +0 -0
  162. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/user/context.md +0 -0
  163. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/deploy-content-writer/user/preferences.md +0 -0
  164. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/arxiv-search/SKILL.md +0 -0
  165. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  166. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/langgraph-docs/SKILL.md +0 -0
  167. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/skill-creator/SKILL.md +0 -0
  168. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  169. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  170. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/examples/skills/web-research/SKILL.md +0 -0
  171. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/images/cli.png +0 -0
  172. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/scripts/check_imports.py +0 -0
  173. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/scripts/debug_server.sh +0 -0
  174. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/scripts/install.sh +0 -0
  175. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/README.md +0 -0
  176. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/__init__.py +0 -0
  177. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/benchmarks/__init__.py +0 -0
  178. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  179. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  180. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/conftest.py +0 -0
  181. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/test_acp_mode.py +0 -0
  182. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/test_compact_resume.py +0 -0
  183. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/test_sandbox_factory.py +0 -0
  184. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/integration_tests/test_sandbox_operations.py +0 -0
  185. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/__init__.py +0 -0
  186. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/deploy/__init__.py +0 -0
  187. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/deploy/test_bundler.py +0 -0
  188. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/deploy/test_commands.py +0 -0
  189. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/deploy/test_config.py +0 -0
  190. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/skills/__init__.py +0 -0
  191. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/skills/test_commands.py +0 -0
  192. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/skills/test_load.py +0 -0
  193. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/skills/test_skills_json.py +0 -0
  194. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_agent_friendly.py +0 -0
  195. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_agent_selector.py +0 -0
  196. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_app.py +0 -0
  197. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_approval.py +0 -0
  198. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_args.py +0 -0
  199. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_ask_user.py +0 -0
  200. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  201. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_autocomplete.py +0 -0
  202. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_charset.py +0 -0
  203. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_chat_input.py +0 -0
  204. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_command_registry.py +0 -0
  205. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_compact_tool.py +0 -0
  206. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_configurable_model.py +0 -0
  207. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_debug.py +0 -0
  208. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_editor.py +0 -0
  209. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_end_to_end.py +0 -0
  210. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_env_vars.py +0 -0
  211. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_exception_handling.py +0 -0
  212. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_extras_info.py +0 -0
  213. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_file_ops.py +0 -0
  214. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_formatting.py +0 -0
  215. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_git.py +0 -0
  216. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_history.py +0 -0
  217. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_hooks.py +0 -0
  218. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_imports.py +0 -0
  219. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_input_parsing.py +0 -0
  220. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_links.py +0 -0
  221. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_loading.py +0 -0
  222. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_main.py +0 -0
  223. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_main_acp_mode.py +0 -0
  224. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_main_args.py +0 -0
  225. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_mcp_tools.py +0 -0
  226. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_mcp_trust.py +0 -0
  227. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_mcp_viewer.py +0 -0
  228. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_media_utils.py +0 -0
  229. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_message_store.py +0 -0
  230. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_messages.py +0 -0
  231. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_model_config.py +0 -0
  232. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_model_selector.py +0 -0
  233. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_non_interactive.py +0 -0
  234. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_notification_center.py +0 -0
  235. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_notification_detail.py +0 -0
  236. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_notifications.py +0 -0
  237. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_offload.py +0 -0
  238. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  239. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_output.py +0 -0
  240. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_reload.py +0 -0
  241. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_remote_client.py +0 -0
  242. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_sandbox_factory.py +0 -0
  243. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server.py +0 -0
  244. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server_config.py +0 -0
  245. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server_graph.py +0 -0
  246. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server_helpers.py +0 -0
  247. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_server_manager.py +0 -0
  248. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_session_stats.py +0 -0
  249. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_sessions.py +0 -0
  250. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_shell_allow_list.py +0 -0
  251. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_skill_invocation.py +0 -0
  252. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_status.py +0 -0
  253. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_subagents.py +0 -0
  254. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_textual_adapter.py +0 -0
  255. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_theme.py +0 -0
  256. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_thread_selector.py +0 -0
  257. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_token_tracker.py +0 -0
  258. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_tool_display.py +0 -0
  259. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_ui.py +0 -0
  260. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_unicode_security.py +0 -0
  261. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_update_available.py +0 -0
  262. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_update_check.py +0 -0
  263. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/test_welcome.py +0 -0
  264. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/tools/__init__.py +0 -0
  265. {deepagents_cli-0.0.41 → deepagents_cli-0.0.43}/tests/unit_tests/tools/test_fetch_url.py +0 -0
@@ -15,6 +15,7 @@ downloads/
15
15
  eggs/
16
16
  .eggs/
17
17
  lib/
18
+ !libs/cli/frontend/src/lib/
18
19
  lib64/
19
20
  parts/
20
21
  sdist/
@@ -227,3 +228,8 @@ libs/cli/TEXTUAL_PROGRESS.md
227
228
 
228
229
  CLAUDE.md
229
230
  .worktrees/
231
+
232
+ # Frontend build artifacts (source tree; package data under libs/cli/deepagents_cli/deploy/frontend_dist/ is tracked)
233
+ libs/cli/frontend/node_modules/
234
+ libs/cli/frontend/dist/
235
+ node_modules/
@@ -1,23 +1,39 @@
1
1
  # Changelog
2
2
 
3
- ## [0.0.41](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.40...deepagents-cli==0.0.41) (2026-04-21)
3
+ ## [0.0.43](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.42...deepagents-cli==0.0.43) (2026-04-29)
4
+
5
+
6
+ ### Features
7
+
8
+ * **cli:** bundled chat frontend for deepagent deploy ([#2940](https://github.com/langchain-ai/deepagents/issues/2940)) ([9bde0c7](https://github.com/langchain-ai/deepagents/commit/9bde0c7835ded20e80466d8361f40784141d68d8))
4
9
 
10
+ ## [0.0.42](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.41...deepagents-cli==0.0.42) (2026-04-29)
5
11
 
6
12
  ### Features
7
13
 
8
- * **cli:** `--startup-cmd` flag ([#2841](https://github.com/langchain-ai/deepagents/issues/2841)) ([8adcc2c](https://github.com/langchain-ai/deepagents/commit/8adcc2c2e612346c263d02d1ec5c33e0d63da5a3))
9
- * **cli:** actionable notifications, update modal ([#2855](https://github.com/langchain-ai/deepagents/issues/2855)) ([5fcd368](https://github.com/langchain-ai/deepagents/commit/5fcd368088079a84f151e0a3f5e4b9ac29c360c1))
10
- * **cli:** custom auth via `[auth]` ([#2734](https://github.com/langchain-ai/deepagents/issues/2734)) ([417ddaa](https://github.com/langchain-ai/deepagents/commit/417ddaab4804a54a8f83721bb8577d65cfa3659f))
11
- * **cli:** refresh footer git branch after shell commands ([#2851](https://github.com/langchain-ai/deepagents/issues/2851)) ([ee4fddd](https://github.com/langchain-ai/deepagents/commit/ee4fddde9454ee8f7ede98ee9a346da6c5ccd3d9))
12
- * **cli:** rework `/version`, add release-age and editable-install guard ([#2854](https://github.com/langchain-ai/deepagents/issues/2854)) ([1ae053f](https://github.com/langchain-ai/deepagents/commit/1ae053f347679e58562d2b81eb6d6e6e9bbf0b07))
14
+ * `shift+enter` newline on kitty-capable terminals ([#2869](https://github.com/langchain-ai/deepagents/issues/2869)) ([34e6614](https://github.com/langchain-ai/deepagents/commit/34e6614a2c6e6a7e33f763ac5b527c13b324a690))
15
+ * Hint `Enter` behavior in `/model` empty state ([#2933](https://github.com/langchain-ai/deepagents/issues/2933)) ([7cffa16](https://github.com/langchain-ai/deepagents/commit/7cffa16a072bc77def78e4cda09c2e5a2cf8ca39))
16
+
17
+ ### Bug Fixes
18
+
19
+ * Queue `/model` switches during server startup ([#2895](https://github.com/langchain-ai/deepagents/issues/2895)) ([6ed7b65](https://github.com/langchain-ai/deepagents/commit/6ed7b65a40ac5bd926e94edd944bd552e8d6b5b4))
20
+
21
+ ## [0.0.41](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.40...deepagents-cli==0.0.41) (2026-04-21)
22
+
23
+ ### Features
13
24
 
25
+ * `--startup-cmd` flag ([#2841](https://github.com/langchain-ai/deepagents/issues/2841)) ([8adcc2c](https://github.com/langchain-ai/deepagents/commit/8adcc2c2e612346c263d02d1ec5c33e0d63da5a3))
26
+ * Actionable notifications, update modal ([#2855](https://github.com/langchain-ai/deepagents/issues/2855)) ([5fcd368](https://github.com/langchain-ai/deepagents/commit/5fcd368088079a84f151e0a3f5e4b9ac29c360c1))
27
+ * Custom auth via `[auth]` in `deepagents deploy` ([#2734](https://github.com/langchain-ai/deepagents/issues/2734)) ([417ddaa](https://github.com/langchain-ai/deepagents/commit/417ddaab4804a54a8f83721bb8577d65cfa3659f))
28
+ * Refresh footer git branch after shell commands ([#2851](https://github.com/langchain-ai/deepagents/issues/2851)) ([ee4fddd](https://github.com/langchain-ai/deepagents/commit/ee4fddde9454ee8f7ede98ee9a346da6c5ccd3d9))
29
+ * Rework `/version`, add release-age and editable-install guard ([#2854](https://github.com/langchain-ai/deepagents/issues/2854)) ([1ae053f](https://github.com/langchain-ai/deepagents/commit/1ae053f347679e58562d2b81eb6d6e6e9bbf0b07))
14
30
 
15
31
  ### Bug Fixes
16
32
 
17
- * **cli:** gate agent-swap resume hint on server checkpoint ([#2862](https://github.com/langchain-ai/deepagents/issues/2862)) ([f14b9cd](https://github.com/langchain-ai/deepagents/commit/f14b9cd3cc41f92ddb089d4294cba8496d517807))
18
- * **cli:** keep thinking spinner visible during text streaming ([#2849](https://github.com/langchain-ai/deepagents/issues/2849)) ([2cb2244](https://github.com/langchain-ai/deepagents/commit/2cb22446bc1351d20e8bbfa9f23b5d668947351f))
19
- * **cli:** re-show thinking spinner on hitl/`ask_user` resume ([#2847](https://github.com/langchain-ai/deepagents/issues/2847)) ([34a6167](https://github.com/langchain-ai/deepagents/commit/34a6167b0c275c7e4da067ef276a837f60da2f8a))
20
- * **cli:** restore ctrl+j newline keybinding ([#2827](https://github.com/langchain-ai/deepagents/issues/2827)) ([2e1a3f4](https://github.com/langchain-ai/deepagents/commit/2e1a3f45a9ff56390e294ea5b0f6a837200874ec))
33
+ * Gate agent-swap resume hint on server checkpoint ([#2862](https://github.com/langchain-ai/deepagents/issues/2862)) ([f14b9cd](https://github.com/langchain-ai/deepagents/commit/f14b9cd3cc41f92ddb089d4294cba8496d517807))
34
+ * Keep thinking spinner visible during text streaming ([#2849](https://github.com/langchain-ai/deepagents/issues/2849)) ([2cb2244](https://github.com/langchain-ai/deepagents/commit/2cb22446bc1351d20e8bbfa9f23b5d668947351f))
35
+ * Re-show thinking spinner on hitl/`ask_user` resume ([#2847](https://github.com/langchain-ai/deepagents/issues/2847)) ([34a6167](https://github.com/langchain-ai/deepagents/commit/34a6167b0c275c7e4da067ef276a837f60da2f8a))
36
+ * Restore `ctrl+j` newline keybinding ([#2827](https://github.com/langchain-ai/deepagents/issues/2827)) ([2e1a3f4](https://github.com/langchain-ai/deepagents/commit/2e1a3f45a9ff56390e294ea5b0f6a837200874ec))
21
37
 
22
38
  ## [0.0.40](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.39...deepagents-cli==0.0.40) (2026-04-20)
23
39
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-cli
3
- Version: 0.0.41
3
+ Version: 0.0.43
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,9 +27,9 @@ 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.3
30
+ Requires-Dist: deepagents==0.5.4
31
31
  Requires-Dist: httpx<1.0.0,>=0.28.1
32
- Requires-Dist: langchain-anthropic<2.0.0,>=1.4.0
32
+ Requires-Dist: langchain-anthropic<2.0.0,>=1.4.2
33
33
  Requires-Dist: langchain-google-genai<5.0.0,>=4.2.1
34
34
  Requires-Dist: langchain-mcp-adapters<1.0.0,>=0.2.0
35
35
  Requires-Dist: langchain-openai<2.0.0,>=1.1.12
@@ -57,7 +57,7 @@ Requires-Dist: uuid-utils<1.0.0,>=0.10.0
57
57
  Provides-Extra: agentcore
58
58
  Requires-Dist: langchain-agentcore-codeinterpreter>=0.0.1; extra == 'agentcore'
59
59
  Provides-Extra: all-providers
60
- Requires-Dist: langchain-anthropic<2.0.0,>=1.4.0; extra == 'all-providers'
60
+ Requires-Dist: langchain-anthropic<2.0.0,>=1.4.2; extra == 'all-providers'
61
61
  Requires-Dist: langchain-aws<2.0.0,>=1.0.0; extra == 'all-providers'
62
62
  Requires-Dist: langchain-baseten<1.0.0,>=0.1.9; extra == 'all-providers'
63
63
  Requires-Dist: langchain-cohere<1.0.0,>=0.5.0; extra == 'all-providers'
@@ -82,7 +82,7 @@ Requires-Dist: langchain-daytona>=0.0.4; extra == 'all-sandboxes'
82
82
  Requires-Dist: langchain-modal>=0.0.2; extra == 'all-sandboxes'
83
83
  Requires-Dist: langchain-runloop>=0.0.3; extra == 'all-sandboxes'
84
84
  Provides-Extra: anthropic
85
- Requires-Dist: langchain-anthropic<2.0.0,>=1.4.0; extra == 'anthropic'
85
+ Requires-Dist: langchain-anthropic<2.0.0,>=1.4.2; extra == 'anthropic'
86
86
  Provides-Extra: baseten
87
87
  Requires-Dist: langchain-baseten<1.0.0,>=0.1.9; extra == 'baseten'
88
88
  Provides-Extra: bedrock
@@ -52,6 +52,9 @@ real PyPI release. Any non-empty value enables the flag (including `"0"` or
52
52
  EXTRA_SKILLS_DIRS = "DEEPAGENTS_CLI_EXTRA_SKILLS_DIRS"
53
53
  """Colon-separated paths added to the skill containment allowlist."""
54
54
 
55
+ KITTY_KEYBOARD = "DEEPAGENTS_CLI_KITTY_KEYBOARD"
56
+ """Override kitty-keyboard detection (`1` forces on, `0` forces off)."""
57
+
55
58
  LANGSMITH_PROJECT = "DEEPAGENTS_CLI_LANGSMITH_PROJECT"
56
59
  """Override LangSmith project name for agent traces."""
57
60
 
@@ -0,0 +1,66 @@
1
+ r"""Preserve the `alt` modifier on legacy `ESC + <byte>` sequences.
2
+
3
+ Upstream `XTermParser._sequence_to_key_events` drops the `alt` flag on
4
+ the tuple-branch fast path, so VSCode's `sendSequence` shift+enter
5
+ binding (which writes `\x1b\r` to the PTY) arrives as bare `enter`
6
+ instead of `alt+enter`. Tracked in Textualize/textual#6378. Remove this
7
+ file and the Textual pin comment in `pyproject.toml` when that lands.
8
+
9
+ Imported for side effect from `app.py` before any `App()` is created.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import logging
15
+ from typing import TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from collections.abc import Iterable
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+ _ESC_PREFIX_LEN = 2
23
+
24
+ try:
25
+ from textual import events
26
+ from textual._ansi_sequences import (
27
+ ANSI_SEQUENCES_KEYS, # noqa: PLC2701
28
+ IGNORE_SEQUENCE, # noqa: PLC2701
29
+ )
30
+ from textual._xterm_parser import XTermParser # noqa: PLC2701
31
+
32
+ _original = XTermParser._sequence_to_key_events
33
+ except (ImportError, AttributeError) as exc: # pragma: no cover - defensive
34
+ logger.warning("Textual keyboard parser patch skipped: %s", exc)
35
+ else:
36
+
37
+ def _emit_alt(keys: tuple, character: str | None) -> Iterable[events.Key]:
38
+ for key in keys:
39
+ yield events.Key(f"alt+{key.value}", character)
40
+
41
+ def _sequence_to_key_events_with_alt(
42
+ self: XTermParser, sequence: str, alt: bool = False
43
+ ) -> Iterable[events.Key]:
44
+ # Fast path: \x1b<byte> on first pass. Short-circuits the ~100 ms
45
+ # escape-delay wait when both bytes arrive together. Semantic side
46
+ # effect: \x1b\x1b dispatches as `alt+escape` with no delay, matching
47
+ # crossterm and Node TTY.
48
+ if not alt and len(sequence) == _ESC_PREFIX_LEN and sequence[0] == "\x1b":
49
+ inner = ANSI_SEQUENCES_KEYS.get(sequence[1])
50
+ if inner is not IGNORE_SEQUENCE and isinstance(inner, tuple):
51
+ yield from _emit_alt(inner, None)
52
+ return
53
+ # Correctness fix (Textualize/textual#6378): preserve `alt` on the
54
+ # reissue path for single-byte tuple mappings.
55
+ if alt:
56
+ keys = ANSI_SEQUENCES_KEYS.get(sequence)
57
+ if keys is not IGNORE_SEQUENCE and isinstance(keys, tuple):
58
+ character = sequence if len(sequence) == 1 else None
59
+ yield from _emit_alt(keys, character)
60
+ return
61
+ yield from _original(self, sequence, alt=alt)
62
+
63
+ try:
64
+ XTermParser._sequence_to_key_events = _sequence_to_key_events_with_alt # ty: ignore[invalid-assignment]
65
+ except (AttributeError, TypeError) as exc: # pragma: no cover - defensive
66
+ logger.warning("Textual keyboard parser patch assignment rejected: %s", exc)
@@ -1,6 +1,6 @@
1
1
  """Version information and lightweight constants for `deepagents-cli`."""
2
2
 
3
- __version__ = "0.0.41" # x-release-please-version
3
+ __version__ = "0.0.43" # 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."""
@@ -16,6 +16,18 @@ from deepagents.backends import CompositeBackend, LocalShellBackend
16
16
  from deepagents.backends.filesystem import FilesystemBackend
17
17
  from deepagents.middleware import MemoryMiddleware, SkillsMiddleware
18
18
 
19
+ # Backwards-compat flag: SDKs before 0.5.4 accept only `list[str]` for
20
+ # `SkillsMiddleware.sources`; newer SDKs expose the `SkillSource` alias
21
+ # that permits `(path, label)` tuples. The `skills` module is already
22
+ # loaded by the `SkillsMiddleware` import above, so the extra lookup
23
+ # here adds no startup cost.
24
+ try:
25
+ from deepagents.middleware.skills import SkillSource as _SkillSource # noqa: F401
26
+ except ImportError:
27
+ _SUPPORTS_SKILL_SOURCE_TUPLES = False
28
+ else:
29
+ _SUPPORTS_SKILL_SOURCE_TUPLES = True
30
+
19
31
  if TYPE_CHECKING:
20
32
  from collections.abc import Awaitable, Callable, Sequence
21
33
 
@@ -1116,25 +1128,40 @@ def create_cli_agent(
1116
1128
  # built-in -> user .deepagents -> user .agents
1117
1129
  # -> project .deepagents -> project .agents
1118
1130
  # -> user .claude (experimental) -> project .claude (experimental)
1119
- sources = [str(settings.get_built_in_skills_dir())]
1120
- sources.extend([str(skills_dir), str(user_agent_skills_dir)])
1131
+ # Labels disambiguate user- vs project-scoped sources that share a
1132
+ # `.../skills` leaf; the middleware would otherwise derive identical
1133
+ # labels from the parent directory name.
1134
+ sources: list[tuple[str, str]] = [
1135
+ (str(settings.get_built_in_skills_dir()), "Built-in"),
1136
+ (str(skills_dir), "User Deepagents"),
1137
+ (str(user_agent_skills_dir), "User Agents"),
1138
+ ]
1121
1139
  if project_skills_dir:
1122
- sources.append(str(project_skills_dir))
1140
+ sources.append((str(project_skills_dir), "Project Deepagents"))
1123
1141
  if project_agent_skills_dir:
1124
- sources.append(str(project_agent_skills_dir))
1142
+ sources.append((str(project_agent_skills_dir), "Project Agents"))
1125
1143
 
1126
1144
  # Experimental: Claude Code skill directories
1127
1145
  user_claude_skills_dir = settings.get_user_claude_skills_dir()
1128
1146
  if user_claude_skills_dir.exists():
1129
- sources.append(str(user_claude_skills_dir))
1147
+ sources.append((str(user_claude_skills_dir), "User Claude"))
1130
1148
  project_claude_skills_dir = settings.get_project_claude_skills_dir()
1131
1149
  if project_claude_skills_dir:
1132
- sources.append(str(project_claude_skills_dir))
1150
+ sources.append((str(project_claude_skills_dir), "Project Claude"))
1151
+
1152
+ # Backwards-compat: strip labels when the installed SDK is too old
1153
+ # to accept `(path, label)` tuples. Label-based disambiguation
1154
+ # regresses to the pre-alias behavior (user- and project-scoped
1155
+ # `.claude/skills` collapse to the same label), but functionality
1156
+ # is preserved.
1157
+ middleware_sources: Sequence[str | tuple[str, str]] = (
1158
+ sources if _SUPPORTS_SKILL_SOURCE_TUPLES else [path for path, _ in sources]
1159
+ )
1133
1160
 
1134
1161
  agent_middleware.append(
1135
1162
  SkillsMiddleware(
1136
1163
  backend=FilesystemBackend(),
1137
- sources=sources,
1164
+ sources=middleware_sources,
1138
1165
  )
1139
1166
  )
1140
1167
 
@@ -33,7 +33,11 @@ from textual.widgets._toast import (
33
33
  Toast as _Toast, # noqa: PLC2701 # for Toast click routing
34
34
  )
35
35
 
36
- from deepagents_cli import theme
36
+ # Applied as an import-time side effect; must come before any App is created.
37
+ from deepagents_cli import (
38
+ _textual_patches, # noqa: F401
39
+ theme,
40
+ )
37
41
  from deepagents_cli._cli_context import CLIContext
38
42
  from deepagents_cli._git import (
39
43
  read_git_branch_from_filesystem,
@@ -6370,6 +6374,24 @@ class DeepAgentsApp(App):
6370
6374
  model_spec = model_spec.removeprefix(":")
6371
6375
 
6372
6376
  if not self._remote_agent():
6377
+ if self._connecting:
6378
+ from functools import partial
6379
+
6380
+ self._defer_action(
6381
+ DeferredAction(
6382
+ kind="model_switch",
6383
+ execute=partial(
6384
+ self._switch_model,
6385
+ model_spec,
6386
+ extra_kwargs=extra_kwargs,
6387
+ ),
6388
+ )
6389
+ )
6390
+ self.notify(
6391
+ "Model will switch once the session is ready.",
6392
+ timeout=3,
6393
+ )
6394
+ return
6373
6395
  await self._mount_message(
6374
6396
  ErrorMessage("Model switching requires a server-backed session.")
6375
6397
  )
@@ -496,14 +496,22 @@ def is_ascii_mode() -> bool:
496
496
 
497
497
 
498
498
  def newline_shortcut() -> str:
499
- """Return the platform-native label for the newline keyboard shortcut.
499
+ """Return the terminal-appropriate label for the newline keyboard shortcut.
500
500
 
501
- macOS labels the modifier "Option" while other platforms use Ctrl+J
502
- as the most reliable cross-terminal shortcut.
501
+ Prefers `Shift+Enter` when the terminal is known to support the kitty
502
+ keyboard protocol, either via conservative terminal-identity heuristics
503
+ or the `DEEPAGENTS_CLI_KITTY_KEYBOARD` override. Falls back to
504
+ `Option+Enter` on macOS and `Ctrl+J` elsewhere — both survive legacy
505
+ terminals that strip the shift modifier from `Enter`.
503
506
 
504
507
  Returns:
505
- A human-readable shortcut string, e.g. `'Option+Enter'` or `'Ctrl+J'`.
508
+ A human-readable shortcut string,
509
+ e.g. `'Shift+Enter'`, `'Option+Enter'`, or `'Ctrl+J'`.
506
510
  """
511
+ from deepagents_cli.terminal_capabilities import supports_kitty_keyboard_protocol
512
+
513
+ if supports_kitty_keyboard_protocol():
514
+ return "Shift+Enter"
507
515
  return "Option+Enter" if sys.platform == "darwin" else "Ctrl+J"
508
516
 
509
517
 
@@ -1854,36 +1862,52 @@ _OPENROUTER_APP_TITLE = "Deep Agents CLI"
1854
1862
  _OPENROUTER_APP_CATEGORIES: list[str] = ["cli-agent"]
1855
1863
  """Default `app_categories` (maps to `X-OpenRouter-Categories`) for OpenRouter."""
1856
1864
 
1865
+ _cli_openrouter_profile_registered = False
1866
+ """Process-wide guard so the CLI OpenRouter profile is registered exactly once."""
1857
1867
 
1858
- def _apply_openrouter_defaults(kwargs: dict[str, Any]) -> None:
1859
- """Inject default OpenRouter attribution kwargs.
1860
1868
 
1861
- Sets `app_url`, `app_title`, and `app_categories` via `setdefault` so
1862
- that user-supplied values in config take precedence. These map to the
1863
- `HTTP-Referer`, `X-Title`, and `X-OpenRouter-Categories` headers that
1864
- `ChatOpenRouter` sends for app attribution
1865
- (see https://openrouter.ai/docs/app-attribution).
1869
+ def _cli_openrouter_attribution_kwargs() -> dict[str, Any]:
1870
+ """CLI-specific OpenRouter attribution kwargs.
1866
1871
 
1867
- Users can override either value provider-wide or per-model in
1868
- `~/.deepagents/config.toml`:
1872
+ Layered on top of the SDK's built-in factory via profile stacking; these
1873
+ values override the SDK defaults but still sit beneath any caller-supplied
1874
+ `kwargs` (i.e. `config.toml`-resolved values), preserving the precedence
1875
+ documented on `apply_provider_profile`.
1869
1876
 
1870
- ```toml
1871
- # Provider-wide
1872
- [models.providers.openrouter.params]
1873
- app_url = "https://myapp.com"
1874
- app_title = "My App"
1877
+ Returns:
1878
+ Mapping of `app_url` and `app_title` to spread into `init_chat_model`.
1879
+ """
1880
+ return {
1881
+ "app_url": _OPENROUTER_APP_URL,
1882
+ "app_title": _OPENROUTER_APP_TITLE,
1883
+ }
1875
1884
 
1876
- # Per-model (shallow-merges on top of provider-wide)
1877
- [models.providers.openrouter.params."openai/gpt-oss-120b"]
1878
- app_title = "My App (GPT)"
1879
- ```
1880
1885
 
1881
- Args:
1882
- kwargs: Mutable kwargs dict to update in place.
1886
+ def _ensure_cli_openrouter_profile_registered() -> None:
1887
+ """Stack the CLI OpenRouter attribution onto the SDK's built-in profile.
1888
+
1889
+ Stacking (vs. duplicating the inline `_get_provider_kwargs` path) means the
1890
+ SDK's `pre_init` version check fires exactly once and the CLI's app-
1891
+ attribution defaults are composed via the same `apply_provider_profile`
1892
+ path used for every other provider. `register_provider_profile` merges on
1893
+ top of the existing built-in registration: the CLI's `init_kwargs` and
1894
+ factory output win on shared keys, while the built-in's `pre_init` and
1895
+ factory still chain.
1883
1896
  """
1884
- kwargs.setdefault("app_url", _OPENROUTER_APP_URL)
1885
- kwargs.setdefault("app_title", _OPENROUTER_APP_TITLE)
1886
- kwargs.setdefault("app_categories", _OPENROUTER_APP_CATEGORIES)
1897
+ global _cli_openrouter_profile_registered # noqa: PLW0603
1898
+ if _cli_openrouter_profile_registered:
1899
+ return
1900
+
1901
+ from deepagents.profiles.provider import ProviderProfile, register_provider_profile
1902
+
1903
+ register_provider_profile(
1904
+ "openrouter",
1905
+ ProviderProfile(
1906
+ init_kwargs={"app_categories": _OPENROUTER_APP_CATEGORIES},
1907
+ init_kwargs_factory=_cli_openrouter_attribution_kwargs,
1908
+ ),
1909
+ )
1910
+ _cli_openrouter_profile_registered = True
1887
1911
 
1888
1912
 
1889
1913
  def _get_provider_kwargs(
@@ -1927,14 +1951,6 @@ def _get_provider_kwargs(
1927
1951
  if api_key:
1928
1952
  result["api_key"] = api_key
1929
1953
 
1930
- if provider == "openrouter":
1931
- from deepagents.profiles._openrouter import (
1932
- check_openrouter_version, # noqa: PLC2701
1933
- )
1934
-
1935
- check_openrouter_version()
1936
- _apply_openrouter_defaults(result)
1937
-
1938
1954
  return result
1939
1955
 
1940
1956
 
@@ -2242,6 +2258,37 @@ def create_model(
2242
2258
  # Provider-specific kwargs (with per-model overrides)
2243
2259
  kwargs = _get_provider_kwargs(provider, model_name=model_name)
2244
2260
 
2261
+ # Compose under existing kwargs: profile < config.toml < --model-params
2262
+ # (applied below). The CLI's OpenRouter profile is stacked on top of the
2263
+ # built-in SDK profile so its `pre_init` (version check) and factory
2264
+ # (app attribution) compose into a single `apply_provider_profile` call.
2265
+ if provider:
2266
+ from deepagents.profiles.provider import apply_provider_profile
2267
+
2268
+ if provider == "openrouter":
2269
+ _ensure_cli_openrouter_profile_registered()
2270
+
2271
+ spec = f"{provider}:{model_name}" if model_name else provider
2272
+ try:
2273
+ kwargs = apply_provider_profile(spec, kwargs)
2274
+ except ModelConfigError:
2275
+ raise
2276
+ except Exception as exc:
2277
+ # `pre_init` and `init_kwargs_factory` callables registered on a
2278
+ # `ProviderProfile` may raise arbitrary exceptions (e.g. an
2279
+ # `ImportError` from the OpenRouter min-version check). Surface
2280
+ # them as `ModelConfigError` so the CLI's error path renders an
2281
+ # actionable message instead of a raw stack trace.
2282
+ logger.debug(
2283
+ "ProviderProfile resolution for %r failed.", spec, exc_info=True
2284
+ )
2285
+ msg = (
2286
+ f"Failed to apply provider profile for '{spec}': {exc}. "
2287
+ f"Check that the provider package is installed and up to date, "
2288
+ f"or set explicit kwargs via `--model-params`."
2289
+ )
2290
+ raise ModelConfigError(msg) from exc
2291
+
2245
2292
  # CLI --model-params take highest priority
2246
2293
  if extra_kwargs:
2247
2294
  kwargs.update(extra_kwargs)
@@ -25,6 +25,8 @@ from __future__ import annotations
25
25
 
26
26
  import json
27
27
  import logging
28
+ import os
29
+ import re
28
30
  import shutil
29
31
  from pathlib import Path
30
32
  from typing import Any
@@ -39,6 +41,7 @@ from deepagents_cli.deploy.config import (
39
41
  load_subagents,
40
42
  )
41
43
  from deepagents_cli.deploy.templates import (
44
+ APP_PY_TEMPLATE,
42
45
  AUTH_BLOCKS,
43
46
  AUTH_ON_HANDLER,
44
47
  DEPLOY_GRAPH_TEMPLATE,
@@ -69,6 +72,97 @@ _MODEL_PROVIDER_DEPS: dict[str, str] = {
69
72
  }
70
73
  """Dependencies inferred from a provider: prefix on the model string."""
71
74
 
75
+ _FRONTEND_DIST_SRC = Path(__file__).parent / "frontend_dist"
76
+ """Location of the shipped pre-built frontend, inside this Python package."""
77
+
78
+ _FRONTEND_PLACEHOLDER_RE = re.compile(
79
+ r"window\.__DEEPAGENTS_CONFIG__\s*=\s*\{[^<]*?\};",
80
+ re.DOTALL,
81
+ )
82
+ """Matches the placeholder script we injected into index.html at build time."""
83
+
84
+
85
+ def _build_runtime_config_json(config: DeployConfig) -> str:
86
+ """Build the JSON value injected into `window.__DEEPAGENTS_CONFIG__`.
87
+
88
+ Only reached when `[frontend].enabled` and `[auth]` is set —
89
+ validation guarantees both. The `is None` guards below exist so
90
+ the optional fields narrow for type-checkers.
91
+ """
92
+ if config.frontend is None:
93
+ msg = "runtime config requires [frontend] to be configured"
94
+ raise ValueError(msg)
95
+ if config.auth is None:
96
+ msg = "runtime config requires [auth] to be configured"
97
+ raise ValueError(msg)
98
+
99
+ app_name = config.frontend.app_name or config.agent.name
100
+ payload: dict[str, Any] = {
101
+ "appName": app_name,
102
+ "assistantId": "agent",
103
+ }
104
+ # Optional UI-customization fields — only injected when the user
105
+ # set them, so the default-bundle case stays small.
106
+ if config.frontend.subtitle is not None:
107
+ payload["subtitle"] = config.frontend.subtitle
108
+ if config.frontend.prompts is not None:
109
+ payload["prompts"] = list(config.frontend.prompts)
110
+
111
+ provider = config.auth.provider
112
+ payload["auth"] = provider
113
+ if provider == "supabase":
114
+ payload["supabaseUrl"] = os.environ["SUPABASE_URL"]
115
+ payload["supabaseAnonKey"] = os.environ["SUPABASE_PUBLISHABLE_DEFAULT_KEY"]
116
+ elif provider == "clerk":
117
+ payload["clerkPublishableKey"] = os.environ["CLERK_PUBLISHABLE_KEY"]
118
+ elif provider == "anonymous":
119
+ # No env vars; payload["auth"] = "anonymous" is enough.
120
+ pass
121
+ else:
122
+ msg = f"Unknown auth provider for frontend: {provider}"
123
+ raise ValueError(msg)
124
+
125
+ # Escape `<` so a hostile or accidental `</script>` inside a string value
126
+ # can't break out of the inline <script> tag.
127
+ return json.dumps(payload, separators=(",", ":")).replace("<", "\\u003c")
128
+
129
+
130
+ def _copy_frontend_dist(config: DeployConfig, build_dir: Path) -> None:
131
+ """Copy the pre-built bundle into build_dir and rewrite the config placeholder."""
132
+ if not _FRONTEND_DIST_SRC.is_dir():
133
+ msg = (
134
+ f"Shipped frontend bundle not found at {_FRONTEND_DIST_SRC}. "
135
+ "Did you run `make build-frontends`?"
136
+ )
137
+ raise RuntimeError(msg)
138
+
139
+ dest = build_dir / "frontend_dist"
140
+ if dest.exists():
141
+ shutil.rmtree(dest)
142
+ shutil.copytree(_FRONTEND_DIST_SRC, dest)
143
+
144
+ index_html = dest / "index.html"
145
+ if not index_html.is_file():
146
+ msg = f"expected index.html inside {_FRONTEND_DIST_SRC}"
147
+ raise RuntimeError(msg)
148
+
149
+ html = index_html.read_text(encoding="utf-8")
150
+ payload = _build_runtime_config_json(config)
151
+ replacement = f"window.__DEEPAGENTS_CONFIG__ = {payload};"
152
+ new_html, count = _FRONTEND_PLACEHOLDER_RE.subn(
153
+ lambda _m: replacement,
154
+ html,
155
+ count=1,
156
+ )
157
+ if count == 0:
158
+ msg = (
159
+ "Could not find window.__DEEPAGENTS_CONFIG__ placeholder in the "
160
+ "shipped index.html. The frontend bundle is out of sync with the "
161
+ "bundler — rebuild with `make build-frontends`."
162
+ )
163
+ raise RuntimeError(msg)
164
+ index_html.write_text(new_html, encoding="utf-8")
165
+
72
166
 
73
167
  def bundle(
74
168
  config: DeployConfig,
@@ -127,18 +221,38 @@ def bundle(
127
221
  )
128
222
  logger.info("Generated deploy_graph.py")
129
223
 
130
- # 6. Generate auth.py if [auth] is configured.
131
- auth_present = config.auth is not None
132
- if config.auth is not None:
224
+ # 6. Generate auth.py from the [auth] provider, if any. Skipped
225
+ # entirely when [auth] is omitted — in that case LangSmith Cloud's
226
+ # default x-api-key auth applies. Validation guarantees [auth] is
227
+ # set whenever [frontend].enabled, so auth.py is always present
228
+ # for frontend deploys (including the "anonymous" provider, whose
229
+ # permissive handler lets the bundled UI reach /threads).
230
+ frontend_enabled = config.frontend is not None and config.frontend.enabled
231
+ auth_provider: str | None = (
232
+ config.auth.provider if config.auth is not None else None
233
+ )
234
+
235
+ auth_present = auth_provider is not None
236
+ if auth_provider is not None:
133
237
  (build_dir / "auth.py").write_text(
134
- _render_auth_py(config.auth.provider),
238
+ _render_auth_py(auth_provider),
135
239
  encoding="utf-8",
136
240
  )
137
- logger.info("Generated auth.py (%s)", config.auth.provider)
241
+ logger.info("Generated auth.py (%s)", auth_provider)
242
+
243
+ # 6b. Copy frontend bundle when enabled.
244
+ if frontend_enabled:
245
+ _copy_frontend_dist(config, build_dir)
246
+ (build_dir / "app.py").write_text(APP_PY_TEMPLATE, encoding="utf-8")
247
+ logger.info("Copied frontend bundle and wrote app.py (%s)", auth_provider)
138
248
 
139
249
  # 7. Render langgraph.json.
140
250
  (build_dir / "langgraph.json").write_text(
141
- _render_langgraph_json(env_present=env_present, auth_present=auth_present),
251
+ _render_langgraph_json(
252
+ env_present=env_present,
253
+ auth_present=auth_present,
254
+ frontend_present=frontend_enabled,
255
+ ),
142
256
  encoding="utf-8",
143
257
  )
144
258
 
@@ -312,8 +426,13 @@ def _render_auth_py(provider: str) -> str:
312
426
  return auth_block + AUTH_ON_HANDLER
313
427
 
314
428
 
315
- def _render_langgraph_json(*, env_present: bool, auth_present: bool = False) -> str:
316
- """Render `langgraph.json` — adds `"env"` and `"auth"` when applicable."""
429
+ def _render_langgraph_json(
430
+ *,
431
+ env_present: bool,
432
+ auth_present: bool = False,
433
+ frontend_present: bool = False,
434
+ ) -> str:
435
+ """Render `langgraph.json` — adds `"env"`, `"auth"`, `"http"` when applicable."""
317
436
  data: dict = {
318
437
  "dependencies": ["."],
319
438
  "graphs": {"agent": "./deploy_graph.py:make_graph"},
@@ -323,6 +442,8 @@ def _render_langgraph_json(*, env_present: bool, auth_present: bool = False) ->
323
442
  data["env"] = ".env"
324
443
  if auth_present:
325
444
  data["auth"] = {"path": "./auth.py:auth"}
445
+ if frontend_present:
446
+ data["http"] = {"app": "./app.py:app"}
326
447
  return json.dumps(data, indent=2) + "\n"
327
448
 
328
449
 
@@ -392,7 +513,12 @@ def print_bundle_summary(config: DeployConfig, build_dir: Path) -> None:
392
513
  print(f"\n Agent: {config.agent.name}")
393
514
  print(f" Model: {config.agent.model}")
394
515
  if config.auth is not None:
395
- print(f" Auth: {config.auth.provider}")
516
+ if config.auth.provider == "anonymous":
517
+ print(" Auth: anonymous (API open to anyone)")
518
+ else:
519
+ print(f" Auth: {config.auth.provider}")
520
+ else:
521
+ print(" Auth: none (LangSmith API key required to call the API)")
396
522
 
397
523
  memory_files = sorted(seed.get("memories", {}).keys())
398
524
  if memory_files: