cade-cli 0.9.0__tar.gz → 0.10.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. {cade_cli-0.9.0 → cade_cli-0.10.0}/.gitignore +1 -1
  2. cade_cli-0.10.0/PKG-INFO +323 -0
  3. cade_cli-0.10.0/README.md +236 -0
  4. {cade_cli-0.9.0 → cade_cli-0.10.0}/pyproject.toml +12 -9
  5. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/__init__.py +1 -1
  6. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/server.py +44 -4
  7. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/tools/__init__.py +27 -2
  8. cade_cli-0.10.0/src/cade_mcp_local/tools/_read_cache.py +60 -0
  9. cade_cli-0.10.0/src/cade_mcp_local/tools/channels.py +76 -0
  10. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/tools/context.py +21 -18
  11. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/tools/filesystem.py +104 -91
  12. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/tools/git.py +22 -26
  13. cade_cli-0.10.0/src/cade_mcp_local/tools/notifications.py +41 -0
  14. cade_cli-0.10.0/src/cade_mcp_local/tools/questions.py +227 -0
  15. cade_cli-0.9.0/src/cade_mcp_local/tools/tool_results.py → cade_cli-0.10.0/src/cade_mcp_local/tools/results.py +21 -63
  16. cade_cli-0.10.0/src/cade_mcp_local/tools/schemas.py +186 -0
  17. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/tools/search.py +14 -26
  18. cade_cli-0.10.0/src/cade_mcp_local/tools/shell.py +259 -0
  19. cade_cli-0.10.0/src/cade_mcp_local/tools/sleep.py +38 -0
  20. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/tools/snippets.py +9 -14
  21. cade_cli-0.10.0/src/cade_mcp_local/tools/tasks.py +155 -0
  22. cade_cli-0.10.0/src/cadecoder/__init__.py +6 -0
  23. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/ai/__init__.py +1 -1
  24. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/ai/prompts.py +34 -14
  25. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/app.py +64 -10
  26. cade_cli-0.10.0/src/cadecoder/cli/commands/channels.py +79 -0
  27. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/commands/context.py +5 -0
  28. cade_cli-0.10.0/src/cadecoder/cli/commands/cron.py +124 -0
  29. cade_cli-0.10.0/src/cadecoder/cli/commands/hooks.py +198 -0
  30. cade_cli-0.10.0/src/cadecoder/cli/commands/mem.py +151 -0
  31. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/commands/persona.py +76 -5
  32. cade_cli-0.10.0/src/cadecoder/cli/commands/serve.py +267 -0
  33. cade_cli-0.10.0/src/cadecoder/cli/commands/tasks.py +150 -0
  34. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/commands/tools.py +47 -0
  35. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/core/errors.py +33 -0
  36. cade_cli-0.10.0/src/cadecoder/execution/mcp_schema_index.py +114 -0
  37. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/execution/orchestrator.py +171 -6
  38. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/execution/tool_schema_cache.py +115 -0
  39. cade_cli-0.10.0/src/cadecoder/hooks/__init__.py +55 -0
  40. cade_cli-0.10.0/src/cadecoder/hooks/config.py +139 -0
  41. cade_cli-0.10.0/src/cadecoder/hooks/engine.py +188 -0
  42. cade_cli-0.10.0/src/cadecoder/hooks/executors/__init__.py +47 -0
  43. cade_cli-0.10.0/src/cadecoder/hooks/executors/callback.py +39 -0
  44. cade_cli-0.10.0/src/cadecoder/hooks/executors/command.py +126 -0
  45. cade_cli-0.10.0/src/cadecoder/hooks/executors/http.py +137 -0
  46. cade_cli-0.10.0/src/cadecoder/hooks/executors/prompt.py +131 -0
  47. cade_cli-0.10.0/src/cadecoder/hooks/executors/ssrf_guard.py +89 -0
  48. cade_cli-0.10.0/src/cadecoder/hooks/matchers.py +109 -0
  49. cade_cli-0.10.0/src/cadecoder/hooks/registry.py +163 -0
  50. cade_cli-0.10.0/src/cadecoder/hooks/types.py +145 -0
  51. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/providers/anthropic.py +105 -92
  52. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/providers/base.py +101 -1
  53. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/providers/ollama.py +106 -87
  54. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/providers/openai.py +85 -77
  55. cade_cli-0.10.0/src/cadecoder/serve/__init__.py +11 -0
  56. cade_cli-0.10.0/src/cadecoder/serve/adapters/__init__.py +18 -0
  57. cade_cli-0.10.0/src/cadecoder/serve/adapters/base.py +173 -0
  58. cade_cli-0.10.0/src/cadecoder/serve/adapters/registry.py +42 -0
  59. cade_cli-0.10.0/src/cadecoder/serve/adapters/stub.py +176 -0
  60. cade_cli-0.10.0/src/cadecoder/serve/adapters/telegram.py +359 -0
  61. cade_cli-0.10.0/src/cadecoder/serve/allowlist.py +172 -0
  62. cade_cli-0.10.0/src/cadecoder/serve/chunker.py +135 -0
  63. cade_cli-0.10.0/src/cadecoder/serve/commands.py +103 -0
  64. cade_cli-0.10.0/src/cadecoder/serve/config.py +159 -0
  65. cade_cli-0.10.0/src/cadecoder/serve/daemon.py +347 -0
  66. cade_cli-0.10.0/src/cadecoder/serve/elicitation.py +291 -0
  67. cade_cli-0.10.0/src/cadecoder/serve/format.py +406 -0
  68. cade_cli-0.10.0/src/cadecoder/serve/install.py +157 -0
  69. cade_cli-0.10.0/src/cadecoder/serve/lock.py +96 -0
  70. cade_cli-0.10.0/src/cadecoder/serve/observability.py +160 -0
  71. cade_cli-0.10.0/src/cadecoder/serve/progress_sink.py +103 -0
  72. cade_cli-0.10.0/src/cadecoder/serve/router.py +56 -0
  73. cade_cli-0.10.0/src/cadecoder/serve/secrets.py +170 -0
  74. cade_cli-0.10.0/src/cadecoder/serve/sinks.py +247 -0
  75. cade_cli-0.10.0/src/cadecoder/serve/worker.py +485 -0
  76. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/storage/threads.py +161 -0
  77. cade_cli-0.10.0/src/cadecoder/tasks/__init__.py +42 -0
  78. cade_cli-0.10.0/src/cadecoder/tasks/channels.py +88 -0
  79. cade_cli-0.10.0/src/cadecoder/tasks/lock.py +125 -0
  80. cade_cli-0.10.0/src/cadecoder/tasks/notifications.py +100 -0
  81. cade_cli-0.10.0/src/cadecoder/tasks/scheduler.py +206 -0
  82. cade_cli-0.10.0/src/cadecoder/tasks/store.py +284 -0
  83. cade_cli-0.10.0/src/cadecoder/tasks/types.py +83 -0
  84. cade_cli-0.10.0/src/cadecoder/templates/serve/launchd.plist.tmpl +30 -0
  85. cade_cli-0.10.0/src/cadecoder/templates/serve/serve.toml.example +34 -0
  86. cade_cli-0.10.0/src/cadecoder/templates/serve/systemd.service.tmpl +16 -0
  87. cade_cli-0.10.0/src/cadecoder/tools/manager/_request_ctx.py +87 -0
  88. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/tools/manager/base.py +7 -1
  89. cade_cli-0.10.0/src/cadecoder/tools/manager/composite.py +852 -0
  90. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/tools/manager/mcp.py +587 -109
  91. cade_cli-0.10.0/src/cadecoder/tools/search/__init__.py +25 -0
  92. cade_cli-0.10.0/src/cadecoder/tools/search/discovered.py +202 -0
  93. cade_cli-0.10.0/src/cadecoder/tools/search/scoring.py +178 -0
  94. cade_cli-0.10.0/src/cadecoder/tools/search/service.py +171 -0
  95. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/ui/__init__.py +1 -1
  96. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/ui/display.py +32 -4
  97. cade_cli-0.10.0/src/cadecoder/ui/elicitation.py +109 -0
  98. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/ui/session.py +319 -1
  99. cade_cli-0.9.0/PKG-INFO +0 -394
  100. cade_cli-0.9.0/README.md +0 -310
  101. cade_cli-0.9.0/src/cade_mcp_local/tools/shell.py +0 -157
  102. cade_cli-0.9.0/src/cade_mcp_local/tools/tool_schemas.py +0 -81
  103. cade_cli-0.9.0/src/cadecoder/__init__.py +0 -1
  104. cade_cli-0.9.0/src/cadecoder/tools/manager/composite.py +0 -464
  105. cade_cli-0.9.0/src/cadecoder/tools/manager.py +0 -765
  106. {cade_cli-0.9.0 → cade_cli-0.10.0}/LICENSE +0 -0
  107. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/__main__.py +0 -0
  108. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/config.py +0 -0
  109. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/errors.py +0 -0
  110. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cade_mcp_local/utils.py +0 -0
  111. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/__init__.py +0 -0
  112. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/auth.py +0 -0
  113. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/commands/__init__.py +0 -0
  114. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/commands/auth.py +0 -0
  115. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/commands/chat.py +0 -0
  116. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/commands/mcp.py +0 -0
  117. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/commands/model.py +0 -0
  118. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/cli/commands/thread.py +0 -0
  119. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/core/__init__.py +0 -0
  120. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/core/config.py +0 -0
  121. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/core/constants.py +0 -0
  122. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/core/git.py +0 -0
  123. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/core/logging.py +0 -0
  124. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/core/names.py +0 -0
  125. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/core/types.py +0 -0
  126. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/execution/__init__.py +0 -0
  127. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/execution/context_window.py +0 -0
  128. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/execution/parallel.py +0 -0
  129. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/execution/tool_result_store.py +0 -0
  130. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/providers/__init__.py +0 -0
  131. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/storage/__init__.py +0 -0
  132. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/storage/personas.py +0 -0
  133. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/templates/login_failed.html +0 -0
  134. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/templates/login_success.html +0 -0
  135. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/templates/styles.css +0 -0
  136. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/tools/__init__.py +0 -0
  137. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/tools/manager/__init__.py +0 -0
  138. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/tools/manager/config.py +0 -0
  139. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/ui/input.py +0 -0
  140. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/voice/__init__.py +0 -0
  141. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/voice/audio.py +0 -0
  142. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/voice/cleanup.py +0 -0
  143. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/voice/session.py +0 -0
  144. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/voice/stt.py +0 -0
  145. {cade_cli-0.9.0 → cade_cli-0.10.0}/src/cadecoder/voice/tts.py +0 -0
