ctb 1.0.0

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.
package/.env.example ADDED
@@ -0,0 +1,76 @@
1
+ # Claude Telegram Bot - Environment Configuration
2
+
3
+ # ==============================================================================
4
+ # REQUIRED
5
+ # ==============================================================================
6
+
7
+ # Telegram bot token from @BotFather
8
+ TELEGRAM_BOT_TOKEN=1234567890:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
9
+
10
+ # Comma-separated Telegram user IDs allowed to use the bot
11
+ # Find your ID: message @userinfobot on Telegram
12
+ TELEGRAM_ALLOWED_USERS=123456789
13
+
14
+ # ==============================================================================
15
+ # RECOMMENDED
16
+ # ==============================================================================
17
+
18
+ # Working directory where Claude runs (loads CLAUDE.md, skills, MCP config)
19
+ CLAUDE_WORKING_DIR=/Users/yourname/personal
20
+
21
+ # OpenAI API key for voice message transcription
22
+ # Without this, voice messages won't work
23
+ OPENAI_API_KEY=sk-...
24
+
25
+ # ==============================================================================
26
+ # OPTIONAL - Security
27
+ # ==============================================================================
28
+
29
+ # Comma-separated paths Claude can access
30
+ # Default: working dir, ~/Documents, ~/Downloads, ~/Desktop, ~/.claude
31
+ # Note: Setting this OVERRIDES defaults. Include ~/.claude for plan mode to work.
32
+ # ALLOWED_PATHS=/Users/yourname/personal,/Users/yourname/projects,/Users/yourname/.claude
33
+
34
+ # Rate limiting (token bucket)
35
+ # RATE_LIMIT_ENABLED=true
36
+ # RATE_LIMIT_REQUESTS=20
37
+ # RATE_LIMIT_WINDOW=60
38
+
39
+ # ==============================================================================
40
+ # OPTIONAL - Claude Authentication
41
+ # ==============================================================================
42
+
43
+ # API key for environments without Claude Code CLI auth
44
+ # Get from: https://console.anthropic.com/
45
+ # Note: API usage is billed per token - CLI auth is more cost-effective
46
+ # ANTHROPIC_API_KEY=sk-ant-api03-...
47
+
48
+ # Path to Claude CLI (auto-detected from PATH by default)
49
+ # CLAUDE_CLI_PATH=/usr/local/bin/claude
50
+
51
+ # ==============================================================================
52
+ # OPTIONAL - Extended Thinking
53
+ # ==============================================================================
54
+
55
+ # Keywords that trigger extended thinking (comma-separated, case-insensitive)
56
+ # THINKING_KEYWORDS=think,pensa,ragiona
57
+
58
+ # Keywords that trigger deep thinking (50k tokens)
59
+ # THINKING_DEEP_KEYWORDS=ultrathink,think hard,pensa bene
60
+
61
+ # ==============================================================================
62
+ # OPTIONAL - Voice Transcription
63
+ # ==============================================================================
64
+
65
+ # Additional context for voice transcription (names, technical terms, etc.)
66
+ # TRANSCRIPTION_CONTEXT=Common names: John, Alice. Tech: Kubernetes, GraphQL.
67
+
68
+ # ==============================================================================
69
+ # OPTIONAL - Logging
70
+ # ==============================================================================
71
+
72
+ # Audit log path
73
+ # AUDIT_LOG_PATH=/tmp/claude-telegram-audit.log
74
+
75
+ # Output audit logs as JSON (default: human-readable)
76
+ # AUDIT_LOG_JSON=false
package/CLAUDE.md ADDED
@@ -0,0 +1,116 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ bun run start # Run the bot
9
+ bun run dev # Run with auto-reload (--watch)
10
+ bun run typecheck # Run TypeScript type checking
11
+ bun install # Install dependencies
12
+ ```
13
+
14
+ ## Architecture
15
+
16
+ This is a Telegram bot (~3,300 lines TypeScript) that lets you control Claude Code from your phone via text, voice, photos, and documents. Built with Bun and grammY.
17
+
18
+ ### Message Flow
19
+
20
+ ```
21
+ Telegram message → Handler → Auth check → Rate limit → Claude session → Streaming response → Audit log
22
+ ```
23
+
24
+ ### Key Modules
25
+
26
+ - **`src/index.ts`** - Entry point, registers handlers, starts polling
27
+ - **`src/config.ts`** - Environment parsing, MCP loading, safety prompts
28
+ - **`src/session.ts`** - `ClaudeSession` class wrapping Agent SDK V2 with streaming, session persistence (`/tmp/claude-telegram-session.json`), and defense-in-depth safety checks
29
+ - **`src/security.ts`** - `RateLimiter` (token bucket), path validation, command safety checks
30
+ - **`src/formatting.ts`** - Markdown→HTML conversion for Telegram, tool status emoji formatting
31
+ - **`src/utils.ts`** - Audit logging, voice transcription (OpenAI), typing indicators
32
+ - **`src/types.ts`** - Shared TypeScript types
33
+
34
+ ### Handlers (`src/handlers/`)
35
+
36
+ Each message type has a dedicated async handler:
37
+ - **`commands.ts`** - `/start`, `/new`, `/stop`, `/status`, `/resume`, `/restart`
38
+ - **`text.ts`** - Text messages with intent filtering
39
+ - **`voice.ts`** - Voice→text via OpenAI, then same flow as text
40
+ - **`photo.ts`** - Image analysis with media group buffering (1s timeout for albums)
41
+ - **`document.ts`** - PDF extraction (pdftotext CLI) and text file processing
42
+ - **`callback.ts`** - Inline keyboard button handling for ask_user MCP
43
+ - **`streaming.ts`** - Shared `StreamingState` and status callback factory
44
+
45
+ ### Security Layers
46
+
47
+ 1. User allowlist (`TELEGRAM_ALLOWED_USERS`)
48
+ 2. Rate limiting (token bucket, configurable)
49
+ 3. Path validation (`ALLOWED_PATHS`)
50
+ 4. Command safety (blocked patterns)
51
+ 5. System prompt constraints
52
+ 6. Audit logging
53
+
54
+ ### Configuration
55
+
56
+ All config via `.env` (copy from `.env.example`). Key variables:
57
+ - `TELEGRAM_BOT_TOKEN`, `TELEGRAM_ALLOWED_USERS` (required)
58
+ - `CLAUDE_WORKING_DIR` - Working directory for Claude
59
+ - `ALLOWED_PATHS` - Directories Claude can access
60
+ - `OPENAI_API_KEY` - For voice transcription
61
+
62
+ MCP servers defined in `mcp-config.ts`.
63
+
64
+ ### Runtime Files
65
+
66
+ - `/tmp/claude-telegram-session.json` - Session persistence for `/resume`
67
+ - `/tmp/telegram-bot/` - Downloaded photos/documents
68
+ - `/tmp/claude-telegram-audit.log` - Audit log
69
+
70
+ ## Patterns
71
+
72
+ **Adding a command**: Create handler in `commands.ts`, register in `index.ts` with `bot.command("name", handler)`
73
+
74
+ **Adding a message handler**: Create in `handlers/`, export from `index.ts`, register in `index.ts` with appropriate filter
75
+
76
+ **Streaming pattern**: All handlers use `createStatusCallback()` from `streaming.ts` and `session.sendMessageStreaming()` for live updates.
77
+
78
+ **Type checking**: Run `bun run typecheck` periodically while editing TypeScript files. Fix any type errors before committing.
79
+
80
+ **After code changes**: Restart the bot so changes can be tested. Use `launchctl kickstart -k gui/$(id -u)/com.claude-telegram-ts` if running as a service, or `bun run start` for manual runs.
81
+
82
+ ## Standalone Build
83
+
84
+ The bot can be compiled to a standalone binary with `bun build --compile`. This is used by the ClaudeBot macOS app wrapper.
85
+
86
+ ### External Dependencies
87
+
88
+ PDF extraction uses `pdftotext` CLI instead of an npm package (to avoid bundling issues):
89
+
90
+ ```bash
91
+ brew install poppler # Provides pdftotext
92
+ ```
93
+
94
+ ### PATH Requirements
95
+
96
+ When running as a standalone binary (especially from a macOS app), the PATH may not include Homebrew. The launcher must ensure PATH includes:
97
+ - `/opt/homebrew/bin` (Apple Silicon Homebrew)
98
+ - `/usr/local/bin` (Intel Homebrew)
99
+
100
+ Without this, `pdftotext` won't be found and PDF parsing will fail silently with an error message.
101
+
102
+ ## Commit Style
103
+
104
+ Do not add "Generated with Claude Code" footers or "Co-Authored-By" trailers to commit messages.
105
+
106
+ ## Running as Service (macOS)
107
+
108
+ ```bash
109
+ cp launchagent/com.claude-telegram-ts.plist.template ~/Library/LaunchAgents/com.claude-telegram-ts.plist
110
+ # Edit plist with your paths
111
+ launchctl load ~/Library/LaunchAgents/com.claude-telegram-ts.plist
112
+
113
+ # Logs
114
+ tail -f /tmp/claude-telegram-bot-ts.log
115
+ tail -f /tmp/claude-telegram-bot-ts.err
116
+ ```
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Fabrizio Rinaldi
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.
package/Makefile ADDED
@@ -0,0 +1,142 @@
1
+ # Claude Telegram Bot - Makefile
2
+ # Usage: make <target>
3
+
4
+ SHELL := /bin/bash
5
+
6
+ PLIST_NAME := com.claude-telegram-ts
7
+ PLIST_PATH := ~/Library/LaunchAgents/$(PLIST_NAME).plist
8
+ PLIST_TEMPLATE := launchagent/$(PLIST_NAME).plist.template
9
+ LOG_FILE := /tmp/claude-telegram-bot.log
10
+ ERR_FILE := /tmp/claude-telegram-bot.err
11
+
12
+ .PHONY: help install setup run dev stop start restart status logs logs-err clean typecheck test
13
+
14
+ # Default target
15
+ help:
16
+ @echo "Claude Telegram Bot"
17
+ @echo ""
18
+ @echo "Quick start:"
19
+ @echo " make setup - First-time setup (install deps, create .env)"
20
+ @echo " make run - Run bot in foreground"
21
+ @echo " make dev - Run with auto-reload (watch mode)"
22
+ @echo ""
23
+ @echo "Background service (macOS LaunchAgent):"
24
+ @echo " make start - Install and start background service"
25
+ @echo " make stop - Stop background service"
26
+ @echo " make restart - Restart background service"
27
+ @echo " make status - Check if service is running"
28
+ @echo " make logs - Tail stdout logs"
29
+ @echo " make logs-err - Tail stderr logs"
30
+ @echo " make uninstall - Remove background service"
31
+ @echo ""
32
+ @echo "Development:"
33
+ @echo " make install - Install dependencies"
34
+ @echo " make test - Run tests"
35
+ @echo " make typecheck - Run TypeScript type check"
36
+ @echo " make clean - Remove temp files and logs"
37
+
38
+ # Install dependencies
39
+ install:
40
+ bun install
41
+
42
+ # First-time setup
43
+ setup: install
44
+ @if [ ! -f .env ]; then \
45
+ cp .env.example .env; \
46
+ echo "Created .env from template"; \
47
+ echo ">>> Edit .env with your TELEGRAM_BOT_TOKEN and TELEGRAM_ALLOWED_USERS"; \
48
+ else \
49
+ echo ".env already exists"; \
50
+ fi
51
+ @echo ""
52
+ @echo "Next steps:"
53
+ @echo " 1. Edit .env with your credentials"
54
+ @echo " 2. Run 'make run' to test"
55
+ @echo " 3. Run 'make start' to run as background service"
56
+
57
+ # Run in foreground
58
+ run:
59
+ bun run start
60
+
61
+ # Run with watch mode
62
+ dev:
63
+ bun run dev
64
+
65
+ # Run tests
66
+ test:
67
+ bun test
68
+
69
+ # TypeScript type check
70
+ typecheck:
71
+ bun run typecheck
72
+
73
+ # === Background Service (macOS LaunchAgent) ===
74
+
75
+ # Install and start service
76
+ start:
77
+ @if [ ! -f .env ]; then \
78
+ echo "Error: .env not found. Run 'make setup' first."; \
79
+ exit 1; \
80
+ fi
81
+ @echo "Installing LaunchAgent..."
82
+ @mkdir -p ~/Library/LaunchAgents
83
+ @export $$(grep -v '^#' .env | xargs) && \
84
+ sed -e "s|/Users/USERNAME/.bun/bin/bun|$$(command -v bun)|g" \
85
+ -e "s|/Users/USERNAME/Dev/claude-telegram-bot-ts|$$(pwd)|g" \
86
+ -e "s|<string>/Users/USERNAME/Dev</string>|<string>$${CLAUDE_WORKING_DIR:-$$(pwd)}</string>|g" \
87
+ -e "s|your-bot-token-here|$${TELEGRAM_BOT_TOKEN}|g" \
88
+ -e "s|<string>123456789</string>|<string>$${TELEGRAM_ALLOWED_USERS}</string>|g" \
89
+ -e "s|<string>sk-...</string>|<string>$${OPENAI_API_KEY:-}</string>|g" \
90
+ -e "s|USERNAME|$$(whoami)|g" \
91
+ $(PLIST_TEMPLATE) > $(PLIST_PATH)
92
+ @echo "Created $(PLIST_PATH) with values from .env"
93
+ @launchctl unload $(PLIST_PATH) 2>/dev/null || true
94
+ @launchctl load $(PLIST_PATH)
95
+ @echo "Service started. Check 'make logs' for output."
96
+
97
+ # Stop service
98
+ stop:
99
+ @launchctl unload $(PLIST_PATH) 2>/dev/null || echo "Service not running"
100
+ @echo "Service stopped"
101
+
102
+ # Restart service
103
+ restart:
104
+ @launchctl kickstart -k gui/$$(id -u)/$(PLIST_NAME) 2>/dev/null || \
105
+ (echo "Service not loaded. Run 'make start' first." && exit 1)
106
+ @echo "Service restarted"
107
+
108
+ # Check service status
109
+ status:
110
+ @if launchctl list | grep -q $(PLIST_NAME); then \
111
+ echo "Service: RUNNING"; \
112
+ launchctl list $(PLIST_NAME); \
113
+ else \
114
+ echo "Service: NOT RUNNING"; \
115
+ fi
116
+
117
+ # Uninstall service
118
+ uninstall: stop
119
+ @rip $(PLIST_PATH) 2>/dev/null || true
120
+ @echo "Service uninstalled"
121
+
122
+ # Tail stdout logs
123
+ logs:
124
+ @if [ -f $(LOG_FILE) ]; then \
125
+ tail -f $(LOG_FILE); \
126
+ else \
127
+ echo "No log file yet. Start the service first."; \
128
+ fi
129
+
130
+ # Tail stderr logs
131
+ logs-err:
132
+ @if [ -f $(ERR_FILE) ]; then \
133
+ tail -f $(ERR_FILE); \
134
+ else \
135
+ echo "No error log yet."; \
136
+ fi
137
+
138
+ # Clean temp files
139
+ clean:
140
+ rip $(LOG_FILE) $(ERR_FILE) 2>/dev/null || true
141
+ rip /tmp/telegram-bot 2>/dev/null || true
142
+ @echo "Cleaned temp files"
package/README.md ADDED
@@ -0,0 +1,268 @@
1
+ # Claude Telegram Bot
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
+ [![Bun](https://img.shields.io/badge/Bun-1.0+-black.svg)](https://bun.sh/)
5
+
6
+ **Turn [Claude Code](https://claude.com/product/claude-code) into your personal assistant, accessible from anywhere via Telegram.**
7
+
8
+ Send text, voice, photos, and documents. See responses and tools usage in real-time.
9
+
10
+ ![Demo](assets/demo.gif)
11
+
12
+ ## Claude Code as a Personal Assistant
13
+
14
+ I've started using Claude Code as a personal assistant, and I've built this bot so I can access it from anywhere.
15
+
16
+ In fact, while Claude Code is described as a powerful AI **coding agent**, it's actually a very capable **general-purpose agent** too when given the right instructions, context, and tools.
17
+
18
+ To achieve this, I set up a folder with a CLAUDE.md that teaches Claude about me (my preferences, where my notes live, my workflows), has a set of tools and scripts based on my needs, and pointed this bot at that folder.
19
+
20
+ → **[📄 See the Personal Assistant Guide](docs/personal-assistant-guide.md)** for detailed setup and examples.
21
+
22
+ ## Bot Features
23
+
24
+ - 💬 **Text**: Ask questions, give instructions, have conversations
25
+ - 🎤 **Voice**: Speak naturally - transcribed via OpenAI and processed by Claude
26
+ - 📸 **Photos**: Send screenshots, documents, or anything visual for analysis
27
+ - 📄 **Documents**: PDFs, text files, and archives (ZIP, TAR) are extracted and analyzed
28
+ - 🔄 **Session persistence**: Conversations continue across messages
29
+ - 📨 **Message queuing**: Send multiple messages while Claude works - they queue up automatically. Prefix with `!` or use `/stop` to interrupt and send immediately
30
+ - 🧠 **Extended thinking**: Trigger Claude's reasoning by using words like "think" or "reason" - you'll see its thought process as it works (configurable via `THINKING_TRIGGER_KEYWORDS`)
31
+ - 🔘 **Interactive buttons**: Claude can present options as tappable inline buttons via the built-in `ask_user` MCP tool
32
+
33
+ ## Quick Start
34
+
35
+ ### Install via npm (Recommended)
36
+
37
+ ```bash
38
+ # Install globally
39
+ npm install -g ctb
40
+
41
+ # Run in any project directory
42
+ cd ~/my-project
43
+ ctb
44
+ ```
45
+
46
+ On first run, `ctb` will prompt for your Telegram bot token and allowed user IDs, then optionally save them to `.env`.
47
+
48
+ **Run multiple instances:** Each project directory gets its own isolated bot session. Open multiple terminals and run `ctb` in different directories.
49
+
50
+ ### Install from Source
51
+
52
+ ```bash
53
+ git clone https://github.com/htlin/claude-telegram-bot
54
+ cd claude-telegram-bot
55
+
56
+ cp .env.example .env
57
+ # Edit .env with your credentials
58
+
59
+ bun install
60
+ bun run start
61
+ ```
62
+
63
+ ### Prerequisites
64
+
65
+ - **Bun 1.0+** - [Install Bun](https://bun.sh/)
66
+ - **Claude Agent SDK** - `@anthropic-ai/claude-agent-sdk` (installed via bun install)
67
+ - **Telegram Bot Token** from [@BotFather](https://t.me/BotFather)
68
+ - **OpenAI API Key** (optional, for voice transcription)
69
+
70
+ ### Claude Authentication
71
+
72
+ The bot uses the `@anthropic-ai/claude-agent-sdk` which supports two authentication methods:
73
+
74
+ | Method | Best For | Setup |
75
+ | -------------------------- | --------------------------------------- | --------------------------------- |
76
+ | **CLI Auth** (recommended) | High usage, cost-effective | Run `claude` once to authenticate |
77
+ | **API Key** | CI/CD, environments without Claude Code | Set `ANTHROPIC_API_KEY` in `.env` |
78
+
79
+ **CLI Auth** (recommended): The SDK automatically uses your Claude Code login. Just ensure you've run `claude` at least once and authenticated. This uses your Claude Code subscription which is much more cost-effective for heavy usage.
80
+
81
+ **API Key**: For environments where Claude Code isn't installed. Get a key from [console.anthropic.com](https://console.anthropic.com/) and add to `.env`:
82
+
83
+ ```bash
84
+ ANTHROPIC_API_KEY=sk-ant-api03-...
85
+ ```
86
+
87
+ Note: API usage is billed per token and can get expensive quickly for heavy use.
88
+
89
+ ## Configuration
90
+
91
+ ### 1. Create Your Bot
92
+
93
+ 1. Open [@BotFather](https://t.me/BotFather) on Telegram
94
+ 2. Send `/newbot` and follow the prompts to create your bot
95
+ 3. Copy the token (looks like `1234567890:ABC-DEF...`)
96
+
97
+ Then send `/setcommands` to BotFather and paste this:
98
+
99
+ ```
100
+ start - Show status and user ID
101
+ new - Start a fresh session
102
+ resume - Resume last session
103
+ stop - Interrupt current query
104
+ status - Check what Claude is doing
105
+ cd - Change working directory
106
+ bookmarks - Manage directory bookmarks
107
+ restart - Restart the bot
108
+ ```
109
+
110
+ ### 2. Configure Environment
111
+
112
+ Create `.env` with your settings:
113
+
114
+ ```bash
115
+ # Required
116
+ TELEGRAM_BOT_TOKEN=1234567890:ABC-DEF... # From @BotFather
117
+ TELEGRAM_ALLOWED_USERS=123456789 # Your Telegram user ID
118
+
119
+ # Recommended
120
+ CLAUDE_WORKING_DIR=/path/to/your/folder # Where Claude runs (loads CLAUDE.md, skills, MCP)
121
+ OPENAI_API_KEY=sk-... # For voice transcription
122
+ ```
123
+
124
+ **Finding your Telegram user ID:** Message [@userinfobot](https://t.me/userinfobot) on Telegram.
125
+
126
+ **File access paths:** By default, Claude can access:
127
+
128
+ - `CLAUDE_WORKING_DIR` (or home directory if not set)
129
+ - `~/Documents`, `~/Downloads`, `~/Desktop`
130
+ - `~/.claude` (for Claude Code plans and settings)
131
+
132
+ To customize, set `ALLOWED_PATHS` in `.env` (comma-separated). Note: this **overrides** all defaults, so include `~/.claude` if you want plan mode to work:
133
+
134
+ ```bash
135
+ ALLOWED_PATHS=/your/project,/other/path,~/.claude
136
+ ```
137
+
138
+ ### 3. Configure MCP Servers (Optional)
139
+
140
+ Copy and edit the MCP config:
141
+
142
+ ```bash
143
+ cp mcp-config.ts mcp-config.local.ts
144
+ # Edit mcp-config.local.ts with your MCP servers
145
+ ```
146
+
147
+ The bot includes a built-in `ask_user` MCP server that lets Claude present options as tappable inline keyboard buttons. Add your own MCP servers (Things, Notion, Typefully, etc.) to give Claude access to your tools.
148
+
149
+ ## Bot Commands
150
+
151
+ | Command | Description |
152
+ | ------------ | --------------------------------- |
153
+ | `/start` | Show status and your user ID |
154
+ | `/new` | Start a fresh session |
155
+ | `/resume` | Resume last session after restart |
156
+ | `/stop` | Interrupt current query |
157
+ | `/status` | Check what Claude is doing |
158
+ | `/cd <path>` | Change working directory |
159
+ | `/bookmarks` | Manage directory bookmarks |
160
+ | `/restart` | Restart the bot |
161
+
162
+ ### Directory Navigation
163
+
164
+ Use `/cd` and `/bookmarks` to quickly switch between project directories:
165
+
166
+ ```
167
+ /cd ~/projects/myapp # Change to directory, shows "Add to bookmarks" button
168
+ /cd # Show current working directory
169
+ /bookmarks # List saved bookmarks with navigation buttons
170
+ ```
171
+
172
+ Each bookmark shows two buttons:
173
+
174
+ - **🆕 Name** - Start a new session in that directory
175
+ - **🗑️** - Remove from bookmarks
176
+
177
+ ## Running as a Service (macOS)
178
+
179
+ ```bash
180
+ cp launchagent/com.claude-telegram-ts.plist.template ~/Library/LaunchAgents/com.claude-telegram-ts.plist
181
+ # Edit the plist with your paths and env vars
182
+ launchctl load ~/Library/LaunchAgents/com.claude-telegram-ts.plist
183
+ ```
184
+
185
+ The bot will start automatically on login and restart if it crashes.
186
+
187
+ **Prevent sleep:** To keep the bot running when your Mac is idle, go to **System Settings → Battery → Options** and enable **"Prevent automatic sleeping when the display is off"** (when on power adapter).
188
+
189
+ **Logs:**
190
+
191
+ ```bash
192
+ tail -f /tmp/claude-telegram-bot-ts.log # stdout
193
+ tail -f /tmp/claude-telegram-bot-ts.err # stderr
194
+ ```
195
+
196
+ **Shell aliases:** If running as a service, these aliases make it easy to manage the bot (add to `~/.zshrc` or `~/.bashrc`):
197
+
198
+ ```bash
199
+ alias cbot='launchctl list | grep com.claude-telegram-ts'
200
+ alias cbot-stop='launchctl bootout gui/$(id -u)/com.claude-telegram-ts 2>/dev/null && echo "Stopped"'
201
+ alias cbot-start='launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.claude-telegram-ts.plist 2>/dev/null && echo "Started"'
202
+ alias cbot-restart='launchctl kickstart -k gui/$(id -u)/com.claude-telegram-ts && echo "Restarted"'
203
+ alias cbot-logs='tail -f /tmp/claude-telegram-bot-ts.log'
204
+ ```
205
+
206
+ ## Development
207
+
208
+ ```bash
209
+ # Run with auto-reload
210
+ bun --watch run src/index.ts
211
+
212
+ # Type check
213
+ bun run typecheck
214
+
215
+ # Or directly
216
+ bun run --bun tsc --noEmit
217
+ ```
218
+
219
+ ## Security
220
+
221
+ > **⚠️ Important:** This bot runs Claude Code with **all permission prompts bypassed**. Claude can read, write, and execute commands without confirmation within the allowed paths. This is intentional for a seamless mobile experience, but you should understand the implications before deploying.
222
+
223
+ **→ [Read the full Security Model](SECURITY.md)** for details on how permissions work and what protections are in place.
224
+
225
+ Multiple layers protect against misuse:
226
+
227
+ 1. **User allowlist** - Only your Telegram IDs can use the bot
228
+ 2. **Intent classification** - AI filter blocks dangerous requests
229
+ 3. **Path validation** - File access restricted to `ALLOWED_PATHS`
230
+ 4. **Command safety** - Destructive patterns like `rm -rf /` are blocked
231
+ 5. **Rate limiting** - Prevents runaway usage
232
+ 6. **Audit logging** - All interactions logged to `/tmp/claude-telegram-audit.log`
233
+
234
+ ## Troubleshooting
235
+
236
+ **Bot doesn't respond**
237
+
238
+ - Verify your user ID is in `TELEGRAM_ALLOWED_USERS`
239
+ - Check the bot token is correct
240
+ - Look at logs: `tail -f /tmp/claude-telegram-bot-ts.err`
241
+ - Ensure the bot process is running
242
+
243
+ **Claude authentication issues**
244
+
245
+ - For CLI auth: run `claude` in terminal and verify you're logged in
246
+ - For API key: check `ANTHROPIC_API_KEY` is set and starts with `sk-ant-api03-`
247
+ - Verify the API key has credits at [console.anthropic.com](https://console.anthropic.com/)
248
+
249
+ **Voice messages fail**
250
+
251
+ - Ensure `OPENAI_API_KEY` is set in `.env`
252
+ - Verify the key is valid and has credits
253
+
254
+ **Claude can't access files**
255
+
256
+ - Check `CLAUDE_WORKING_DIR` points to an existing directory
257
+ - Verify `ALLOWED_PATHS` includes directories you want Claude to access
258
+ - Ensure the bot process has read/write permissions
259
+
260
+ **MCP tools not working**
261
+
262
+ - Verify `mcp-config.ts` exists and exports properly
263
+ - Check that MCP server dependencies are installed
264
+ - Look for MCP errors in the logs
265
+
266
+ ## License
267
+
268
+ MIT