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.
- {cade_cli-0.16.1 → cade_cli-0.16.2}/PKG-INFO +4 -4
- {cade_cli-0.16.1 → cade_cli-0.16.2}/README.md +3 -3
- {cade_cli-0.16.1 → cade_cli-0.16.2}/pyproject.toml +1 -1
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/app.py +18 -12
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/auth.py +6 -6
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/mcp.py +51 -19
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/onboarding.py +173 -15
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/__init__.py +4 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/config.py +32 -12
- {cade_cli-0.16.1 → cade_cli-0.16.2}/.gitignore +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/LICENSE +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/__main__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/_metadata.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/config.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/errors.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/grants.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/resources.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/sandbox.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/server.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/_read_cache.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/access.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/agents.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/context.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/filesystem.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/git.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/notifications.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/questions.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/results.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/schemas.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/search.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/shell.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/snippets.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/tasks.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/web_fetch.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/tools/web_search.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/utils.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/arcade_client.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/cache.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/extract.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/markdown.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/preapproved.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/prompts.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/scrape.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/search/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/search/arcade.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/search/base.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cade_mcp_local/web/search/http.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ai/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ai/prompts.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/auth.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/account.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/agents.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/chat.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/cron.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/daemon.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/grant.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/hooks.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/mem.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/tasks.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/thread.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/cli/commands/tools.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/agent.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/comms.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/config.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/constants.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/errors.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/frozen.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/git.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/inbox.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/logging.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/memory.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/model_specs.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/names.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/paths.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/runtime.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/secrets.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/spawn.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/core/types.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/base.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/factory.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/imessage.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/registry.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/stub.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/adapters/telegram.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/allowlist.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/attach.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/chunker.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/client.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/commands.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/config.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/control.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/cron.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/elicitation.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/ensure.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/format.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/app.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/arcade_export.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/auth.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/constants.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/elicitation.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/exposure.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/limits.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/middleware.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/resources.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/subscriptions.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/gateway/turn_bridge.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/grants.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/inbox_cron.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/install.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/live.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/lock.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/mesh.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/message_pump.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/observability.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/owner.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/progress_sink.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/registry.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/router.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/runner.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/runner_main.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/secrets.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/secrets_broker.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/server.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/services.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/shim.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/sinks.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/supervisor.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/tokens.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/traffic.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/turns.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/daemon/wake.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/context_window.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/mcp_schema_index.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/orchestrator.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/parallel.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/tool_result_store.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/execution/tool_schema_cache.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/config.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/engine.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/callback.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/command.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/http.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/prompt.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/executors/ssrf_guard.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/matchers.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/registry.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/hooks/types.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/anthropic.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/base.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/ollama.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/providers/openai.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/serve/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/storage/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/storage/threads.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tasks/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tasks/scheduler.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tasks/store.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tasks/types.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/login_failed.html +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/login_success.html +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/serve/launchd.plist.tmpl +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/serve/serve.toml.example +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/serve/systemd.service.tmpl +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/templates/styles.css +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/_request_ctx.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/base.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/composite.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/manager/mcp.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/search/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/search/discovered.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/search/scoring.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/tools/search/service.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/completion.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/display.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/elicitation.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/input.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/session.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/ui/slash.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/__init__.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/audio.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/cleanup.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/session.py +0 -0
- {cade_cli-0.16.1 → cade_cli-0.16.2}/src/cadecoder/voice/stt.py +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
|
@@ -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
|
|
488
|
-
|
|
489
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
500
|
-
|
|
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
|
-
|
|
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
|
|
90
|
-
# (Gmail, Slack, web search, …) without a separate API key.
|
|
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
|
|
93
|
+
from cadecoder.cli.commands.mcp import offer_connect_hub
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
offer_connect_hub(console)
|
|
96
96
|
except Exception as e: # noqa: BLE001
|
|
97
|
-
log.debug(f"
|
|
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
|
-
``
|
|
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
|
-
|
|
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 =
|
|
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 '
|
|
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
|
|
519
|
-
"""Offer to connect Arcade
|
|
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
|
|
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]
|
|
546
|
-
"
|
|
547
|
-
"
|
|
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(
|
|
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(
|
|
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(
|
|
560
|
-
con.print(
|
|
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
|
|
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
|
172
|
-
"""
|
|
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
|
-
|
|
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
|
|
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
|
|
334
|
+
return OnboardingResult()
|
|
188
335
|
|
|
189
336
|
console.print(
|
|
190
337
|
Panel.fit(
|
|
191
|
-
"Welcome to [bold]Cade[/bold] —
|
|
192
|
-
"
|
|
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
|
|
398
|
+
return OnboardingResult()
|
|
242
399
|
except OnboardingAborted as e:
|
|
243
400
|
console.print(f"[yellow]Setup cancelled: {e}[/yellow]")
|
|
244
|
-
return
|
|
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]
|
|
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
|
-
"
|
|
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=
|
|
131
|
-
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.
|
|
153
|
-
# meta-discovery server: once authorized over
|
|
154
|
-
# tool catalog (Gmail, Slack, GitHub, web
|
|
155
|
-
# no ARCADE_API_KEY required (auth rides
|
|
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
|
-
|
|
158
|
-
"url":
|
|
169
|
+
HUB_SERVER_NAME: {
|
|
170
|
+
"url": HUB_SERVER_URL,
|
|
159
171
|
"description": (
|
|
160
|
-
"Arcade
|
|
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
|
-
|
|
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=
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|