@@ -5,6 +5,7 @@ __pycache__/
5
5
 
6
6
  .claude/
7
7
  CLAUDE.md
8
+ .context/
8
9
  .env
9
10
 
10
11
 
@@ -40,7 +41,6 @@ build/
40
41
  # Virtual environment
41
42
  .venv
42
43
  activate.sh
43
- docs/
44
44
 
45
45
  # uv
46
46
  uv.lock
@@ -0,0 +1,323 @@
1
+ Metadata-Version: 2.4
2
+ Name: cade-cli
3
+ Version: 0.10.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.1.0
49
+ Requires-Dist: arcade-mcp-server>=1.0.0
50
+ Requires-Dist: arcade-tdk>=2.0.0
51
+ Requires-Dist: authlib<2.0.0,>=1.6.0
52
+ Requires-Dist: croniter<4.0.0,>=2.0.0
53
+ Requires-Dist: filelock<4.0.0,>=3.0.0
54
+ Requires-Dist: httpx<1.0.0,>=0.27.0
55
+ Requires-Dist: keyring<26.0,>=24.0
56
+ Requires-Dist: openai<2.0.0,>=1.0.0
57
+ Requires-Dist: prompt-toolkit<4.0.0,>=3.0.52
58
+ Requires-Dist: pydantic[email]<3.0.0,>=2.0.0
59
+ Requires-Dist: pyperclip<2.0.0,>=1.8.0
60
+ Requires-Dist: python-telegram-bot<22.0,>=21.0
61
+ Requires-Dist: pyyaml<7.0.0,>=6.0
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
+ Requires-Dist: toml<1.0.0,>=0.10.0
66
+ Requires-Dist: typer>0.10.0
67
+ Requires-Dist: ulid==1.1
68
+ Provides-Extra: dev
69
+ Requires-Dist: mypy<2.0.0,>=1.10.0; extra == 'dev'
70
+ Requires-Dist: pytest-asyncio<1.0.0,>=0.24.0; extra == 'dev'
71
+ Requires-Dist: pytest-cov<5.0.0,>=4.0.0; extra == 'dev'
72
+ Requires-Dist: pytest-mock<4.0.0,>=3.11.0; extra == 'dev'
73
+ Requires-Dist: pytest<9.0.0,>=8.0.0; extra == 'dev'
74
+ Requires-Dist: ruff<1.0.0,>=0.5.0; extra == 'dev'
75
+ Provides-Extra: training
76
+ Requires-Dist: accelerate>=0.27.0; extra == 'training'
77
+ Requires-Dist: safetensors>=0.4.2; extra == 'training'
78
+ Requires-Dist: torch>=2.1.0; extra == 'training'
79
+ Requires-Dist: transformers>=4.38.0; extra == 'training'
80
+ Provides-Extra: voice
81
+ Requires-Dist: mlx-audio<0.4.0,>=0.2.0; extra == 'voice'
82
+ Requires-Dist: mlx-whisper>=0.1.0; extra == 'voice'
83
+ Requires-Dist: numpy>=1.24.0; extra == 'voice'
84
+ Requires-Dist: sounddevice>=0.4.0; extra == 'voice'
85
+ Requires-Dist: webrtcvad>=2.0.10; extra == 'voice'
86
+ Description-Content-Type: text/markdown
87
+
88
+ # Cade
89
+
90
+ 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.
91
+
92
+ ```bash
93
+ brew install ArcadeAI/tap/cade # or: uv tool install cade-cli | pip install cade-cli
94
+ cade login
95
+ cade
96
+ ```
97
+
98
+ ---
99
+
100
+ ## Highlights
101
+
102
+ - **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`).
103
+ - **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.
104
+ - **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).
105
+ - **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/).
106
+ - **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>`.
107
+ - **Bring your own LLM.** OpenAI, Anthropic, or any OpenAI-compatible endpoint (Ollama, vLLM, Together, Groq, Fireworks, …). `--local-only` skips Arcade Cloud entirely.
108
+
109
+ ---
110
+
111
+ ## Install
112
+
113
+ | Source | Command |
114
+ |---|---|
115
+ | Homebrew | `brew install ArcadeAI/tap/cade` |
116
+ | uv | `uv tool install cade-cli` |
117
+ | pip | `pip install cade-cli` |
118
+ | From source | `git clone https://github.com/arcadeai-labs/cade.git && cd cade && uv sync` |
119
+
120
+ **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
+
122
+ ```bash
123
+ cade login # Arcade Cloud OAuth (skip with --local-only)
124
+ cade --version
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Quick start
130
+
131
+ ```bash
132
+ cade # interactive chat
133
+ cade -m "What changed in HEAD?" # single message, then exit
134
+ cat error.log | cade -m "What went wrong?" # pipe input
135
+ cade -r # resume the most recent thread
136
+ cade resume "auth-rewrite" # resume a thread by name
137
+ cade --persona reviewer # use a saved persona's system prompt
138
+ cade --voice # speak / hear (voice mode)
139
+ ```
140
+
141
+ ### Top-level options
142
+
143
+ | Flag | Description |
144
+ |---|---|
145
+ | `-r`, `--resume` | Resume most recent thread |
146
+ | `-m`, `--message` | Single-message mode (reads stdin if no arg) |
147
+ | `-P`, `--persona` | Use a saved persona |
148
+ | `-V`, `--voice` | Voice mode |
149
+ | `-v`, `--verbose` | Debug logging |
150
+ | `--version` | Print version |
151
+
152
+ ### In-chat slash commands
153
+
154
+ | Command | Description |
155
+ |---|---|
156
+ | `/help` | List commands |
157
+ | `/clear` | Clear screen |
158
+ | `/copy` | Copy last response |
159
+ | `/logs` | Recent log entries |
160
+ | `/thread`, `/history` | Current thread info |
161
+ | `/pin`, `/unpin` | Pin reference material into the session |
162
+ | `/task`, `/cron`, `/hooks`, `/channel`, `/notify` | Coordination surfaces |
163
+ | `/cd`, `/pwd`, `/!` | Shell shortcuts |
164
+ | `Ctrl+C` | Exit |
165
+
166
+ ---
167
+
168
+ ## Tools
169
+
170
+ Tools come from three sources and are addressed uniformly by their registered name:
171
+
172
+ - **`Local_*`** — built-in: filesystem (`ReadFile`, `WriteFile`, `Edit`, `ListFiles`), shell (`Bash` — async with progress reporting), `Search`, `Git`, `Task*`, `Channel`, `AskUserQuestion`, `RetrieveToolResult`, `ToolSchema`, `Sleep`, `PinContext`, `PushNotification`.
173
+ - **`Memory_*`** — agent-library backed, per-persona indexed knowledge store.
174
+ - **Arcade Cloud + user MCP servers** — anything you register.
175
+
176
+ ```bash
177
+ cade tools list # all tools, all sources
178
+ cade tools list --source local # filter by source
179
+ cade tools search "send slack" # keyword search
180
+ cade tools info Local_ReadFile # full schema + description
181
+ ```
182
+
183
+ The full local tool surface (including the bidirectional MCP capabilities and `cade serve` integration) is documented in [`docs/mcp.md`](./docs/mcp.md).
184
+
185
+ ### Custom MCP servers
186
+
187
+ ```bash
188
+ cade mcp add my-server http://localhost:8080
189
+ cade mcp add my-server http://… --auth bearer -t <token>
190
+ cade mcp authorize my-server # OAuth flow (browser)
191
+ cade mcp list / status / test / enable / disable / rm
192
+ ```
193
+
194
+ User MCP servers register at `~/.cadecoder/mcp_servers.yaml`. Servers with large catalogs are auto-deferred (parameter schemas stripped to keep tool-list bytes down) and fetched on demand via `Local_ToolSchema`.
195
+
196
+ ---
197
+
198
+ ## Personas + memory
199
+
200
+ ```bash
201
+ cade persona list / create / get / edit / delete / default # manage system prompts
202
+ cade --persona reviewer # use one for a session
203
+
204
+ cade mem list # sources indexed for the active persona
205
+ cade mem add ~/notes # index a directory
206
+ cade mem search "auth design" # semantic search
207
+ ```
208
+
209
+ Memory is persona-scoped — each persona has its own `~/.cadecoder/memory/<persona>/.librarian/` index, so a `reviewer` persona's notes never leak into `default`.
210
+
211
+ ---
212
+
213
+ ## Headless daemon: `cade serve`
214
+
215
+ 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.
216
+
217
+ ```bash
218
+ cade serve init # wizard: bot token, allowed senders
219
+ cade serve # foreground
220
+ cade serve --install launchd # macOS LaunchAgent (or --install systemd)
221
+ cade serve status / stop # health, uptime; SIGTERM running daemon
222
+ ```
223
+
224
+ Config lives at `~/.cadecoder/serve.toml`. Edit and `kill -HUP $(cat ~/.cadecoder/serve.pid)` to reload without restart.
225
+
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.
227
+
228
+ 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.
229
+
230
+ ---
231
+
232
+ ## Extensibility: hooks, tasks, cron, channels
233
+
234
+ Four primitives the agent uses directly (as `Local_*` tools) and you can drive from the CLI:
235
+
236
+ | Surface | What it is | CLI |
237
+ |---|---|---|
238
+ | **Hooks** | Lifecycle event handlers (pre/post tool, user prompt submit) | `cade hooks list / add / remove / test` |
239
+ | **Tasks** | File-backed durable work units that survive turn boundaries | `cade tasks list / get / create / update / delete` |
240
+ | **Cron** | Scheduled prompts the agent runs on a timer | `cade cron list / add / remove / enable / disable / run-now` |
241
+ | **Channels** | JSONL-backed inter-session pub/sub | `cade channels list / send / recv / clear` |
242
+
243
+ See [`docs/channels.md`](./docs/channels.md) for the channels protocol; hooks and tasks/cron details live in their respective `cade <subcommand> --help` outputs.
244
+
245
+ ---
246
+
247
+ ## Bring your own LLM
248
+
249
+ Cade works with any OpenAI-compatible endpoint. Three ways to wire one in (CLI flag → env → config, first match wins):
250
+
251
+ ```bash
252
+ # CLI flag
253
+ cade chat --endpoint http://localhost:11434/v1 --model llama3
254
+
255
+ # Environment
256
+ export OPENAI_BASE_URL="http://localhost:11434/v1"
257
+ export OPENAI_API_KEY="ollama" # any non-empty value
258
+ cade chat --model llama3
259
+
260
+ # Config — ~/.cadecoder/cadecoder.toml
261
+ [model_settings]
262
+ host = "http://localhost:11434/v1"
263
+ api_key = "ollama"
264
+ ```
265
+
266
+ Skip Arcade Cloud authentication entirely with `--local-only` or `CADE_LOCAL_ONLY=1` when running against local LLMs.
267
+
268
+ ---
269
+
270
+ ## Configuration
271
+
272
+ All state lives under `~/.cadecoder/`. Override the location with `CADECODER_HOME=/path/to/alt`.
273
+
274
+ | File | Purpose |
275
+ |---|---|
276
+ | `cadecoder.toml` | Model / provider / UI settings |
277
+ | `cadecoder_history.db` | Thread + message storage |
278
+ | `cadecoder.log` | Rotating log file |
279
+ | `mcp_servers.yaml` | User MCP server registry |
280
+ | `serve.toml` | `cade serve` daemon config |
281
+ | `personas/`, `memory/`, `tasks/`, `channels/` | Persona-scoped state |
282
+
283
+ Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/configuration.md).
284
+
285
+ ### Common env vars
286
+
287
+ | Variable | Purpose |
288
+ |---|---|
289
+ | `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` | LLM provider keys |
290
+ | `OPENAI_BASE_URL` | Custom OpenAI-compatible endpoint |
291
+ | `ARCADE_API_KEY`, `ARCADE_BASE_URL` | Arcade Cloud (alternative to OAuth) |
292
+ | `CADE_LOCAL_ONLY=1` | Skip remote tools entirely |
293
+ | `CADECODER_HOME` | Override config directory |
294
+ | `CADE_PROJECT_ROOT` | Sandbox `Local_*` filesystem tools to this root |
295
+
296
+ ---
297
+
298
+ ## Contributing
299
+
300
+ ```bash
301
+ git clone https://github.com/arcadeai-labs/cade.git
302
+ cd cade
303
+ uv sync --all-extras --dev
304
+ pytest # full suite
305
+ ruff check src/ tests/ && ruff format src/ tests/
306
+ ```
307
+
308
+ 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
+
310
+ PRs welcome — open an issue first for anything substantial.
311
+
312
+ ---
313
+
314
+ ## Resources
315
+
316
+ - [arcade.dev](https://arcade.dev) — product
317
+ - [docs.arcade.dev](https://docs.arcade.dev) — API and tool catalog
318
+ - [`docs/`](./docs/) — `mcp.md` (tool protocol), `configuration.md`, `channels.md`, `install.md`
319
+ - [Issues](https://github.com/arcadeai-labs/cade/issues) · [Releases](https://github.com/arcadeai-labs/cade/releases)
320
+
321
+ ## License
322
+
323
+ MIT
@@ -0,0 +1,236 @@
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
+ | `/task`, `/cron`, `/hooks`, `/channel`, `/notify` | Coordination surfaces |
76
+ | `/cd`, `/pwd`, `/!` | Shell shortcuts |
77
+ | `Ctrl+C` | Exit |
78
+
79
+ ---
80
+
81
+ ## Tools
82
+
83
+ Tools come from three sources and are addressed uniformly by their registered name:
84
+
85
+ - **`Local_*`** — built-in: filesystem (`ReadFile`, `WriteFile`, `Edit`, `ListFiles`), shell (`Bash` — async with progress reporting), `Search`, `Git`, `Task*`, `Channel`, `AskUserQuestion`, `RetrieveToolResult`, `ToolSchema`, `Sleep`, `PinContext`, `PushNotification`.
86
+ - **`Memory_*`** — agent-library backed, per-persona indexed knowledge store.
87
+ - **Arcade Cloud + user MCP servers** — anything you register.
88
+
89
+ ```bash
90
+ cade tools list # all tools, all sources
91
+ cade tools list --source local # filter by source
92
+ cade tools search "send slack" # keyword search
93
+ cade tools info Local_ReadFile # full schema + description
94
+ ```
95
+
96
+ The full local tool surface (including the bidirectional MCP capabilities and `cade serve` integration) is documented in [`docs/mcp.md`](./docs/mcp.md).
97
+
98
+ ### Custom MCP servers
99
+
100
+ ```bash
101
+ cade mcp add my-server http://localhost:8080
102
+ cade mcp add my-server http://… --auth bearer -t <token>
103
+ cade mcp authorize my-server # OAuth flow (browser)
104
+ cade mcp list / status / test / enable / disable / rm
105
+ ```
106
+
107
+ User MCP servers register at `~/.cadecoder/mcp_servers.yaml`. Servers with large catalogs are auto-deferred (parameter schemas stripped to keep tool-list bytes down) and fetched on demand via `Local_ToolSchema`.
108
+
109
+ ---
110
+
111
+ ## Personas + memory
112
+
113
+ ```bash
114
+ cade persona list / create / get / edit / delete / default # manage system prompts
115
+ cade --persona reviewer # use one for a session
116
+
117
+ cade mem list # sources indexed for the active persona
118
+ cade mem add ~/notes # index a directory
119
+ cade mem search "auth design" # semantic search
120
+ ```
121
+
122
+ Memory is persona-scoped — each persona has its own `~/.cadecoder/memory/<persona>/.librarian/` index, so a `reviewer` persona's notes never leak into `default`.
123
+
124
+ ---
125
+
126
+ ## Headless daemon: `cade serve`
127
+
128
+ 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.
129
+
130
+ ```bash
131
+ cade serve init # wizard: bot token, allowed senders
132
+ cade serve # foreground
133
+ cade serve --install launchd # macOS LaunchAgent (or --install systemd)
134
+ cade serve status / stop # health, uptime; SIGTERM running daemon
135
+ ```
136
+
137
+ Config lives at `~/.cadecoder/serve.toml`. Edit and `kill -HUP $(cat ~/.cadecoder/serve.pid)` to reload without restart.
138
+
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.
140
+
141
+ 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.
142
+
143
+ ---
144
+
145
+ ## Extensibility: hooks, tasks, cron, channels
146
+
147
+ Four primitives the agent uses directly (as `Local_*` tools) and you can drive from the CLI:
148
+
149
+ | Surface | What it is | CLI |
150
+ |---|---|---|
151
+ | **Hooks** | Lifecycle event handlers (pre/post tool, user prompt submit) | `cade hooks list / add / remove / test` |
152
+ | **Tasks** | File-backed durable work units that survive turn boundaries | `cade tasks list / get / create / update / delete` |
153
+ | **Cron** | Scheduled prompts the agent runs on a timer | `cade cron list / add / remove / enable / disable / run-now` |
154
+ | **Channels** | JSONL-backed inter-session pub/sub | `cade channels list / send / recv / clear` |
155
+
156
+ See [`docs/channels.md`](./docs/channels.md) for the channels protocol; hooks and tasks/cron details live in their respective `cade <subcommand> --help` outputs.
157
+
158
+ ---
159
+
160
+ ## Bring your own LLM
161
+
162
+ Cade works with any OpenAI-compatible endpoint. Three ways to wire one in (CLI flag → env → config, first match wins):
163
+
164
+ ```bash
165
+ # CLI flag
166
+ cade chat --endpoint http://localhost:11434/v1 --model llama3
167
+
168
+ # Environment
169
+ export OPENAI_BASE_URL="http://localhost:11434/v1"
170
+ export OPENAI_API_KEY="ollama" # any non-empty value
171
+ cade chat --model llama3
172
+
173
+ # Config — ~/.cadecoder/cadecoder.toml
174
+ [model_settings]
175
+ host = "http://localhost:11434/v1"
176
+ api_key = "ollama"
177
+ ```
178
+
179
+ Skip Arcade Cloud authentication entirely with `--local-only` or `CADE_LOCAL_ONLY=1` when running against local LLMs.
180
+
181
+ ---
182
+
183
+ ## Configuration
184
+
185
+ All state lives under `~/.cadecoder/`. Override the location with `CADECODER_HOME=/path/to/alt`.
186
+
187
+ | File | Purpose |
188
+ |---|---|
189
+ | `cadecoder.toml` | Model / provider / UI settings |
190
+ | `cadecoder_history.db` | Thread + message storage |
191
+ | `cadecoder.log` | Rotating log file |
192
+ | `mcp_servers.yaml` | User MCP server registry |
193
+ | `serve.toml` | `cade serve` daemon config |
194
+ | `personas/`, `memory/`, `tasks/`, `channels/` | Persona-scoped state |
195
+
196
+ Full layout, env vars, and TOML schema in [`docs/configuration.md`](./docs/configuration.md).
197
+
198
+ ### Common env vars
199
+
200
+ | Variable | Purpose |
201
+ |---|---|
202
+ | `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` | LLM provider keys |
203
+ | `OPENAI_BASE_URL` | Custom OpenAI-compatible endpoint |
204
+ | `ARCADE_API_KEY`, `ARCADE_BASE_URL` | Arcade Cloud (alternative to OAuth) |
205
+ | `CADE_LOCAL_ONLY=1` | Skip remote tools entirely |
206
+ | `CADECODER_HOME` | Override config directory |
207
+ | `CADE_PROJECT_ROOT` | Sandbox `Local_*` filesystem tools to this root |
208
+
209
+ ---
210
+
211
+ ## Contributing
212
+
213
+ ```bash
214
+ git clone https://github.com/arcadeai-labs/cade.git
215
+ cd cade
216
+ uv sync --all-extras --dev
217
+ pytest # full suite
218
+ ruff check src/ tests/ && ruff format src/ tests/
219
+ ```
220
+
221
+ 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
+
223
+ PRs welcome — open an issue first for anything substantial.
224
+
225
+ ---
226
+
227
+ ## Resources
228
+
229
+ - [arcade.dev](https://arcade.dev) — product
230
+ - [docs.arcade.dev](https://docs.arcade.dev) — API and tool catalog
231
+ - [`docs/`](./docs/) — `mcp.md` (tool protocol), `configuration.md`, `channels.md`, `install.md`
232
+ - [Issues](https://github.com/arcadeai-labs/cade/issues) · [Releases](https://github.com/arcadeai-labs/cade/releases)
233
+
234
+ ## License
235
+
236
+ MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cade-cli"
3
- version = "0.9.0"
3
+ version = "0.10.0"
4
4
  description = "Cade - The CLI Agent from Arcade.dev"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -40,8 +40,11 @@ dependencies = [
40
40
  "tiktoken>=0.11.0,<1.0.0",
41
41
  "httpx>=0.27.0,<1.0.0",
42
42
  "filelock>=3.0.0,<4.0.0",
43
- "agent-library>=0.11.0,<1.0.0",
43
+ "agent-library>=0.12.0,<1.0.0",
44
44
  "sounddevice>=0.5.5",
45
+ "croniter>=2.0.0,<4.0.0",
46
+ "python-telegram-bot>=21.0,<22.0",
47
+ "keyring>=24.0,<26.0",
45
48
  ]
46
49
 
47
50
  [project.urls]
@@ -116,19 +119,19 @@ python_version = "3.11"
116
119
  warn_unused_ignores = false
117
120
  ignore_missing_imports = true
118
121
  follow_imports = "silent"
122
+ plugins = ["pydantic.mypy"]
119
123
  disable_error_code = [
124
+ # Third-party stubs are inconsistently shipped; ignore unrelated import noise.
120
125
  "import-untyped",
121
- "assignment",
126
+ # Pydantic models with Field(alias="id") aren't recognised by mypy as
127
+ # accepting init-by-alias, even with populate_by_name=True. Re-enabling
128
+ # requires switching every callsite away from the alias.
122
129
  "call-arg",
130
+ # Tracked tech debt — re-enable in follow-up passes.
131
+ "assignment",
123
132
  "arg-type",
124
- "var-annotated",
125
133
  "attr-defined",
126
- "index",
127
134
  "union-attr",
128
- "typeddict-item",
129
- "no-redef",
130
- "return-value",
131
- "annotation-unchecked",
132
135
  ]
133
136
  files = ["src/cadecoder", "src/cade_mcp_local"]
134
137
 
@@ -69,4 +69,4 @@ __all__ = [
69
69
  "FileOperationError",
70
70
  ]
71
71
 
72
- __version__ = "0.9.0"
72
+ from cadecoder import __version__ as __version__ # noqa: E402