Files
takopi/docs/user-guide.md
T

15 KiB

Takopi User Guide

Takopi is a command-line tool that lets you control coding agents—like Codex, Claude, and others—through Telegram. Send a message, and takopi runs the agent in your repo, streaming progress back to your chat. It supports multi-repo workflows, git worktrees, and per-project routing.

This guide starts simple and layers on features as you go. Jump to any section or read straight through.

Prerequisites

Before you begin, make sure you have:

  • A Telegram account
  • Python 3.14+ and uv installed
  • At least one supported agent CLI installed and on your PATH (codex, claude, opencode, pi)
  • Basic familiarity with git (especially if you plan to use worktrees)

Key concepts

A few terms you'll see throughout:

Term Meaning
Engine A coding agent backend (Codex, Claude, opencode, pi)
Project A repo/workdir alias used for routing (can set default engine, worktrees, chat ID)
Worktree A git feature that lets you check out multiple branches simultaneously in separate directories
Topic A Telegram forum thread bound to a project/branch; stores per-topic resume tokens
Resume token State that allows an engine to continue from where it left off

How conversations work

Takopi is stateless by default. Each message starts a new engine session unless a resume token is present.

To continue a session:

  • Reply to a bot message. Takopi reads the resume token from the footer and resumes that session.
  • Forum topics (optional) store resume tokens per topic and auto-resume for new messages in that topic. Reset with /new.
  • Chat sessions (optional) store one resume token per chat (per sender in groups) so new messages auto-resume without replying. Enable with session_mode = "chat" and reset with /new. State is stored in telegram_chat_sessions_state.json. You can hide resume lines by setting [transports.telegram].show_resume_line = false when auto-resume is available and a project context is resolved.

Reply-to-continue always works, even if chat sessions or topics are enabled.


1. Installation and setup

Install takopi with:

uv tool install -U takopi

Run it once to start the onboarding wizard:

takopi

The wizard walks you through:

  1. Creating a Telegram bot token via @BotFather
  2. Capturing your chat_id (the wizard listens for a message from you)
  3. Choosing a default engine

To re-run onboarding later, use takopi --onboard.

Your configuration is stored at ~/.takopi/takopi.toml.

Minimal configuration

After onboarding, your config looks something like this:

default_engine = "codex"
transport = "telegram"

[transports.telegram]
bot_token = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
chat_id = 123456789

Optional: split long final responses instead of trimming them:

[transports.telegram]
message_overflow = "split" # trim | split

2. Your first handoff

The simplest workflow:

  1. cd into any git repository
  2. Run takopi
  3. Send a message to your bot

Takopi streams progress in the chat and sends a final response when the agent finishes.

Basic controls

  • Reply to a bot message to continue the session (takopi reads the resume token in the footer)
  • Cancel a run by clicking the cancel button or replying to the progress message with /cancel

3. Switching engines

Prefix your message with an engine directive to override the default:

/codex hard reset the timeline
/claude shrink and store artifacts forever
/opencode hide their paper until they reply
/pi render a diorama of this timeline

Directives are only parsed at the start of the first non-empty line.

Default agent per chat or topic

Use /agent to view or set a persistent default for the current scope:

/agent
/agent set claude
/agent clear
  • Inside a forum topic, /agent set affects that topic.
  • In normal chats, it affects the whole chat.
  • In group chats, only admins can change defaults.

Precedence (highest to lowest): resume token → /engine directive → topic default → chat default → project default → global default.

Setting up engines

Takopi shells out to the agent CLIs. Install them and make sure they're on your PATH (codex, claude, opencode, pi). Authentication is handled by each CLI (login, config files, or environment variables).


4. Projects

For repos you work with often, register them as projects:

cd ~/dev/happy-gadgets
takopi init happy-gadgets

This adds a project entry to your config (for example):

[projects.happy-gadgets]
path = "~/dev/happy-gadgets"

Now you can target it from anywhere using the /project directive:

/happy-gadgets pinky-link two threads

If you expect to add or edit projects while takopi is running, enable config watching so changes are picked up automatically:

watch_config = true

Project-specific settings

