deltachat-claude-code 0.1.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.
- deltachat_claude_code-0.1.0/LICENSE +21 -0
- deltachat_claude_code-0.1.0/PKG-INFO +279 -0
- deltachat_claude_code-0.1.0/README.md +250 -0
- deltachat_claude_code-0.1.0/agentbot/__init__.py +0 -0
- deltachat_claude_code-0.1.0/agentbot/__main__.py +3 -0
- deltachat_claude_code-0.1.0/agentbot/avatar.py +61 -0
- deltachat_claude_code-0.1.0/agentbot/bot.py +268 -0
- deltachat_claude_code-0.1.0/agentbot/commands.py +456 -0
- deltachat_claude_code-0.1.0/agentbot/provision.py +88 -0
- deltachat_claude_code-0.1.0/agentbot/render.py +241 -0
- deltachat_claude_code-0.1.0/agentbot/session.py +292 -0
- deltachat_claude_code-0.1.0/agentbot/store.py +179 -0
- deltachat_claude_code-0.1.0/agentbot/transcribe.py +39 -0
- deltachat_claude_code-0.1.0/deltachat_claude_code.egg-info/PKG-INFO +279 -0
- deltachat_claude_code-0.1.0/deltachat_claude_code.egg-info/SOURCES.txt +19 -0
- deltachat_claude_code-0.1.0/deltachat_claude_code.egg-info/dependency_links.txt +1 -0
- deltachat_claude_code-0.1.0/deltachat_claude_code.egg-info/entry_points.txt +3 -0
- deltachat_claude_code-0.1.0/deltachat_claude_code.egg-info/requires.txt +6 -0
- deltachat_claude_code-0.1.0/deltachat_claude_code.egg-info/top_level.txt +1 -0
- deltachat_claude_code-0.1.0/pyproject.toml +54 -0
- deltachat_claude_code-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Emory Shaw
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deltachat-claude-code
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Access Claude Code from your phone — full CLI sessions over Delta Chat
|
|
5
|
+
Author: Emory Shaw
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/maphouse/deltachat-claude-code
|
|
8
|
+
Project-URL: Repository, https://github.com/maphouse/deltachat-claude-code
|
|
9
|
+
Keywords: claude-code,delta-chat,deltachat,chatbot,cli,anthropic,claude,remote-access,encrypted-chat
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: No Input/Output (Daemon)
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Communications :: Chat
|
|
19
|
+
Classifier: Topic :: Software Development
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: deltachat-rpc-client>=1.0
|
|
24
|
+
Requires-Dist: deltachat-rpc-server>=1.0
|
|
25
|
+
Requires-Dist: pillow>=10.0
|
|
26
|
+
Provides-Extra: voice
|
|
27
|
+
Requires-Dist: faster-whisper>=1.0; extra == "voice"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# deltachat-claude-code <img width="45" alt="social-preview" src="https://github.com/user-attachments/assets/91703ad9-b5ad-434b-aa85-237e5851266c" />
|
|
31
|
+
|
|
32
|
+
**Access self-hosted Claude Code from your phone — full CLI sessions over encrypted chat, no signup, no terminal needed.**
|
|
33
|
+
|
|
34
|
+
Host a bot that proxies full
|
|
35
|
+
[Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI sessions to any device via lightweight encrypted chat. This is not an API wrapper or a chatbot skin, it's the whole `claude` binary over a chat transport. Everything you get in a terminal session is bridged into an easy chat interface: file editing, bash, git,
|
|
36
|
+
multi-step tool chains, code review, subagents, CLAUDE.md context, and the full
|
|
37
|
+
slash-command surface.
|
|
38
|
+
|
|
39
|
+
[Delta Chat](https://delta.chat) is the messenger of choice here: a decentralized, encrypted chat system with no signup and that requires no
|
|
40
|
+
phone number, email or login: install it, add the bot as a contact, and start
|
|
41
|
+
prompting. See [why](#why) this is the best way to interact with Claude Code.
|
|
42
|
+
|
|
43
|
+
## Contents
|
|
44
|
+
|
|
45
|
+
- [Why](#why)
|
|
46
|
+
- [Screenshots](#screenshots)
|
|
47
|
+
- [Architecture](#architecture)
|
|
48
|
+
- [System requirements](#system-requirements)
|
|
49
|
+
- [How to setup](#how-to-setup)
|
|
50
|
+
- [Using Claude Code through the chat](#using-claude-code-through-the-chat)
|
|
51
|
+
- [Security](#security)
|
|
52
|
+
- [To note](#to-note)
|
|
53
|
+
- [Known limitations](#known-limitations)
|
|
54
|
+
|
|
55
|
+
## Why
|
|
56
|
+
|
|
57
|
+
- **Why Delta Chat?** Your prompts aren't stored anywhere but your machine. Delta Chat is
|
|
58
|
+
decentralized, encrypted email under the hood, so no third-party platform ever sees your
|
|
59
|
+
conversation. It also requires no account, no phone number, no signup: it's the lowest-friction path
|
|
60
|
+
between "I have a server" and "I'm talking to it from any device."
|
|
61
|
+
|
|
62
|
+
- **Cumulative chat transcripts.** Claude Code session contexts are ephemeral: they live
|
|
63
|
+
in a terminal that scrolls away. A project conversation turns every project
|
|
64
|
+
into an infinitely scrollable, searchable chat thread, no matter how many sessions you created or /clear commands you used. The Delta Chat thread is a really useful project diary.
|
|
65
|
+
|
|
66
|
+
- **Reply-to context.** When you reply to a specific message in the chat, the
|
|
67
|
+
quoted text is forwarded to Claude as context. Instead of re-explaining what
|
|
68
|
+
you're referring to, just swipe-reply on the message and add your follow-up.
|
|
69
|
+
This is something a terminal can't do — you can't "reply to" a specific line
|
|
70
|
+
of output.
|
|
71
|
+
|
|
72
|
+
- **Project-based chats.** Use `/commission <name> <directory>` to create a dedicated group
|
|
73
|
+
chat for a project in a given folder. Each commissioned chat gets its own session and randomly generated identicon avatar.
|
|
74
|
+
|
|
75
|
+
- **Vibe code with friends.** The bot is a Delta Chat contact like any other, and a commissioned group chat is just a group chat. Add your other contacts to a chat with the agent and work on a project together!
|
|
76
|
+
|
|
77
|
+
- **Session portability.** A session started from your phone can be resumed from
|
|
78
|
+
a terminal (`claude --resume <id>`), and vice versa. The underlying `.jsonl`
|
|
79
|
+
session file is the same one Claude Code uses natively. You're not locked into
|
|
80
|
+
the chat interface; it's just another way in.
|
|
81
|
+
|
|
82
|
+
- **Voice memos.** With optional
|
|
83
|
+
[faster-whisper](https://github.com/SYSTRAN/faster-whisper) integration, send
|
|
84
|
+
voice memos and they'll be transcribed before reaching Claude. The bot echoes
|
|
85
|
+
the transcription back so you can verify what Claude received.
|
|
86
|
+
|
|
87
|
+
- **Screenshots and file delivery.** Send images for Claude to analyze; use
|
|
88
|
+
`/send <path>` to deliver generated files (images, PDFs, build artifacts)
|
|
89
|
+
back to your chat. Attachments are saved to `.agentbot-inbox/` in the
|
|
90
|
+
session's working directory.
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## Screenshots
|
|
94
|
+
|
|
95
|
+
| Tool output in a project chat |Transcription echo before Claude responds | Multi-turn conversation with file analysis |Committing and pushing from chat |
|
|
96
|
+
|:---:|:---:|:---:|:---:|
|
|
97
|
+
|  |  |  |  |
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
## Architecture
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
bot.py event loop: DC message in → slash command or session.send_user()
|
|
104
|
+
session.py Session wraps `claude -p --stream-json` subprocess; SessionManager
|
|
105
|
+
caps concurrent processes, idle-reaps after timeout
|
|
106
|
+
render.py stream-json events → coalesced DC messages + emoji reactions (⏳/✅/❌)
|
|
107
|
+
commands.py slash router: /new, /clear, /exit, /resume, /model, /mode, /commission, etc.
|
|
108
|
+
store.py SQLite: chat↔session bindings, per-turn usage tracking
|
|
109
|
+
avatar.py random identicon avatars for commissioned project chats
|
|
110
|
+
transcribe.py optional faster-whisper voice memo transcription
|
|
111
|
+
provision.py one-time setup: creates chatmail account, avatar, systemd unit
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## System requirements
|
|
115
|
+
|
|
116
|
+
### Prerequisites
|
|
117
|
+
|
|
118
|
+
- A Linux machine with [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
|
119
|
+
installed and authenticated (`claude` on your PATH)
|
|
120
|
+
- Python 3.11+
|
|
121
|
+
- [Delta Chat](https://delta.chat) on your phone (or any device)
|
|
122
|
+
|
|
123
|
+
### Resource usage
|
|
124
|
+
|
|
125
|
+
The bot itself is lightweight (~20 MB RSS). The cost is in the Claude Code
|
|
126
|
+
subprocesses it manages — each one is a full Node.js process.
|
|
127
|
+
|
|
128
|
+
| Component | RAM | Notes |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| agentbot (Python) | ~20 MB | Always resident while the service is running |
|
|
131
|
+
| Each Claude Code session | ~300 MB | One per active chat; idle sessions are reaped |
|
|
132
|
+
| faster-whisper (optional) | ~200 MB | Loaded per transcription, then released |
|
|
133
|
+
|
|
134
|
+
With the default `max_live_sessions = 3`, peak usage is roughly **1 GB** (bot +
|
|
135
|
+
3 sessions). Idle-reaped sessions release their memory; sending a new message
|
|
136
|
+
respawns the subprocess.
|
|
137
|
+
|
|
138
|
+
**Minimum:** 2 GB free RAM is comfortable for typical use (1-2 concurrent
|
|
139
|
+
sessions). Whisper memory is transient — it loads for each voice memo and
|
|
140
|
+
releases after. Machines with 4 GB+ total RAM should have no issues.
|
|
141
|
+
|
|
142
|
+
The bot uses negligible CPU when idle. CPU spikes briefly when Claude Code
|
|
143
|
+
processes a turn, but the actual inference happens on Anthropic's servers — your
|
|
144
|
+
machine just runs the tool calls (bash, file I/O, git).
|
|
145
|
+
|
|
146
|
+
## How to setup
|
|
147
|
+
|
|
148
|
+
### Install
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pip install deltachat-claude-code
|
|
152
|
+
|
|
153
|
+
# Optional: voice memo transcription
|
|
154
|
+
pip install deltachat-claude-code[voice]
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Or install from source:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
git clone https://github.com/maphouse/deltachat-claude-code
|
|
161
|
+
cd deltachat-claude-code
|
|
162
|
+
pip install . # or: pip install .[voice]
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Configure and provision
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Create a directory for your bot instance
|
|
169
|
+
mkdir my-agentbot && cd my-agentbot
|
|
170
|
+
|
|
171
|
+
# Copy the example config and edit it
|
|
172
|
+
cp /path/to/config.example.toml config.toml
|
|
173
|
+
# Or download it:
|
|
174
|
+
# curl -O https://raw.githubusercontent.com/maphouse/deltachat-claude-code/main/config.example.toml
|
|
175
|
+
# Edit config.toml: set admin_addresses, allowed_roots, default_cwd
|
|
176
|
+
|
|
177
|
+
# Provision (creates chatmail account, avatar, systemd unit)
|
|
178
|
+
deltachat-claude-code-provision
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Provisioning prints the bot's chatmail address. Open Delta Chat on your phone,
|
|
182
|
+
tap "New Chat," and enter that address. Send any message to start a session.
|
|
183
|
+
|
|
184
|
+
### Running as a service
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Foreground (for testing)
|
|
188
|
+
deltachat-claude-code
|
|
189
|
+
# or: python3 -m agentbot
|
|
190
|
+
|
|
191
|
+
# As a systemd service (provisioning installs this)
|
|
192
|
+
sudo systemctl enable --now agentbot.service
|
|
193
|
+
journalctl -u agentbot -f # watch logs
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Using Claude Code through the chat
|
|
197
|
+
|
|
198
|
+
Any `/command` not listed below is forwarded to Claude Code as-is — so
|
|
199
|
+
`/code-review`, `/security-review`, `/init`, `/compact`, and all other Claude Code
|
|
200
|
+
slash commands work.
|
|
201
|
+
|
|
202
|
+
### Commissioning chats
|
|
203
|
+
|
|
204
|
+
Use `/commission <name> [dir]` to create a dedicated group chat for a project.
|
|
205
|
+
Each commissioned chat gets its own session, working directory, and randomly
|
|
206
|
+
generated identicon avatar. This is how you keep multiple long-running projects
|
|
207
|
+
separate.
|
|
208
|
+
|
|
209
|
+
### Session control inside a chat
|
|
210
|
+
|
|
211
|
+
These commands control the Claude Code session from inside a persistent chat.
|
|
212
|
+
|
|
213
|
+
| Command | What it does |
|
|
214
|
+
|---|---|
|
|
215
|
+
| `/new [dir]` | Fresh session, optionally in a different directory |
|
|
216
|
+
| `/clear` | Restart session in the same directory |
|
|
217
|
+
| `/exit` | End session — prints a `claude --resume` command for terminal pickup |
|
|
218
|
+
| `/resume <id>` | Resume a previous session by ID |
|
|
219
|
+
| `/sessions` | List bound chats and recent sessions on disk |
|
|
220
|
+
| `/stop` | Interrupt a running turn |
|
|
221
|
+
|
|
222
|
+
### Settings
|
|
223
|
+
|
|
224
|
+
| Command | What it does |
|
|
225
|
+
|---|---|
|
|
226
|
+
| `/model [name]` | Show or set model (sonnet, opus, haiku, fable, or full ID) |
|
|
227
|
+
| `/mode [name]` | Show, set, or cycle permission mode |
|
|
228
|
+
| `/cwd [path]` | Show or change working directory |
|
|
229
|
+
| `/effort [level]` | Show or set effort (low, medium, high, xhigh, max) |
|
|
230
|
+
| `/verbose [on\|off]` | Toggle tool and thinking visibility in chat |
|
|
231
|
+
| `/maxsessions [n]` | Show or set max concurrent Claude subprocesses |
|
|
232
|
+
|
|
233
|
+
### Info
|
|
234
|
+
|
|
235
|
+
| Command | What it does |
|
|
236
|
+
|---|---|
|
|
237
|
+
| `/usage` | Session, today, and weekly stats (turns, tokens, context fill) |
|
|
238
|
+
| `/send <path>` | Send a file (image, PDF, etc.) from the server to this chat |
|
|
239
|
+
| `/help` | All bot commands plus Claude Code's own command list |
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
## Security
|
|
243
|
+
|
|
244
|
+
The `admin_addresses` list in `config.toml` is the **only access control**. The
|
|
245
|
+
bot runs with `bypassPermissions`, meaning Claude Code will execute any tool
|
|
246
|
+
without confirmation. This is deliberate — confirmation prompts can't work over
|
|
247
|
+
chat — but it means the allowlist is load-bearing. Only add addresses you trust
|
|
248
|
+
with full shell access to the machine.
|
|
249
|
+
|
|
250
|
+
## To note
|
|
251
|
+
|
|
252
|
+
- **Concurrent subprocess cap** (default 3). You can have unlimited chat groups,
|
|
253
|
+
but only 3 can have a live Claude Code process at once. You can adjust this maximum
|
|
254
|
+
at runtime with `/maxsessions <n>`, or permanently in `config.toml`. If you message a
|
|
255
|
+
chat beyond the limit, the least-recently-used subprocess is terminated to make
|
|
256
|
+
room. Nothing is lost — the session resumes automatically on the next message.
|
|
257
|
+
- **Idle reaping** (default 30 minutes). Inactive sessions are terminated to free
|
|
258
|
+
memory (~300 MB per subprocess). The session resumes transparently when you send
|
|
259
|
+
the next message. Configure with `idle_timeout_min` in `config.toml`.
|
|
260
|
+
- Messages are split at 4000 chars
|
|
261
|
+
|
|
262
|
+
## Known limitations
|
|
263
|
+
|
|
264
|
+
- **No plan usage visibility.** `/usage` shows context window fill and
|
|
265
|
+
session-level token counts, but can't show how much of your Claude Pro/Max
|
|
266
|
+
subscription quota you've consumed — the CLI doesn't expose that. Check
|
|
267
|
+
[claude.ai/settings](https://claude.ai/settings) for plan-level usage.
|
|
268
|
+
- **No interactive prompts.** The bot runs with `bypassPermissions` because
|
|
269
|
+
confirmation dialogs can't work over chat. This is a security tradeoff,
|
|
270
|
+
not a bug.
|
|
271
|
+
- **No inline artifacts.** Claude Code artifacts and HTML previews don't
|
|
272
|
+
render in Delta Chat. Generated files (images, PDFs) can be delivered
|
|
273
|
+
to the chat with `/send <path>`.
|
|
274
|
+
- **Some slash commands need a TTY.** `/config`, `/keybindings`, `/loop`,
|
|
275
|
+
and `/schedule` are blocked because they require interactive terminal input.
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
MIT
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# deltachat-claude-code <img width="45" alt="social-preview" src="https://github.com/user-attachments/assets/91703ad9-b5ad-434b-aa85-237e5851266c" />
|
|
2
|
+
|
|
3
|
+
**Access self-hosted Claude Code from your phone — full CLI sessions over encrypted chat, no signup, no terminal needed.**
|
|
4
|
+
|
|
5
|
+
Host a bot that proxies full
|
|
6
|
+
[Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI sessions to any device via lightweight encrypted chat. This is not an API wrapper or a chatbot skin, it's the whole `claude` binary over a chat transport. Everything you get in a terminal session is bridged into an easy chat interface: file editing, bash, git,
|
|
7
|
+
multi-step tool chains, code review, subagents, CLAUDE.md context, and the full
|
|
8
|
+
slash-command surface.
|
|
9
|
+
|
|
10
|
+
[Delta Chat](https://delta.chat) is the messenger of choice here: a decentralized, encrypted chat system with no signup and that requires no
|
|
11
|
+
phone number, email or login: install it, add the bot as a contact, and start
|
|
12
|
+
prompting. See [why](#why) this is the best way to interact with Claude Code.
|
|
13
|
+
|
|
14
|
+
## Contents
|
|
15
|
+
|
|
16
|
+
- [Why](#why)
|
|
17
|
+
- [Screenshots](#screenshots)
|
|
18
|
+
- [Architecture](#architecture)
|
|
19
|
+
- [System requirements](#system-requirements)
|
|
20
|
+
- [How to setup](#how-to-setup)
|
|
21
|
+
- [Using Claude Code through the chat](#using-claude-code-through-the-chat)
|
|
22
|
+
- [Security](#security)
|
|
23
|
+
- [To note](#to-note)
|
|
24
|
+
- [Known limitations](#known-limitations)
|
|
25
|
+
|
|
26
|
+
## Why
|
|
27
|
+
|
|
28
|
+
- **Why Delta Chat?** Your prompts aren't stored anywhere but your machine. Delta Chat is
|
|
29
|
+
decentralized, encrypted email under the hood, so no third-party platform ever sees your
|
|
30
|
+
conversation. It also requires no account, no phone number, no signup: it's the lowest-friction path
|
|
31
|
+
between "I have a server" and "I'm talking to it from any device."
|
|
32
|
+
|
|
33
|
+
- **Cumulative chat transcripts.** Claude Code session contexts are ephemeral: they live
|
|
34
|
+
in a terminal that scrolls away. A project conversation turns every project
|
|
35
|
+
into an infinitely scrollable, searchable chat thread, no matter how many sessions you created or /clear commands you used. The Delta Chat thread is a really useful project diary.
|
|
36
|
+
|
|
37
|
+
- **Reply-to context.** When you reply to a specific message in the chat, the
|
|
38
|
+
quoted text is forwarded to Claude as context. Instead of re-explaining what
|
|
39
|
+
you're referring to, just swipe-reply on the message and add your follow-up.
|
|
40
|
+
This is something a terminal can't do — you can't "reply to" a specific line
|
|
41
|
+
of output.
|
|
42
|
+
|
|
43
|
+
- **Project-based chats.** Use `/commission <name> <directory>` to create a dedicated group
|
|
44
|
+
chat for a project in a given folder. Each commissioned chat gets its own session and randomly generated identicon avatar.
|
|
45
|
+
|
|
46
|
+
- **Vibe code with friends.** The bot is a Delta Chat contact like any other, and a commissioned group chat is just a group chat. Add your other contacts to a chat with the agent and work on a project together!
|
|
47
|
+
|
|
48
|
+
- **Session portability.** A session started from your phone can be resumed from
|
|
49
|
+
a terminal (`claude --resume <id>`), and vice versa. The underlying `.jsonl`
|
|
50
|
+
session file is the same one Claude Code uses natively. You're not locked into
|
|
51
|
+
the chat interface; it's just another way in.
|
|
52
|
+
|
|
53
|
+
- **Voice memos.** With optional
|
|
54
|
+
[faster-whisper](https://github.com/SYSTRAN/faster-whisper) integration, send
|
|
55
|
+
voice memos and they'll be transcribed before reaching Claude. The bot echoes
|
|
56
|
+
the transcription back so you can verify what Claude received.
|
|
57
|
+
|
|
58
|
+
- **Screenshots and file delivery.** Send images for Claude to analyze; use
|
|
59
|
+
`/send <path>` to deliver generated files (images, PDFs, build artifacts)
|
|
60
|
+
back to your chat. Attachments are saved to `.agentbot-inbox/` in the
|
|
61
|
+
session's working directory.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
## Screenshots
|
|
65
|
+
|
|
66
|
+
| Tool output in a project chat |Transcription echo before Claude responds | Multi-turn conversation with file analysis |Committing and pushing from chat |
|
|
67
|
+
|:---:|:---:|:---:|:---:|
|
|
68
|
+
|  |  |  |  |
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
## Architecture
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
bot.py event loop: DC message in → slash command or session.send_user()
|
|
75
|
+
session.py Session wraps `claude -p --stream-json` subprocess; SessionManager
|
|
76
|
+
caps concurrent processes, idle-reaps after timeout
|
|
77
|
+
render.py stream-json events → coalesced DC messages + emoji reactions (⏳/✅/❌)
|
|
78
|
+
commands.py slash router: /new, /clear, /exit, /resume, /model, /mode, /commission, etc.
|
|
79
|
+
store.py SQLite: chat↔session bindings, per-turn usage tracking
|
|
80
|
+
avatar.py random identicon avatars for commissioned project chats
|
|
81
|
+
transcribe.py optional faster-whisper voice memo transcription
|
|
82
|
+
provision.py one-time setup: creates chatmail account, avatar, systemd unit
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## System requirements
|
|
86
|
+
|
|
87
|
+
### Prerequisites
|
|
88
|
+
|
|
89
|
+
- A Linux machine with [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
|
90
|
+
installed and authenticated (`claude` on your PATH)
|
|
91
|
+
- Python 3.11+
|
|
92
|
+
- [Delta Chat](https://delta.chat) on your phone (or any device)
|
|
93
|
+
|
|
94
|
+
### Resource usage
|
|
95
|
+
|
|
96
|
+
The bot itself is lightweight (~20 MB RSS). The cost is in the Claude Code
|
|
97
|
+
subprocesses it manages — each one is a full Node.js process.
|
|
98
|
+
|
|
99
|
+
| Component | RAM | Notes |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| agentbot (Python) | ~20 MB | Always resident while the service is running |
|
|
102
|
+
| Each Claude Code session | ~300 MB | One per active chat; idle sessions are reaped |
|
|
103
|
+
| faster-whisper (optional) | ~200 MB | Loaded per transcription, then released |
|
|
104
|
+
|
|
105
|
+
With the default `max_live_sessions = 3`, peak usage is roughly **1 GB** (bot +
|
|
106
|
+
3 sessions). Idle-reaped sessions release their memory; sending a new message
|
|
107
|
+
respawns the subprocess.
|
|
108
|
+
|
|
109
|
+
**Minimum:** 2 GB free RAM is comfortable for typical use (1-2 concurrent
|
|
110
|
+
sessions). Whisper memory is transient — it loads for each voice memo and
|
|
111
|
+
releases after. Machines with 4 GB+ total RAM should have no issues.
|
|
112
|
+
|
|
113
|
+
The bot uses negligible CPU when idle. CPU spikes briefly when Claude Code
|
|
114
|
+
processes a turn, but the actual inference happens on Anthropic's servers — your
|
|
115
|
+
machine just runs the tool calls (bash, file I/O, git).
|
|
116
|
+
|
|
117
|
+
## How to setup
|
|
118
|
+
|
|
119
|
+
### Install
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pip install deltachat-claude-code
|
|
123
|
+
|
|
124
|
+
# Optional: voice memo transcription
|
|
125
|
+
pip install deltachat-claude-code[voice]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Or install from source:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
git clone https://github.com/maphouse/deltachat-claude-code
|
|
132
|
+
cd deltachat-claude-code
|
|
133
|
+
pip install . # or: pip install .[voice]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Configure and provision
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Create a directory for your bot instance
|
|
140
|
+
mkdir my-agentbot && cd my-agentbot
|
|
141
|
+
|
|
142
|
+
# Copy the example config and edit it
|
|
143
|
+
cp /path/to/config.example.toml config.toml
|
|
144
|
+
# Or download it:
|
|
145
|
+
# curl -O https://raw.githubusercontent.com/maphouse/deltachat-claude-code/main/config.example.toml
|
|
146
|
+
# Edit config.toml: set admin_addresses, allowed_roots, default_cwd
|
|
147
|
+
|
|
148
|
+
# Provision (creates chatmail account, avatar, systemd unit)
|
|
149
|
+
deltachat-claude-code-provision
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Provisioning prints the bot's chatmail address. Open Delta Chat on your phone,
|
|
153
|
+
tap "New Chat," and enter that address. Send any message to start a session.
|
|
154
|
+
|
|
155
|
+
### Running as a service
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Foreground (for testing)
|
|
159
|
+
deltachat-claude-code
|
|
160
|
+
# or: python3 -m agentbot
|
|
161
|
+
|
|
162
|
+
# As a systemd service (provisioning installs this)
|
|
163
|
+
sudo systemctl enable --now agentbot.service
|
|
164
|
+
journalctl -u agentbot -f # watch logs
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Using Claude Code through the chat
|
|
168
|
+
|
|
169
|
+
Any `/command` not listed below is forwarded to Claude Code as-is — so
|
|
170
|
+
`/code-review`, `/security-review`, `/init`, `/compact`, and all other Claude Code
|
|
171
|
+
slash commands work.
|
|
172
|
+
|
|
173
|
+
### Commissioning chats
|
|
174
|
+
|
|
175
|
+
Use `/commission <name> [dir]` to create a dedicated group chat for a project.
|
|
176
|
+
Each commissioned chat gets its own session, working directory, and randomly
|
|
177
|
+
generated identicon avatar. This is how you keep multiple long-running projects
|
|
178
|
+
separate.
|
|
179
|
+
|
|
180
|
+
### Session control inside a chat
|
|
181
|
+
|
|
182
|
+
These commands control the Claude Code session from inside a persistent chat.
|
|
183
|
+
|
|
184
|
+
| Command | What it does |
|
|
185
|
+
|---|---|
|
|
186
|
+
| `/new [dir]` | Fresh session, optionally in a different directory |
|
|
187
|
+
| `/clear` | Restart session in the same directory |
|
|
188
|
+
| `/exit` | End session — prints a `claude --resume` command for terminal pickup |
|
|
189
|
+
| `/resume <id>` | Resume a previous session by ID |
|
|
190
|
+
| `/sessions` | List bound chats and recent sessions on disk |
|
|
191
|
+
| `/stop` | Interrupt a running turn |
|
|
192
|
+
|
|
193
|
+
### Settings
|
|
194
|
+
|
|
195
|
+
| Command | What it does |
|
|
196
|
+
|---|---|
|
|
197
|
+
| `/model [name]` | Show or set model (sonnet, opus, haiku, fable, or full ID) |
|
|
198
|
+
| `/mode [name]` | Show, set, or cycle permission mode |
|
|
199
|
+
| `/cwd [path]` | Show or change working directory |
|
|
200
|
+
| `/effort [level]` | Show or set effort (low, medium, high, xhigh, max) |
|
|
201
|
+
| `/verbose [on\|off]` | Toggle tool and thinking visibility in chat |
|
|
202
|
+
| `/maxsessions [n]` | Show or set max concurrent Claude subprocesses |
|
|
203
|
+
|
|
204
|
+
### Info
|
|
205
|
+
|
|
206
|
+
| Command | What it does |
|
|
207
|
+
|---|---|
|
|
208
|
+
| `/usage` | Session, today, and weekly stats (turns, tokens, context fill) |
|
|
209
|
+
| `/send <path>` | Send a file (image, PDF, etc.) from the server to this chat |
|
|
210
|
+
| `/help` | All bot commands plus Claude Code's own command list |
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
## Security
|
|
214
|
+
|
|
215
|
+
The `admin_addresses` list in `config.toml` is the **only access control**. The
|
|
216
|
+
bot runs with `bypassPermissions`, meaning Claude Code will execute any tool
|
|
217
|
+
without confirmation. This is deliberate — confirmation prompts can't work over
|
|
218
|
+
chat — but it means the allowlist is load-bearing. Only add addresses you trust
|
|
219
|
+
with full shell access to the machine.
|
|
220
|
+
|
|
221
|
+
## To note
|
|
222
|
+
|
|
223
|
+
- **Concurrent subprocess cap** (default 3). You can have unlimited chat groups,
|
|
224
|
+
but only 3 can have a live Claude Code process at once. You can adjust this maximum
|
|
225
|
+
at runtime with `/maxsessions <n>`, or permanently in `config.toml`. If you message a
|
|
226
|
+
chat beyond the limit, the least-recently-used subprocess is terminated to make
|
|
227
|
+
room. Nothing is lost — the session resumes automatically on the next message.
|
|
228
|
+
- **Idle reaping** (default 30 minutes). Inactive sessions are terminated to free
|
|
229
|
+
memory (~300 MB per subprocess). The session resumes transparently when you send
|
|
230
|
+
the next message. Configure with `idle_timeout_min` in `config.toml`.
|
|
231
|
+
- Messages are split at 4000 chars
|
|
232
|
+
|
|
233
|
+
## Known limitations
|
|
234
|
+
|
|
235
|
+
- **No plan usage visibility.** `/usage` shows context window fill and
|
|
236
|
+
session-level token counts, but can't show how much of your Claude Pro/Max
|
|
237
|
+
subscription quota you've consumed — the CLI doesn't expose that. Check
|
|
238
|
+
[claude.ai/settings](https://claude.ai/settings) for plan-level usage.
|
|
239
|
+
- **No interactive prompts.** The bot runs with `bypassPermissions` because
|
|
240
|
+
confirmation dialogs can't work over chat. This is a security tradeoff,
|
|
241
|
+
not a bug.
|
|
242
|
+
- **No inline artifacts.** Claude Code artifacts and HTML previews don't
|
|
243
|
+
render in Delta Chat. Generated files (images, PDFs) can be delivered
|
|
244
|
+
to the chat with `/send <path>`.
|
|
245
|
+
- **Some slash commands need a TTY.** `/config`, `/keybindings`, `/loop`,
|
|
246
|
+
and `/schedule` are blocked because they require interactive terminal input.
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
MIT
|
|
File without changes
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import colorsys
|
|
2
|
+
import random
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from PIL import Image
|
|
6
|
+
|
|
7
|
+
GRID = 24
|
|
8
|
+
SCALE = 8
|
|
9
|
+
FACE_CELLS = 4
|
|
10
|
+
CELL_SIZE = GRID // FACE_CELLS # 6px per cell
|
|
11
|
+
|
|
12
|
+
BLACK = (17, 17, 17, 255)
|
|
13
|
+
WHITE = (255, 255, 255, 255)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def random_color() -> tuple[int, int, int, int]:
|
|
17
|
+
h = random.random()
|
|
18
|
+
s = random.uniform(0.55, 0.85)
|
|
19
|
+
l = random.uniform(0.45, 0.65)
|
|
20
|
+
r, g, b = colorsys.hls_to_rgb(h, l, s)
|
|
21
|
+
return (int(r * 255), int(g * 255), int(b * 255), 255)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def random_face() -> list[list[bool]]:
|
|
25
|
+
"""4x4 grid with left-right symmetry. Left 2 columns are random,
|
|
26
|
+
right 2 columns mirror them. 2*4 = 8 independent bits = 256 patterns.
|
|
27
|
+
Excludes all-off and all-on."""
|
|
28
|
+
while True:
|
|
29
|
+
left = [[random.choice([True, False]) for _ in range(2)] for _ in range(FACE_CELLS)]
|
|
30
|
+
grid = []
|
|
31
|
+
for row in left:
|
|
32
|
+
grid.append(row + list(reversed(row)))
|
|
33
|
+
on_count = sum(c for row in grid for c in row)
|
|
34
|
+
if 0 < on_count < FACE_CELLS * FACE_CELLS:
|
|
35
|
+
return grid
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def make_avatar(out_path: Path, color: tuple = None, face: list = None):
|
|
39
|
+
if color is None:
|
|
40
|
+
color = random_color()
|
|
41
|
+
if face is None:
|
|
42
|
+
face = random_face()
|
|
43
|
+
|
|
44
|
+
img = Image.new("RGBA", (GRID, GRID), color)
|
|
45
|
+
fg = WHITE if _is_dark(color) else BLACK
|
|
46
|
+
for row in range(FACE_CELLS):
|
|
47
|
+
for col in range(FACE_CELLS):
|
|
48
|
+
if face[row][col]:
|
|
49
|
+
x0 = col * CELL_SIZE
|
|
50
|
+
y0 = row * CELL_SIZE
|
|
51
|
+
for y in range(y0, y0 + CELL_SIZE):
|
|
52
|
+
for x in range(x0, x0 + CELL_SIZE):
|
|
53
|
+
img.putpixel((x, y), fg)
|
|
54
|
+
|
|
55
|
+
img.resize((GRID * SCALE, GRID * SCALE), Image.NEAREST).save(out_path)
|
|
56
|
+
return color, face
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _is_dark(color: tuple) -> bool:
|
|
60
|
+
r, g, b = color[:3]
|
|
61
|
+
return (r * 299 + g * 587 + b * 114) / 1000 < 128
|