Leave your desk, keep your Codex session alive, and reply from your phone.
Pocket Operator is now the product name and the primary repository name. The legacy Python import path telegram_codex_controller remains temporarily supported for compatibility, while the forward-looking module path is pocket_operator.
It turns Telegram into a practical mobile console for Codex and other terminal-based agents running on your own machine. The core use case is simple:
you start a Codex session on your computer, step away from your desk, and still want to monitor it, answer it, continue it, and recover it from your phone.
This is not a raw stdout mirror. It gives you:
- one editable session card instead of endless log spam
- direct reply routing back into the exact running session
INDEX + ALERTS + one topic per sessionwhen you need a full mobile console
Dogfooding proof: the project itself was developed entirely over Telegram from a phone.
Start here:
- 3-minute fast demo
- 15-minute full console
- Quick deployment
- Security model
- 30-second demo script
- Demo session script
- Use case: overnight build watcher
- Use case: mobile research monitor
- Use case: multi-agent operations console
Screenshots:
Most remote-development tools assume you want a full remote shell. That is not the problem this project solves.
The problem is narrower and more common:
- you already have a valuable local Codex session running
- you leave your desk
- the session keeps working, blocks on human input, or needs a follow-up instruction
- you want to handle that from your phone without losing the original session context
That is the product:
- keep the existing session
- see the current state clearly
- send the next instruction from Telegram
- continue the same line of work without reopening everything
| Option | Works well for | Friction on a phone | Why Pocket Operator exists |
|---|---|---|---|
| SSH | full terminal control | too much raw output, weak prioritization, awkward on mobile | Pocket Operator is optimized for session status and intervention, not full shell work |
| Remote desktop | visual access to the exact desktop | clumsy on mobile, too much UI overhead | Pocket Operator gives you a purpose-built mobile control surface |
| Pocket Operator | continuing a running Codex session | narrower scope than a full shell by design | that narrower scope is what makes it fast and usable on a phone |
The main use case is existing-session takeover, but the project also supports:
- New long-running jobs
Start named
tmuxtasks from Telegram and keep them alive independently of your current shell. - SDK-backed sessions Start and continue Codex or Claude SDK sessions through the sidecar runner.
- Multi-session operations Run a Telegram supergroup as a compact multi-agent control console with one topic per session.
If you already run Codex, Claude, research scripts, or builds locally, the hardest part usually starts after launch:
- you lose visibility as soon as you leave the machine
- multiple sessions become hard to distinguish on a phone
- a task pauses for input and you do not notice in time
- the fallback is reading noisy terminal output with no hierarchy
This project turns that into a cleaner mobile workflow:
- Clear status: one session card per workflow
- Clear priority:
INDEXfor overview,ALERTSfor intervention - Low noise: cards are edited in place
- Direct intervention: respond from Telegram without recreating the session
- Preserved context: keep the exact local session that is already doing useful work
- you run multiple Codex, Claude, or research-agent sessions at the same time
- you have long jobs that may require login, approval, or a short human reply
- you already have valuable local terminal state and do not want to migrate all of it
- you want overnight or weekend monitoring from your phone
- you want to package agent operations as a usable product, not a pile of personal scripts
- track many sessions in parallel
- support three session sources:
tmux, existingTerminal.appwindows, and SDK sessions - keep separate status, summary, log access, and reply routing per session
π’ running: active and healthyπ‘ waiting: waiting for human input, login, approval, or confirmationπ΄ error: failed or detected as abnormalβ done: completedβ« stopped: intentionally stopped or no longer presentβͺ idle: ready but inactive
- one editable
INDEXcard for the whole console - one
ALERTSstream or topic for waiting, error, done, and stuck states - one topic per session for detailed inspection and direct interaction
- coalesced card updates to reduce Telegram noise
- full logs exported as documents when needed
/codexto start new Codex CLI work/runto launch long-runningtmuxtasks/agent_*to manage SDK-backed Codex or Claude sessions/mirrorto attach existingTerminal.appCodex windows/focusto bring the corresponding Terminal tab to the foreground/send, reply-to-card, or topic message routing to push input back into the right session
- persistent aliases for
ttysNNNsessions, for examplesession-alpha - topic titles that follow current state, such as
π’ session-alphaorπ΄ mobile-layout INDEXordering that highlights error and waiting states first- compact summaries optimized for small screens
- restrict access with
AUTHORIZED_USER_IDS - keep
/shelldisabled by default - export logs without exposing a full remote shell workflow
- suitable for private developer machines or controlled internal environments
The best product shape is:
- one Telegram supergroup
- Topics / Forum enabled
- one
INDEXtopic - one
ALERTStopic - one topic per session, agent, or tracked window
A Telegram supergroup is not a separate app. It is Telegramβs larger group type. When Topics are enabled, the group behaves like a multi-page control console.
Recommended topic layout:
INDEXALERTSBUILD-2 | parser-upgradeRESEARCH-1 | retrieval-notesFIX-3 | mobile-layout
Daily phone workflow:
- Open
INDEXfor the global view. - Check
ALERTSfor anything that needs action now. - Enter a specific session topic for current summary, logs, and controls.
- When a human reply is needed, either reply to the session card or send text directly in that topic.
If you want plain text sent directly inside a topic to be routed back to the session, disable the botβs group privacy mode in @BotFather. If privacy mode stays enabled, reply-to-card and /send still work, but plain topic text may not be delivered to the bot.
Phone (Telegram)
β
βΌ
Telegram Bot
β
βΌ
Command Router
β
βββ Telegram console manager
β βββ editable session cards
β βββ INDEX summary
β βββ ALERTS topic/feed
β βββ optional forum topics
βββ SDK assistant runner
βββ Terminal mirror watcher
βββ Codex CLI task launcher
βββ Optional shell runner
βββ tmux session manager
β
βΌ
tmux sessions
The sections above describe the product. This section covers the operating surface you use in Telegram.
/startβ show help/helpβ show help/pingβ health check/forum_onβ enable forum/topic mode for the current console chat/forum_offβ disable forum/topic mode for the current console chat/forum_bootstrapβ create INDEX, ALERTS, and topics for current sessions/index_hereβ bind the current chat/topic as INDEX/alerts_hereβ bind the current chat/topic as ALERTS/open <session>β bind a tracked session to the current topic and refresh its status card/focus <mirror-session>β bring an existing Terminal Codex tab to the front/topic_create <session> [topic name]β create and bind a forum topic for a session/send <session> <text>β send text directly to a mirror/tmux/agent session/find <session> <pattern>β search recent logs/transcript/history/recent_errors [limit]β show recent error/waiting sessions/sessionsβ list tracked sessions/run <name> <command...>β start a named task in tmux/codex <name> <prompt...>β start a Codex task using the configured Codex command template/logs <session>β export full tmux logs, mirror history, or assistant transcripts, usually as a.logdocument/tail <session> [lines]β return a short on-demand summary instead of starting a stream/stop <name>β stop a session/shell <command...>β run a shell command when enabled/agentsβ list tracked SDK-backed Codex or Claude sessions/agent_new <assistant> <name> [cwd]β create a named SDK session/agent <name> <prompt...>β continue a named SDK session/agent_log <name>β show recent transcript for a named SDK session/agent_cwd <name> <cwd>β change SDK session working directory and clear resume state/agent_stop <name>β delete a tracked SDK session/mirror [status|on|off|snapshot [tty-or-alias]|alias <tty-or-alias> <alias>|unalias <tty-or-alias>|aliases]β manage Terminal mirroring/mirrorsβ alias for/mirror- Reply to a status card or routed event, or just send a plain text message inside that session topic β automatically send text back to the mirrored Terminal tab, tmux session, or SDK assistant session
Status cards now include inline keyboard actions for the most common flows:
ContinueRefreshRecentFocusfor mirrored Terminal sessionsStopfor tmux and SDK assistant sessions
Examples:
/run research codex exec "Analyze parser edge cases"
/codex ontology Build an ontology plan for repository structure
/agent_new codex triage ./workspace
/agent triage "Summarize the repo structure"
/agent_log triage
/forum_on
/forum_bootstrap
/index_here
/alerts_here
/open triage
/topic_create triage
/send session-alpha Reply with the single word ok.
/focus session-alpha
/mirror alias ttys003 ocna-vpn
/mirror snapshot ocna-vpn
/open ocna-vpn
/find ocna-vpn yubikey
/recent_errors
/mirror snapshot
/mirrors
/logs ontology
/tail ontology
/stop ontology
/sessionsRecommended mobile flow:
- Watch the editable
INDEXmessage for overall state. - Use the
INDEXbuttons to refresh the overview, surface recent errors, or open a specific session. - Watch
ALERTSfor errors, waiting-for-human-input, completion, and stuck sessions. - Use the inline buttons on a session card for continue, refresh, recent output, focus, and stop.
- Reply directly to that session card, or type inside that session topic, when you need to send text back into the session.
The bot also registers high-frequency commands through setMyCommands, so they appear directly in Telegramβs command picker.
Mirror sessions keep the real ttysNNN routing key internally, but you can attach a persistent alias like ocna-vpn so status cards, topics, and alerts are easier to recognize.
This repository supports two release paths:
- Push a version tag from your machine:
git tag v0.1.0
git push origin v0.1.0- Run the
Releaseworkflow manually from the GitHub Actions UI and provide:- a tag such as
v0.1.0 - an optional target ref such as
mainor a commit SHA - an optional custom title
- optional release notes
- a tag such as
If notes are left empty, GitHub release notes are generated automatically.
- Python 3.11+
- Node.js 20+
tmux- a Telegram bot token created through
@BotFather - your Telegram numeric user id for authorization
- Codex CLI installed locally if you want
/codex - macOS
Terminal.appif you want to mirror existing local windows - a Telegram supergroup with Topics enabled if you want the recommended one-topic-per-session layout
Choose one of these paths:
- 3-minute fast demo if you want to prove the core value quickly
- 15-minute full console if you want the complete
INDEX + ALERTS + topicsworkflow
If you want the shortest possible path to the core experience, do this:
- Run:
./scripts/install.sh
./scripts/doctor.sh-
Edit
.envand set:TELEGRAM_BOT_TOKENAUTHORIZED_USER_IDS
-
Start the controller:
./scripts/run_service.sh- In
Terminal.app, run the deterministic demo session:
./scripts/demo_phone_takeover.sh- Open Telegram, talk to the bot, and route a reply back into that same terminal session.
This is the fastest way to prove the core promise:
the same local session keeps going after you leave the desk.
If you want the full product shape instead of a quick trial:
- create a private Telegram supergroup
- enable Topics / Forum
- add the bot
- run
/forum_on - run
/forum_bootstrap - use
INDEX,ALERTS, and one topic per session
This is the mode to use when you want:
- multiple concurrent sessions
- better mobile information hierarchy
- ongoing operations, not just a one-off demo
These steps are written for first-time setup with the recommended product shape:
- the controller runs on your computer
- Telegram on your phone is the operator interface
- one supergroup hosts the full console
INDEX + ALERTS + one topic per sessionis the default layout
The recommended shape is not a one-on-one bot chat. It is:
- one Telegram supergroup
- Topics / Forum enabled
- the bot added to that supergroup
INDEX,ALERTS, and session topics living inside the group
If you only want a fast local trial, you can start with a direct bot chat. For long-term use, multi-session visibility, and cleaner mobile navigation, supergroup + topics is the better shape.
- Open
@BotFatherin Telegram - Send
/newbot - Follow the prompts for bot name and username
- Save the returned bot token
You will place this token in .env as TELEGRAM_BOT_TOKEN.
If you want plain text typed directly inside a session topic to be routed back to that session, disable the botβs group privacy mode:
- Open
@BotFather - Send
/setprivacy - Select your bot
- Choose
Disable
Behavior difference:
- Privacy disabled: plain text sent inside a session topic can route back to the session
- Privacy enabled:
/sendand reply-to-card still work, but plain topic text may not reach the bot
- Create a new Telegram group
- Convert or configure it as a supergroup
- Enable
Topics/Forum - Add your bot to the group
- Prefer granting the bot these admin capabilities:
Manage TopicsPin MessagesDelete Messages
Without topic-management permissions, /forum_bootstrap, automatic topic creation, and message maintenance features may fail.
Open @userinfobot and record your numeric Telegram user id.
You will place it in .env as AUTHORIZED_USER_IDS.
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
(cd sidecar && npm install)Install tmux:
macOS:
brew install tmuxUbuntu / Debian:
sudo apt-get update
sudo apt-get install -y tmuxcp .env.example .envMinimum working configuration:
TELEGRAM_BOT_TOKEN=your_bot_token_here
AUTHORIZED_USER_IDS=123456789
MIRROR_CHAT_IDS=123456789Recommended product-style configuration:
TELEGRAM_BOT_TOKEN=your_bot_token_here
AUTHORIZED_USER_IDS=123456789
MIRROR_CHAT_IDS=123456789
MIRROR_ENABLED=true
CODEX_COMMAND_TEMPLATE=codex exec "{prompt}"
CONSOLE_FORUM_ENABLED=true
CONSOLE_AUTO_CREATE_TOPICS=true
CONSOLE_SEND_LOG_DOCUMENTS=true
CONSOLE_TOPIC_BUMP_ENABLED=true
CONSOLE_STATUS_SUMMARY_LINES=15
CONSOLE_RUNNING_UPDATE_MIN_INTERVAL_SECONDS=12
CONSOLE_GLOBAL_WRITE_SPACING_SECONDS=2Deployment notes:
CONSOLE_CHAT_IDcan be left empty for the first boot After startup, run/forum_onin the target supergroup and the controller will remember that chat as the main consoleCONSOLE_INDEX_TOPIC_IDandCONSOLE_ALERTS_TOPIC_IDcan also be left empty They can be created automatically during bootstrap or bound later with/index_hereand/alerts_here- If you are the only operator,
MIRROR_CHAT_IDSusually only needs your own user id
If you want the shortest setup path:
./scripts/install.sh
./scripts/doctor.sh
./scripts/bootstrap.shRun in the foreground:
PYTHONPATH=src python -m pocket_operator.mainOr use the helper script:
./scripts/run.shIf dependencies are already installed, the lightweight long-running entrypoint is:
./scripts/run_service.shFor macOS background execution, see docs/launchd.plist.example.
After the service is running, use this order:
- Open a direct chat with the bot and send
/startThis confirms the bot is online and yourAUTHORIZED_USER_IDSsetting is correct - Enter your supergroup
- Send
/forum_on - Send
/forum_bootstrap
After that, the recommended result is:
- one
INDEXtopic - one
ALERTStopic - one topic per currently known session
If you want to bind things manually:
- enter the
INDEXtopic and run/index_here - enter the
ALERTStopic and run/alerts_here - enter any session topic and run
/open <session>
Recommended smoke test:
- Make sure you already have a Codex window on the computer, or run:
/codex demo Explain this repo- In the supergroup, run:
/forum_bootstrap-
Confirm that your phone shows:
INDEXALERTS- a
demotopic, or a topic for the mirrored session
-
Enter that session topic and try both input paths:
- reply to the status card
- send a plain text message directly in the topic
-
If the target terminal receives the input, reply routing is working
If privacy mode is still enabled, the plain topic message in step 4 may not work. That is a Telegram limitation, not a controller bug.
After deployment, these are usually the most useful commands:
/forum_on/forum_bootstrap/open <session>/mirror on/mirror alias <tty> <alias>/send <session> <text>/tail <session>/logs <session>/recent_errors
For daily use, think of the Telegram workspace like this:
INDEX: control overviewALERTS: action queue for waiting, errors, completions, and stuck worksession topic: detailed status, logs, and direct reply path for one session
All configuration is done via environment variables.
| Variable | Required | Default | Description |
|---|---|---|---|
TELEGRAM_BOT_TOKEN |
yes | - | Telegram bot token |
AUTHORIZED_USER_IDS |
yes | - | Comma-separated Telegram user IDs allowed to use the bot |
MIRROR_CHAT_IDS |
no | AUTHORIZED_USER_IDS |
Telegram chat IDs that receive automatic Terminal mirror events |
TMUX_BIN |
no | tmux |
Path to tmux binary |
LOG_LINES_DEFAULT |
no | 80 |
Default log lines returned by /logs |
POLL_INTERVAL_SECONDS |
no | 3 |
Background poll interval for log streaming |
ALLOW_SHELL |
no | false |
Enable /shell |
SHELL_TIMEOUT_SECONDS |
no | 20 |
Timeout for /shell |
CODEX_COMMAND_TEMPLATE |
no | codex exec "{prompt}" |
Command template used by /codex |
MAX_MESSAGE_CHARS |
no | 3500 |
Chunk size for Telegram messages |
SESSION_NAME_PREFIX |
no | tgc_ |
Prefix added to tmux session names |
MIRROR_ENABLED |
no | true |
Enable automatic mirroring of existing Terminal Codex tabs |
MIRROR_POLL_INTERVAL_SECONDS |
no | 3 |
Poll interval for Terminal snapshot diffing |
MIRROR_INITIAL_LINES |
no | 24 |
Initial line count sent when a new Terminal Codex tab is attached |
NODE_BIN |
no | node |
Node executable used for the SDK sidecar |
ASSISTANT_STATE_PATH |
no | ./.state/assistant_sessions.json |
JSON file storing SDK session metadata and resume IDs |
ASSISTANT_SIDECAR_SCRIPT |
no | ./sidecar/runner.mjs |
Node entrypoint used for SDK-backed Codex or Claude sessions |
CONSOLE_CHAT_ID |
no | first chat in MIRROR_CHAT_IDS |
Main chat or supergroup where the console lives |
CONSOLE_FORUM_ENABLED |
no | false |
Enable one-topic-per-session delivery inside a forum-enabled supergroup |
CONSOLE_AUTO_CREATE_TOPICS |
no | true |
Auto-create INDEX, ALERTS, and session topics when forum mode is enabled |
CONSOLE_INDEX_TOPIC_ID |
no | auto | Existing topic id to use for INDEX |
CONSOLE_ALERTS_TOPIC_ID |
no | auto | Existing topic id to use for ALERTS |
CONSOLE_STATUS_SUMMARY_LINES |
no | 15 |
Number of important lines to keep in each status card summary |
CONSOLE_STATUS_UPDATE_MIN_INTERVAL_SECONDS |
no | 5 |
Minimum interval between status-card edits for the same session |
CONSOLE_RUNNING_UPDATE_MIN_INTERVAL_SECONDS |
no | 12 |
Minimum interval for sessions that are simply running normally |
CONSOLE_GLOBAL_WRITE_SPACING_SECONDS |
no | 2 |
Global spacing between automatic Telegram card/index writes |
CONSOLE_STUCK_MINUTES |
no | 15 |
How long a running session can go without updates before ALERTS marks it stuck |
CONSOLE_COMPLETED_RETENTION_MINUTES |
no | 60 |
How long completed/stopped sessions stay visible in INDEX before dropping out |
CONSOLE_TOPIC_BUMP_ENABLED |
no | true |
Periodically bump active session topics so they stay near the top of the forum list |
CONSOLE_TOPIC_BUMP_MINUTES |
no | 10 |
Minimum interval between low-noise active-topic bumps |
CONSOLE_SEND_LOG_DOCUMENTS |
no | true |
Send full logs/transcripts as .log documents instead of large text blobs |
CONSOLE_PIN_STATUS_MESSAGES |
no | false |
Pin each session status card when created |
For the full security model, see SECURITY.md.
This bot can control your development machine. Use it carefully.
Recommended safeguards:
- Only approve your own Telegram user ID.
- Keep
/shelldisabled unless you truly need it. - Run the bot with a low-privilege user.
- Avoid putting secrets directly into commands.
- Prefer
/codexor/runwith known-safe commands. - Keep the machine protected behind your usual OS security controls.
- Remember that
/agent_*can invoke Codex or Claude with tool access in your local workspace. - If you move the console into a supergroup, keep forum topics restricted to trusted users only.
The /codex command builds a shell command from CODEX_COMMAND_TEMPLATE.
Template example:
CODEX_COMMAND_TEMPLATE=codex exec "{prompt}"Then:
/codex research Investigate SOAP validation edge casesbecomes:
codex exec "Investigate SOAP validation edge cases"If your local Codex workflow uses a different command, just change the template.
Examples:
CODEX_COMMAND_TEMPLATE=codex exec --profile prod "{prompt}"
CODEX_COMMAND_TEMPLATE=codex run research_agent --input "{prompt}"For day-to-day use, the controller should run as a background service rather than inside a temporary interactive shell.
On macOS, the recommended mode is a user launchd LaunchAgent.
That gives you:
- automatic start after login through
RunAtLoad - automatic restart through
KeepAlive - access to the logged-in GUI session, which is required for existing
Terminal.appmirroring
To keep the Telegram console available after a machine restart, all of these conditions must hold:
- the Mac is powered on
- the macOS user session is logged in
- the machine has network access
- the machine is not asleep
Because existing Terminal.app mirroring depends on the GUI session, a LaunchAgent is usually the correct mode for this project. A LaunchDaemon can start earlier, but it does not have the same access to logged-in Terminal windows.
Sample files:
- macOS:
docs/launchd.plist.example - Linux:
docs/systemd.service.example
Typical macOS flow:
cp docs/launchd.plist.example ~/Library/LaunchAgents/com.example.pocket-operator.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.pocket-operator.plist
launchctl kickstart -k gui/$(id -u)/com.example.pocket-operatorThis repository now includes two operational helper scripts:
./scripts/service_status.sh
./scripts/service_restart.shThe sample LaunchAgent label used in this documentation is com.example.pocket-operator.
If you use a different LaunchAgent label or plist path, override them with:
TGC_LAUNCHD_LABELTGC_LAUNCHD_PLISTTGC_LOG_PATH
Examples:
TGC_LAUNCHD_LABEL=com.example.pocket-operator ./scripts/service_status.sh
TGC_LAUNCHD_PLIST=$HOME/Library/LaunchAgents/com.example.pocket-operator.plist ./scripts/service_restart.shCommon commands:
./scripts/service_status.sh
./scripts/service_restart.sh
tail -f logs/stderr.logIf you want short shell commands for everyday service operations, add aliases like these:
alias tgService="/path/to/repo/scripts/service_restart.sh"
alias tgStatus="/path/to/repo/scripts/service_status.sh"
alias tgLogs="tail -f /path/to/repo/logs/stderr.log"- The bot process itself does not need to run inside
tmux, though spawned tasks can. - Existing terminal mirroring is macOS-specific because it reads
Terminal.apptab contents through AppleScript. - Sessions running in another terminal emulator are not mirrored automatically.
If CONSOLE_FORUM_ENABLED=true and CONSOLE_CHAT_ID points at a forum-enabled Telegram supergroup, the controller can keep:
- one editable INDEX card in an INDEX topic
- one ALERTS stream in an ALERTS topic
- one status card per session in its own topic
- topic titles that follow session state, e.g.
π΄ session-alpha
A practical setup flow is:
- In the target supergroup, run
/forum_on. - Run
/forum_bootstraponce to create INDEX, ALERTS, and topics for currently active sessions. - Run
/index_hereinside the INDEX topic if you want to rebind it manually later. - Run
/alerts_hereinside the ALERTS topic if you want to rebind it manually later. - Run
/topic_create session-alphaor/topic_create research-alphato create additional per-session topics. - Use
/open <session>inside a topic if you want to rebind or refresh that session card there. - Inside a session topic, you can either reply to the status card or just send plain text in that topic to route input back to the bound session.
Without forum mode, the same architecture still works in a single chat, but session separation is weaker.
pocket-operator/
βββ CHANGELOG.md
βββ CONTRIBUTING.md
βββ .env.example
βββ README.md
βββ SECURITY.md
βββ requirements.txt
βββ sidecar/
β βββ package.json
β βββ runner.mjs
βββ docs/
β βββ demo-script-30s.md
β βββ launchd.plist.example
β βββ systemd.service.example
β βββ use-case-mobile-research-monitor.md
β βββ use-case-multi-agent-operations-console.md
β βββ use-case-overnight-build-watcher.md
βββ scripts/
β βββ bootstrap.sh
β βββ demo_phone_takeover.sh
β βββ doctor.sh
β βββ install.sh
β βββ service_restart.sh
β βββ service_status.sh
β βββ run.sh
β βββ run_service.sh
βββ src/
βββ pocket_operator/
βββ telegram_codex_controller/
βββ assistant_sessions.py
βββ __init__.py
βββ bot.py
βββ console.py
βββ config.py
βββ main.py
βββ security.py
βββ session_manager.py
βββ terminal_mirror.py
βββ utils.py
Check:
- Codex CLI is installed on the same machine
- The command works directly in your shell
CODEX_COMMAND_TEMPLATEmatches your real Codex CLI syntax
Check:
sidecar/node_modulesexists andnpm installcompletednodeis available to the launch environment- Your local Codex or Claude authentication is already working outside Telegram
Check:
- The Codex session is running inside macOS
Terminal.app - The bot process has permission to automate
Terminal.app MIRROR_ENABLED=true- The Telegram chat ID is present in
MIRROR_CHAT_IDS
Install tmux and ensure TMUX_BIN points to it if needed.
Check:
- Your Telegram user ID is listed in
AUTHORIZED_USER_IDS - Your bot token is correct
- The bot process is running
Session cards keep only the most recent important lines. Use /logs, /agent_log, or /find when you need deeper detail. By default, full logs are sent as .log documents to avoid chat spam.
MIT