Proposal: Telegram remote-control integration
Why
The existing remote-access capability (openspec/specs/remote-access/spec.md) lets users see their agents on a phone, but requires:
- Phone and desktop on the same LAN, or sharing a Tailscale tailnet
- A browser session held open to receive any updates
It cannot:
- Deliver a push notification when an agent stops to ask a question
- Wake the user when an agent crashes overnight
- Work on networks where LAN/Tailscale isn't an option (mobile data, locked corporate WiFi, café hotspots)
A Telegram bot solves all three: Telegram's relay reaches the desktop from any network, and Telegram delivers native push notifications.
What
Opt-in telegram-control capability covering:
- Bot lifecycle on top of Electron
safeStorage (OS keychain — macOS Keychain / libsecret on Linux). Refuses to save when keychain unavailable.
- Per-project opt-in (
telegramOptIn); master toggle + token alone are not enough.
- Commands:
/start, /help, /agents, /status <id>, /tail <id>, /input <id> <text>, /focus <id>, /audit, /commands, plus codebase-integration commands /steps, /ci, /cov, /run <bookmark>, /ask.
- Inline transcript replies with backpressure pause/resume so live-tail can't run away from Telegram rate limits.
- Mini App initData HMAC verification — opening the existing remote SPA inside Telegram authenticates automatically; QR + token path stays untouched.
- Optional cloudflared auto-tunnel for users without their own public URL.
- Voice prompt → text via OpenAI Whisper (opt-in, separately gated).
- File-upload-to-path: drop a file into the chat → bot writes it into a configured path and signals the agent.
- Audit log of every accepted command.
- 949-line capability spec under
openspec/changes/add-telegram-control/; openspec validate --all --strict passes (10/10).
Scope numbers
- 61 files changed, +9785 / -19
- 5 new IPC channels behind
IPC enum + ALLOWED_CHANNELS allowlist
- 1 new parallel subscriber surface on
electron/ipc/pty.ts (existing renderer Exit event unchanged)
persistenceVersion bumped to 2 with backward-compat read of v1 snapshots
Security posture
- Bot token + Whisper key stored only under
<userData>/telegram-*.bin mode 0o600, encrypted via safeStorage. Renderer never sees either credential.
- Chat allowlist enforced on every command, not just
/start.
- Mini App initData verified by HMAC with 60s
auth_date window and timingSafeEqual against the embedded hash; tampered or expired payloads rejected.
- Per-pattern redaction filter applied before any chat-side write.
- Tunnel is opt-in and points only at the existing remote-access HTTP server.
Questions before I send a PR
- Acceptance. Does this fit the project's direction, or would you rather see it as an out-of-tree plugin / fork?
- PR shape. The branch was developed as three slices (bot lifecycle + commands → live-tail + notifications → Mini App + tunnel + voice + uploads). I squashed for cleanliness, but I can re-split into a stacked series if you prefer reviewing slice by slice.
- Optional deps. Voice transcription pulls in the OpenAI Whisper SDK; the auto-tunnel shells out to
cloudflared. Both are opt-in and gated behind explicit settings — let me know if you'd rather they be optional peer deps, dynamic imports, or removed entirely.
- OpenSpec. I added an
openspec/changes/add-telegram-control/ proposal + tasks + spec following the existing pattern. Happy to relocate or reshape if the layout doesn't match your conventions.
If this is interesting, I have a clean branch ready to push and a PR description drafted. Otherwise no hard feelings — I'll keep it on my fork.
— truongducthang/parallel-code, branch telegram-control-clean
Proposal: Telegram remote-control integration
Why
The existing remote-access capability (
openspec/specs/remote-access/spec.md) lets users see their agents on a phone, but requires:It cannot:
A Telegram bot solves all three: Telegram's relay reaches the desktop from any network, and Telegram delivers native push notifications.
What
Opt-in
telegram-controlcapability covering:safeStorage(OS keychain — macOS Keychain / libsecret on Linux). Refuses to save when keychain unavailable.telegramOptIn); master toggle + token alone are not enough./start,/help,/agents,/status <id>,/tail <id>,/input <id> <text>,/focus <id>,/audit,/commands, plus codebase-integration commands/steps,/ci,/cov,/run <bookmark>,/ask.openspec/changes/add-telegram-control/;openspec validate --all --strictpasses (10/10).Scope numbers
IPCenum +ALLOWED_CHANNELSallowlistelectron/ipc/pty.ts(existing rendererExitevent unchanged)persistenceVersionbumped to2with backward-compat read of v1 snapshotsSecurity posture
<userData>/telegram-*.binmode0o600, encrypted viasafeStorage. Renderer never sees either credential./start.auth_datewindow andtimingSafeEqualagainst the embedded hash; tampered or expired payloads rejected.Questions before I send a PR
cloudflared. Both are opt-in and gated behind explicit settings — let me know if you'd rather they be optional peer deps, dynamic imports, or removed entirely.openspec/changes/add-telegram-control/proposal + tasks + spec following the existing pattern. Happy to relocate or reshape if the layout doesn't match your conventions.If this is interesting, I have a clean branch ready to push and a PR description drafted. Otherwise no hard feelings — I'll keep it on my fork.
—
truongducthang/parallel-code, branchtelegram-control-clean