Skip to main content

Discord and Telegram to tmux session bridge for agent-driven workflows.

Project description

tetherly icon

tetherly

Discord / Telegram channel ↔ tmux session bridge.

📖 Full documentation: docs/. Start with Getting Started, then Command Reference, Architecture, and Security. This README is a quick start.

Features

Same slash commands work in both Discord and Telegram:

  • /bind <session>: bind the current chat to a tmux session
  • /unbind: release this chat from its tmux session
  • /config: toggle plain-text auto-send (Discord auto_send:true|false, Telegram /config on|off) and trust_chat to let every member of a chat run commands without enumerating user IDs (owner-only)
  • /send <text>: send text plus Enter into the bound tmux session
  • /key <Enter|Escape|Ctrl-C|Ctrl-D|Tab|Up|Down|Left|Right>: send a special key
  • /tail [lines]: fetch recent tmux output
  • /status: inspect the current binding and tmux session status
  • Quick keys (no arguments): /enter, /esc, /ctrlc, /ctrld, /tab
  • Inline buttons on Codex alerts and on /status / /tail: tap [Enter], [Yes], [Refresh], [Stop] directly in chat — no typing needed

CLI helpers (run from inside a tmux session):

  • tetherly send --message <text>: forward a reply to whichever chat (Discord or Telegram) is bound to the session
  • tetherly codex-stop / tetherly codex-permission-request: Codex hook handlers that route messages to the bound chat

A tmux session is globally unique across platforms — it can be bound to one Discord channel or one Telegram chat, not both. Run /unbind first to move it.

Requirements

  • Python 3.11+
  • tmux installed
  • A Discord bot token and/or a Telegram bot token (at least one)

Setup

Install once on your machine:

pipx install tetherly
# or: uv tool install tetherly
tetherly init

tetherly init is interactive. It writes ~/.tetherly/.env and lets you enable Discord, Telegram, or both. It also asks where to install Codex hooks:

  • Global — writes ~/.codex/hooks.json once. Hooks fire in every project automatically.
  • Project — skip global hooks and run tetherly install-hooks inside each project.
  • Skip — don't touch Codex hooks.

Then start the bot(s):

tetherly

A single process runs whichever bots are configured. State lives at ~/.tetherly/state.json so one process serves every project.

Per-project usage

For each project you want to drive from chat:

tmux new -s <session-name>
# then in the bound chat:
#   /bind <session-name>            (Telegram)
#   /bind session:<session-name>    (Discord)
#   /config on   (Telegram)  /  /config auto_send:true   (Discord)

If you chose Project mode during init, also run once per project:

cd <project>
tetherly install-hooks

install-hooks accepts --global to (re)install user-level hooks instead.

Sending from inside a session

tetherly send --message "작업 끝났습니다"
cat result.txt | tetherly send --stdin
tetherly send --session t1 --message "..."   # explicit session

tetherly send automatically routes to whichever chat (Discord or Telegram) the session is bound to. The legacy tetherly discord-send is still accepted as an alias.

Configuration

tetherly init writes everything you need. Advanced overrides live in ~/.tetherly/.env or shell env.

Discord

Variable Default Notes
DISCORD_BOT_TOKEN Bot token (required to enable Discord)
TETHERLY_ALLOWED_USER_IDS Comma-separated user IDs
TETHERLY_ALLOWED_GUILD_IDS Restrict commands to these guilds
TETHERLY_ALLOWED_ROLE_IDS Allow members holding any of these roles
TETHERLY_TEST_GUILD_ID Dev guild for instant slash-command sync

Telegram

Variable Default Notes
TELEGRAM_BOT_TOKEN Bot token from @BotFather (required to enable Telegram)
TETHERLY_TELEGRAM_ALLOWED_USER_IDS Comma-separated user IDs (required)
TETHERLY_TELEGRAM_ALLOWED_CHAT_IDS Restrict commands to these chats

Shared

Variable Default Notes
TETHERLY_STATE_PATH ~/.tetherly/state.json Where bindings are persisted
TETHERLY_DEFAULT_TAIL_LINES 40 Default /tail line count
TETHERLY_MAX_TAIL_LINES 200 Cap for /tail
TETHERLY_LOG_LEVEL INFO Logger verbosity

A .env in the current working directory still overrides ~/.tetherly/.env. At least one of DISCORD_BOT_TOKEN or TELEGRAM_BOT_TOKEN must be set.

Codex hooks

Both hooks only fire when the active tmux session has TETHERLY_NOTIFY_ON_FINISH=1/bind sets this flag automatically and /unbind clears it, so projects without a binding stay silent even when global hooks are installed.

  • Stoptetherly codex-stop forwards last_assistant_message to the bound chat (Discord or Telegram).
  • PermissionRequesttetherly codex-permission-request forwards the tool/command/reason. It does not return an allow/deny decision, so Codex's normal approval prompt still appears.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tetherly-0.2.0.tar.gz (689.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tetherly-0.2.0-py3-none-any.whl (33.5 kB view details)

Uploaded Python 3

File details

Details for the file tetherly-0.2.0.tar.gz.

File metadata

  • Download URL: tetherly-0.2.0.tar.gz
  • Upload date:
  • Size: 689.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tetherly-0.2.0.tar.gz
Algorithm Hash digest
SHA256 274f74bda0b040aa6290abf8668a579e1ae8b33f5265c8b765c7ab5af4f66bab
MD5 71bc1a080294faa3d336d8b2745c36bc
BLAKE2b-256 347db2a1de321f7891cdad65eb4826dbf03a520dd1bdf71e08c80e372dc32825

See more details on using hashes here.

Provenance

The following attestation bundles were made for tetherly-0.2.0.tar.gz:

Publisher: publish.yml on changhyeon363/tetherly

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tetherly-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: tetherly-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 33.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tetherly-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c753b2b08c90b04b35912f98435a27cc1c06478073d5359830a4162d64fbeb4b
MD5 9a6d44c969c313eebf3e4e37b419d7ba
BLAKE2b-256 880f98ec6a896bf1ebd5652fdd7357e236a0650df4d28e83972ff24b2a7811fb

See more details on using hashes here.

Provenance

The following attestation bundles were made for tetherly-0.2.0-py3-none-any.whl:

Publisher: publish.yml on changhyeon363/tetherly

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page