Architecture
Components
┌─────────────────────────────┐ ┌──────────────────────┐ ┌────────────────────┐
│ Your Mac │ │ Relay │ │ Telegram Mini App │
│ │ │ │ │ │
│ Teleportus daemon │ │ │ │ │
│ ├── screen capture │ WS │ ├── session router │ WS │ ├── WebSocket │
│ ├── input controller │────►│ ├── frame fanout │────►│ ├── JPEG renderer │
│ ├── audio capture / play │◄────│ └── auth check │◄────│ └── input events │
│ ├── camera capture │ │ │ │ │
│ ├── voice transcriber │ └──────────────────────┘ └────────────────────┘
│ └── AI task runner │
└─────────────────────────────┘Daemon
The daemon is a Node.js/Bun process that runs on your Mac.
Screen capture — spawns a precompiled Swift binary that uses ScreenCaptureKit to grab a JPEG of the main display. The binary is compiled on first launch using the system swiftc compiler. Capture is skipped while no viewers are connected.
Input controller — dispatches mouse clicks, mouse moves, keyboard events, and scroll wheel events. Text input uses the clipboard + Cmd+V to support arbitrary Unicode without key code mapping.
Audio — two native Swift binaries capture system audio (output) and play microphone audio (input). Both are universal binaries (arm64 + x86_64).
Camera — a third Swift binary streams the default camera via AVFoundation. Camera frames are never forwarded to view-only share guests.
Voice transcription — audio from the Mini App is transcribed locally using Whisper, a small voice model built into the daemon that runs right on your Mac. No audio leaves the machine for transcription.
AI runner — receives natural-language instructions from the bot and executes them as multi-step actions using Claude. The AI has access to the screen capture, the input controller, and a shell runner.
Relay
The relay runs as a long-running HTTP/WebSocket server, deployable to any host that supports WebSockets.
WebSocket router — manages one room per SESSION_TOKEN. Both the daemon and the Mini App connect to the same room by token. The relay never interprets frames — it buffers the last frame and fans it out to connected viewers.
Authentication — Mini App connections present Telegram's signed login data. The relay verifies its signature to confirm the viewer is a real Telegram user. Share guests are verified separately by their share token.
Frame caching — the last frame per room is cached in memory so new viewers get an instant picture without waiting for the next capture tick.
Daemon staleness — if a daemon's WebSocket goes silent for 45 seconds, its slot is considered stale and the next registration takes over. This handles sleep/wake cycles gracefully.
Mini App
The Mini App is served as a Telegram Web App. It:
- Opens a WebSocket to the relay using the session URL parameters
- Renders incoming JPEG frames
- Translates touch events to input messages (click, scroll, key, type)
- Handles the screen/camera toggle by switching the visual source
- Records microphone audio and sends it to the daemon via the relay
Data flow
capture tick (every 1/FPS seconds)
daemon → JPEG binary frame → relay → broadcast to all room clients
user tap on Mini App
Mini App → JSON input msg → relay → daemon → input dispatch
voice message
Mini App → audio blob → relay → daemon → Whisper → text
→ same as typing the transcription
AI task (text to bot)
Telegram bot → relay → daemon → AI task runner
→ screen caps + input actions as side effectsSecurity model
- Every Mini App connection is verified by Telegram's signed login data — no anonymous access
- Share guests get a separate token; they are forwarded screen frames only
- Camera frames are never sent to share guests
- The relay stores no frames on disk — only last-frame in memory, evicted when room is empty
- Session tokens are randomly generated per-user; invalidated on
/revoke