返回 CodeWhale
README.md
1 # Telegram Bridge
2
3 This bridge lets a Telegram chat control a local `codewhale serve --http`
4 runtime from a phone. It uses Telegram Bot API long polling, so the first
5 version does not need a public webhook URL or inbound port.
6
7 Security model:
8
9 - `codewhale serve --http` stays bound to `127.0.0.1`.
10 - `/v1/*` runtime calls use `CODEWHALE_RUNTIME_TOKEN`. Legacy
11 `DEEPSEEK_RUNTIME_TOKEN` is accepted only as a compatibility fallback.
12 - Telegram chats must be allowlisted unless `TELEGRAM_ALLOW_UNLISTED=true` is
13 set for first pairing.
14 - Direct messages are the intended MVP control surface. Group chat control is
15 disabled unless `TELEGRAM_ALLOW_GROUPS=true`.
16 - Tool approvals are text commands: `/allow <approval_id>` or `/deny <approval_id>`.
17 - The bridge also sends inline button controls for common actions. Text
18 commands remain the fallback.
19
20 ## Setup
21
22 Create a bot with Telegram's `@BotFather`, then configure the bridge:
23
24 ```bash
25 cd /opt/codewhale/telegram-bridge
26 npm install --omit=dev
27 cp .env.example /etc/codewhale/telegram-bridge.env
28 sudoedit /etc/codewhale/telegram-bridge.env
29 node src/index.mjs
30 ```
31
32 Validate env files before starting the service:
33
34 ```bash
35 npm run validate:config -- \
36 --env /etc/codewhale/telegram-bridge.env \
37 --runtime-env /etc/codewhale/runtime.env \
38 --workspace-root /opt/whalebro \
39 --check-filesystem
40 ```
41
42 For first pairing, temporarily set `TELEGRAM_ALLOW_UNLISTED=true`, send the bot
43 `/status`, copy the returned `chat_id` or `user_id` into
44 `TELEGRAM_CHAT_ALLOWLIST`, then turn `TELEGRAM_ALLOW_UNLISTED=false`.
45
46 ## Commands
47
48 - `/menu`
49 - `/status`
50 - `/threads`
51 - `/new`
52 - `/resume <thread_id>`
53 - `/model <name|default>`
54 - `/interrupt`
55 - `/compact`
56 - `/allow <approval_id> [remember]`
57 - `/deny <approval_id>`
58
59 Anything else is sent as a prompt. If group control is explicitly enabled,
60 messages must start with `/cw` by default, for example:
61
62 ```text
63 /cw check git status and tell me what is dirty
64 ```
65
66 The `/menu`, `/status`, `/threads`, active-turn, and approval messages include
67 tap targets for common actions. Approval buttons map to the same runtime API as
68 `/allow` and `/deny`; they do not enable blanket auto-approval unless you tap
69 the explicit "Allow + remember" button.
70
71
72 ## Restart access checks
73
74 Recovered deliveries require a saved, previously admitted sender identity that
75 still matches the current allowlist and group policy. Removing access and
76 restarting the bridge also stops recovery messages to that chat. Legacy state
77 without this identity stays detached; it does not cancel the runtime turn.
78 Use an authorized chat to inspect or interrupt that turn. A fresh admitted
79 message records identity for subsequent restart recovery. Keep allow-unlisted
80 mode off when operating with private workspace or runtime data.
81
81 lines MARKDOWN