cade-cli 0.17.0__tar.gz → 0.18.0__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 (220) hide show
  1. {cade_cli-0.17.0 → cade_cli-0.18.0}/PKG-INFO +2 -2
  2. {cade_cli-0.17.0 → cade_cli-0.18.0}/README.md +1 -1
  3. {cade_cli-0.17.0 → cade_cli-0.18.0}/pyproject.toml +1 -1
  4. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/daemon.py +17 -9
  5. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/mcp.py +45 -7
  6. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/mcp_hosts.py +140 -1
  7. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/onboarding.py +1 -1
  8. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/server.py +1 -1
  9. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/.claude-plugin/plugin.json +1 -1
  10. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/.cursor-plugin/plugin.json +1 -1
  11. {cade_cli-0.17.0 → cade_cli-0.18.0}/.gitignore +0 -0
  12. {cade_cli-0.17.0 → cade_cli-0.18.0}/LICENSE +0 -0
  13. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/__init__.py +0 -0
  14. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/__main__.py +0 -0
  15. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/_metadata.py +0 -0
  16. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/config.py +0 -0
  17. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/errors.py +0 -0
  18. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/grants.py +0 -0
  19. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/resources.py +0 -0
  20. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/sandbox.py +0 -0
  21. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/server.py +0 -0
  22. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/__init__.py +0 -0
  23. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/_read_cache.py +0 -0
  24. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/access.py +0 -0
  25. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/agents.py +0 -0
  26. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/filesystem.py +0 -0
  27. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/git.py +0 -0
  28. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/notifications.py +0 -0
  29. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/questions.py +0 -0
  30. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/results.py +0 -0
  31. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/schemas.py +0 -0
  32. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/search.py +0 -0
  33. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/shell.py +0 -0
  34. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/tasks.py +0 -0
  35. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/web_fetch.py +0 -0
  36. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/tools/web_search.py +0 -0
  37. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/utils.py +0 -0
  38. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/__init__.py +0 -0
  39. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/arcade_client.py +0 -0
  40. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/cache.py +0 -0
  41. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/extract.py +0 -0
  42. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/markdown.py +0 -0
  43. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/preapproved.py +0 -0
  44. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/prompts.py +0 -0
  45. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/scrape.py +0 -0
  46. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/search/__init__.py +0 -0
  47. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/search/arcade.py +0 -0
  48. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/search/base.py +0 -0
  49. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cade_mcp_local/web/search/http.py +0 -0
  50. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/__init__.py +0 -0
  51. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/ai/__init__.py +0 -0
  52. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/ai/prompts.py +0 -0
  53. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/__init__.py +0 -0
  54. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/app.py +0 -0
  55. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/auth.py +0 -0
  56. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/__init__.py +0 -0
  57. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/account.py +0 -0
  58. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/agent_group.py +0 -0
  59. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/agents.py +0 -0
  60. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/auth.py +0 -0
  61. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/chat.py +0 -0
  62. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/cron.py +0 -0
  63. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/grant.py +0 -0
  64. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/hooks.py +0 -0
  65. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/mem.py +0 -0
  66. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/tasks.py +0 -0
  67. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/thread.py +0 -0
  68. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/commands/tools.py +0 -0
  69. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/cli/ui.py +0 -0
  70. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/__init__.py +0 -0
  71. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/agent.py +0 -0
  72. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/binary.py +0 -0
  73. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/comms.py +0 -0
  74. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/config.py +0 -0
  75. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/constants.py +0 -0
  76. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/errors.py +0 -0
  77. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/frozen.py +0 -0
  78. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/git.py +0 -0
  79. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/inbox.py +0 -0
  80. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/logging.py +0 -0
  81. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/memory.py +0 -0
  82. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/model_specs.py +0 -0
  83. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/names.py +0 -0
  84. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/paths.py +0 -0
  85. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/runtime.py +0 -0
  86. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/secrets.py +0 -0
  87. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/spawn.py +0 -0
  88. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/text.py +0 -0
  89. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/core/types.py +0 -0
  90. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/__init__.py +0 -0
  91. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/adapters/__init__.py +0 -0
  92. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/adapters/base.py +0 -0
  93. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/adapters/factory.py +0 -0
  94. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/adapters/imessage.py +0 -0
  95. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/adapters/registry.py +0 -0
  96. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/adapters/stub.py +0 -0
  97. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/adapters/telegram.py +0 -0
  98. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/allowlist.py +0 -0
  99. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/attach.py +0 -0
  100. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/chunker.py +0 -0
  101. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/client.py +0 -0
  102. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/commands.py +0 -0
  103. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/config.py +0 -0
  104. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/control.py +0 -0
  105. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/cron.py +0 -0
  106. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/elicitation.py +0 -0
  107. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/ensure.py +0 -0
  108. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/format.py +0 -0
  109. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/__init__.py +0 -0
  110. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/app.py +0 -0
  111. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/auth.py +0 -0
  112. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/constants.py +0 -0
  113. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/elicitation.py +0 -0
  114. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/exposure.py +0 -0
  115. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/host_agent.py +0 -0
  116. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/limits.py +0 -0
  117. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/middleware.py +0 -0
  118. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/resources.py +0 -0
  119. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/subscriptions.py +0 -0
  120. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/gateway/turn_bridge.py +0 -0
  121. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/grants.py +0 -0
  122. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/inbox.py +0 -0
  123. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/inbox_cron.py +0 -0
  124. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/install.py +0 -0
  125. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/lock.py +0 -0
  126. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/mesh.py +0 -0
  127. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/message_pump.py +0 -0
  128. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/observability.py +0 -0
  129. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/owner.py +0 -0
  130. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/progress_sink.py +0 -0
  131. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/registry.py +0 -0
  132. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/router.py +0 -0
  133. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/runner.py +0 -0
  134. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/runner_main.py +0 -0
  135. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/secrets.py +0 -0
  136. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/secrets_broker.py +0 -0
  137. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/services.py +0 -0
  138. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/sinks.py +0 -0
  139. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/supervisor.py +0 -0
  140. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/tokens.py +0 -0
  141. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/traffic.py +0 -0
  142. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/turns.py +0 -0
  143. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/daemon/wake.py +0 -0
  144. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/execution/__init__.py +0 -0
  145. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/execution/context_window.py +0 -0
  146. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/execution/mcp_schema_index.py +0 -0
  147. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/execution/orchestrator.py +0 -0
  148. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/execution/parallel.py +0 -0
  149. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/execution/tool_result_store.py +0 -0
  150. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/execution/tool_schema_cache.py +0 -0
  151. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/__init__.py +0 -0
  152. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/config.py +0 -0
  153. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/engine.py +0 -0
  154. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/executors/__init__.py +0 -0
  155. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/executors/callback.py +0 -0
  156. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/executors/command.py +0 -0
  157. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/executors/http.py +0 -0
  158. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/executors/prompt.py +0 -0
  159. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/executors/ssrf_guard.py +0 -0
  160. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/matchers.py +0 -0
  161. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/registry.py +0 -0
  162. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/hooks/types.py +0 -0
  163. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/__init__.py +0 -0
  164. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/.claude-plugin/marketplace.json +0 -0
  165. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/.cursor-plugin/marketplace.json +0 -0
  166. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/agents/operator.md +0 -0
  167. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/commands/ask.md +0 -0
  168. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/commands/memory.md +0 -0
  169. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/commands/tasks.md +0 -0
  170. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/mcp.json +0 -0
  171. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/rules/gateway.mdc +0 -0
  172. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/skills/ask/SKILL.md +0 -0
  173. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/skills/memory/SKILL.md +0 -0
  174. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/assets/skills/tasks/SKILL.md +0 -0
  175. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/doctor.py +0 -0
  176. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/install.py +0 -0
  177. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/paths.py +0 -0
  178. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/host_plugin/state.py +0 -0
  179. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/providers/__init__.py +0 -0
  180. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/providers/anthropic.py +0 -0
  181. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/providers/base.py +0 -0
  182. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/providers/http_client.py +0 -0
  183. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/providers/ollama.py +0 -0
  184. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/providers/openai.py +0 -0
  185. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/storage/__init__.py +0 -0
  186. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/storage/threads.py +0 -0
  187. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tasks/__init__.py +0 -0
  188. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tasks/scheduler.py +0 -0
  189. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tasks/store.py +0 -0
  190. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tasks/types.py +0 -0
  191. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/templates/login_failed.html +0 -0
  192. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/templates/login_success.html +0 -0
  193. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/templates/serve/launchd.plist.tmpl +0 -0
  194. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/templates/serve/serve.toml.example +0 -0
  195. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/templates/serve/systemd.service.tmpl +0 -0
  196. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/templates/styles.css +0 -0
  197. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/__init__.py +0 -0
  198. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/manager/__init__.py +0 -0
  199. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/manager/_request_ctx.py +0 -0
  200. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/manager/base.py +0 -0
  201. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/manager/composite.py +0 -0
  202. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/manager/config.py +0 -0
  203. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/manager/mcp.py +0 -0
  204. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/search/__init__.py +0 -0
  205. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/search/discovered.py +0 -0
  206. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/search/scoring.py +0 -0
  207. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/tools/search/service.py +0 -0
  208. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/ui/__init__.py +0 -0
  209. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/ui/completion.py +0 -0
  210. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/ui/display.py +0 -0
  211. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/ui/elicitation.py +0 -0
  212. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/ui/input.py +0 -0
  213. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/ui/session.py +0 -0
  214. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/ui/slash.py +0 -0
  215. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/voice/__init__.py +0 -0
  216. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/voice/audio.py +0 -0
  217. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/voice/cleanup.py +0 -0
  218. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/voice/session.py +0 -0
  219. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/voice/stt.py +0 -0
  220. {cade_cli-0.17.0 → cade_cli-0.18.0}/src/cadecoder/voice/tts.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cade-cli