Projects can override global defaults:

[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
default_engine = "claude"
worktrees_dir = ".worktrees"
worktree_base = "master"

Setting a default project

If you mostly work in one repo:

default_project = "happy-gadgets"

5. Worktrees

Worktrees let you work on multiple branches without switching back and forth. Use @branch to run a task in a dedicated worktree:

/happy-gadgets @feat/memory-box freeze artifacts forever

Takopi creates (or reuses) a worktree at:

<worktrees_root>/<branch>

worktrees_root is <project.path>/<worktrees_dir> unless worktrees_dir is an absolute path. If the branch matches the repo's current branch, Takopi runs in the main repo instead of creating a new worktree.

Worktree configuration

[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
worktrees_dir = ".worktrees"      # relative to project path
worktree_base = "master"          # base branch for new worktrees

To avoid .worktrees/ showing up as untracked, add it to your global gitignore:

git config --global core.excludesfile ~/.config/git/ignore
echo ".worktrees/" >> ~/.config/git/ignore

Context persistence

Takopi adds a ctx: footer to messages with project and branch info. When you reply, this context carries forward—no need to repeat /project @branch each time.


6. Per-project chat routing

Give each project its own Telegram chat:

takopi chat-id --project happy-gadgets

Send any message in the target chat. Takopi captures the chat_id and updates your config:

[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
chat_id = -1001234567890

Messages from that chat automatically route to the project.

Rules for chat IDs

  • Each projects.*.chat_id must be unique
  • Project chat IDs must not match transports.telegram.chat_id
  • Telegram uses positive IDs for private chats and negative IDs for groups/supergroups

Capture a chat ID without saving

To see a chat ID without writing to config:

takopi chat-id

7. Topics

Topics bind Telegram forum threads to specific project/branch contexts. They also preserve resume tokens and can store a default agent per topic.

Enabling topics

[transports.telegram.topics]
enabled = true

Your bot needs Manage Topics permission in the group.

If any projects.<alias>.chat_id are configured, topics are managed in those project chats; otherwise topics are managed in the main chat.

Topic behavior

┌────────────────────────────┐
│ takopi projects            │
├────────────────────────────┤
│ takopi @master             │
│ takopi @feat/topics        │
│ happy-gadgets @master      │
│ happy-gadgets @feat/camera │
└────────────────────────────┘

Each project can have its own forum-enabled supergroup. Topics still include the project name for consistency, but the project is inferred from the chat. Regular messages in that chat also infer the project, so /project is usually optional.

┌────────────────────────────────┐  ┌───────────────────────────────────┐
│ takopi                         │  │ happy-gadgets                     │
├────────────────────────────────┤  ├───────────────────────────────────┤
│ takopi @master                 │  │ happy-gadgets @master             │
│ takopi @feat/topics            │  │ happy-gadgets @feat/happy-camera  │
│ takopi @feat/voice             │  │ happy-gadgets @feat/memory-box    │
└────────────────────────────────┘  └───────────────────────────────────┘

Topic commands

Run these inside a topic thread:

Command Description
/topic <project> @branch Create a new topic bound to context
/ctx Show the current binding
/ctx set <project> @branch Update the binding
/ctx clear Remove the binding
/new Clear resume tokens for this topic

In project chats, omit the project: /topic @branch or /ctx set @branch.

Configuration examples

Main chat only:

[transports.telegram]
chat_id = -1001234567890
# show_resume_line = false

[transports.telegram.topics]
enabled = true

Project chats:

[transports.telegram]
chat_id = 123456789   # main chat (private, for non-project messages)
# show_resume_line = false

[transports.telegram.topics]
enabled = true

[projects.takopi]
path = "~/dev/takopi"
chat_id = -1001111111111   # forum-enabled group

Topic state is stored in telegram_topics_state.json next to your config file. Chat defaults live in telegram_chat_prefs_state.json.


8. Voice notes

Dictate tasks instead of typing:

[transports.telegram]
voice_transcription = true
voice_transcription_model = "gpt-4o-mini-transcribe" # optional

Set OPENAI_API_KEY in your environment (uses OpenAI's transcription API with the gpt-4o-mini-transcribe model by default). To use a local OpenAI-compatible Whisper server, also set OPENAI_BASE_URL (for example, http://localhost:8000/v1) and a dummy OPENAI_API_KEY if your server ignores it. If your server requires a specific model name, set voice_transcription_model accordingly (for example, whisper-1).

When you send a voice note, takopi transcribes it and runs the result as a normal text message. If transcription fails, you'll get an error message and the run is skipped.



9. File transfer

Upload files into the active repo/worktree or fetch files back into Telegram.

Upload a file

Send a document with a caption:

/file put <path>

Examples:

/file put docs/spec.pdf
/file put /happy-gadgets @feat/camera assets/logo.png

If you send a file without a caption, takopi saves it to:

incoming/<original_filename>

If you set auto_put_mode = "prompt", a caption/question will start a run immediately after upload, with the prompt annotated with the uploaded path.

Use --force to overwrite an existing file:

/file put --force docs/spec.pdf

Fetch a file

Send:

/file get <path>

Directories are zipped automatically.

File transfer config

[transports.telegram.files]
enabled = true
auto_put = true
auto_put_mode = "upload"
uploads_dir = "incoming"
allowed_user_ids = [123456789]
deny_globs = [".git/**", ".env", ".envrc", "**/*.pem", "**/.ssh/**"]

Notes:

  • File transfer is disabled by default.
  • If allowed_user_ids is empty, private chats are allowed and group usage requires admin privileges.

10. Configuration reference

Full example with all options:

# Global defaults
default_engine = "codex"
default_project = "takopi"
transport = "telegram"
watch_config = true   # hot-reload on config changes (except transport)

[transports.telegram]
bot_token = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
chat_id = 123456789
voice_transcription = true
voice_transcription_model = "gpt-4o-mini-transcribe"
session_mode = "stateless" # or "chat" for auto-resume per chat
show_resume_line = true

[transports.telegram.files]
enabled = true
auto_put = true
auto_put_mode = "upload"
uploads_dir = "incoming"
allowed_user_ids = [123456789]
deny_globs = [".git/**", ".env", ".envrc", "**/*.pem", "**/.ssh/**"]

[transports.telegram.topics]
enabled = true
scope = "auto"

# Project definitions
[projects.takopi]
path = "~/dev/takopi"
default_engine = "codex"
worktrees_dir = ".worktrees"
worktree_base = "master"
# chat_id = -1001234567890   # optional: dedicated chat

[projects.happy-planet]
path = "~/dev/happy-planet"
default_engine = "claude"
worktrees_dir = "~/.takopi/worktrees/happy-planet"
worktree_base = "develop"

11. Command cheatsheet

Message directives

Directive Example Description
/engine /codex make threads resolve their differences Use a specific engine
/project /happy-gadgets add escape-pod Target a project
@branch @feat/happy-camera rewind to checkpoint Run in a worktree
Combined /happy-gadgets @feat/flower-pin observe unseen Project + branch

In-chat commands

Command Description
/cancel Reply to the progress message to stop the current run
/file put <path> Upload a document into the repo/worktree
/file get <path> Fetch a file (directories are zipped)
/agent Show/set the default agent for the current scope
/topic <project> @branch Create/bind a topic
/ctx Show current context
/ctx set <project> @branch Update context binding
/ctx clear Remove context binding
/new Clear stored resume tokens (topic or chat session)

CLI commands

Command Description
takopi Start the bot (runs onboarding if first time)
takopi --onboard Re-run onboarding wizard
takopi init <alias> Register current directory as a project
takopi chat-id Capture a chat ID
takopi chat-id --project <alias> Set a project's chat ID
takopi --debug Write debug logs to debug.log

12. Tips

Schedule tasks with Telegram

Telegram has a native message scheduling feature that works seamlessly with takopi. Long-press the send button and choose "Schedule Message" to run tasks at a specific time. You can also set up recurring schedules (daily, weekly, etc.) for automated workflows.


13. Troubleshooting

If something isn't working, rerun with takopi --debug and check debug.log for errors. Include it when reporting issues.