cade-cli 0.10.0__tar.gz → 0.13.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.10.0 → cade_cli-0.13.2}/PKG-INFO +51 -42
- {cade_cli-0.10.0 → cade_cli-0.13.2}/README.md +40 -32
- {cade_cli-0.10.0 → cade_cli-0.13.2}/pyproject.toml +15 -10
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/__init__.py +10 -0
- cade_cli-0.13.2/src/cade_mcp_local/_metadata.py +84 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/errors.py +46 -0
- cade_cli-0.13.2/src/cade_mcp_local/resources.py +131 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/server.py +22 -17
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/__init__.py +5 -10
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/context.py +22 -4
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/filesystem.py +57 -104
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/git.py +26 -7
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/notifications.py +10 -2
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/questions.py +20 -6
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/results.py +76 -29
- cade_cli-0.13.2/src/cade_mcp_local/tools/schemas.py +128 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/search.py +22 -5
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/shell.py +14 -2
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/snippets.py +16 -2
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/tasks.py +31 -19
- cade_cli-0.13.2/src/cade_mcp_local/tools/web_fetch.py +256 -0
- cade_cli-0.13.2/src/cade_mcp_local/tools/web_search.py +158 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/__init__.py +1 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/arcade_client.py +131 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/cache.py +136 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/extract.py +54 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/markdown.py +64 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/preapproved.py +57 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/prompts.py +29 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/scrape.py +77 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/search/__init__.py +5 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/search/arcade.py +103 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/search/base.py +41 -0
- cade_cli-0.13.2/src/cade_mcp_local/web/search/http.py +129 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/ai/prompts.py +15 -19
- cade_cli-0.13.2/src/cadecoder/cli/app.py +342 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/auth.py +34 -46
- cade_cli-0.13.2/src/cadecoder/cli/commands/account.py +203 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/auth.py +30 -38
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/chat.py +20 -21
- cade_cli-0.13.2/src/cadecoder/cli/commands/context.py +191 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/mcp.py +1 -6
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/mem.py +4 -6
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/model.py +12 -9
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/persona.py +15 -158
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/serve.py +7 -15
- cade_cli-0.13.2/src/cadecoder/core/config.py +568 -0
- cade_cli-0.13.2/src/cadecoder/core/frozen.py +37 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/core/logging.py +5 -5
- cade_cli-0.13.2/src/cadecoder/core/paths.py +147 -0
- cade_cli-0.13.2/src/cadecoder/core/runtime.py +116 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/execution/context_window.py +3 -1
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/execution/mcp_schema_index.py +4 -9
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/execution/orchestrator.py +42 -25
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/execution/parallel.py +102 -27
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/execution/tool_result_store.py +8 -4
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/execution/tool_schema_cache.py +39 -5
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/__init__.py +1 -1
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/config.py +33 -21
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/providers/__init__.py +10 -4
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/providers/ollama.py +36 -6
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/__init__.py +1 -1
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/adapters/__init__.py +4 -1
- cade_cli-0.13.2/src/cadecoder/serve/adapters/desktop.py +408 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/allowlist.py +2 -3
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/config.py +49 -16
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/daemon.py +73 -37
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/install.py +4 -2
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/lock.py +2 -2
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/observability.py +8 -4
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/secrets.py +4 -4
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/worker.py +91 -15
- cade_cli-0.13.2/src/cadecoder/storage/personas.py +216 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/storage/threads.py +20 -14
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tasks/channels.py +4 -3
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tasks/lock.py +6 -7
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tasks/scheduler.py +6 -6
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tasks/store.py +3 -3
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tasks/types.py +1 -1
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/templates/serve/launchd.plist.tmpl +4 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/templates/serve/serve.toml.example +18 -8
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/templates/serve/systemd.service.tmpl +2 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/manager/composite.py +280 -74
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/manager/config.py +20 -28
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/manager/mcp.py +51 -10
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/search/discovered.py +3 -3
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/search/service.py +62 -13
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/ui/display.py +207 -33
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/ui/input.py +4 -18
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/ui/session.py +114 -24
- cade_cli-0.13.2/src/cadecoder/ui/slash.py +47 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/voice/__init__.py +7 -1
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/voice/session.py +92 -39
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/voice/tts.py +62 -37
- cade_cli-0.10.0/src/cade_mcp_local/tools/channels.py +0 -76
- cade_cli-0.10.0/src/cade_mcp_local/tools/schemas.py +0 -186
- cade_cli-0.10.0/src/cade_mcp_local/tools/sleep.py +0 -38
- cade_cli-0.10.0/src/cadecoder/cli/app.py +0 -250
- cade_cli-0.10.0/src/cadecoder/cli/commands/context.py +0 -338
- cade_cli-0.10.0/src/cadecoder/core/config.py +0 -444
- cade_cli-0.10.0/src/cadecoder/storage/personas.py +0 -403
- {cade_cli-0.10.0 → cade_cli-0.13.2}/.gitignore +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/LICENSE +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/__main__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/config.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/tools/_read_cache.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cade_mcp_local/utils.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/ai/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/channels.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/cron.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/hooks.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/tasks.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/thread.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/cli/commands/tools.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/core/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/core/constants.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/core/errors.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/core/git.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/core/names.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/core/types.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/execution/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/engine.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/executors/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/executors/callback.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/executors/command.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/executors/http.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/executors/prompt.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/executors/ssrf_guard.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/matchers.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/registry.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/hooks/types.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/providers/anthropic.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/providers/base.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/providers/openai.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/adapters/base.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/adapters/registry.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/adapters/stub.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/adapters/telegram.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/chunker.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/commands.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/elicitation.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/format.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/progress_sink.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/router.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/serve/sinks.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/storage/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tasks/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tasks/notifications.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/templates/login_failed.html +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/templates/login_success.html +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/templates/styles.css +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/manager/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/manager/_request_ctx.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/manager/base.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/search/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/tools/search/scoring.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/ui/__init__.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/ui/elicitation.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/voice/audio.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/voice/cleanup.py +0 -0
- {cade_cli-0.10.0 → cade_cli-0.13.2}/src/cadecoder/voice/stt.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cade-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.2
|
|
4
4
|
Summary: Cade - The CLI Agent from Arcade.dev
|
|
5
5
|
Project-URL: Homepage, https://arcade.dev
|
|
6
6
|
Project-URL: Documentation, https://docs.arcade.dev
|
|
@@ -43,28 +43,29 @@ Classifier: Topic :: Software Development
|
|
|
43
43
|
Classifier: Topic :: Software Development :: Code Generators
|
|
44
44
|
Classifier: Typing :: Typed
|
|
45
45
|
Requires-Python: >=3.11
|
|
46
|
-
Requires-Dist: agent-library<1.0.0,>=0.
|
|
46
|
+
Requires-Dist: agent-library<1.0.0,>=0.13.1
|
|
47
47
|
Requires-Dist: anthropic<1.0.0,>=0.34.0
|
|
48
|
-
Requires-Dist: arcade-core<5.0.0,>=4.
|
|
49
|
-
Requires-Dist: arcade-mcp-server
|
|
50
|
-
Requires-Dist: arcade-tdk
|
|
48
|
+
Requires-Dist: arcade-core<5.0.0,>=4.7.0
|
|
49
|
+
Requires-Dist: arcade-mcp-server<2.0.0,>=1.22.0
|
|
50
|
+
Requires-Dist: arcade-tdk<4.0.0,>=3.8.0
|
|
51
|
+
Requires-Dist: arcadepy<2.0.0,>=1.10.0
|
|
51
52
|
Requires-Dist: authlib<2.0.0,>=1.6.0
|
|
52
53
|
Requires-Dist: croniter<4.0.0,>=2.0.0
|
|
53
54
|
Requires-Dist: filelock<4.0.0,>=3.0.0
|
|
55
|
+
Requires-Dist: html2text>=2024.2.26
|
|
54
56
|
Requires-Dist: httpx<1.0.0,>=0.27.0
|
|
55
57
|
Requires-Dist: keyring<26.0,>=24.0
|
|
56
58
|
Requires-Dist: openai<2.0.0,>=1.0.0
|
|
57
59
|
Requires-Dist: prompt-toolkit<4.0.0,>=3.0.52
|
|
58
60
|
Requires-Dist: pydantic[email]<3.0.0,>=2.0.0
|
|
59
|
-
Requires-Dist: pyperclip<2.0.0,>=1.8.0
|
|
60
61
|
Requires-Dist: python-telegram-bot<22.0,>=21.0
|
|
61
|
-
Requires-Dist: pyyaml<7.0.0,>=6.0
|
|
62
62
|
Requires-Dist: rich<14.0.0,>=13.0.0
|
|
63
|
-
Requires-Dist: sounddevice>=0.5.5
|
|
64
|
-
Requires-Dist: tiktoken<1.0.0,>=0.11.0
|
|
65
63
|
Requires-Dist: toml<1.0.0,>=0.10.0
|
|
66
64
|
Requires-Dist: typer>0.10.0
|
|
67
65
|
Requires-Dist: ulid==1.1
|
|
66
|
+
Requires-Dist: websockets<16.0,>=14.0
|
|
67
|
+
Provides-Extra: build
|
|
68
|
+
Requires-Dist: pyinstaller<7.0.0,>=6.16.0; extra == 'build'
|
|
68
69
|
Provides-Extra: dev
|
|
69
70
|
Requires-Dist: mypy<2.0.0,>=1.10.0; extra == 'dev'
|
|
70
71
|
Requires-Dist: pytest-asyncio<1.0.0,>=0.24.0; extra == 'dev'
|
|
@@ -81,7 +82,7 @@ Provides-Extra: voice
|
|
|
81
82
|
Requires-Dist: mlx-audio<0.4.0,>=0.2.0; extra == 'voice'
|
|
82
83
|
Requires-Dist: mlx-whisper>=0.1.0; extra == 'voice'
|
|
83
84
|
Requires-Dist: numpy>=1.24.0; extra == 'voice'
|
|
84
|
-
Requires-Dist: sounddevice
|
|
85
|
+
Requires-Dist: sounddevice<1.0.0,>=0.5.5; extra == 'voice'
|
|
85
86
|
Requires-Dist: webrtcvad>=2.0.10; extra == 'voice'
|
|
86
87
|
Description-Content-Type: text/markdown
|
|
87
88
|
|
|
@@ -117,6 +118,8 @@ cade
|
|
|
117
118
|
| pip | `pip install cade-cli` |
|
|
118
119
|
| From source | `git clone https://github.com/arcadeai-labs/cade.git && cd cade && uv sync` |
|
|
119
120
|
|
|
121
|
+
Homebrew installs from a private release feed. Export `HOMEBREW_GITHUB_API_TOKEN` (a token with read access to `arcadeai-labs/cade`) before running `brew install`.
|
|
122
|
+
|
|
120
123
|
**Prerequisites:** Python 3.11+, an Arcade account ([arcade.dev](https://arcade.dev)) for cloud tools, and an LLM provider key (`OPENAI_API_KEY` or `ANTHROPIC_API_KEY`). Skip the Arcade account with `--local-only` or `CADE_LOCAL_ONLY=1`.
|
|
121
124
|
|
|
122
125
|
```bash
|
|
@@ -124,6 +127,9 @@ cade login # Arcade Cloud OAuth (skip with --local-only)
|
|
|
124
127
|
cade --version
|
|
125
128
|
```
|
|
126
129
|
|
|
130
|
+
Full install and first-run docs: [`docs/install.md`](./docs/install.md) and
|
|
131
|
+
[`docs/quickstart.md`](./docs/quickstart.md).
|
|
132
|
+
|
|
127
133
|
---
|
|
128
134
|
|
|
129
135
|
## Quick start
|
|
@@ -131,11 +137,11 @@ cade --version
|
|
|
131
137
|
```bash
|
|
132
138
|
cade # interactive chat
|
|
133
139
|
cade -m "What changed in HEAD?" # single message, then exit
|
|
134
|
-
|
|
140
|
+
cade -m "What went wrong?" < error.log # prompt + file/stdin
|
|
135
141
|
cade -r # resume the most recent thread
|
|
136
142
|
cade resume "auth-rewrite" # resume a thread by name
|
|
137
143
|
cade --persona reviewer # use a saved persona's system prompt
|
|
138
|
-
cade --voice # speak / hear (voice
|
|
144
|
+
cade --voice # speak / hear (requires cade-cli[voice])
|
|
139
145
|
```
|
|
140
146
|
|
|
141
147
|
### Top-level options
|
|
@@ -143,9 +149,9 @@ cade --voice # speak / hear (voice mode)
|
|
|
143
149
|
| Flag | Description |
|
|
144
150
|
|---|---|
|
|
145
151
|
| `-r`, `--resume` | Resume most recent thread |
|
|
146
|
-
| `-m`, `--message` | Single-message mode
|
|
152
|
+
| `-m`, `--message` | Single-message mode; piped stdin is appended to the prompt |
|
|
147
153
|
| `-P`, `--persona` | Use a saved persona |
|
|
148
|
-
| `-V`, `--voice` | Voice mode |
|
|
154
|
+
| `-V`, `--voice` | Voice mode; install `cade-cli[voice]` first |
|
|
149
155
|
| `-v`, `--verbose` | Debug logging |
|
|
150
156
|
| `--version` | Print version |
|
|
151
157
|
|
|
@@ -159,7 +165,8 @@ cade --voice # speak / hear (voice mode)
|
|
|
159
165
|
| `/logs` | Recent log entries |
|
|
160
166
|
| `/thread`, `/history` | Current thread info |
|
|
161
167
|
| `/pin`, `/unpin` | Pin reference material into the session |
|
|
162
|
-
| `/
|
|
168
|
+
| `/tasks`, `/cron`, `/hooks`, `/channels`, `/notify` | Coordination surfaces (mirrored as `cade tasks` / `cade cron` / `cade hooks` / `cade channels`) |
|
|
169
|
+
| `/usage` | Context-window status and token usage |
|
|
163
170
|
| `/cd`, `/pwd`, `/!` | Shell shortcuts |
|
|
164
171
|
| `Ctrl+C` | Exit |
|
|
165
172
|
|
|
@@ -169,7 +176,7 @@ cade --voice # speak / hear (voice mode)
|
|
|
169
176
|
|
|
170
177
|
Tools come from three sources and are addressed uniformly by their registered name:
|
|
171
178
|
|
|
172
|
-
- **`Local_*`** — built-in: filesystem (`ReadFile`, `WriteFile`, `Edit`, `ListFiles`), shell (`Bash`
|
|
179
|
+
- **`Local_*`** — built-in: filesystem (`ReadFile`, `WriteFile`, `Edit`, `ListFiles`), shell (`Bash`), `Search`, `Git`, `Task*`, `AskUserQuestion`, `RetrieveToolResult`, `ToolSchema`, `PinContext`, `PushNotification`, `WebFetch`, and `WebSearch`.
|
|
173
180
|
- **`Memory_*`** — agent-library backed, per-persona indexed knowledge store.
|
|
174
181
|
- **Arcade Cloud + user MCP servers** — anything you register.
|
|
175
182
|
|
|
@@ -191,7 +198,7 @@ cade mcp authorize my-server # OAuth flow (browser)
|
|
|
191
198
|
cade mcp list / status / test / enable / disable / rm
|
|
192
199
|
```
|
|
193
200
|
|
|
194
|
-
User MCP servers register at `~/.
|
|
201
|
+
User MCP servers register at `~/.cade/config/contexts/<context>.toml [[mcp]]`. Servers with large catalogs are auto-deferred (parameter schemas stripped to keep tool-list bytes down) and fetched on demand via `Local_ToolSchema`.
|
|
195
202
|
|
|
196
203
|
---
|
|
197
204
|
|
|
@@ -206,13 +213,13 @@ cade mem add ~/notes # index a directory
|
|
|
206
213
|
cade mem search "auth design" # semantic search
|
|
207
214
|
```
|
|
208
215
|
|
|
209
|
-
Memory is persona-scoped — each persona has its own `~/.
|
|
216
|
+
Memory is persona-scoped — each persona has its own `~/.cade/data/contexts/<context>/memory/<persona>/.librarian/` index, so a `reviewer` persona's notes never leak into `default`.
|
|
210
217
|
|
|
211
218
|
---
|
|
212
219
|
|
|
213
220
|
## Headless daemon: `cade serve`
|
|
214
221
|
|
|
215
|
-
Run Cade as a long-lived daemon that replies
|
|
222
|
+
Run Cade as a long-lived daemon that replies through adapters. Telegram is supported for personal bot workflows, and Desktop exposes a local WebSocket for native clients. Each conversation gets its own persistent thread — persona, memory, and tools carry across messages.
|
|
216
223
|
|
|
217
224
|
```bash
|
|
218
225
|
cade serve init # wizard: bot token, allowed senders
|
|
@@ -221,11 +228,11 @@ cade serve --install launchd # macOS LaunchAgent (or --install syste
|
|
|
221
228
|
cade serve status / stop # health, uptime; SIGTERM running daemon
|
|
222
229
|
```
|
|
223
230
|
|
|
224
|
-
Config lives at `~/.
|
|
231
|
+
Config lives at `~/.cade/config/contexts/<context>.toml [serve]`. Edit and `kill -HUP $(cat ~/.cade/run/serve.pid)` to reload without restart.
|
|
225
232
|
|
|
226
|
-
**Security defaults are fail-closed:** `allowed_senders = []` blocks everyone; tools are default-deny against `[tools].allow` (globs / regex / pipe lists supported); `deny` always wins.
|
|
233
|
+
**Security defaults are fail-closed:** `allowed_senders = []` blocks everyone; tools are default-deny against `[serve.tools].allow` (globs / regex / pipe lists supported); `deny` always wins.
|
|
227
234
|
|
|
228
|
-
The MCP transport is fully bidirectional, so tools running inside the daemon can elicit structured input
|
|
235
|
+
The MCP transport is fully bidirectional, so tools running inside the daemon can elicit structured input, stream live progress, and emit logs through whichever adapter is active. See [`docs/adapters/`](./docs/adapters/) for adapter details, [`docs/mcp.md`](./docs/mcp.md) for protocol details, and [`docs/configuration.md`](./docs/configuration.md) for the full daemon config reference.
|
|
229
236
|
|
|
230
237
|
---
|
|
231
238
|
|
|
@@ -249,17 +256,18 @@ See [`docs/channels.md`](./docs/channels.md) for the channels protocol; hooks an
|
|
|
249
256
|
Cade works with any OpenAI-compatible endpoint. Three ways to wire one in (CLI flag → env → config, first match wins):
|
|
250
257
|
|
|
251
258
|
```bash
|
|
252
|
-
# CLI flag
|
|
253
|
-
cade chat --endpoint http://localhost:11434
|
|
259
|
+
# CLI flag for Ollama. Use a model from `ollama list`.
|
|
260
|
+
cade chat -L --endpoint http://localhost:11434 --model qwen3:4b
|
|
254
261
|
|
|
255
|
-
# Environment
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
262
|
+
# Environment for one-shot mode
|
|
263
|
+
cade context create local-qwen --model qwen3:4b
|
|
264
|
+
cade context use local-qwen
|
|
265
|
+
export OLLAMA_BASE_URL="http://localhost:11434"
|
|
266
|
+
CADE_LOCAL_ONLY=1 cade -m "hello from a local model"
|
|
259
267
|
|
|
260
|
-
# Config — ~/.
|
|
268
|
+
# Config — ~/.cade/config/cade.toml
|
|
261
269
|
[model_settings]
|
|
262
|
-
host = "http://localhost:
|
|
270
|
+
host = "http://localhost:8000/v1"
|
|
263
271
|
api_key = "ollama"
|
|
264
272
|
```
|
|
265
273
|
|
|
@@ -269,15 +277,15 @@ Skip Arcade Cloud authentication entirely with `--local-only` or `CADE_LOCAL_ONL
|
|
|
269
277
|
|
|
270
278
|
## Configuration
|
|
271
279
|
|
|
272
|
-
All state lives under `~/.
|
|
280
|
+
All state lives under `~/.cade/`. Override the location with `CADE_HOME=/path/to/alt`.
|
|
273
281
|
|
|
274
282
|
| File | Purpose |
|
|
275
283
|
|---|---|
|
|
276
|
-
| `
|
|
277
|
-
| `
|
|
278
|
-
| `
|
|
279
|
-
| `
|
|
280
|
-
| `serve
|
|
284
|
+
| `config/cade.toml` | Model / provider / UI settings |
|
|
285
|
+
| `data/contexts/<context>/history.db` | Thread + message storage |
|
|
286
|
+
| `logs/cade.log` | Rotating log file |
|
|
287
|
+
| `config/contexts/<context>.toml [[mcp]]` | User MCP server registry |
|
|
288
|
+
| `config/contexts/<context>.toml [serve]` | `cade serve` daemon config |
|
|
281
289
|
| `personas/`, `memory/`, `tasks/`, `channels/` | Persona-scoped state |
|
|
282
290
|
|
|
283
291
|
Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/configuration.md).
|
|
@@ -290,7 +298,7 @@ Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/confi
|
|
|
290
298
|
| `OPENAI_BASE_URL` | Custom OpenAI-compatible endpoint |
|
|
291
299
|
| `ARCADE_API_KEY`, `ARCADE_BASE_URL` | Arcade Cloud (alternative to OAuth) |
|
|
292
300
|
| `CADE_LOCAL_ONLY=1` | Skip remote tools entirely |
|
|
293
|
-
| `
|
|
301
|
+
| `CADE_HOME` | Override config directory |
|
|
294
302
|
| `CADE_PROJECT_ROOT` | Sandbox `Local_*` filesystem tools to this root |
|
|
295
303
|
|
|
296
304
|
---
|
|
@@ -300,14 +308,15 @@ Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/confi
|
|
|
300
308
|
```bash
|
|
301
309
|
git clone https://github.com/arcadeai-labs/cade.git
|
|
302
310
|
cd cade
|
|
303
|
-
uv sync --
|
|
304
|
-
|
|
305
|
-
|
|
311
|
+
uv sync --extra dev
|
|
312
|
+
uv run pytest
|
|
313
|
+
uv run ruff check src/ tests/
|
|
306
314
|
```
|
|
307
315
|
|
|
308
316
|
Style: Python 3.11+ with modern type hints (`dict`, `list`, `| None`); ruff for lint + format; pytest with `asyncio_mode = "auto"`. Public functions and classes get docstrings.
|
|
309
317
|
|
|
310
|
-
|
|
318
|
+
Build/release docs live in [`docs/development.md`](./docs/development.md). PRs
|
|
319
|
+
welcome — open an issue first for anything substantial.
|
|
311
320
|
|
|
312
321
|
---
|
|
313
322
|
|
|
@@ -315,7 +324,7 @@ PRs welcome — open an issue first for anything substantial.
|
|
|
315
324
|
|
|
316
325
|
- [arcade.dev](https://arcade.dev) — product
|
|
317
326
|
- [docs.arcade.dev](https://docs.arcade.dev) — API and tool catalog
|
|
318
|
-
- [`docs/`](./docs/) —
|
|
327
|
+
- [`docs/`](./docs/) — quickstart, examples, install, config, MCP, channels, voice, development, and adapters
|
|
319
328
|
- [Issues](https://github.com/arcadeai-labs/cade/issues) · [Releases](https://github.com/arcadeai-labs/cade/releases)
|
|
320
329
|
|
|
321
330
|
## License
|
|
@@ -30,6 +30,8 @@ cade
|
|
|
30
30
|
| pip | `pip install cade-cli` |
|
|
31
31
|
| From source | `git clone https://github.com/arcadeai-labs/cade.git && cd cade && uv sync` |
|
|
32
32
|
|
|
33
|
+
Homebrew installs from a private release feed. Export `HOMEBREW_GITHUB_API_TOKEN` (a token with read access to `arcadeai-labs/cade`) before running `brew install`.
|
|
34
|
+
|
|
33
35
|
**Prerequisites:** Python 3.11+, an Arcade account ([arcade.dev](https://arcade.dev)) for cloud tools, and an LLM provider key (`OPENAI_API_KEY` or `ANTHROPIC_API_KEY`). Skip the Arcade account with `--local-only` or `CADE_LOCAL_ONLY=1`.
|
|
34
36
|
|
|
35
37
|
```bash
|
|
@@ -37,6 +39,9 @@ cade login # Arcade Cloud OAuth (skip with --local-only)
|
|
|
37
39
|
cade --version
|
|
38
40
|
```
|
|
39
41
|
|
|
42
|
+
Full install and first-run docs: [`docs/install.md`](./docs/install.md) and
|
|
43
|
+
[`docs/quickstart.md`](./docs/quickstart.md).
|
|
44
|
+
|
|
40
45
|
---
|
|
41
46
|
|
|
42
47
|
## Quick start
|
|
@@ -44,11 +49,11 @@ cade --version
|
|
|
44
49
|
```bash
|
|
45
50
|
cade # interactive chat
|
|
46
51
|
cade -m "What changed in HEAD?" # single message, then exit
|
|
47
|
-
|
|
52
|
+
cade -m "What went wrong?" < error.log # prompt + file/stdin
|
|
48
53
|
cade -r # resume the most recent thread
|
|
49
54
|
cade resume "auth-rewrite" # resume a thread by name
|
|
50
55
|
cade --persona reviewer # use a saved persona's system prompt
|
|
51
|
-
cade --voice # speak / hear (voice
|
|
56
|
+
cade --voice # speak / hear (requires cade-cli[voice])
|
|
52
57
|
```
|
|
53
58
|
|
|
54
59
|
### Top-level options
|
|
@@ -56,9 +61,9 @@ cade --voice # speak / hear (voice mode)
|
|
|
56
61
|
| Flag | Description |
|
|
57
62
|
|---|---|
|
|
58
63
|
| `-r`, `--resume` | Resume most recent thread |
|
|
59
|
-
| `-m`, `--message` | Single-message mode
|
|
64
|
+
| `-m`, `--message` | Single-message mode; piped stdin is appended to the prompt |
|
|
60
65
|
| `-P`, `--persona` | Use a saved persona |
|
|
61
|
-
| `-V`, `--voice` | Voice mode |
|
|
66
|
+
| `-V`, `--voice` | Voice mode; install `cade-cli[voice]` first |
|
|
62
67
|
| `-v`, `--verbose` | Debug logging |
|
|
63
68
|
| `--version` | Print version |
|
|
64
69
|
|
|
@@ -72,7 +77,8 @@ cade --voice # speak / hear (voice mode)
|
|
|
72
77
|
| `/logs` | Recent log entries |
|
|
73
78
|
| `/thread`, `/history` | Current thread info |
|
|
74
79
|
| `/pin`, `/unpin` | Pin reference material into the session |
|
|
75
|
-
| `/
|
|
80
|
+
| `/tasks`, `/cron`, `/hooks`, `/channels`, `/notify` | Coordination surfaces (mirrored as `cade tasks` / `cade cron` / `cade hooks` / `cade channels`) |
|
|
81
|
+
| `/usage` | Context-window status and token usage |
|
|
76
82
|
| `/cd`, `/pwd`, `/!` | Shell shortcuts |
|
|
77
83
|
| `Ctrl+C` | Exit |
|
|
78
84
|
|
|
@@ -82,7 +88,7 @@ cade --voice # speak / hear (voice mode)
|
|
|
82
88
|
|
|
83
89
|
Tools come from three sources and are addressed uniformly by their registered name:
|
|
84
90
|
|
|
85
|
-
- **`Local_*`** — built-in: filesystem (`ReadFile`, `WriteFile`, `Edit`, `ListFiles`), shell (`Bash`
|
|
91
|
+
- **`Local_*`** — built-in: filesystem (`ReadFile`, `WriteFile`, `Edit`, `ListFiles`), shell (`Bash`), `Search`, `Git`, `Task*`, `AskUserQuestion`, `RetrieveToolResult`, `ToolSchema`, `PinContext`, `PushNotification`, `WebFetch`, and `WebSearch`.
|
|
86
92
|
- **`Memory_*`** — agent-library backed, per-persona indexed knowledge store.
|
|
87
93
|
- **Arcade Cloud + user MCP servers** — anything you register.
|
|
88
94
|
|
|
@@ -104,7 +110,7 @@ cade mcp authorize my-server # OAuth flow (browser)
|
|
|
104
110
|
cade mcp list / status / test / enable / disable / rm
|
|
105
111
|
```
|
|
106
112
|
|
|
107
|
-
User MCP servers register at `~/.
|
|
113
|
+
User MCP servers register at `~/.cade/config/contexts/<context>.toml [[mcp]]`. Servers with large catalogs are auto-deferred (parameter schemas stripped to keep tool-list bytes down) and fetched on demand via `Local_ToolSchema`.
|
|
108
114
|
|
|
109
115
|
---
|
|
110
116
|
|
|
@@ -119,13 +125,13 @@ cade mem add ~/notes # index a directory
|
|
|
119
125
|
cade mem search "auth design" # semantic search
|
|
120
126
|
```
|
|
121
127
|
|
|
122
|
-
Memory is persona-scoped — each persona has its own `~/.
|
|
128
|
+
Memory is persona-scoped — each persona has its own `~/.cade/data/contexts/<context>/memory/<persona>/.librarian/` index, so a `reviewer` persona's notes never leak into `default`.
|
|
123
129
|
|
|
124
130
|
---
|
|
125
131
|
|
|
126
132
|
## Headless daemon: `cade serve`
|
|
127
133
|
|
|
128
|
-
Run Cade as a long-lived daemon that replies
|
|
134
|
+
Run Cade as a long-lived daemon that replies through adapters. Telegram is supported for personal bot workflows, and Desktop exposes a local WebSocket for native clients. Each conversation gets its own persistent thread — persona, memory, and tools carry across messages.
|
|
129
135
|
|
|
130
136
|
```bash
|
|
131
137
|
cade serve init # wizard: bot token, allowed senders
|
|
@@ -134,11 +140,11 @@ cade serve --install launchd # macOS LaunchAgent (or --install syste
|
|
|
134
140
|
cade serve status / stop # health, uptime; SIGTERM running daemon
|
|
135
141
|
```
|
|
136
142
|
|
|
137
|
-
Config lives at `~/.
|
|
143
|
+
Config lives at `~/.cade/config/contexts/<context>.toml [serve]`. Edit and `kill -HUP $(cat ~/.cade/run/serve.pid)` to reload without restart.
|
|
138
144
|
|
|
139
|
-
**Security defaults are fail-closed:** `allowed_senders = []` blocks everyone; tools are default-deny against `[tools].allow` (globs / regex / pipe lists supported); `deny` always wins.
|
|
145
|
+
**Security defaults are fail-closed:** `allowed_senders = []` blocks everyone; tools are default-deny against `[serve.tools].allow` (globs / regex / pipe lists supported); `deny` always wins.
|
|
140
146
|
|
|
141
|
-
The MCP transport is fully bidirectional, so tools running inside the daemon can elicit structured input
|
|
147
|
+
The MCP transport is fully bidirectional, so tools running inside the daemon can elicit structured input, stream live progress, and emit logs through whichever adapter is active. See [`docs/adapters/`](./docs/adapters/) for adapter details, [`docs/mcp.md`](./docs/mcp.md) for protocol details, and [`docs/configuration.md`](./docs/configuration.md) for the full daemon config reference.
|
|
142
148
|
|
|
143
149
|
---
|
|
144
150
|
|
|
@@ -162,17 +168,18 @@ See [`docs/channels.md`](./docs/channels.md) for the channels protocol; hooks an
|
|
|
162
168
|
Cade works with any OpenAI-compatible endpoint. Three ways to wire one in (CLI flag → env → config, first match wins):
|
|
163
169
|
|
|
164
170
|
```bash
|
|
165
|
-
# CLI flag
|
|
166
|
-
cade chat --endpoint http://localhost:11434
|
|
171
|
+
# CLI flag for Ollama. Use a model from `ollama list`.
|
|
172
|
+
cade chat -L --endpoint http://localhost:11434 --model qwen3:4b
|
|
167
173
|
|
|
168
|
-
# Environment
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
174
|
+
# Environment for one-shot mode
|
|
175
|
+
cade context create local-qwen --model qwen3:4b
|
|
176
|
+
cade context use local-qwen
|
|
177
|
+
export OLLAMA_BASE_URL="http://localhost:11434"
|
|
178
|
+
CADE_LOCAL_ONLY=1 cade -m "hello from a local model"
|
|
172
179
|
|
|
173
|
-
# Config — ~/.
|
|
180
|
+
# Config — ~/.cade/config/cade.toml
|
|
174
181
|
[model_settings]
|
|
175
|
-
host = "http://localhost:
|
|
182
|
+
host = "http://localhost:8000/v1"
|
|
176
183
|
api_key = "ollama"
|
|
177
184
|
```
|
|
178
185
|
|
|
@@ -182,15 +189,15 @@ Skip Arcade Cloud authentication entirely with `--local-only` or `CADE_LOCAL_ONL
|
|
|
182
189
|
|
|
183
190
|
## Configuration
|
|
184
191
|
|
|
185
|
-
All state lives under `~/.
|
|
192
|
+
All state lives under `~/.cade/`. Override the location with `CADE_HOME=/path/to/alt`.
|
|
186
193
|
|
|
187
194
|
| File | Purpose |
|
|
188
195
|
|---|---|
|
|
189
|
-
| `
|
|
190
|
-
| `
|
|
191
|
-
| `
|
|
192
|
-
| `
|
|
193
|
-
| `serve
|
|
196
|
+
| `config/cade.toml` | Model / provider / UI settings |
|
|
197
|
+
| `data/contexts/<context>/history.db` | Thread + message storage |
|
|
198
|
+
| `logs/cade.log` | Rotating log file |
|
|
199
|
+
| `config/contexts/<context>.toml [[mcp]]` | User MCP server registry |
|
|
200
|
+
| `config/contexts/<context>.toml [serve]` | `cade serve` daemon config |
|
|
194
201
|
| `personas/`, `memory/`, `tasks/`, `channels/` | Persona-scoped state |
|
|
195
202
|
|
|
196
203
|
Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/configuration.md).
|
|
@@ -203,7 +210,7 @@ Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/confi
|
|
|
203
210
|
| `OPENAI_BASE_URL` | Custom OpenAI-compatible endpoint |
|
|
204
211
|
| `ARCADE_API_KEY`, `ARCADE_BASE_URL` | Arcade Cloud (alternative to OAuth) |
|
|
205
212
|
| `CADE_LOCAL_ONLY=1` | Skip remote tools entirely |
|
|
206
|
-
| `
|
|
213
|
+
| `CADE_HOME` | Override config directory |
|
|
207
214
|
| `CADE_PROJECT_ROOT` | Sandbox `Local_*` filesystem tools to this root |
|
|
208
215
|
|
|
209
216
|
---
|
|
@@ -213,14 +220,15 @@ Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/confi
|
|
|
213
220
|
```bash
|
|
214
221
|
git clone https://github.com/arcadeai-labs/cade.git
|
|
215
222
|
cd cade
|
|
216
|
-
uv sync --
|
|
217
|
-
|
|
218
|
-
|
|
223
|
+
uv sync --extra dev
|
|
224
|
+
uv run pytest
|
|
225
|
+
uv run ruff check src/ tests/
|
|
219
226
|
```
|
|
220
227
|
|
|
221
228
|
Style: Python 3.11+ with modern type hints (`dict`, `list`, `| None`); ruff for lint + format; pytest with `asyncio_mode = "auto"`. Public functions and classes get docstrings.
|
|
222
229
|
|
|
223
|
-
|
|
230
|
+
Build/release docs live in [`docs/development.md`](./docs/development.md). PRs
|
|
231
|
+
welcome — open an issue first for anything substantial.
|
|
224
232
|
|
|
225
233
|
---
|
|
226
234
|
|
|
@@ -228,7 +236,7 @@ PRs welcome — open an issue first for anything substantial.
|
|
|
228
236
|
|
|
229
237
|
- [arcade.dev](https://arcade.dev) — product
|
|
230
238
|
- [docs.arcade.dev](https://docs.arcade.dev) — API and tool catalog
|
|
231
|
-
- [`docs/`](./docs/) —
|
|
239
|
+
- [`docs/`](./docs/) — quickstart, examples, install, config, MCP, channels, voice, development, and adapters
|
|
232
240
|
- [Issues](https://github.com/arcadeai-labs/cade/issues) · [Releases](https://github.com/arcadeai-labs/cade/releases)
|
|
233
241
|
|
|
234
242
|
## License
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cade-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.13.2"
|
|
4
4
|
description = "Cade - The CLI Agent from Arcade.dev"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -27,24 +27,23 @@ dependencies = [
|
|
|
27
27
|
"typer>0.10.0",
|
|
28
28
|
"pydantic[email]>=2.0.0,<3.0.0",
|
|
29
29
|
"toml>=0.10.0,<1.0.0",
|
|
30
|
-
"pyyaml>=6.0,<7.0.0",
|
|
31
30
|
"openai>=1.0.0,<2.0.0",
|
|
32
31
|
"anthropic>=0.34.0,<1.0.0",
|
|
33
32
|
"ulid==1.1",
|
|
34
|
-
"arcade-tdk>=
|
|
35
|
-
"arcade-mcp-server>=1.0.0",
|
|
36
|
-
"arcade-core>=4.
|
|
33
|
+
"arcade-tdk>=3.8.0,<4.0.0",
|
|
34
|
+
"arcade-mcp-server>=1.22.0,<2.0.0",
|
|
35
|
+
"arcade-core>=4.7.0,<5.0.0",
|
|
36
|
+
"arcadepy>=1.10.0,<2.0.0",
|
|
37
37
|
"authlib>=1.6.0,<2.0.0",
|
|
38
|
-
"pyperclip>=1.8.0,<2.0.0",
|
|
39
38
|
"prompt-toolkit>=3.0.52,<4.0.0",
|
|
40
|
-
"tiktoken>=0.11.0,<1.0.0",
|
|
41
39
|
"httpx>=0.27.0,<1.0.0",
|
|
42
40
|
"filelock>=3.0.0,<4.0.0",
|
|
43
|
-
"agent-library>=0.
|
|
44
|
-
"sounddevice>=0.5.5",
|
|
41
|
+
"agent-library>=0.13.1,<1.0.0",
|
|
45
42
|
"croniter>=2.0.0,<4.0.0",
|
|
46
43
|
"python-telegram-bot>=21.0,<22.0",
|
|
47
44
|
"keyring>=24.0,<26.0",
|
|
45
|
+
"html2text>=2024.2.26",
|
|
46
|
+
"websockets>=14.0,<16.0",
|
|
48
47
|
]
|
|
49
48
|
|
|
50
49
|
[project.urls]
|
|
@@ -67,10 +66,13 @@ dev = [
|
|
|
67
66
|
"pytest-cov>=4.0.0,<5.0.0",
|
|
68
67
|
"mypy>=1.10.0,<2.0.0",
|
|
69
68
|
]
|
|
69
|
+
build = [
|
|
70
|
+
"pyinstaller>=6.16.0,<7.0.0",
|
|
71
|
+
]
|
|
70
72
|
voice = [
|
|
71
73
|
"mlx-audio>=0.2.0,<0.4.0",
|
|
72
74
|
"mlx-whisper>=0.1.0",
|
|
73
|
-
"sounddevice>=0.
|
|
75
|
+
"sounddevice>=0.5.5,<1.0.0",
|
|
74
76
|
"numpy>=1.24.0",
|
|
75
77
|
"webrtcvad>=2.0.10",
|
|
76
78
|
]
|
|
@@ -98,6 +100,9 @@ packages = ["src/cadecoder", "src/cade_mcp_local"]
|
|
|
98
100
|
testpaths = ["tests"]
|
|
99
101
|
asyncio_mode = "auto"
|
|
100
102
|
asyncio_default_fixture_loop_scope = "function"
|
|
103
|
+
markers = [
|
|
104
|
+
"integration: tests that cross process or network boundaries without external services",
|
|
105
|
+
]
|
|
101
106
|
|
|
102
107
|
[tool.ruff]
|
|
103
108
|
line-length = 100
|
|
@@ -27,12 +27,17 @@ from cade_mcp_local.config import (
|
|
|
27
27
|
from cade_mcp_local.errors import (
|
|
28
28
|
CommandExecutionError,
|
|
29
29
|
CommandTimeoutError,
|
|
30
|
+
ContentTooLargeError,
|
|
30
31
|
FileOperationError,
|
|
31
32
|
GitOperationError,
|
|
32
33
|
InvalidInputError,
|
|
33
34
|
PathNotFoundError,
|
|
34
35
|
PathSecurityError,
|
|
36
|
+
RedirectError,
|
|
35
37
|
SearchError,
|
|
38
|
+
WebFetchError,
|
|
39
|
+
WebSearchError,
|
|
40
|
+
WebTransientError,
|
|
36
41
|
)
|
|
37
42
|
from cade_mcp_local.server import app, create_app
|
|
38
43
|
|
|
@@ -67,6 +72,11 @@ __all__ = [
|
|
|
67
72
|
"GitOperationError",
|
|
68
73
|
"SearchError",
|
|
69
74
|
"FileOperationError",
|
|
75
|
+
"WebFetchError",
|
|
76
|
+
"WebSearchError",
|
|
77
|
+
"RedirectError",
|
|
78
|
+
"ContentTooLargeError",
|
|
79
|
+
"WebTransientError",
|
|
70
80
|
]
|
|
71
81
|
|
|
72
82
|
from cadecoder import __version__ as __version__ # noqa: E402
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Reusable :class:`ToolMetadata` builders for Local_* tools.
|
|
2
|
+
|
|
3
|
+
Local tools run in-process against the user's machine. None of them have a
|
|
4
|
+
``ServiceDomain`` (those describe an external service like Slack or Gmail);
|
|
5
|
+
``open_world`` is therefore ``False`` for everything in this package, and
|
|
6
|
+
the per-tool metadata below only varies on operation/read-only/destructive/
|
|
7
|
+
idempotent.
|
|
8
|
+
|
|
9
|
+
Web tools (``WebFetch`` / ``WebSearch``) are the exception — they declare
|
|
10
|
+
``ServiceDomain.WEB_SCRAPING`` and ``open_world=True`` inline, since their
|
|
11
|
+
backing data lives on the open internet.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from arcade_mcp_server.metadata import (
|
|
15
|
+
Behavior,
|
|
16
|
+
Classification,
|
|
17
|
+
Operation,
|
|
18
|
+
ToolMetadata,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _meta(
|
|
23
|
+
*,
|
|
24
|
+
operations: list[Operation],
|
|
25
|
+
read_only: bool,
|
|
26
|
+
destructive: bool = False,
|
|
27
|
+
idempotent: bool = False,
|
|
28
|
+
) -> ToolMetadata:
|
|
29
|
+
"""All Local_* tools share open_world=False and no service_domains."""
|
|
30
|
+
return ToolMetadata(
|
|
31
|
+
classification=Classification(service_domains=None),
|
|
32
|
+
behavior=Behavior(
|
|
33
|
+
operations=operations,
|
|
34
|
+
read_only=read_only,
|
|
35
|
+
destructive=destructive,
|
|
36
|
+
idempotent=idempotent,
|
|
37
|
+
open_world=False,
|
|
38
|
+
),
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
READ_META = _meta(operations=[Operation.READ], read_only=True, idempotent=True)
|
|
43
|
+
"""Pure read of local state. Idempotent."""
|
|
44
|
+
|
|
45
|
+
READ_VOLATILE_META = _meta(operations=[Operation.READ], read_only=True, idempotent=False)
|
|
46
|
+
"""Reads local state that changes under the agent's feet (e.g. compaction backups)."""
|
|
47
|
+
|
|
48
|
+
CREATE_META = _meta(operations=[Operation.CREATE], read_only=False, idempotent=False)
|
|
49
|
+
"""Creates a new local resource (file, task, snippet, notification)."""
|
|
50
|
+
|
|
51
|
+
UPDATE_META = _meta(operations=[Operation.UPDATE], read_only=False, idempotent=False)
|
|
52
|
+
"""Modifies an existing local resource."""
|
|
53
|
+
|
|
54
|
+
CREATE_OR_UPDATE_META = _meta(operations=[Operation.CREATE, Operation.UPDATE], read_only=False)
|
|
55
|
+
"""Upsert-style write that may create or update."""
|
|
56
|
+
|
|
57
|
+
DELETE_META = _meta(
|
|
58
|
+
operations=[Operation.DELETE], read_only=False, destructive=True, idempotent=True
|
|
59
|
+
)
|
|
60
|
+
"""Removes a local resource. Destructive."""
|
|
61
|
+
|
|
62
|
+
OPAQUE_META = ToolMetadata(
|
|
63
|
+
classification=Classification(service_domains=None),
|
|
64
|
+
behavior=Behavior(
|
|
65
|
+
operations=[Operation.OPAQUE],
|
|
66
|
+
read_only=False,
|
|
67
|
+
destructive=False,
|
|
68
|
+
idempotent=False,
|
|
69
|
+
open_world=False,
|
|
70
|
+
),
|
|
71
|
+
strict=False, # Bash/Channel can do anything; we keep destructive=False per "best case"
|
|
72
|
+
)
|
|
73
|
+
"""Action depends on runtime inputs (e.g. Bash, Channel multiplexer)."""
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
__all__ = (
|
|
77
|
+
"CREATE_META",
|
|
78
|
+
"CREATE_OR_UPDATE_META",
|
|
79
|
+
"DELETE_META",
|
|
80
|
+
"OPAQUE_META",
|
|
81
|
+
"READ_META",
|
|
82
|
+
"READ_VOLATILE_META",
|
|
83
|
+
"UPDATE_META",
|
|
84
|
+
)
|
|
@@ -120,3 +120,49 @@ class FileOperationError(FatalToolError):
|
|
|
120
120
|
self.operation = operation
|
|
121
121
|
self.path = path
|
|
122
122
|
super().__init__(f"Failed to {operation} '{path}': {message}")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class WebFetchError(FatalToolError):
|
|
126
|
+
"""Generic non-retriable WebFetch failure (DNS, 4xx, blocked host)."""
|
|
127
|
+
|
|
128
|
+
def __init__(self, url: str, message: str):
|
|
129
|
+
self.url = url
|
|
130
|
+
super().__init__(f"WebFetch failed for {url}: {message}")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class RedirectError(FatalToolError):
|
|
134
|
+
"""Cross-host redirect; the agent should re-fetch the new URL explicitly."""
|
|
135
|
+
|
|
136
|
+
def __init__(self, from_url: str, to_url: str):
|
|
137
|
+
self.from_url = from_url
|
|
138
|
+
self.to_url = to_url
|
|
139
|
+
super().__init__(
|
|
140
|
+
f"Cross-host redirect from {from_url} to {to_url}; re-call WebFetch with the new URL."
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class ContentTooLargeError(FatalToolError):
|
|
145
|
+
"""Body exceeded max_bytes."""
|
|
146
|
+
|
|
147
|
+
def __init__(self, url: str, limit_bytes: int):
|
|
148
|
+
self.url = url
|
|
149
|
+
self.limit_bytes = limit_bytes
|
|
150
|
+
super().__init__(f"Body for {url} exceeded {limit_bytes} bytes; aborted.")
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class WebSearchError(FatalToolError):
|
|
154
|
+
"""Backend misconfigured or returned an unparseable response."""
|
|
155
|
+
|
|
156
|
+
def __init__(self, backend: str, message: str):
|
|
157
|
+
self.backend = backend
|
|
158
|
+
super().__init__(f"WebSearch ({backend}) failed: {message}")
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class WebTransientError(RetryableToolError):
|
|
162
|
+
"""5xx, network reset, rate-limit. Agent may retry."""
|
|
163
|
+
|
|
164
|
+
def __init__(self, url: str, status: int | None, message: str):
|
|
165
|
+
self.url = url
|
|
166
|
+
self.status = status
|
|
167
|
+
detail = f" (HTTP {status})" if status else ""
|
|
168
|
+
super().__init__(f"Transient web error for {url}{detail}: {message}")
|