3
- Version: 0.17.0
3
+ Version: 0.18.0
4
4
  Summary: Cade - The CLI Agent from Arcade.dev (install: curl -fsSL https://arcadeagent.dev/install | sh)
5
5
  Project-URL: Homepage, https://arcade.dev
6
6
  Project-URL: Documentation, https://arcadeagent.dev/docs
@@ -104,7 +104,7 @@ toolchain. First `cade` walks you through model setup, Arcade login, and
104
104
  Arcade cloud tools. Re-run the same curl to upgrade.
105
105
 
106
106
  New here? The [Quickstart](docs/quickstart.md) is the shortest path to a
107
- working session; [Use Cade in Cursor](docs/use-in-cursor.md) is the same thing
107
+ working session; [Connect Cade to your AI app](docs/use-in-cursor.md) is the same thing
108
108
  without a terminal. Everything else is in [docs/](docs/index.md).
109
109
 
110
110
  ---
@@ -13,7 +13,7 @@ toolchain. First `cade` walks you through model setup, Arcade login, and
13
13
  Arcade cloud tools. Re-run the same curl to upgrade.
14
14
 
15
15
  New here? The [Quickstart](docs/quickstart.md) is the shortest path to a
16
- working session; [Use Cade in Cursor](docs/use-in-cursor.md) is the same thing
16
+ working session; [Connect Cade to your AI app](docs/use-in-cursor.md) is the same thing
17
17
  without a terminal. Everything else is in [docs/](docs/index.md).
18
18
 
19
19
  ---
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cade-cli"
3
- version = "0.17.0"
3
+ version = "0.18.0"
4
4
  description = "Cade - The CLI Agent from Arcade.dev (install: curl -fsSL https://arcadeagent.dev/install | sh)"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -6,7 +6,6 @@ One process serves every agent to MCP hosts and messaging adapters.
6
6
  from __future__ import annotations
7
7
 
8
8
  import asyncio
9
- import json
10
9
  import os
11
10
  import signal
12
11
  import sys
@@ -110,7 +109,7 @@ def start(
110
109
  typer.Option(
111
110
  "--auth/--no-auth",
112
111
  help=(
113
- "Require bearer tokens. Default: off on loopback (stdio MCP hosts / "
112
+ "Require bearer tokens. Default: off on loopback (local MCP hosts / "
114
113
  "CLI attach), on for non-loopback binds. --no-auth is refused off-loopback."
115
114
  ),
116
115
  ),
@@ -175,7 +174,15 @@ def status(
175
174
  if prewarm:
176
175
  console.print(f" prewarmed agents: {', '.join(prewarm)}")
177
176
  else:
178
- console.print("[dim]○ cade daemon NOT RUNNING[/dim] (start: cade daemon start)")
177
+ # Someone checking status is usually here because an MCP host could not
178
+ # reach Cade, and hosts cannot start it — so name the fix that keeps it
179
+ # up rather than `start`, which only holds the current terminal. With a
180
+ # unit already installed, `start` would also spawn a second daemon
181
+ # outside the service manager; restart drives the unit instead.
182
+ from cadecoder.daemon.install import service_install_hint, service_installed
183
+
184
+ fix = "cade daemon restart" if service_installed() else service_install_hint()
185
+ console.print(f"[dim]○ cade daemon NOT RUNNING[/dim] (start: {fix})")
179
186
 
180
187
  store = TokenStore()
181
188
  try:
@@ -354,17 +361,18 @@ def init(
354
361
 
355
362
  def _host_config_json() -> str:
356
363
  """Return the MCP-host JSON snippet for a manually configured host."""
357
- from cadecoder.cli.mcp_hosts import http_entry
364
+ from cadecoder.cli.mcp_hosts import client_recipe
358
365
 
359
- return json.dumps({"mcpServers": {"cade": http_entry()}}, indent=2)
366
+ return client_recipe("generic").to_json()
360
367
 
361
368
 
362
369
  def _report_mcp_hosts(*, print_config: bool) -> None:
363
370
  """Tell the user how their MCP hosts get configured.
364
371
 
365
- Autodetection handles Cursor, Claude Desktop, Claude Code, OpenCode, and
366
- Windsurf, so the JSON snippet is a fallback for hosts we cannot find (or
367
- for anyone who explicitly asked for it), not the headline instruction.
372
+ Autodetection handles Cursor, Claude Desktop, Claude Code, OpenCode,
373
+ Windsurf, and VS Code, so the JSON snippet is a fallback for hosts we
374
+ cannot find (or for anyone who explicitly asked for it), not the headline
375
+ instruction. ``cade mcp config <app>`` gives per-app variants.
368
376
 
369
377
  Args:
370
378
  print_config: Force the raw JSON snippet to be shown.
@@ -396,7 +404,7 @@ def _report_mcp_hosts(*, print_config: bool) -> None:
396
404
  else:
397
405
  console.print(
398
406
  "\n[yellow]No MCP hosts detected[/yellow] "
399
- "(looked for Cursor, Claude Desktop, Claude Code, OpenCode, Windsurf)."
407
+ "(looked for Cursor, Claude Desktop, Claude Code, OpenCode, Windsurf, VS Code)."
400
408
  )
401
409
  console.print(
402
410
  "Install one and run [bold]cade mcp install-hosts[/bold], or add this "
@@ -694,9 +694,10 @@ def install_hosts_cmd(
694
694
  ) -> None:
695
695
  """Register Cade as an MCP server and install the host plugin.
696
696
 
697
- Points Cursor, Claude Code, OpenCode, and Windsurf at the daemon's HTTP
698
- endpoint; Claude Desktop gets an ``npx mcp-remote`` bridge because its
699
- config file only accepts stdio entries. Also materializes a
697
+ Points Cursor, Claude Code, OpenCode, Windsurf, and VS Code (Copilot) at
698
+ the daemon's HTTP endpoint; Claude Desktop gets an ``npx mcp-remote``
699
+ bridge because its config file only accepts stdio entries. For an app that
700
+ is not detected, ``cade mcp config <app>`` prints what to paste. Also materializes a
700
701
  marketplace-shaped plugin at ``~/.cade/host-plugin`` and
701
702
  ``~/.cursor/plugins/local/cade`` (plus Claude Code user skills).
702
703
 
@@ -721,12 +722,12 @@ def install_hosts_cmd(
721
722
  if not updates and all(u.status == "skipped" for u in plugin_updates):
722
723
  console.print(
723
724
  "[dim]No MCP hosts detected (looked for Cursor, Claude Desktop, "
724
- "Claude Code, OpenCode, Windsurf).[/dim]"
725
+ "Claude Code, OpenCode, Windsurf, VS Code).[/dim]"
725
726
  )
726
727
  console.print(
727
728
  "[dim]After installing a host, re-run [bold]cade mcp install-hosts[/bold] — "
728
- "it writes each host's config for you. For a host Cade cannot detect, "
729
- "[bold]cade daemon init --print-config[/bold] prints the JSON to add by hand.[/dim]"
729
+ "it writes each host's config for you. For an app Cade cannot detect "
730
+ "(Cowork, for one), [bold]cade mcp config <app>[/bold] prints what to paste.[/dim]"
730
731
  )
731
732
  return
732
733
 
@@ -768,11 +769,48 @@ def install_hosts_cmd(
768
769
  console.print(" 2. Reload Cursor/Claude (quit and reopen, or Developer: Reload Window)")
769
770
  console.print(" 3. In chat: [bold]Ask Cade to say hello[/bold]")
770
771
  console.print(" 4. Check: [bold]cade doctor[/bold]")
771
- console.print("[dim]Guide: docs → Use Cade in Cursor[/dim]")
772
+ console.print("[dim]Guide: https://arcadeagent.dev/docs/use-in-cursor/[/dim]")
772
773
  else:
773
774
  console.print(f"\n[dim]Dry run — {changed} change(s) would apply.[/dim]")
774
775
 
775
776
 
777
+ @mcp_app.command("config", rich_help_panel=PANEL_HOSTS)
778
+ def config_cmd(
779
+ client: Annotated[
780
+ str,
781
+ typer.Argument(
782
+ help="Which app: generic, cowork, vscode (or copilot), claude-desktop.",
783
+ ),
784
+ ] = "generic",
785
+ ) -> None:
786
+ """Print the config to paste into an AI app Cade cannot set up itself.
787
+
788
+ `cade mcp install-hosts` handles Cursor, Claude Code, Claude Desktop,
789
+ OpenCode, Windsurf, and VS Code. Use this for anything else — Cowork, whose
790
+ config is per-project, or an app that was not detected.
791
+ """
792
+ from cadecoder.cli.mcp_hosts import CLIENT_NAMES, client_recipe
793
+ from cadecoder.daemon.services import gateway_endpoint, read_gateway_manifest
794
+
795
+ try:
796
+ recipe = client_recipe(client, endpoint=gateway_endpoint())
797
+ except KeyError:
798
+ fail(f"Unknown app '{client}'. Try one of: {', '.join(CLIENT_NAMES)}")
799
+ return
800
+
801
+ console.print(f"[bold]{recipe.label}[/bold] [dim]— add to {recipe.where}[/dim]\n")
802
+ console.print(recipe.to_json())
803
+ if recipe.note:
804
+ console.print(f"\n[dim]{recipe.note}[/dim]")
805
+ # The URL above is only reachable if something is serving it, and no app
806
+ # starts Cade on its own — so a snippet without a daemon is a dead end.
807
+ if read_gateway_manifest() is None:
808
+ from cadecoder.daemon.install import service_install_hint, service_installed
809
+
810
+ fix = "cade daemon restart" if service_installed() else service_install_hint()
811
+ console.print(f"\n[yellow]Cade is not running[/yellow] [dim]— start it with: {fix}[/dim]")
812
+
813
+
776
814
  @mcp_app.command("token-info", rich_help_panel=PANEL_HOSTS)
777
815
  def token_info(
778
816
  name: Annotated[str, typer.Argument(help="Name of the server")],
@@ -1,7 +1,7 @@
1
1
  """Register Cade as an MCP server in detected AI host apps.
2
2
 
3
3
  Scans typical home-directory config locations for Claude Desktop, Cursor,
4
- Claude Code, OpenCode, and Windsurf. When a host's config dir (or file)
4
+ Claude Code, OpenCode, Windsurf, and VS Code (Copilot). When a host's config dir (or file)
5
5
  already exists, merges a ``cade`` entry pointing at the daemon's Streamable
6
6
  HTTP endpoint, so no per-host process is involved.
7
7
 
@@ -45,6 +45,7 @@ class HostKind(str, Enum):
45
45
  CLAUDE_DESKTOP = "claudeDesktop" # mcpServers, but stdio-only — needs a bridge
46
46
  OPENCODE = "opencode" # OpenCode ``mcp`` map with type/url
47
47
  WINDSURF = "windsurf" # Windsurf mcp_config.json
48
+ VSCODE = "vscode" # VS Code / Copilot — root key ``servers``, explicit ``type``
48
49
 
49
50
 
50
51
  @dataclass(frozen=True)
@@ -139,6 +140,100 @@ def opencode_entry(*, endpoint: str | None = None) -> dict[str, Any]:
139
140
  }
140
141
 
141
142
 
143
+ def vscode_entry(*, endpoint: str | None = None) -> dict[str, Any]:
144
+ """VS Code / Copilot ``servers.<name>`` entry.
145
+
146
+ Unlike every other host here, VS Code will not infer the transport: a block
147
+ without an explicit ``type`` is invalid and Copilot drops it with only a
148
+ line in an output channel, so the tool silently never appears.
149
+ """
150
+ return {"type": "http", "url": endpoint or gateway_endpoint()}
151
+
152
+
153
+ @dataclass(frozen=True)
154
+ class ClientRecipe:
155
+ """A paste-ready MCP config for a client Cade cannot configure itself."""
156
+
157
+ label: str
158
+ config: dict[str, Any]
159
+ where: str
160
+ note: str = ""
161
+
162
+ def to_json(self) -> str:
163
+ """The snippet, formatted the way it should appear in the file."""
164
+ return json.dumps(self.config, indent=2)
165
+
166
+
167
+ def client_recipe(client: str, *, endpoint: str | None = None) -> ClientRecipe:
168
+ """Config snippet plus where it goes, for one MCP client.
169
+
170
+ Covers the clients that ``install-hosts`` cannot write for itself — either
171
+ because their config is per-project (Cowork) or because the user is pasting
172
+ into an app we do not detect.
173
+
174
+ Args:
175
+ client: One of ``cowork``, ``vscode``/``copilot``, ``claude-desktop``,
176
+ or ``generic``.
177
+ endpoint: Gateway URL to embed. Defaults to the running daemon's.
178
+
179
+ Returns:
180
+ The recipe for that client.
181
+
182
+ Raises:
183
+ KeyError: If ``client`` is not a known name.
184
+
185
+ Example:
186
+ >>> client_recipe("cowork").config["mcpServers"]["cade"]["type"]
187
+ 'streamable-http'
188
+ """
189
+ url = endpoint or gateway_endpoint()
190
+ key = client.strip().lower()
191
+ if key in ("vscode", "copilot", "vs-code"):
192
+ return ClientRecipe(
193
+ label="VS Code / GitHub Copilot",
194
+ config={"servers": {SERVER_KEY: vscode_entry(endpoint=url)}},
195
+ where="Command Palette → 'MCP: Open User Configuration', "
196
+ "or .vscode/mcp.json in your project",
197
+ note="VS Code keys this 'servers', not 'mcpServers', and needs the "
198
+ "explicit 'type'. Copilot must be in Agent mode to use tools.",
199
+ )
200
+ if key == "cowork":
201
+ # Cowork's sandbox reaches tools only over HTTP, which is what the
202
+ # gateway already speaks — so unlike a stdio server it needs no bridge.
203
+ return ClientRecipe(
204
+ label="Claude Cowork",
205
+ config={
206
+ "mcpServers": {
207
+ SERVER_KEY: {"type": "streamable-http", "url": url},
208
+ }
209
+ },
210
+ where=".mcp.json in your project directory",
211
+ note="Start a new Cowork session afterwards. If it cannot reach "
212
+ "this address, its sandbox is isolated from your machine — bind "
213
+ "Cade to a reachable address with a token instead.",
214
+ )
215
+ if key in ("claude-desktop", "claudedesktop"):
216
+ return ClientRecipe(
217
+ label="Claude Desktop",
218
+ config={"mcpServers": {SERVER_KEY: mcp_remote_entry(endpoint=url)}},
219
+ where="claude_desktop_config.json",
220
+ note="Claude Desktop accepts stdio entries only, so this goes "
221
+ "through a bridge and needs Node.js 18+. 'cade mcp install-hosts' "
222
+ "writes it for you.",
223
+ )
224
+ if key == "generic":
225
+ return ClientRecipe(
226
+ label="Most MCP clients",
227
+ config={"mcpServers": {SERVER_KEY: {"type": "http", "url": url}}},
228
+ where="your app's MCP config file",
229
+ note="Restart the app afterwards — most read their config only at startup.",
230
+ )
231
+ raise KeyError(client)
232
+
233
+
234
+ CLIENT_NAMES = ("generic", "cowork", "vscode", "claude-desktop")
235
+
236
+
142
237
  def discover_hosts(home: Path | None = None) -> list[HostTarget]:
143
238
  """Return host configs that look installed (marker path exists)."""
144
239
  home = home or Path.home()
@@ -223,6 +318,25 @@ def discover_hosts(home: Path | None = None) -> list[HostTarget]:
223
318
  )
224
319
  )
225
320
 
321
+ # VS Code (GitHub Copilot). User-profile config, so it applies to every
322
+ # workspace; the per-workspace `.vscode/mcp.json` is the user's to manage.
323
+ for label, folder in (("VS Code", "Code"), ("VS Code Insiders", "Code - Insiders")):
324
+ if system == "Darwin":
325
+ user_dir = home / "Library" / "Application Support" / folder / "User"
326
+ elif system == "Windows":
327
+ appdata = os.environ.get("APPDATA", str(home / "AppData" / "Roaming"))
328
+ user_dir = Path(appdata) / folder / "User"
329
+ else:
330
+ user_dir = home / ".config" / folder / "User"
331
+ targets.append(
332
+ HostTarget(
333
+ name=label,
334
+ path=user_dir / "mcp.json",
335
+ kind=HostKind.VSCODE,
336
+ marker=user_dir,
337
+ )
338
+ )
339
+
226
340
  return [t for t in targets if t.marker.exists()]
227
341
 
228
342
 
@@ -322,6 +436,27 @@ def _merge_opencode(
322
436
  return data, "added" if existing is None else "updated"
323
437
 
324
438
 
439
+ def _merge_vscode(
440
+ data: dict[str, Any],
441
+ entry: dict[str, Any],
442
+ *,
443
+ force: bool,
444
+ ) -> tuple[dict[str, Any], str]:
445
+ """Merge into VS Code's ``servers`` map (not ``mcpServers``)."""
446
+ del force # same reasoning as _merge_mcp_servers: always take the new entry
447
+ servers = data.get("servers")
448
+ if servers is None:
449
+ servers = {}
450
+ data["servers"] = servers
451
+ if not isinstance(servers, dict):
452
+ raise ValueError("servers must be an object")
453
+ existing = servers.get(SERVER_KEY)
454
+ if existing == entry:
455
+ return data, "unchanged"
456
+ servers[SERVER_KEY] = entry
457
+ return data, "added" if existing is None else "updated"
458
+
459
+
325
460
  def _merge_windsurf(
326
461
  data: dict[str, Any],
327
462
  entry: dict[str, Any],
@@ -346,6 +481,9 @@ def register_host(
346
481
  if target.kind == HostKind.OPENCODE:
347
482
  entry = opencode_entry(endpoint=url)
348
483
  data, status = _merge_opencode(data, entry, force=force)
484
+ elif target.kind == HostKind.VSCODE:
485
+ entry = vscode_entry(endpoint=url)
486
+ data, status = _merge_vscode(data, entry, force=force)
349
487
  elif target.kind == HostKind.CLAUDE_DESKTOP:
350
488
  entry = mcp_remote_entry(endpoint=url)
351
489
  data, status = _merge_mcp_servers(data, entry, force=force)
@@ -395,4 +533,5 @@ __all__ = [
395
533
  "mcp_remote_entry",
396
534
  "opencode_entry",
397
535
  "register_host",
536
+ "vscode_entry",
398
537
  ]
@@ -337,7 +337,7 @@ def finish_first_run_cloud(console: Console, *, prefer_skip_login: bool = False)
337
337
  console.print(
338
338
  f"\n[yellow]Could not update:[/yellow] {names}\n"
339
339
  "[dim]Retry with [bold]cade mcp install-hosts --force[/bold], or see the "
340
- "config to add by hand with [bold]cade daemon init --print-config[/bold].[/dim]"
340
+ "config to add by hand with [bold]cade mcp config <app>[/bold].[/dim]"
341
341
  )
342
342
  if plugin_touched:
343
343
  migrated_n = sum(1 for u in plugin_touched if u.status == "migrated")
@@ -46,7 +46,7 @@ def resolve_require_auth(*, bind: str, auth: bool | None) -> bool:
46
46
  """Decide whether the gateway should require bearer tokens.
47
47
 
48
48
  When ``auth`` is ``None`` (CLI default), loopback binds run unauthenticated
49
- so stdio MCP hosts and CLI attach work without a token; non-loopback binds
49
+ so local MCP hosts and CLI attach work without a token; non-loopback binds
50
50
  require auth. Explicit ``--auth`` / ``--no-auth`` always win (subject to
51
51
  :func:`_guard_auth_bind`).
52
52
  """
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cade",
3
3
  "description": "Your persistent on-device agent: notes memory, durable tasks, and connected tools via Ask.",
4
- "version": "0.17.0",
4
+ "version": "0.18.0",
5
5
  "author": {
6
6
  "name": "Arcade.dev",
7
7
  "url": "https://docs.cade.dev"
@@ -2,7 +2,7 @@
2
2
  "name": "cade",
3
3
  "displayName": "Cade",
4
4
  "description": "Your persistent on-device agent: notes memory, durable tasks, and connected tools via Ask.",
5
- "version": "0.17.0",
5
+ "version": "0.18.0",
6
6
  "author": {
7
7
  "name": "Arcade.dev",
8
8
  "email": "support@arcade.dev"
File without changes
File without changes