Telegram as a fast remote frontend for local Codex Desktop on macOS.
This is not "another bot chat". The product shape is simple:
- Telegram folder
codex= the external Codex container. - One Telegram group = one Codex project.
- One Telegram topic = one Codex thread.
- Direct bot chat with private topics = Codex Desktop
Chats. - Codex Desktop stays the engine and source of truth.
The goal is a clean phone-sized working set, not a landfill mirror of every thread you have ever opened.
This is a working beta, not an official Codex or Telegram product.
The current version is intentionally local-first: macOS, local Codex.app, local Telegram bot/user session, local state files. The normal send path now uses Codex app-server on ws://127.0.0.1:27890, with app-control on http://127.0.0.1:9222 kept as an optional near-Desktop lane. That is the less crashy shape: Telegram starts turns through the backend protocol, while progress and final replies mirror back into Telegram.
Current v1 target: macOS with local Codex.app.
Open this repo in Codex and paste this into a fresh thread from the repo root:
Install codex-telegram-frontend on this Mac.
Run the documented onboarding path in this order: prepare local config from examples, guide me through the unavoidable Telegram steps, run the onboarding doctor, then run the quickstart onboarding path.
Do not ask me to paste bot tokens, Telegram API hashes, login codes or 2FA passwords into Codex chat. Use local terminal prompts, Keychain, ignored config files, browser/Telegram UI and phone/code login instead. QR login is only a fallback.
Keep interactive setup in one clear local terminal/input surface. Do not open extra Terminal windows via AppleScript just to collect prompts. If you cannot run an interactive command cleanly, stop and ask me to run the exact command from the repo root.
Create or reuse the Telegram folder `codex`, scan my pinned Codex threads first and then my latest active Codex project threads and Codex Chats, create one group per detected Codex project, create one topic per selected Codex project thread, map Codex Chats into private topics inside the bot direct chat, import about 10 clean messages into each topic, start the bridge, run a real Telegram smoke test, and leave the repo in a clean documented state.
Default to about 10 active threads total, with pinned Codex threads treated as the user's keep list. Do not ask me to choose projects unless the quickstart preview looks wrong. Keep Telegram as a clean remote Codex working set, not a landfill.
In your final install summary, include the live status, the normal app-server status, the optional app-control launch command, and the optional Codex Personalization offer from docs/ONBOARDING.md: Personality `Friendly` plus the Custom Instructions preset. Do not leave that buried in command output.
What still needs a human:
- Create or reuse a Telegram bot through @BotFather.
- Create or reuse Telegram app credentials at my.telegram.org/apps if the admin helper asks. These are
api_id/api_hashfor the user-side helper, not the bot token. - Authorize one local Telegram user session so the helper can create folders, groups and topics. Phone/code login is the normal path.
- Keep
Codex.appavailable. Normal path:
/Applications/Codex.app/Contents/MacOS/CodexIf you want the optional app-control lane too, launch with --remote-debugging-port=9222 or run npm run codex:launch from this repo.
Codex should handle local config, Keychain/env wiring, bootstrap, backfill and smoke. The human should click/type into local Telegram or one clearly explained terminal prompt, not dump secrets into the conversation transcript. If setup gets weird, use docs/ONBOARDING.md.
Optional polish after install: set Codex Personality to Friendly and use the ready Custom Instructions preset in docs/ONBOARDING.md. It is the OpenClaw-style "make the agent feel like a real teammate, not corporate fog" bit, and it changes the phone experience more than it has any right to.
This project is a frontend. It does not replace Codex.
- Preferred send path: Codex
app-serveronws://127.0.0.1:27890. - Optional Desktop-aware lane:
app-controlonhttp://127.0.0.1:9222, started with/Applications/Codex.app/Contents/MacOS/Codex --remote-debugging-port=9222ornpm run codex:launch. - The old app-server helper script is legacy fallback; the bridge now uses the shared app-server protocol client directly for Telegram-originated turns.
- If
Codex.appis closed or crashed, the bridge should say that plainly in Telegram.
Two modes matter: app-server is the normal calm lane for phone-originated turns; app-control is the live near-Mac lane when you specifically want Desktop renderer behavior. Default to app-server; switch nativeIngressTransport to app-control only if you are deliberately testing that UI path.
Voice notes are optional. The supported STT paths today are Deepgram, OpenAI, or a local command. Deepgram is the friendliest default for Telegram voice notes; OpenAI is handy if that key is already your normal local setup; local command is for people who like owning the whole stack.
- Telegram Bot API long polling for direct chats and forum topics.
- Bindings:
/attach,/attach-latest,/detach,/status. - Codex controls from Telegram:
/model,/thinkor/reasoning,/fast,/compact. - Ops:
/health,/settings,/project-status,/sync-project,/mode native. - Topic queues: normal messages wait behind a running turn;
/queue,/pause,/resume,/cancel-queue,/steer <text>and/cancelhandle the cockpit bits. - Telegram-menu-safe aliases:
/attach_latest,/project_status,/sync_project,/mode_native,/cancel_queue. - App-server send-only by default: Codex accepts the turn through
turn/start; Telegram gets live progress/final from app-server events, with the rollout mirror kept as reconciliation. - Codex approvals and "needs input" prompts bridge into Telegram: command/file/permission approvals get inline buttons, and user-input prompts can be answered by replying to the Telegram request.
- Live turn controls are app-server-native:
/steerusesturn/steer,/canceland/interruptuseturn/interrupt, so they do not need the Desktop renderer debug lane. - In-place progress bubble with live steps, Todo, changed files and final state.
- Native Telegram typing heartbeat while Codex is working.
- Reply-chain UX: final answers reply to the triggering user/surrogate message.
- Pinned compact status bar per active topic.
- Markdown-ish Telegram rendering: bold, italic, quotes, lists, code, links, tables and local file links.
- Codex Desktop-originated prompts and final answers mirrored into Telegram.
- Attachments: photos/documents, including media albums, are saved to ignored local storage and forwarded to Codex as file paths.
- Voice/audio: Telegram voice is transcribed first, shown as an italic quoted transcript, then sent to Codex as text.
- Clean bounded history backfill: user prompts plus assistant final answers by default.
- Quickstart onboarding: pinned Codex threads are included first, latest active Codex project threads become Telegram groups/topics, and existing Codex Chats become private topics inside the bot direct chat when the bot has Threaded Mode enabled.
- After onboarding, fresh existing Codex Desktop
Chatscan auto-sync into bot-private topics without rerunning the whole bootstrap. - New private bot topics are not auto-created as Desktop
Chatsby default. The app-serverthread/startpath is useful, but it does not yet behave exactly like pressingNew chatin Codex Desktop, so the safe default is explicit/attachinstead of fake magic. - Private bot topic preflight for Codex Desktop
Chats:npm run bot:topics. - Bootstrap can create/reuse Telegram folder, project groups, topics, bot folder entry, themed generated project group avatars and status bars.
- Optional curated topic auto-sync for fresh Codex threads in already bootstrapped project groups.
- Bot polish: generated group avatars, command menu, profile text, suggested admin rights and bundled bot avatar. Quickstart applies the bot avatar best-effort through the official Bot API;
npm run bot:avataris the manual retry. - Structured event log at
logs/bridge.events.ndjson;/healthsamples it. - Local state doctor for stale topic bindings, orphan mirror state and bootstrap-index drift.
- Cross-platform runtime. v1 is macOS plus local Codex Desktop.
- Official Codex integration. This uses local Desktop app-server/app-control surfaces that can change.
- Raw token-by-token Telegram streaming. Current progress is coalesced into readable bubbles on purpose.
- Rich voice controls such as provider picker, live partial transcripts or confidence display.
- Dedicated ops topic/router for noisy admin flows.
Install/development preflight, in order:
npm run onboard:prepare
npm run onboard:doctorGuided setup:
npm run onboard:quickstart
npm run onboard:wizard
npm run onboard:wizard:rehearsalRun the bridge:
cd /path/to/codex-telegram-frontend
npm startnpm run codex:launch is optional. Use it only when you want the app-control debug lane available too.
Self-check and full check:
npm run self-check
npm run state:doctor
npm run checkRecent bridge events:
npm run events
npm run events -- --jsonBot polish:
npm run bot:polish
npm run bot:polish -- --apply
npm run bot:topics
npm run bot:avatarRefresh existing project group avatars from the current bootstrap index:
npm run group:avatarsLow-level app-server probe for creating a Codex Chat without touching Telegram:
npm run app-server:start-chat -- --title "Scratch idea"Install or refresh launchd:
./ops/install-launchd.shCopy config.example.json to config.local.json. The local file is ignored by git.
Secrets can come from env, local config or macOS Keychain:
- bot token:
CODEX_TELEGRAM_BOT_TOKENor Keychain servicecodex-telegram-bridge-bot-token - Deepgram STT:
DEEPGRAM_API_KEYorcodex-telegram-bridge-deepgram-api-key - OpenAI STT:
OPENAI_API_KEYorcodex-telegram-bridge-openai-api-key - local STT:
voiceTranscriptionCommandinconfig.local.json - Telegram user helper:
admin/.envwithAPI_IDandAPI_HASH
Full config map: docs/CONFIGURATION.md.
These are local runtime files and should not be committed:
config.local.jsonstate/state.jsonstate/bootstrap-result.jsonstate/telegram_user.sessionstate/attachments/logs/*admin/.envadmin/.venv/admin/bootstrap-plan.jsonadmin/bootstrap-plan.rehearsal.json
state/ is local memory for the bridge, not repo content.
- docs/ARCHITECTURE.md - how the bridge is shaped and where refactors should go
- bridge.mjs - thin polling bridge and top-level loop
- lib/inbound-turn-runner.mjs - Telegram-originated Codex turn orchestration
- lib/telegram.mjs - Telegram Bot API helpers
- lib/codex-native.mjs - Codex send wrapper: app-server first, optional app-control lane
- lib/command-handlers.mjs - Telegram slash-command routing
- lib/binding-send-validation.mjs - pre-send binding safety checks and archived-thread rescue
- lib/unbound-group-rescue.mjs - General/All message rescue into the active topic
- lib/voice-transcription.mjs - Telegram voice/audio STT
- lib/health-report.mjs -
/statusand/healthtext shaping - lib/project-sync-runner.mjs - project topic status/sync orchestration
- lib/outbound-mirror-runner.mjs - Codex rollout reconciliation/backfill loop
- lib/outbound-memory.mjs - remembered Telegram message ids and mirror suppression helpers
- lib/outbound-progress.mjs - Telegram progress bubble content
- lib/outbound-progress-message.mjs - progress bubble send/edit state
- lib/app-server-stream-runner.mjs - app-server event stream bridge for live progress, final replies, approvals and generated images
- lib/worktree-summary.mjs - changed-file summaries and turn baselines
- lib/status-bar-runner.mjs - pinned topic status refresh loop
- lib/typing-heartbeat-runner.mjs - native Telegram "typing" loop for active turns
- lib/state-doctor.mjs - local state/index drift inspection and safe repairs
- scripts/onboard.mjs - onboarding scan/plan/wizard
- scripts/state_doctor.mjs - CLI for local state repair previews
- admin/telegram_user_admin.py - Telethon admin helper for folders/groups/topics
- docs/ONBOARDING.md - setup flow
- docs/RUNBOOK.md - operations and recovery
- docs/TRANSPORT_RESEARCH.md - app-server/hooks/Telegram research notes
- BACKLOG.md - product backlog
Keep Telegram close to Codex Desktop:
- curated project groups
- curated topic working set
- visible progress and status
- minimal ops noise
- no infinite historical dump
That is the v1. Everything else is how a useful tool slowly turns into a swamp.
MIT. Use it, fork it, make it better. Just keep the license notice.