cade-cli 0.9.0__tar.gz → 0.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cade_cli-0.9.0 → cade_cli-0.11.0}/.gitignore +1 -1
- cade_cli-0.11.0/PKG-INFO +326 -0
- cade_cli-0.11.0/README.md +237 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/pyproject.toml +17 -12
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/__init__.py +11 -1
- cade_cli-0.11.0/src/cade_mcp_local/_metadata.py +84 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/errors.py +46 -0
- cade_cli-0.11.0/src/cade_mcp_local/resources.py +131 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/server.py +45 -4
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/tools/__init__.py +24 -4
- cade_cli-0.11.0/src/cade_mcp_local/tools/_read_cache.py +60 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/tools/context.py +43 -22
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/tools/filesystem.py +129 -163
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/tools/git.py +48 -33
- cade_cli-0.11.0/src/cade_mcp_local/tools/notifications.py +49 -0
- cade_cli-0.11.0/src/cade_mcp_local/tools/questions.py +241 -0
- cade_cli-0.9.0/src/cade_mcp_local/tools/tool_results.py → cade_cli-0.11.0/src/cade_mcp_local/tools/results.py +97 -92
- cade_cli-0.11.0/src/cade_mcp_local/tools/schemas.py +128 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/tools/search.py +34 -29
- cade_cli-0.11.0/src/cade_mcp_local/tools/shell.py +271 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/tools/snippets.py +25 -16
- cade_cli-0.11.0/src/cade_mcp_local/tools/tasks.py +167 -0
- cade_cli-0.11.0/src/cade_mcp_local/tools/web_fetch.py +256 -0
- cade_cli-0.11.0/src/cade_mcp_local/tools/web_search.py +158 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/__init__.py +1 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/arcade_client.py +131 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/cache.py +136 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/extract.py +54 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/markdown.py +64 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/preapproved.py +57 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/prompts.py +29 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/scrape.py +77 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/search/__init__.py +5 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/search/arcade.py +103 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/search/base.py +41 -0
- cade_cli-0.11.0/src/cade_mcp_local/web/search/http.py +129 -0
- cade_cli-0.11.0/src/cadecoder/__init__.py +6 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/ai/__init__.py +1 -1
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/ai/prompts.py +44 -28
- cade_cli-0.11.0/src/cadecoder/cli/app.py +307 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/auth.py +34 -46
- cade_cli-0.11.0/src/cadecoder/cli/commands/account.py +203 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/commands/auth.py +30 -38
- cade_cli-0.11.0/src/cadecoder/cli/commands/channels.py +79 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/commands/chat.py +20 -21
- cade_cli-0.11.0/src/cadecoder/cli/commands/context.py +184 -0
- cade_cli-0.11.0/src/cadecoder/cli/commands/cron.py +124 -0
- cade_cli-0.11.0/src/cadecoder/cli/commands/hooks.py +198 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/commands/mcp.py +1 -6
- cade_cli-0.11.0/src/cadecoder/cli/commands/mem.py +149 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/commands/model.py +12 -9
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/commands/persona.py +89 -161
- cade_cli-0.11.0/src/cadecoder/cli/commands/serve.py +259 -0
- cade_cli-0.11.0/src/cadecoder/cli/commands/tasks.py +150 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/commands/tools.py +47 -0
- cade_cli-0.11.0/src/cadecoder/core/config.py +556 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/core/errors.py +33 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/core/logging.py +5 -5
- cade_cli-0.11.0/src/cadecoder/core/paths.py +147 -0
- cade_cli-0.11.0/src/cadecoder/core/runtime.py +116 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/execution/context_window.py +3 -1
- cade_cli-0.11.0/src/cadecoder/execution/mcp_schema_index.py +109 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/execution/orchestrator.py +211 -29
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/execution/parallel.py +102 -27
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/execution/tool_result_store.py +4 -2
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/execution/tool_schema_cache.py +120 -3
- cade_cli-0.11.0/src/cadecoder/hooks/__init__.py +55 -0
- cade_cli-0.11.0/src/cadecoder/hooks/config.py +151 -0
- cade_cli-0.11.0/src/cadecoder/hooks/engine.py +188 -0
- cade_cli-0.11.0/src/cadecoder/hooks/executors/__init__.py +47 -0
- cade_cli-0.11.0/src/cadecoder/hooks/executors/callback.py +39 -0
- cade_cli-0.11.0/src/cadecoder/hooks/executors/command.py +126 -0
- cade_cli-0.11.0/src/cadecoder/hooks/executors/http.py +137 -0
- cade_cli-0.11.0/src/cadecoder/hooks/executors/prompt.py +131 -0
- cade_cli-0.11.0/src/cadecoder/hooks/executors/ssrf_guard.py +89 -0
- cade_cli-0.11.0/src/cadecoder/hooks/matchers.py +109 -0
- cade_cli-0.11.0/src/cadecoder/hooks/registry.py +163 -0
- cade_cli-0.11.0/src/cadecoder/hooks/types.py +145 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/providers/__init__.py +10 -4
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/providers/anthropic.py +105 -92
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/providers/base.py +101 -1
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/providers/ollama.py +106 -87
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/providers/openai.py +85 -77
- cade_cli-0.11.0/src/cadecoder/serve/__init__.py +11 -0
- cade_cli-0.11.0/src/cadecoder/serve/adapters/__init__.py +18 -0
- cade_cli-0.11.0/src/cadecoder/serve/adapters/base.py +173 -0
- cade_cli-0.11.0/src/cadecoder/serve/adapters/registry.py +42 -0
- cade_cli-0.11.0/src/cadecoder/serve/adapters/stub.py +176 -0
- cade_cli-0.11.0/src/cadecoder/serve/adapters/telegram.py +359 -0
- cade_cli-0.11.0/src/cadecoder/serve/allowlist.py +171 -0
- cade_cli-0.11.0/src/cadecoder/serve/chunker.py +135 -0
- cade_cli-0.11.0/src/cadecoder/serve/commands.py +103 -0
- cade_cli-0.11.0/src/cadecoder/serve/config.py +183 -0
- cade_cli-0.11.0/src/cadecoder/serve/daemon.py +353 -0
- cade_cli-0.11.0/src/cadecoder/serve/elicitation.py +291 -0
- cade_cli-0.11.0/src/cadecoder/serve/format.py +406 -0
- cade_cli-0.11.0/src/cadecoder/serve/install.py +159 -0
- cade_cli-0.11.0/src/cadecoder/serve/lock.py +96 -0
- cade_cli-0.11.0/src/cadecoder/serve/observability.py +161 -0
- cade_cli-0.11.0/src/cadecoder/serve/progress_sink.py +103 -0
- cade_cli-0.11.0/src/cadecoder/serve/router.py +56 -0
- cade_cli-0.11.0/src/cadecoder/serve/secrets.py +170 -0
- cade_cli-0.11.0/src/cadecoder/serve/sinks.py +247 -0
- cade_cli-0.11.0/src/cadecoder/serve/worker.py +481 -0
- cade_cli-0.11.0/src/cadecoder/storage/personas.py +216 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/storage/threads.py +181 -14
- cade_cli-0.11.0/src/cadecoder/tasks/__init__.py +42 -0
- cade_cli-0.11.0/src/cadecoder/tasks/channels.py +89 -0
- cade_cli-0.11.0/src/cadecoder/tasks/lock.py +124 -0
- cade_cli-0.11.0/src/cadecoder/tasks/notifications.py +100 -0
- cade_cli-0.11.0/src/cadecoder/tasks/scheduler.py +206 -0
- cade_cli-0.11.0/src/cadecoder/tasks/store.py +284 -0
- cade_cli-0.11.0/src/cadecoder/tasks/types.py +83 -0
- cade_cli-0.11.0/src/cadecoder/templates/serve/launchd.plist.tmpl +34 -0
- cade_cli-0.11.0/src/cadecoder/templates/serve/serve.toml.example +35 -0
- cade_cli-0.11.0/src/cadecoder/templates/serve/systemd.service.tmpl +18 -0
- cade_cli-0.11.0/src/cadecoder/tools/manager/_request_ctx.py +87 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/tools/manager/base.py +7 -1
- cade_cli-0.11.0/src/cadecoder/tools/manager/composite.py +1048 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/tools/manager/config.py +20 -28
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/tools/manager/mcp.py +638 -119
- cade_cli-0.11.0/src/cadecoder/tools/search/__init__.py +25 -0
- cade_cli-0.11.0/src/cadecoder/tools/search/discovered.py +202 -0
- cade_cli-0.11.0/src/cadecoder/tools/search/scoring.py +178 -0
- cade_cli-0.11.0/src/cadecoder/tools/search/service.py +171 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/ui/__init__.py +1 -1
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/ui/display.py +238 -36
- cade_cli-0.11.0/src/cadecoder/ui/elicitation.py +109 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/ui/input.py +4 -18
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/ui/session.py +350 -17
- cade_cli-0.11.0/src/cadecoder/ui/slash.py +46 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/voice/session.py +26 -32
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/voice/tts.py +47 -37
- cade_cli-0.9.0/PKG-INFO +0 -394
- cade_cli-0.9.0/README.md +0 -310
- cade_cli-0.9.0/src/cade_mcp_local/tools/shell.py +0 -157
- cade_cli-0.9.0/src/cade_mcp_local/tools/tool_schemas.py +0 -81
- cade_cli-0.9.0/src/cadecoder/__init__.py +0 -1
- cade_cli-0.9.0/src/cadecoder/cli/app.py +0 -196
- cade_cli-0.9.0/src/cadecoder/cli/commands/context.py +0 -333
- cade_cli-0.9.0/src/cadecoder/core/config.py +0 -444
- cade_cli-0.9.0/src/cadecoder/storage/personas.py +0 -403
- cade_cli-0.9.0/src/cadecoder/tools/manager/composite.py +0 -464
- cade_cli-0.9.0/src/cadecoder/tools/manager.py +0 -765
- {cade_cli-0.9.0 → cade_cli-0.11.0}/LICENSE +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/__main__.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/config.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cade_mcp_local/utils.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/__init__.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/commands/__init__.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/cli/commands/thread.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/core/__init__.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/core/constants.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/core/git.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/core/names.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/core/types.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/execution/__init__.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/storage/__init__.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/templates/login_failed.html +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/templates/login_success.html +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/templates/styles.css +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/tools/__init__.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/tools/manager/__init__.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/voice/__init__.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/voice/audio.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/voice/cleanup.py +0 -0
- {cade_cli-0.9.0 → cade_cli-0.11.0}/src/cadecoder/voice/stt.py +0 -0
cade_cli-0.11.0/PKG-INFO
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cade-cli
|
|
3
|
+
Version: 0.11.0
|
|
4
|
+
Summary: Cade - The CLI Agent from Arcade.dev
|
|
5
|
+
Project-URL: Homepage, https://arcade.dev
|
|
6
|
+
Project-URL: Documentation, https://docs.arcade.dev
|
|
7
|
+
Project-URL: Repository, https://github.com/arcadeai-labs/cade
|
|
8
|
+
Project-URL: Issues, https://github.com/arcadeai-labs/cade/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/arcadeai-labs/cade/releases
|
|
10
|
+
Author-email: "Arcade AI Inc." <dev@arcade.dev>
|
|
11
|
+
License: MIT License
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2024 Arcade AI Inc.
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Keywords: agent,ai,arcade,cli,coding-assistant,llm,mcp
|
|
34
|
+
Classifier: Development Status :: 4 - Beta
|
|
35
|
+
Classifier: Environment :: Console
|
|
36
|
+
Classifier: Intended Audience :: Developers
|
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
38
|
+
Classifier: Operating System :: OS Independent
|
|
39
|
+
Classifier: Programming Language :: Python :: 3
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
42
|
+
Classifier: Topic :: Software Development
|
|
43
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
44
|
+
Classifier: Typing :: Typed
|
|
45
|
+
Requires-Python: >=3.11
|
|
46
|
+
Requires-Dist: agent-library<1.0.0,>=0.12.0
|
|
47
|
+
Requires-Dist: anthropic<1.0.0,>=0.34.0
|
|
48
|
+
Requires-Dist: arcade-core<5.0.0,>=4.7.0
|
|
49
|
+
Requires-Dist: arcade-mcp-server<2.0.0,>=1.21.0
|
|
50
|
+
Requires-Dist: arcade-tdk<4.0.0,>=3.8.0
|
|
51
|
+
Requires-Dist: arcadepy<2.0.0,>=1.10.0
|
|
52
|
+
Requires-Dist: authlib<2.0.0,>=1.6.0
|
|
53
|
+
Requires-Dist: croniter<4.0.0,>=2.0.0
|
|
54
|
+
Requires-Dist: filelock<4.0.0,>=3.0.0
|
|
55
|
+
Requires-Dist: html2text>=2024.2.26
|
|
56
|
+
Requires-Dist: httpx<1.0.0,>=0.27.0
|
|
57
|
+
Requires-Dist: keyring<26.0,>=24.0
|
|
58
|
+
Requires-Dist: openai<2.0.0,>=1.0.0
|
|
59
|
+
Requires-Dist: prompt-toolkit<4.0.0,>=3.0.52
|
|
60
|
+
Requires-Dist: pydantic[email]<3.0.0,>=2.0.0
|
|
61
|
+
Requires-Dist: pyperclip<2.0.0,>=1.8.0
|
|
62
|
+
Requires-Dist: python-telegram-bot<22.0,>=21.0
|
|
63
|
+
Requires-Dist: pyyaml<7.0.0,>=6.0
|
|
64
|
+
Requires-Dist: rich<14.0.0,>=13.0.0
|
|
65
|
+
Requires-Dist: sounddevice>=0.5.5
|
|
66
|
+
Requires-Dist: tiktoken<1.0.0,>=0.11.0
|
|
67
|
+
Requires-Dist: toml<1.0.0,>=0.10.0
|
|
68
|
+
Requires-Dist: typer>0.10.0
|
|
69
|
+
Requires-Dist: ulid==1.1
|
|
70
|
+
Provides-Extra: dev
|
|
71
|
+
Requires-Dist: mypy<2.0.0,>=1.10.0; extra == 'dev'
|
|
72
|
+
Requires-Dist: pytest-asyncio<1.0.0,>=0.24.0; extra == 'dev'
|
|
73
|
+
Requires-Dist: pytest-cov<5.0.0,>=4.0.0; extra == 'dev'
|
|
74
|
+
Requires-Dist: pytest-mock<4.0.0,>=3.11.0; extra == 'dev'
|
|
75
|
+
Requires-Dist: pytest<9.0.0,>=8.0.0; extra == 'dev'
|
|
76
|
+
Requires-Dist: ruff<1.0.0,>=0.5.0; extra == 'dev'
|
|
77
|
+
Provides-Extra: training
|
|
78
|
+
Requires-Dist: accelerate>=0.27.0; extra == 'training'
|
|
79
|
+
Requires-Dist: safetensors>=0.4.2; extra == 'training'
|
|
80
|
+
Requires-Dist: torch>=2.1.0; extra == 'training'
|
|
81
|
+
Requires-Dist: transformers>=4.38.0; extra == 'training'
|
|
82
|
+
Provides-Extra: voice
|
|
83
|
+
Requires-Dist: mlx-audio<0.4.0,>=0.2.0; extra == 'voice'
|
|
84
|
+
Requires-Dist: mlx-whisper>=0.1.0; extra == 'voice'
|
|
85
|
+
Requires-Dist: numpy>=1.24.0; extra == 'voice'
|
|
86
|
+
Requires-Dist: sounddevice>=0.4.0; extra == 'voice'
|
|
87
|
+
Requires-Dist: webrtcvad>=2.0.10; extra == 'voice'
|
|
88
|
+
Description-Content-Type: text/markdown
|
|
89
|
+
|
|
90
|
+
# Cade
|
|
91
|
+
|
|
92
|
+
The CLI agent from [Arcade.dev](https://arcade.dev). Coding, research, and everyday automation — driven from a terminal, a single shell pipe, or a long-lived daemon that replies over Telegram.
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
brew install ArcadeAI/tap/cade # or: uv tool install cade-cli | pip install cade-cli
|
|
96
|
+
cade login
|
|
97
|
+
cade
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Highlights
|
|
103
|
+
|
|
104
|
+
- **Three deployment modes from the same binary.** Interactive chat (`cade`), one-shot or pipe (`cade -m "…"`), or a headless daemon that replies over messaging (`cade serve`).
|
|
105
|
+
- **Tools from anywhere.** Built-in local tools (filesystem / shell / git / search / tasks / channels / memory), [Arcade Cloud](https://arcade.dev) tools (Slack, GitHub, Gmail, calendars, …), and any [MCP](https://modelcontextprotocol.io/) server you register — all unified under one tool surface.
|
|
106
|
+
- **Bidirectional MCP.** Tools can call `context.ui.elicit(…)` for structured input, `context.log.*` for live operator logs, and `context.progress.report(…)` for editable progress UI — routed end-to-end through whichever adapter is active (Telegram inline keyboard, terminal prompt).
|
|
107
|
+
- **Personas + per-persona memory.** Multiple agent profiles with their own system prompt and an indexed memory store backed by [agent-library](https://pypi.org/project/agent-library/).
|
|
108
|
+
- **Extensibility surface.** Hooks (lifecycle events), tasks (file-backed durable work), cron (scheduled prompts), channels (cross-session pub/sub) — all available to the agent as `Local_*` tools and to you as `cade <subcommand>`.
|
|
109
|
+
- **Bring your own LLM.** OpenAI, Anthropic, or any OpenAI-compatible endpoint (Ollama, vLLM, Together, Groq, Fireworks, …). `--local-only` skips Arcade Cloud entirely.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Install
|
|
114
|
+
|
|
115
|
+
| Source | Command |
|
|
116
|
+
|---|---|
|
|
117
|
+
| Homebrew | `brew install ArcadeAI/tap/cade` |
|
|
118
|
+
| uv | `uv tool install cade-cli` |
|
|
119
|
+
| pip | `pip install cade-cli` |
|
|
120
|
+
| From source | `git clone https://github.com/arcadeai-labs/cade.git && cd cade && uv sync` |
|
|
121
|
+
|
|
122
|
+
**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`.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
cade login # Arcade Cloud OAuth (skip with --local-only)
|
|
126
|
+
cade --version
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Quick start
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
cade # interactive chat
|
|
135
|
+
cade -m "What changed in HEAD?" # single message, then exit
|
|
136
|
+
cat error.log | cade -m "What went wrong?" # pipe input
|
|
137
|
+
cade -r # resume the most recent thread
|
|
138
|
+
cade resume "auth-rewrite" # resume a thread by name
|
|
139
|
+
cade --persona reviewer # use a saved persona's system prompt
|
|
140
|
+
cade --voice # speak / hear (voice mode)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Top-level options
|
|
144
|
+
|
|
145
|
+
| Flag | Description |
|
|
146
|
+
|---|---|
|
|
147
|
+
| `-r`, `--resume` | Resume most recent thread |
|
|
148
|
+
| `-m`, `--message` | Single-message mode (reads stdin if no arg) |
|
|
149
|
+
| `-P`, `--persona` | Use a saved persona |
|
|
150
|
+
| `-V`, `--voice` | Voice mode |
|
|
151
|
+
| `-v`, `--verbose` | Debug logging |
|
|
152
|
+
| `--version` | Print version |
|
|
153
|
+
|
|
154
|
+
### In-chat slash commands
|
|
155
|
+
|
|
156
|
+
| Command | Description |
|
|
157
|
+
|---|---|
|
|
158
|
+
| `/help` | List commands |
|
|
159
|
+
| `/clear` | Clear screen |
|
|
160
|
+
| `/copy` | Copy last response |
|
|
161
|
+
| `/logs` | Recent log entries |
|
|
162
|
+
| `/thread`, `/history` | Current thread info |
|
|
163
|
+
| `/pin`, `/unpin` | Pin reference material into the session |
|
|
164
|
+
| `/tasks`, `/cron`, `/hooks`, `/channels`, `/notify` | Coordination surfaces (mirrored as `cade tasks` / `cade cron` / `cade hooks` / `cade channels`) |
|
|
165
|
+
| `/usage` | Context-window status and token usage |
|
|
166
|
+
| `/cd`, `/pwd`, `/!` | Shell shortcuts |
|
|
167
|
+
| `Ctrl+C` | Exit |
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Tools
|
|
172
|
+
|
|
173
|
+
Tools come from three sources and are addressed uniformly by their registered name:
|
|
174
|
+
|
|
175
|
+
- **`Local_*`** — built-in: filesystem (`ReadFile`, `WriteFile`, `Edit`, `ListFiles`), shell (`Bash` — async with progress reporting), `Search`, `Git`, `Task*`, `Channel`, `AskUserQuestion`, `RetrieveToolResult`, `ToolSchema`, `Sleep`, `PinContext`, `PushNotification`.
|
|
176
|
+
- **`Memory_*`** — agent-library backed, per-persona indexed knowledge store.
|
|
177
|
+
- **Arcade Cloud + user MCP servers** — anything you register.
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
cade tools list # all tools, all sources
|
|
181
|
+
cade tools list --source local # filter by source
|
|
182
|
+
cade tools search "send slack" # keyword search
|
|
183
|
+
cade tools info Local_ReadFile # full schema + description
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The full local tool surface (including the bidirectional MCP capabilities and `cade serve` integration) is documented in [`docs/mcp.md`](./docs/mcp.md).
|
|
187
|
+
|
|
188
|
+
### Custom MCP servers
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
cade mcp add my-server http://localhost:8080
|
|
192
|
+
cade mcp add my-server http://… --auth bearer -t <token>
|
|
193
|
+
cade mcp authorize my-server # OAuth flow (browser)
|
|
194
|
+
cade mcp list / status / test / enable / disable / rm
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
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`.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Personas + memory
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
cade persona list / create / get / edit / delete / default # manage system prompts
|
|
205
|
+
cade --persona reviewer # use one for a session
|
|
206
|
+
|
|
207
|
+
cade mem list # sources indexed for the active persona
|
|
208
|
+
cade mem add ~/notes # index a directory
|
|
209
|
+
cade mem search "auth design" # semantic search
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
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`.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Headless daemon: `cade serve`
|
|
217
|
+
|
|
218
|
+
Run Cade as a long-lived daemon that replies over messaging platforms (Telegram supported today; the adapter protocol is generic). Each chat gets its own persistent thread — persona, memory, and tools carry across messages.
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
cade serve init # wizard: bot token, allowed senders
|
|
222
|
+
cade serve # foreground
|
|
223
|
+
cade serve --install launchd # macOS LaunchAgent (or --install systemd)
|
|
224
|
+
cade serve status / stop # health, uptime; SIGTERM running daemon
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Config lives at `~/.cade/config/contexts/<context>.toml [serve]`. Edit and `kill -HUP $(cat ~/.cade/run/serve.pid)` to reload without restart.
|
|
228
|
+
|
|
229
|
+
**Security defaults are fail-closed:** `allowed_senders = []` blocks everyone; tools are default-deny against `[tools].allow` (globs / regex / pipe lists supported); `deny` always wins.
|
|
230
|
+
|
|
231
|
+
The MCP transport is fully bidirectional, so tools running inside the daemon can elicit structured input (rendered as Telegram inline keyboards), stream live progress (rendered as edited placeholder messages), and emit logs that flow into the daemon log. See [`docs/mcp.md`](./docs/mcp.md) for the protocol details, [`docs/configuration.md`](./docs/configuration.md) for the full daemon config reference.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Extensibility: hooks, tasks, cron, channels
|
|
236
|
+
|
|
237
|
+
Four primitives the agent uses directly (as `Local_*` tools) and you can drive from the CLI:
|
|
238
|
+
|
|
239
|
+
| Surface | What it is | CLI |
|
|
240
|
+
|---|---|---|
|
|
241
|
+
| **Hooks** | Lifecycle event handlers (pre/post tool, user prompt submit) | `cade hooks list / add / remove / test` |
|
|
242
|
+
| **Tasks** | File-backed durable work units that survive turn boundaries | `cade tasks list / get / create / update / delete` |
|
|
243
|
+
| **Cron** | Scheduled prompts the agent runs on a timer | `cade cron list / add / remove / enable / disable / run-now` |
|
|
244
|
+
| **Channels** | JSONL-backed inter-session pub/sub | `cade channels list / send / recv / clear` |
|
|
245
|
+
|
|
246
|
+
See [`docs/channels.md`](./docs/channels.md) for the channels protocol; hooks and tasks/cron details live in their respective `cade <subcommand> --help` outputs.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Bring your own LLM
|
|
251
|
+
|
|
252
|
+
Cade works with any OpenAI-compatible endpoint. Three ways to wire one in (CLI flag → env → config, first match wins):
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# CLI flag
|
|
256
|
+
cade chat --endpoint http://localhost:11434/v1 --model llama3
|
|
257
|
+
|
|
258
|
+
# Environment
|
|
259
|
+
export OPENAI_BASE_URL="http://localhost:11434/v1"
|
|
260
|
+
export OPENAI_API_KEY="ollama" # any non-empty value
|
|
261
|
+
cade chat --model llama3
|
|
262
|
+
|
|
263
|
+
# Config — ~/.cade/config/cade.toml
|
|
264
|
+
[model_settings]
|
|
265
|
+
host = "http://localhost:11434/v1"
|
|
266
|
+
api_key = "ollama"
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Skip Arcade Cloud authentication entirely with `--local-only` or `CADE_LOCAL_ONLY=1` when running against local LLMs.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Configuration
|
|
274
|
+
|
|
275
|
+
All state lives under `~/.cade/`. Override the location with `CADE_HOME=/path/to/alt`.
|
|
276
|
+
|
|
277
|
+
| File | Purpose |
|
|
278
|
+
|---|---|
|
|
279
|
+
| `config/cade.toml` | Model / provider / UI settings |
|
|
280
|
+
| `data/contexts/<context>/history.db` | Thread + message storage |
|
|
281
|
+
| `logs/cade.log` | Rotating log file |
|
|
282
|
+
| `config/contexts/<context>.toml [[mcp]]` | User MCP server registry |
|
|
283
|
+
| `config/contexts/<context>.toml [serve]` | `cade serve` daemon config |
|
|
284
|
+
| `personas/`, `memory/`, `tasks/`, `channels/` | Persona-scoped state |
|
|
285
|
+
|
|
286
|
+
Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/configuration.md).
|
|
287
|
+
|
|
288
|
+
### Common env vars
|
|
289
|
+
|
|
290
|
+
| Variable | Purpose |
|
|
291
|
+
|---|---|
|
|
292
|
+
| `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` | LLM provider keys |
|
|
293
|
+
| `OPENAI_BASE_URL` | Custom OpenAI-compatible endpoint |
|
|
294
|
+
| `ARCADE_API_KEY`, `ARCADE_BASE_URL` | Arcade Cloud (alternative to OAuth) |
|
|
295
|
+
| `CADE_LOCAL_ONLY=1` | Skip remote tools entirely |
|
|
296
|
+
| `CADE_HOME` | Override config directory |
|
|
297
|
+
| `CADE_PROJECT_ROOT` | Sandbox `Local_*` filesystem tools to this root |
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Contributing
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
git clone https://github.com/arcadeai-labs/cade.git
|
|
305
|
+
cd cade
|
|
306
|
+
uv sync --all-extras --dev
|
|
307
|
+
pytest # full suite
|
|
308
|
+
ruff check src/ tests/ && ruff format src/ tests/
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
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.
|
|
312
|
+
|
|
313
|
+
PRs welcome — open an issue first for anything substantial.
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Resources
|
|
318
|
+
|
|
319
|
+
- [arcade.dev](https://arcade.dev) — product
|
|
320
|
+
- [docs.arcade.dev](https://docs.arcade.dev) — API and tool catalog
|
|
321
|
+
- [`docs/`](./docs/) — `mcp.md` (tool protocol), `configuration.md`, `channels.md`, `install.md`
|
|
322
|
+
- [Issues](https://github.com/arcadeai-labs/cade/issues) · [Releases](https://github.com/arcadeai-labs/cade/releases)
|
|
323
|
+
|
|
324
|
+
## License
|
|
325
|
+
|
|
326
|
+
MIT
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# Cade
|
|
2
|
+
|
|
3
|
+
The CLI agent from [Arcade.dev](https://arcade.dev). Coding, research, and everyday automation — driven from a terminal, a single shell pipe, or a long-lived daemon that replies over Telegram.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
brew install ArcadeAI/tap/cade # or: uv tool install cade-cli | pip install cade-cli
|
|
7
|
+
cade login
|
|
8
|
+
cade
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Highlights
|
|
14
|
+
|
|
15
|
+
- **Three deployment modes from the same binary.** Interactive chat (`cade`), one-shot or pipe (`cade -m "…"`), or a headless daemon that replies over messaging (`cade serve`).
|
|
16
|
+
- **Tools from anywhere.** Built-in local tools (filesystem / shell / git / search / tasks / channels / memory), [Arcade Cloud](https://arcade.dev) tools (Slack, GitHub, Gmail, calendars, …), and any [MCP](https://modelcontextprotocol.io/) server you register — all unified under one tool surface.
|
|
17
|
+
- **Bidirectional MCP.** Tools can call `context.ui.elicit(…)` for structured input, `context.log.*` for live operator logs, and `context.progress.report(…)` for editable progress UI — routed end-to-end through whichever adapter is active (Telegram inline keyboard, terminal prompt).
|
|
18
|
+
- **Personas + per-persona memory.** Multiple agent profiles with their own system prompt and an indexed memory store backed by [agent-library](https://pypi.org/project/agent-library/).
|
|
19
|
+
- **Extensibility surface.** Hooks (lifecycle events), tasks (file-backed durable work), cron (scheduled prompts), channels (cross-session pub/sub) — all available to the agent as `Local_*` tools and to you as `cade <subcommand>`.
|
|
20
|
+
- **Bring your own LLM.** OpenAI, Anthropic, or any OpenAI-compatible endpoint (Ollama, vLLM, Together, Groq, Fireworks, …). `--local-only` skips Arcade Cloud entirely.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
| Source | Command |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Homebrew | `brew install ArcadeAI/tap/cade` |
|
|
29
|
+
| uv | `uv tool install cade-cli` |
|
|
30
|
+
| pip | `pip install cade-cli` |
|
|
31
|
+
| From source | `git clone https://github.com/arcadeai-labs/cade.git && cd cade && uv sync` |
|
|
32
|
+
|
|
33
|
+
**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
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cade login # Arcade Cloud OAuth (skip with --local-only)
|
|
37
|
+
cade --version
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Quick start
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
cade # interactive chat
|
|
46
|
+
cade -m "What changed in HEAD?" # single message, then exit
|
|
47
|
+
cat error.log | cade -m "What went wrong?" # pipe input
|
|
48
|
+
cade -r # resume the most recent thread
|
|
49
|
+
cade resume "auth-rewrite" # resume a thread by name
|
|
50
|
+
cade --persona reviewer # use a saved persona's system prompt
|
|
51
|
+
cade --voice # speak / hear (voice mode)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Top-level options
|
|
55
|
+
|
|
56
|
+
| Flag | Description |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `-r`, `--resume` | Resume most recent thread |
|
|
59
|
+
| `-m`, `--message` | Single-message mode (reads stdin if no arg) |
|
|
60
|
+
| `-P`, `--persona` | Use a saved persona |
|
|
61
|
+
| `-V`, `--voice` | Voice mode |
|
|
62
|
+
| `-v`, `--verbose` | Debug logging |
|
|
63
|
+
| `--version` | Print version |
|
|
64
|
+
|
|
65
|
+
### In-chat slash commands
|
|
66
|
+
|
|
67
|
+
| Command | Description |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `/help` | List commands |
|
|
70
|
+
| `/clear` | Clear screen |
|
|
71
|
+
| `/copy` | Copy last response |
|
|
72
|
+
| `/logs` | Recent log entries |
|
|
73
|
+
| `/thread`, `/history` | Current thread info |
|
|
74
|
+
| `/pin`, `/unpin` | Pin reference material into the session |
|
|
75
|
+
| `/tasks`, `/cron`, `/hooks`, `/channels`, `/notify` | Coordination surfaces (mirrored as `cade tasks` / `cade cron` / `cade hooks` / `cade channels`) |
|
|
76
|
+
| `/usage` | Context-window status and token usage |
|
|
77
|
+
| `/cd`, `/pwd`, `/!` | Shell shortcuts |
|
|
78
|
+
| `Ctrl+C` | Exit |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Tools
|
|
83
|
+
|
|
84
|
+
Tools come from three sources and are addressed uniformly by their registered name:
|
|
85
|
+
|
|
86
|
+
- **`Local_*`** — built-in: filesystem (`ReadFile`, `WriteFile`, `Edit`, `ListFiles`), shell (`Bash` — async with progress reporting), `Search`, `Git`, `Task*`, `Channel`, `AskUserQuestion`, `RetrieveToolResult`, `ToolSchema`, `Sleep`, `PinContext`, `PushNotification`.
|
|
87
|
+
- **`Memory_*`** — agent-library backed, per-persona indexed knowledge store.
|
|
88
|
+
- **Arcade Cloud + user MCP servers** — anything you register.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cade tools list # all tools, all sources
|
|
92
|
+
cade tools list --source local # filter by source
|
|
93
|
+
cade tools search "send slack" # keyword search
|
|
94
|
+
cade tools info Local_ReadFile # full schema + description
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The full local tool surface (including the bidirectional MCP capabilities and `cade serve` integration) is documented in [`docs/mcp.md`](./docs/mcp.md).
|
|
98
|
+
|
|
99
|
+
### Custom MCP servers
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
cade mcp add my-server http://localhost:8080
|
|
103
|
+
cade mcp add my-server http://… --auth bearer -t <token>
|
|
104
|
+
cade mcp authorize my-server # OAuth flow (browser)
|
|
105
|
+
cade mcp list / status / test / enable / disable / rm
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
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`.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Personas + memory
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
cade persona list / create / get / edit / delete / default # manage system prompts
|
|
116
|
+
cade --persona reviewer # use one for a session
|
|
117
|
+
|
|
118
|
+
cade mem list # sources indexed for the active persona
|
|
119
|
+
cade mem add ~/notes # index a directory
|
|
120
|
+
cade mem search "auth design" # semantic search
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
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`.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Headless daemon: `cade serve`
|
|
128
|
+
|
|
129
|
+
Run Cade as a long-lived daemon that replies over messaging platforms (Telegram supported today; the adapter protocol is generic). Each chat gets its own persistent thread — persona, memory, and tools carry across messages.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
cade serve init # wizard: bot token, allowed senders
|
|
133
|
+
cade serve # foreground
|
|
134
|
+
cade serve --install launchd # macOS LaunchAgent (or --install systemd)
|
|
135
|
+
cade serve status / stop # health, uptime; SIGTERM running daemon
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Config lives at `~/.cade/config/contexts/<context>.toml [serve]`. Edit and `kill -HUP $(cat ~/.cade/run/serve.pid)` to reload without restart.
|
|
139
|
+
|
|
140
|
+
**Security defaults are fail-closed:** `allowed_senders = []` blocks everyone; tools are default-deny against `[tools].allow` (globs / regex / pipe lists supported); `deny` always wins.
|
|
141
|
+
|
|
142
|
+
The MCP transport is fully bidirectional, so tools running inside the daemon can elicit structured input (rendered as Telegram inline keyboards), stream live progress (rendered as edited placeholder messages), and emit logs that flow into the daemon log. See [`docs/mcp.md`](./docs/mcp.md) for the protocol details, [`docs/configuration.md`](./docs/configuration.md) for the full daemon config reference.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Extensibility: hooks, tasks, cron, channels
|
|
147
|
+
|
|
148
|
+
Four primitives the agent uses directly (as `Local_*` tools) and you can drive from the CLI:
|
|
149
|
+
|
|
150
|
+
| Surface | What it is | CLI |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| **Hooks** | Lifecycle event handlers (pre/post tool, user prompt submit) | `cade hooks list / add / remove / test` |
|
|
153
|
+
| **Tasks** | File-backed durable work units that survive turn boundaries | `cade tasks list / get / create / update / delete` |
|
|
154
|
+
| **Cron** | Scheduled prompts the agent runs on a timer | `cade cron list / add / remove / enable / disable / run-now` |
|
|
155
|
+
| **Channels** | JSONL-backed inter-session pub/sub | `cade channels list / send / recv / clear` |
|
|
156
|
+
|
|
157
|
+
See [`docs/channels.md`](./docs/channels.md) for the channels protocol; hooks and tasks/cron details live in their respective `cade <subcommand> --help` outputs.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Bring your own LLM
|
|
162
|
+
|
|
163
|
+
Cade works with any OpenAI-compatible endpoint. Three ways to wire one in (CLI flag → env → config, first match wins):
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# CLI flag
|
|
167
|
+
cade chat --endpoint http://localhost:11434/v1 --model llama3
|
|
168
|
+
|
|
169
|
+
# Environment
|
|
170
|
+
export OPENAI_BASE_URL="http://localhost:11434/v1"
|
|
171
|
+
export OPENAI_API_KEY="ollama" # any non-empty value
|
|
172
|
+
cade chat --model llama3
|
|
173
|
+
|
|
174
|
+
# Config — ~/.cade/config/cade.toml
|
|
175
|
+
[model_settings]
|
|
176
|
+
host = "http://localhost:11434/v1"
|
|
177
|
+
api_key = "ollama"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Skip Arcade Cloud authentication entirely with `--local-only` or `CADE_LOCAL_ONLY=1` when running against local LLMs.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Configuration
|
|
185
|
+
|
|
186
|
+
All state lives under `~/.cade/`. Override the location with `CADE_HOME=/path/to/alt`.
|
|
187
|
+
|
|
188
|
+
| File | Purpose |
|
|
189
|
+
|---|---|
|
|
190
|
+
| `config/cade.toml` | Model / provider / UI settings |
|
|
191
|
+
| `data/contexts/<context>/history.db` | Thread + message storage |
|
|
192
|
+
| `logs/cade.log` | Rotating log file |
|
|
193
|
+
| `config/contexts/<context>.toml [[mcp]]` | User MCP server registry |
|
|
194
|
+
| `config/contexts/<context>.toml [serve]` | `cade serve` daemon config |
|
|
195
|
+
| `personas/`, `memory/`, `tasks/`, `channels/` | Persona-scoped state |
|
|
196
|
+
|
|
197
|
+
Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/configuration.md).
|
|
198
|
+
|
|
199
|
+
### Common env vars
|
|
200
|
+
|
|
201
|
+
| Variable | Purpose |
|
|
202
|
+
|---|---|
|
|
203
|
+
| `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` | LLM provider keys |
|
|
204
|
+
| `OPENAI_BASE_URL` | Custom OpenAI-compatible endpoint |
|
|
205
|
+
| `ARCADE_API_KEY`, `ARCADE_BASE_URL` | Arcade Cloud (alternative to OAuth) |
|
|
206
|
+
| `CADE_LOCAL_ONLY=1` | Skip remote tools entirely |
|
|
207
|
+
| `CADE_HOME` | Override config directory |
|
|
208
|
+
| `CADE_PROJECT_ROOT` | Sandbox `Local_*` filesystem tools to this root |
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Contributing
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
git clone https://github.com/arcadeai-labs/cade.git
|
|
216
|
+
cd cade
|
|
217
|
+
uv sync --all-extras --dev
|
|
218
|
+
pytest # full suite
|
|
219
|
+
ruff check src/ tests/ && ruff format src/ tests/
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
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.
|
|
223
|
+
|
|
224
|
+
PRs welcome — open an issue first for anything substantial.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Resources
|
|
229
|
+
|
|
230
|
+
- [arcade.dev](https://arcade.dev) — product
|
|
231
|
+
- [docs.arcade.dev](https://docs.arcade.dev) — API and tool catalog
|
|
232
|
+
- [`docs/`](./docs/) — `mcp.md` (tool protocol), `configuration.md`, `channels.md`, `install.md`
|
|
233
|
+
- [Issues](https://github.com/arcadeai-labs/cade/issues) · [Releases](https://github.com/arcadeai-labs/cade/releases)
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
MIT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cade-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.11.0"
|
|
4
4
|
description = "Cade - The CLI Agent from Arcade.dev"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -31,17 +31,22 @@ dependencies = [
|
|
|
31
31
|
"openai>=1.0.0,<2.0.0",
|
|
32
32
|
"anthropic>=0.34.0,<1.0.0",
|
|
33
33
|
"ulid==1.1",
|
|
34
|
-
"arcade-tdk>=
|
|
35
|
-
"arcade-mcp-server>=1.0.0",
|
|
36
|
-
"arcade-core>=4.
|
|
34
|
+
"arcade-tdk>=3.8.0,<4.0.0",
|
|
35
|
+
"arcade-mcp-server>=1.21.0,<2.0.0",
|
|
36
|
+
"arcade-core>=4.7.0,<5.0.0",
|
|
37
|
+
"arcadepy>=1.10.0,<2.0.0",
|
|
37
38
|
"authlib>=1.6.0,<2.0.0",
|
|
38
39
|
"pyperclip>=1.8.0,<2.0.0",
|
|
39
40
|
"prompt-toolkit>=3.0.52,<4.0.0",
|
|
40
41
|
"tiktoken>=0.11.0,<1.0.0",
|
|
41
42
|
"httpx>=0.27.0,<1.0.0",
|
|
42
43
|
"filelock>=3.0.0,<4.0.0",
|
|
43
|
-
"agent-library>=0.
|
|
44
|
+
"agent-library>=0.12.0,<1.0.0",
|
|
44
45
|
"sounddevice>=0.5.5",
|
|
46
|
+
"croniter>=2.0.0,<4.0.0",
|
|
47
|
+
"python-telegram-bot>=21.0,<22.0",
|
|
48
|
+
"keyring>=24.0,<26.0",
|
|
49
|
+
"html2text>=2024.2.26",
|
|
45
50
|
]
|
|
46
51
|
|
|
47
52
|
[project.urls]
|
|
@@ -116,19 +121,19 @@ python_version = "3.11"
|
|
|
116
121
|
warn_unused_ignores = false
|
|
117
122
|
ignore_missing_imports = true
|
|
118
123
|
follow_imports = "silent"
|
|
124
|
+
plugins = ["pydantic.mypy"]
|
|
119
125
|
disable_error_code = [
|
|
126
|
+
# Third-party stubs are inconsistently shipped; ignore unrelated import noise.
|
|
120
127
|
"import-untyped",
|
|
121
|
-
"
|
|
128
|
+
# Pydantic models with Field(alias="id") aren't recognised by mypy as
|
|
129
|
+
# accepting init-by-alias, even with populate_by_name=True. Re-enabling
|
|
130
|
+
# requires switching every callsite away from the alias.
|
|
122
131
|
"call-arg",
|
|
132
|
+
# Tracked tech debt — re-enable in follow-up passes.
|
|
133
|
+
"assignment",
|
|
123
134
|
"arg-type",
|
|
124
|
-
"var-annotated",
|
|
125
135
|
"attr-defined",
|
|
126
|
-
"index",
|
|
127
136
|
"union-attr",
|
|
128
|
-
"typeddict-item",
|
|
129
|
-
"no-redef",
|
|
130
|
-
"return-value",
|
|
131
|
-
"annotation-unchecked",
|
|
132
137
|
]
|
|
133
138
|
files = ["src/cadecoder", "src/cade_mcp_local"]
|
|
134
139
|
|
|
@@ -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
|
-
__version__
|
|
82
|
+
from cadecoder import __version__ as __version__ # noqa: E402
|