cade-cli 0.16.1__tar.gz → 0.16.2__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 (200) hide show
  1. {cade_cli-0.16.1 → cade_cli-0.16.2}/PKG-INFO +4 -4
  2. {cade_cli-0.16.1 → cade_cli-0.16.2}/README.md +3 -3
  3. {cade_cli-0.16.1 → cade_cli-0.16.2}/pyproject.toml +1 -1
  4. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/app.py +18 -12
  5. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/auth.py +6 -6
  6. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/mcp.py +51 -19
  7. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/onboarding.py +173 -15
  8. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/__init__.py +4 -0
  9. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/config.py +32 -12
  10. {cade_cli-0.16.1 → cade_cli-0.16.2}/.gitignore +0 -0
  11. {cade_cli-0.16.1 → cade_cli-0.16.2}/LICENSE +0 -0
  12. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/__init__.py +0 -0
  13. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/__main__.py +0 -0
  14. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/_metadata.py +0 -0
  15. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/config.py +0 -0
  16. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/errors.py +0 -0
  17. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/grants.py +0 -0
  18. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/resources.py +0 -0
  19. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/sandbox.py +0 -0
  20. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/server.py +0 -0
  21. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/__init__.py +0 -0
  22. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/_read_cache.py +0 -0
  23. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/access.py +0 -0
  24. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/agents.py +0 -0
  25. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/context.py +0 -0
  26. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/filesystem.py +0 -0
  27. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/git.py +0 -0
  28. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/notifications.py +0 -0
  29. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/questions.py +0 -0
  30. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/results.py +0 -0
  31. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/schemas.py +0 -0
  32. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/search.py +0 -0
  33. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/shell.py +0 -0
  34. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/snippets.py +0 -0
  35. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/tasks.py +0 -0
  36. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/web_fetch.py +0 -0
  37. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/web_search.py +0 -0
  38. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/utils.py +0 -0
  39. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/__init__.py +0 -0
  40. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/arcade_client.py +0 -0
  41. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/cache.py +0 -0
  42. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/extract.py +0 -0
  43. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/markdown.py +0 -0
  44. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/preapproved.py +0 -0
  45. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/prompts.py +0 -0
  46. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/scrape.py +0 -0
  47. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/search/__init__.py +0 -0
  48. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/search/arcade.py +0 -0
  49. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/search/base.py +0 -0
  50. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/search/http.py +0 -0
  51. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/__init__.py +0 -0
  52. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ai/__init__.py +0 -0
  53. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ai/prompts.py +0 -0
  54. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/__init__.py +0 -0
  55. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/auth.py +0 -0
  56. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/__init__.py +0 -0
  57. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/account.py +0 -0
  58. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/agents.py +0 -0
  59. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/chat.py +0 -0
  60. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/cron.py +0 -0
  61. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/daemon.py +0 -0
  62. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/grant.py +0 -0
  63. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/hooks.py +0 -0
  64. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/mem.py +0 -0
  65. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/tasks.py +0 -0
  66. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/thread.py +0 -0
  67. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/tools.py +0 -0
  68. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/__init__.py +0 -0
  69. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/agent.py +0 -0
  70. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/comms.py +0 -0
  71. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/config.py +0 -0
  72. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/constants.py +0 -0
  73. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/errors.py +0 -0
  74. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/frozen.py +0 -0
  75. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/git.py +0 -0
  76. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/inbox.py +0 -0
  77. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/logging.py +0 -0
  78. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/memory.py +0 -0
  79. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/model_specs.py +0 -0
  80. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/names.py +0 -0
  81. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/paths.py +0 -0
  82. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/runtime.py +0 -0
  83. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/secrets.py +0 -0
  84. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/spawn.py +0 -0
  85. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/types.py +0 -0
  86. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/__init__.py +0 -0
  87. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/__init__.py +0 -0
  88. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/base.py +0 -0
  89. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/factory.py +0 -0
  90. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/imessage.py +0 -0
  91. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/registry.py +0 -0
  92. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/stub.py +0 -0
  93. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/telegram.py +0 -0
  94. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/allowlist.py +0 -0
  95. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/attach.py +0 -0
  96. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/chunker.py +0 -0
  97. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/client.py +0 -0
  98. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/commands.py +0 -0
  99. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/config.py +0 -0
  100. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/control.py +0 -0
  101. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/cron.py +0 -0
  102. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/elicitation.py +0 -0
  103. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/ensure.py +0 -0
  104. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/format.py +0 -0
  105. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/__init__.py +0 -0
  106. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/app.py +0 -0
  107. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/arcade_export.py +0 -0
  108. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/auth.py +0 -0
  109. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/constants.py +0 -0
  110. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/elicitation.py +0 -0
  111. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/exposure.py +0 -0
  112. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/limits.py +0 -0
  113. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/middleware.py +0 -0
  114. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/resources.py +0 -0
  115. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/subscriptions.py +0 -0
  116. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/turn_bridge.py +0 -0
  117. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/grants.py +0 -0
  118. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/inbox_cron.py +0 -0
  119. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/install.py +0 -0
  120. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/live.py +0 -0
  121. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/lock.py +0 -0
  122. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/mesh.py +0 -0
  123. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/message_pump.py +0 -0
  124. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/observability.py +0 -0
  125. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/owner.py +0 -0
  126. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/progress_sink.py +0 -0
  127. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/registry.py +0 -0
  128. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/router.py +0 -0
  129. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/runner.py +0 -0
  130. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/runner_main.py +0 -0
  131. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/secrets.py +0 -0
  132. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/secrets_broker.py +0 -0
  133. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/server.py +0 -0
  134. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/services.py +0 -0
  135. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/shim.py +0 -0
  136. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/sinks.py +0 -0
  137. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/supervisor.py +0 -0
  138. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/tokens.py +0 -0
  139. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/traffic.py +0 -0
  140. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/turns.py +0 -0
  141. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/wake.py +0 -0
  142. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/__init__.py +0 -0
  143. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/context_window.py +0 -0
  144. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/mcp_schema_index.py +0 -0
  145. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/orchestrator.py +0 -0
  146. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/parallel.py +0 -0
  147. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/tool_result_store.py +0 -0
  148. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/tool_schema_cache.py +0 -0
  149. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/__init__.py +0 -0
  150. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/config.py +0 -0
  151. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/engine.py +0 -0
  152. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/__init__.py +0 -0
  153. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/callback.py +0 -0
  154. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/command.py +0 -0
  155. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/http.py +0 -0
  156. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/prompt.py +0 -0
  157. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/ssrf_guard.py +0 -0
  158. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/matchers.py +0 -0
  159. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/registry.py +0 -0
  160. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/types.py +0 -0
  161. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/__init__.py +0 -0
  162. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/anthropic.py +0 -0
  163. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/base.py +0 -0
  164. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/ollama.py +0 -0
  165. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/openai.py +0 -0
  166. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/serve/__init__.py +0 -0
  167. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/storage/__init__.py +0 -0
  168. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/storage/threads.py +0 -0
  169. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tasks/__init__.py +0 -0
  170. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tasks/scheduler.py +0 -0
  171. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tasks/store.py +0 -0
  172. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tasks/types.py +0 -0
  173. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/login_failed.html +0 -0
  174. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/login_success.html +0 -0
  175. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/serve/launchd.plist.tmpl +0 -0
  176. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/serve/serve.toml.example +0 -0
  177. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/serve/systemd.service.tmpl +0 -0
  178. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/styles.css +0 -0
  179. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/__init__.py +0 -0
  180. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/_request_ctx.py +0 -0
  181. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/base.py +0 -0
  182. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/composite.py +0 -0
  183. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/mcp.py +0 -0
  184. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/search/__init__.py +0 -0
  185. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/search/discovered.py +0 -0
  186. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/search/scoring.py +0 -0
  187. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/search/service.py +0 -0
  188. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/__init__.py +0 -0
  189. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/completion.py +0 -0
  190. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/display.py +0 -0
  191. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/elicitation.py +0 -0
  192. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/input.py +0 -0
  193. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/session.py +0 -0
  194. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/slash.py +0 -0
  195. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/__init__.py +0 -0
  196. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/audio.py +0 -0
  197. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/cleanup.py +0 -0
  198. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/session.py +0 -0
  199. {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/stt.py +0 -0
  200. {cade_cli-0.16.1 → cade_cli-0.16.2}/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.16.1
3
+ Version: 0.16.2
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
@@ -95,13 +95,13 @@ The CLI agent from [Arcade.dev](https://arcade.dev). Coding, research, and every
95
95
 
96
96
  ```bash
97
97
  curl -fsSL https://arcadeagent.dev/install | sh
98
- cade login
99
98
  cade
100
99
  ```
101
100
 
102
101
  That is the **recommended install** — a prebuilt binary from
103
102
  [arcadeagent.dev](https://arcadeagent.dev/install). No GitHub token, no Python
104
- toolchain. Re-run the same command to upgrade.
103
+ toolchain. First `cade` walks you through model setup, Arcade login, and the
104
+ [Arcade Agent Hub](https://hub.arcade.dev). Re-run the same curl to upgrade.
105
105
 
106
106
  ---
107
107
 
@@ -129,7 +129,7 @@ The script detects your OS/arch, downloads the matching prebuilt binary
129
129
  `~/.local/bin`. Pin a version or install location:
130
130
 
131
131
  ```bash
132
- CADE_VERSION=0.16.1 CADE_INSTALL_DIR=/usr/local/bin \
132
+ CADE_VERSION=0.16.2 CADE_INSTALL_DIR=/usr/local/bin \
133
133
  sh -c "$(curl -fsSL https://arcadeagent.dev/install)"
134
134
  ```
135
135
 
@@ -4,13 +4,13 @@ The CLI agent from [Arcade.dev](https://arcade.dev). Coding, research, and every
4
4
 
5
5
  ```bash
6
6
  curl -fsSL https://arcadeagent.dev/install | sh
7
- cade login
8
7
  cade
9
8
  ```
10
9
 
11
10
  That is the **recommended install** — a prebuilt binary from
12
11
  [arcadeagent.dev](https://arcadeagent.dev/install). No GitHub token, no Python
13
- toolchain. Re-run the same command to upgrade.
12
+ toolchain. First `cade` walks you through model setup, Arcade login, and the
13
+ [Arcade Agent Hub](https://hub.arcade.dev). Re-run the same curl to upgrade.
14
14
 
15
15
  ---
16
16
 
@@ -38,7 +38,7 @@ The script detects your OS/arch, downloads the matching prebuilt binary
38
38
  `~/.local/bin`. Pin a version or install location:
39
39
 
40
40
  ```bash
41
- CADE_VERSION=0.16.1 CADE_INSTALL_DIR=/usr/local/bin \
41
+ CADE_VERSION=0.16.2 CADE_INSTALL_DIR=/usr/local/bin \
42
42
  sh -c "$(curl -fsSL https://arcadeagent.dev/install)"
43
43
  ```
44
44
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cade-cli"
3
- version = "0.16.1"
3
+ version = "0.16.2"
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"
@@ -304,7 +304,7 @@ def _doctor_paths(runtime: Any) -> dict[str, Any]:
304
304
  rich_help_panel=PANEL_SETUP,
305
305
  )
306
306
  def init_cmd() -> None:
307
- from cadecoder.cli.onboarding import can_prompt, run_onboarding
307
+ from cadecoder.cli.onboarding import can_prompt, finish_first_run_cloud, run_onboarding
308
308
 
309
309
  if not can_prompt():
310
310
  console.print(
@@ -312,7 +312,11 @@ def init_cmd() -> None:
312
312
  "Set OPENAI_API_KEY or ANTHROPIC_API_KEY instead."
313
313
  )
314
314
  raise typer.Exit(1)
315
- run_onboarding(console, force=True)
315
+ result = run_onboarding(console, force=True)
316
+ if result:
317
+ runtime = build_runtime()
318
+ set_runtime(runtime)
319
+ finish_first_run_cloud(console, prefer_skip_login=result.chose_local)
316
320
 
317
321
 
318
322
  @app.command(
@@ -484,11 +488,16 @@ def main_callback(
484
488
  # provider + model before we build the runtime, so the first session uses
485
489
  # what they chose (not the hardcoded default). No-ops when already set up or
486
490
  # when not attached to an interactive terminal (piped/CI).
487
- from cadecoder.cli.onboarding import needs_onboarding, run_onboarding
488
-
489
- did_onboard = False
491
+ from cadecoder.cli.onboarding import (
492
+ finish_first_run_cloud,
493
+ needs_onboarding,
494
+ run_onboarding,
495
+ )
496
+ from cadecoder.cli.onboarding import OnboardingResult
497
+
498
+ onboard_result = OnboardingResult()
490
499
  if needs_onboarding():
491
- did_onboard = run_onboarding(console)
500
+ onboard_result = run_onboarding(console)
492
501
 
493
502
  # Interaction + runtime-backed commands run as the current agent, auto-creating
494
503
  # a `default` agent on first run via build_runtime → ensure_current_agent.
@@ -496,13 +505,10 @@ def main_callback(
496
505
  set_runtime(runtime)
497
506
  ctx.obj["runtime"] = runtime
498
507
 
499
- # Right after first-run setup (runtime now available), offer to connect
500
- # Arcade Omni so external tools work out of the box. No-op otherwise.
501
- if did_onboard:
508
+ # After runtime is up: Arcade login (if needed) + Arcade Agent Hub connect.
509
+ if onboard_result:
502
510
  try:
503
- from cadecoder.cli.commands.mcp import offer_connect_omni
504
-
505
- offer_connect_omni(console)
511
+ finish_first_run_cloud(console, prefer_skip_login=onboard_result.chose_local)
506
512
  except Exception: # noqa: BLE001
507
513
  pass
508
514
 
@@ -86,15 +86,15 @@ def login(
86
86
 
87
87
  log.info(f"User {whoami.email} logged in via OAuth.")
88
88
 
89
- # Offer to connect Arcade Omni so the agent can use external tools
90
- # (Gmail, Slack, web search, …) without a separate API key. No-op when
91
- # non-interactive or already authorized.
89
+ # Offer to connect the Arcade Agent Hub so the agent can use external
90
+ # tools (Gmail, Slack, web search, …) without a separate API key.
91
+ # No-op when non-interactive or already authorized.
92
92
  try:
93
- from cadecoder.cli.commands.mcp import offer_connect_omni
93
+ from cadecoder.cli.commands.mcp import offer_connect_hub
94
94
 
95
- offer_connect_omni(console)
95
+ offer_connect_hub(console)
96
96
  except Exception as e: # noqa: BLE001
97
- log.debug(f"omni connect offer skipped: {e}")
97
+ log.debug(f"hub connect offer skipped: {e}")
98
98
 
99
99
  except OAuthLoginError as e:
100
100
  console.print(f"\n[red]✗ Login failed:[/red] {escape(str(e))}")
@@ -372,22 +372,26 @@ def run_mcp_authorization(
372
372
  """Run the MCP OAuth authorization flow for a server. Returns success.
373
373
 
374
374
  If ``name`` isn't configured yet but is a built-in known server (e.g.
375
- ``omni``), it's added in a disabled state first and only enabled once
375
+ ``hub``), it's added in a disabled state first and only enabled once
376
376
  authorization succeeds — so a cancelled/failed flow never leaves a broken
377
- server that would error during chat.
377
+ server that would error during chat. The legacy name ``omni`` resolves to
378
+ the Arcade Agent Hub.
378
379
  """
379
380
  global _oauth_result
380
381
  _oauth_result = {"code": None, "error": None}
381
382
 
382
383
  store = MCPServerStore()
383
- server = store.get(name)
384
+ # Resolve aliases (omni → hub) before looking up a stored config.
385
+ known = known_server_config(name)
386
+ lookup_name = known.name if known is not None else name
387
+ server = store.get(lookup_name) or store.get(name)
384
388
  if server is None:
385
- server = known_server_config(name)
389
+ server = known
386
390
  if server is None:
387
391
  console.print(f"[red]Server '{name}' not found.[/red]")
388
392
  console.print(
389
393
  "[dim]Add it with 'cade mcp add <name> <url>', "
390
- "or authorize a known server like 'omni'.[/dim]"
394
+ "or authorize a known server like 'hub'.[/dim]"
391
395
  )
392
396
  return False
393
397
  store.add(server) # persisted disabled; enabled on success
@@ -515,16 +519,17 @@ def run_mcp_authorization(
515
519
  return asyncio.run(run_oauth_flow())
516
520
 
517
521
 
518
- def offer_connect_omni(target_console: Console | None = None) -> None:
519
- """Offer to connect Arcade Omni (external tools) if not already authorized.
522
+ def offer_connect_hub(target_console: Console | None = None) -> None:
523
+ """Offer to connect the Arcade Agent Hub if not already authorized.
520
524
 
521
525
  Called after ``cade login`` and after first-run onboarding. No-op when the
522
- terminal isn't interactive or when Omni is already authorized, so it never
523
- blocks scripted/CI use.
526
+ terminal isn't interactive or when the Hub is already authorized, so it
527
+ never blocks scripted/CI use.
524
528
  """
525
529
  con = target_console or console
526
530
 
527
- from cadecoder.cli.onboarding import can_prompt
531
+ from cadecoder.cli.onboarding import can_prompt, is_arcade_logged_in, offer_arcade_login
532
+ from cadecoder.tools.manager.config import HUB_SERVER_NAME
528
533
 
529
534
  if not can_prompt():
530
535
  return
@@ -534,30 +539,57 @@ def offer_connect_omni(target_console: Console | None = None) -> None:
534
539
  except Exception: # noqa: BLE001
535
540
  return
536
541
 
537
- existing = store.get("omni")
542
+ existing = store.get(HUB_SERVER_NAME) or store.get("omni")
538
543
  if existing is not None and existing.oauth_tokens is not None:
539
544
  return # already connected
540
545
 
546
+ if not is_arcade_logged_in():
547
+ con.print()
548
+ con.print(
549
+ "[bold]Arcade login required[/bold] before connecting the "
550
+ "[cyan]Arcade Agent Hub[/cyan]."
551
+ )
552
+ if not offer_arcade_login(con, prefer_skip=False):
553
+ con.print(
554
+ "[dim]Skipped. Log in later with [bold]cade login[/bold], then "
555
+ "[bold]cade mcp authorize hub[/bold].[/dim]"
556
+ )
557
+ return
558
+
541
559
  from rich.prompt import Confirm
542
560
 
543
561
  con.print()
544
562
  con.print(
545
- "[bold]Connect external tools?[/bold] Arcade [cyan]Omni[/cyan] lets Cade use "
546
- "Gmail, Slack, GitHub, web search and more — authorized with your Arcade login "
547
- "(no API key needed)."
563
+ "[bold]Connect external tools?[/bold] The [cyan]Arcade Agent Hub[/cyan] "
564
+ "([link=https://hub.arcade.dev]hub.arcade.dev[/link]) lets Cade use "
565
+ "Gmail, Slack, GitHub, web search and more — authorized with your Arcade "
566
+ "login (no API key needed)."
548
567
  )
549
568
  try:
550
- proceed = Confirm.ask("Authorize Omni now? (opens your browser)", default=True, console=con)
569
+ proceed = Confirm.ask(
570
+ "Authorize Arcade Agent Hub now? (opens your browser)",
571
+ default=True,
572
+ console=con,
573
+ )
551
574
  except (KeyboardInterrupt, EOFError):
552
575
  con.print()
553
576
  return
554
577
 
555
578
  if not proceed:
556
- con.print("[dim]Skipped. Connect anytime with [bold]cade mcp authorize omni[/bold].[/dim]")
579
+ con.print(
580
+ "[dim]Skipped. Connect anytime with [bold]cade mcp authorize hub[/bold].[/dim]"
581
+ )
557
582
  return
558
583
 
559
- if not run_mcp_authorization("omni"):
560
- con.print("[dim]You can retry later with [bold]cade mcp authorize omni[/bold].[/dim]")
584
+ if not run_mcp_authorization(HUB_SERVER_NAME):
585
+ con.print(
586
+ "[dim]You can retry later with [bold]cade mcp authorize hub[/bold].[/dim]"
587
+ )
588
+
589
+
590
+ def offer_connect_omni(target_console: Console | None = None) -> None:
591
+ """Deprecated alias for :func:`offer_connect_hub`."""
592
+ offer_connect_hub(target_console)
561
593
 
562
594
 
563
595
  @mcp_app.command("authorize")
@@ -579,7 +611,7 @@ def authorize_server(
579
611
  """Authorize an MCP server over OAuth (browser flow).
580
612
 
581
613
  Works with any configured server, or a built-in known server by name
582
- (e.g. ``cade mcp authorize omni`` to connect Arcade's external tools).
614
+ (e.g. ``cade mcp authorize hub`` to connect the Arcade Agent Hub).
583
615
  """
584
616
  if not run_mcp_authorization(name, client_id=client_id, scope=scope, skip_dcr=skip_dcr):
585
617
  raise typer.Exit(1)
@@ -3,14 +3,18 @@
3
3
  A brand-new install has no obvious way to pick a model provider, and the silent
4
4
  provider fallback used to log a GPT model even when only an Anthropic key was
5
5
  set. This wizard runs once on first launch (and on demand via ``cade init``):
6
- it asks which provider to use, captures/stores an API key in the OS keyring,
7
- records a recommended default model, and writes the global config + default
8
- agent so the very first session uses exactly what the user chose.
6
+
7
+ 1. Model provider + API key + default model
8
+ 2. Arcade Cloud login (browser OAuth) skipped only if the user opts out
9
+ 3. Arcade Agent Hub connect (after the runtime is up)
10
+
11
+ Step 3 is :func:`finish_first_run_cloud` and must run after ``build_runtime``.
9
12
  """
10
13
 
11
14
  from __future__ import annotations
12
15
 
13
16
  import os
17
+ from dataclasses import dataclass
14
18
 
15
19
  from rich.console import Console
16
20
  from rich.panel import Panel
@@ -28,6 +32,17 @@ _PROVIDER_LOCAL = "local"
28
32
  _KEYRING_SERVICE = "cade/model"
29
33
 
30
34
 
35
+ @dataclass(frozen=True)
36
+ class OnboardingResult:
37
+ """Outcome of the model-setup half of first-run onboarding."""
38
+
39
+ configured: bool = False
40
+ chose_local: bool = False
41
+
42
+ def __bool__(self) -> bool:
43
+ return self.configured
44
+
45
+
31
46
  def _marker_path():
32
47
  """Path to the sentinel that records onboarding has completed."""
33
48
  return get_paths().state_dir / "onboarded"
@@ -168,28 +183,170 @@ class OnboardingAborted(Exception):
168
183
  """Raised when the user cancels onboarding (Ctrl-C / empty required input)."""
169
184
 
170
185
 
171
- def run_onboarding(console: Console, *, force: bool = False) -> bool:
172
- """Run the interactive setup wizard.
186
+ def is_arcade_logged_in() -> bool:
187
+ """Return True when Arcade Cloud credentials are present and usable."""
188
+ try:
189
+ from cadecoder.cli.auth import check_existing_login
190
+
191
+ return check_existing_login(suppress_message=True)
192
+ except Exception: # noqa: BLE001
193
+ return False
194
+
195
+
196
+ def offer_arcade_login(console: Console, *, prefer_skip: bool = False) -> bool:
197
+ """Offer Arcade Cloud OAuth during first-run / init.
198
+
199
+ Args:
200
+ console: Rich console for prompts.
201
+ prefer_skip: When True (local model path), default the confirm to No.
202
+
203
+ Returns:
204
+ True if the user is logged in when this returns (already was, or just did).
205
+ """
206
+ if not can_prompt():
207
+ return is_arcade_logged_in()
208
+
209
+ if is_arcade_logged_in():
210
+ console.print()
211
+ console.print("[green]✓[/green] Already logged in to Arcade Cloud.")
212
+ return True
213
+
214
+ console.print()
215
+ console.print(
216
+ Panel.fit(
217
+ "[bold]Step 2 of 3 — Arcade Cloud[/bold]\n\n"
218
+ "Log in so Cade can use Gmail, Slack, GitHub, calendars, and the\n"
219
+ "rest of the Arcade catalogue. Opens your browser (free account).\n\n"
220
+ "[dim]Skip only if you want local tools + your model — nothing else.[/dim]",
221
+ border_style="cyan",
222
+ )
223
+ )
224
+ try:
225
+ proceed = Confirm.ask(
226
+ "Log in to Arcade Cloud now?",
227
+ default=not prefer_skip,
228
+ console=console,
229
+ )
230
+ except (KeyboardInterrupt, EOFError):
231
+ console.print()
232
+ proceed = False
233
+
234
+ if not proceed:
235
+ console.print(
236
+ "[dim]Skipped. Chat still works with your model and local tools.\n"
237
+ "Run [bold]cade login[/bold] anytime for cloud apps "
238
+ "(or [bold]cade --local-only[/bold] to stay offline).[/dim]"
239
+ )
240
+ return False
241
+
242
+ return try_interactive_login(console)
243
+
244
+
245
+ def try_interactive_login(console: Console) -> bool:
246
+ """Run browser OAuth login; return True on success. Never raises Exit."""
247
+ from arcade_core.constants import PROD_COORDINATOR_HOST
248
+ from rich.markup import escape
249
+
250
+ from cadecoder.cli.auth import (
251
+ OAuthLoginError,
252
+ build_coordinator_url,
253
+ perform_oauth_login,
254
+ save_credentials_from_whoami,
255
+ )
256
+
257
+ try:
258
+ coordinator_url = build_coordinator_url(PROD_COORDINATOR_HOST, None)
259
+
260
+ def on_status(msg: str) -> None:
261
+ console.print(f"[dim]{msg}[/dim]")
262
+
263
+ tokens, whoami, client_id = perform_oauth_login(coordinator_url, on_status=on_status)
264
+ save_credentials_from_whoami(tokens, whoami, coordinator_url, client_id)
265
+ console.print("\n[green]✓ Login successful![/green]")
266
+ console.print(f" Email: {whoami.email}")
267
+ org = whoami.get_selected_org()
268
+ project = whoami.get_selected_project()
269
+ if org and project:
270
+ console.print(
271
+ f" Active: {org.get('name', 'unknown')} / {project.get('name', 'unknown')}"
272
+ )
273
+ return True
274
+ except OAuthLoginError as e:
275
+ console.print(f"\n[red]✗ Login failed:[/red] {escape(str(e))}")
276
+ console.print(
277
+ "[dim]Continue without cloud tools for now — "
278
+ "retry with [bold]cade login[/bold].[/dim]"
279
+ )
280
+ return False
281
+ except (KeyboardInterrupt, EOFError):
282
+ console.print("\n[yellow]Login cancelled.[/yellow]")
283
+ return False
284
+ except Exception as e: # noqa: BLE001
285
+ console.print(f"\n[red]✗ Login failed:[/red] {escape(str(e))}")
286
+ console.print("[dim]Retry anytime with [bold]cade login[/bold].[/dim]")
287
+ return False
288
+
289
+
290
+ def finish_first_run_cloud(console: Console, *, prefer_skip_login: bool = False) -> None:
291
+ """After runtime is ready: Arcade login (if needed), then Agent Hub connect.
292
+
293
+ Call this only after ``build_runtime()`` / ``set_runtime()`` so the Hub
294
+ MCP store can resolve the current agent.
295
+ """
296
+ if not can_prompt():
297
+ return
298
+
299
+ logged_in = offer_arcade_login(console, prefer_skip=prefer_skip_login)
300
+ if not logged_in:
301
+ return
302
+
303
+ try:
304
+ from cadecoder.cli.commands.mcp import offer_connect_hub
305
+
306
+ console.print()
307
+ console.print("[bold]Step 3 of 3 — Arcade Agent Hub[/bold] ([cyan]hub.arcade.dev[/cyan])")
308
+ offer_connect_hub(console)
309
+ except Exception: # noqa: BLE001
310
+ console.print(
311
+ "[dim]Skipped Arcade Agent Hub. Connect later with "
312
+ "[bold]cade mcp authorize hub[/bold].[/dim]"
313
+ )
314
+
315
+
316
+ def run_onboarding(console: Console, *, force: bool = False) -> OnboardingResult:
317
+ """Run the interactive model-setup wizard (step 1 of first-run).
173
318
 
174
319
  Args:
175
320
  console: Rich console (stderr) to render prompts on.
176
321
  force: Re-run even if already onboarded (``cade init``).
177
322
 
178
323
  Returns:
179
- True if a provider was configured; False if skipped/aborted.
324
+ :class:`OnboardingResult` (truthy when a provider was configured).
325
+ Call :func:`finish_first_run_cloud` after the runtime is built for
326
+ steps 2–3 (login + Arcade Agent Hub).
180
327
  """
181
328
  if not force and not needs_onboarding():
182
- return False
329
+ return OnboardingResult()
183
330
 
184
331
  if not can_prompt():
185
332
  # Non-interactive (piped/CI). Don't block; the provider error path will
186
333
  # guide the user if nothing is configured.
187
- return False
334
+ return OnboardingResult()
188
335
 
189
336
  console.print(
190
337
  Panel.fit(
191
- "Welcome to [bold]Cade[/bold] — let's pick a model provider.\n"
192
- "You can change this anytime with [bold]cade init[/bold].",
338
+ "Welcome to [bold]Cade[/bold] — three quick steps:\n"
339
+ " [bold]1.[/bold] Pick a model provider\n"
340
+ " [bold]2.[/bold] Log in to Arcade Cloud (cloud apps)\n"
341
+ " [bold]3.[/bold] Connect the Arcade Agent Hub\n\n"
342
+ "You can re-run this anytime with [bold]cade init[/bold].",
343
+ border_style="cyan",
344
+ )
345
+ )
346
+ console.print()
347
+ console.print(
348
+ Panel.fit(
349
+ "[bold]Step 1 of 3 — Model provider[/bold]",
193
350
  border_style="cyan",
194
351
  )
195
352
  )
@@ -238,10 +395,10 @@ def run_onboarding(console: Console, *, force: bool = False) -> bool:
238
395
  model = Prompt.ask("Model", default=default_model, console=console).strip() or default_model
239
396
  except (KeyboardInterrupt, EOFError):
240
397
  console.print("\n[yellow]Setup cancelled.[/yellow]")
241
- return False
398
+ return OnboardingResult()
242
399
  except OnboardingAborted as e:
243
400
  console.print(f"[yellow]Setup cancelled: {e}[/yellow]")
244
- return False
401
+ return OnboardingResult()
245
402
 
246
403
  _persist(
247
404
  provider=provider,
@@ -257,15 +414,16 @@ def run_onboarding(console: Console, *, force: bool = False) -> bool:
257
414
  console.print()
258
415
  console.print(
259
416
  Panel.fit(
260
- f"[bold]You're set up.[/bold]\n"
417
+ f"[bold]Step 1 done.[/bold]\n"
261
418
  f"Model: [cyan]{model}[/cyan]\n"
262
419
  f"Provider: [cyan]{label}[/cyan]\n\n"
263
- "Change it later with [bold]cade init[/bold] or edit "
420
+ "Next: Arcade login + Arcade Agent Hub (cloud apps).\n"
421
+ "Change the model later with [bold]cade init[/bold] or edit "
264
422
  f"[dim]{get_paths().global_config}[/dim].",
265
423
  border_style="green",
266
424
  )
267
425
  )
268
- return True
426
+ return OnboardingResult(configured=True, chose_local=(choice == "3"))
269
427
 
270
428
 
271
429
  def _persist(
@@ -7,6 +7,8 @@ from cadecoder.tools.manager.base import (
7
7
  )
8
8
  from cadecoder.tools.manager.composite import CompositeToolManager
9
9
  from cadecoder.tools.manager.config import (
10
+ HUB_SERVER_NAME,
11
+ HUB_SERVER_URL,
10
12
  KNOWN_SERVERS,
11
13
  MCPAuthType,
12
14
  MCPOAuthTokens,
@@ -33,6 +35,8 @@ __all__ = [
33
35
  "MCPOAuthTokens",
34
36
  "MCPTransportType",
35
37
  # Known remote servers
38
+ "HUB_SERVER_NAME",
39
+ "HUB_SERVER_URL",
36
40
  "KNOWN_SERVERS",
37
41
  "known_server_config",
38
42
  ]
@@ -126,9 +126,17 @@ class MCPServerConfig:
126
126
  if data.get("oauth_tokens"):
127
127
  oauth_tokens = MCPOAuthTokens.from_dict(data["oauth_tokens"])
128
128
 
129
+ name = data["name"]
130
+ url = data["url"]
131
+ # Migrate retired Omni endpoint → Arcade Agent Hub.
132
+ if isinstance(url, str) and "omni.arcade.dev" in url:
133
+ url = url.replace("omni.arcade.dev", "hub.arcade.dev")
134
+ if name == "omni":
135
+ name = "hub"
136
+
129
137
  return cls(
130
- name=data["name"],
131
- url=data["url"],
138
+ name=name,
139
+ url=url,
132
140
  transport=MCPTransportType(data.get("transport", "http")),
133
141
  auth_type=MCPAuthType(data.get("auth_type") or data.get("auth", "none")),
134
142
  auth_value=data.get("auth_value"),
@@ -149,31 +157,43 @@ class MCPServerConfig:
149
157
 
150
158
  # Built-in, well-known remote MCP servers a user can connect with one command
151
159
  # (`cade mcp authorize <name>`). They are *not* added to an agent until the user
152
- # authorizes them, so they never break a fresh install. Omni is Arcade's
153
- # meta-discovery server: once authorized over OAuth it exposes the whole Arcade
154
- # tool catalog (Gmail, Slack, GitHub, web search, …) via SelectTools/UseTool —
155
- # no ARCADE_API_KEY required (auth rides the user's Arcade login).
160
+ # authorizes them, so they never break a fresh install. The Arcade Agent Hub
161
+ # (`hub.arcade.dev`) is Arcade's meta-discovery server: once authorized over
162
+ # OAuth it exposes the whole Arcade tool catalog (Gmail, Slack, GitHub, web
163
+ # search, …) via SelectTools/UseTool — no ARCADE_API_KEY required (auth rides
164
+ # the user's Arcade login).
165
+ HUB_SERVER_NAME = "hub"
166
+ HUB_SERVER_URL = "https://hub.arcade.dev/mcp"
167
+
156
168
  KNOWN_SERVERS: dict[str, dict[str, str]] = {
157
- "omni": {
158
- "url": "https://omni.arcade.dev/mcp",
169
+ HUB_SERVER_NAME: {
170
+ "url": HUB_SERVER_URL,
159
171
  "description": (
160
- "Arcade Omni — discover & run external tools (Gmail, Slack, GitHub, web search, …)"
172
+ "Arcade Agent Hub — discover & run external tools "
173
+ "(Gmail, Slack, GitHub, web search, …)"
161
174
  ),
162
175
  },
163
176
  }
164
177
 
178
+ # Retired name → canonical known-server name (authorize / list still accept it).
179
+ _KNOWN_SERVER_ALIASES: dict[str, str] = {
180
+ "omni": HUB_SERVER_NAME,
181
+ }
182
+
165
183
 
166
184
  def known_server_config(name: str) -> "MCPServerConfig | None":
167
185
  """Return a fresh, disabled OAuth config for a built-in known server.
168
186
 
169
187
  Disabled by default so it is only connected after a successful
170
- ``cade mcp authorize <name>`` (which flips ``enabled`` on).
188
+ ``cade mcp authorize <name>`` (which flips ``enabled`` on). The legacy
189
+ name ``omni`` resolves to the Arcade Agent Hub (``hub``).
171
190
  """
172
- info = KNOWN_SERVERS.get(name)
191
+ canonical = _KNOWN_SERVER_ALIASES.get(name, name)
192
+ info = KNOWN_SERVERS.get(canonical)
173
193
  if info is None:
174
194
  return None
175
195
  return MCPServerConfig(
176
- name=name,
196
+ name=canonical,
177
197
  url=info["url"],
178
198
  transport=MCPTransportType.HTTP,
179
199
  auth_type=MCPAuthType.OAUTH,
File without changes
File without changes