Архитектура
Компоненты
┌─────────────────────────────┐ ┌──────────────────────┐ ┌────────────────────┐
│ Ваш Mac │ │ Релей │ │ Telegram Mini App │
│ │ │ │ │ │
│ Демон Teleportus │ │ │ │ │
│ ├── захват экрана │ WS │ ├── session router │ WS │ ├── WebSocket │
│ ├── контроллер ввода │────►│ ├── рассылка кадров │────►│ ├── JPEG-рендеринг │
│ ├── захват / вывод аудио │◄────│ └── проверка входа │◄────│ └── события ввода │
│ ├── захват камеры │ │ │ │ │
│ ├── расшифровка голоса │ └──────────────────────┘ └────────────────────┘
│ └── AI-раннер │
└─────────────────────────────┘Демон
Демон — Node.js/Bun-процесс на вашем Mac.
Захват экрана — порождает предкомпилированный Swift-бинарник, который использует ScreenCaptureKit для захвата JPEG основного дисплея. Бинарник компилируется при первом запуске через системный swiftc. Захват приостанавливается пока нет подключённых зрителей.
Контроллер ввода — отправляет клики мышью, движения, нажатия клавиш и прокрутку. Текстовый ввод реализован через буфер обмена + Cmd+V — поддерживается любой Unicode без перемаппинга кодов.
Аудио — два нативных Swift-бинарника захватывают системный звук (выход) и воспроизводят аудио с микрофона (вход). Оба universal binary (arm64 + x86_64).
Камера — третий Swift-бинарник стримит дефолтную камеру через AVFoundation. Кадры с камеры никогда не пересылаются гостям шеринга.
Расшифровка голоса — аудио из Mini App расшифровывается локально через Whisper — небольшую голосовую модель, встроенную в демон и работающую прямо на вашем Mac. Аудио никуда не уходит для обработки.
AI-раннер — принимает инструкции на естественном языке от бота и выполняет их как многошаговые действия через Claude. AI имеет доступ к захвату экрана, контроллеру ввода и шелл-раннеру.
Релей
Релей работает как HTTP/WebSocket-сервер и разворачивается на любом хостинге с поддержкой WebSocket.
WebSocket-роутер — управляет одной комнатой на SESSION_TOKEN. Демон и Mini App подключаются к одной комнате по токену. Релей не интерпретирует кадры — он буферизует последний кадр и рассылает всем.
Авторизация — Mini App-подключения передают подписанные данные входа Telegram. Релей проверяет подпись, подтверждая что зритель — реальный пользователь Telegram. Гости шеринга проверяются отдельно через share-токен.
Кеш кадра — последний кадр каждой комнаты кешируется в памяти, чтобы новые зрители мгновенно получали картинку без ожидания следующего тика.
Устаревание демона — если WebSocket демона молчит 45 секунд, слот считается устаревшим и следующая регистрация его вытесняет. Это корректно обрабатывает циклы сна/пробуждения Mac.
Mini App
Mini App отдаётся как Telegram Web App:
- Открывает WebSocket на релей через параметры URL сессии
- Рендерит входящие JPEG-кадры
- Переводит touch-события в input-сообщения (click, scroll, key, type)
- Обрабатывает переключение экран/камера сменой источника
- Записывает аудио микрофона и отправляет в демон через релей
Поток данных
тик захвата (каждые 1/FPS секунд)
демон → бинарный JPEG-кадр → релей → broadcast всем клиентам комнаты
тап пользователя в Mini App
Mini App → JSON input msg → релей → демон → диспатч ввода
голосовое сообщение
Mini App → audio blob → релей → демон → Whisper → текст
→ обрабатывается как текстовый ввод
AI-задача (текст боту)
Telegram бот → релей → демон → AI-раннер
→ захват экрана + действия ввода как побочные эффектыМодель безопасности
- Каждое Mini App-подключение проверяется по подписанным данным входа Telegram — анонимного доступа нет
- Гости шеринга получают отдельный токен; им пересылаются только кадры экрана
- Кадры камеры никогда не отправляются гостям шеринга
- Релей не хранит кадры на диске — только последний кадр в памяти, вытесняется когда комната пустеет
- Session-токены генерируются рандомно для каждого пользователя; инвалидируются по
/revoke