docs: restructure docs into diataxis (#121)
This commit is contained in:
+19
-539
@@ -1,546 +1,26 @@
|
||||
# Takopi User Guide
|
||||
# Takopi User Guide (moved)
|
||||
|
||||
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 has been reorganized into smaller Diátaxis pages.
|
||||
|
||||
This guide starts simple and layers on features as you go. Jump to any section or read straight through.
|
||||
## Start here
|
||||
|
||||
## Prerequisites
|
||||
- [Install & onboard](tutorials/install-and-onboard.md)
|
||||
- [First run](tutorials/first-run.md)
|
||||
|
||||
Before you begin, make sure you have:
|
||||
## Common tasks
|
||||
|
||||
- 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)
|
||||
- [Switch engines](how-to/switch-engines.md)
|
||||
- [Projects](how-to/projects.md)
|
||||
- [Worktrees](how-to/worktrees.md)
|
||||
- [Route by chat](how-to/route-by-chat.md)
|
||||
- [Topics](how-to/topics.md)
|
||||
- [Voice notes](how-to/voice-notes.md)
|
||||
- [File transfer](how-to/file-transfer.md)
|
||||
- [Schedule tasks](how-to/schedule-tasks.md)
|
||||
- [Troubleshooting](how-to/troubleshooting.md)
|
||||
|
||||
## Key concepts
|
||||
## Reference
|
||||
|
||||
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:
|
||||
|
||||
```sh
|
||||
uv tool install -U takopi
|
||||
```
|
||||
|
||||
Run it once to start the onboarding wizard:
|
||||
|
||||
```sh
|
||||
takopi
|
||||
```
|
||||
|
||||
The wizard walks you through:
|
||||
|
||||
1. Creating a Telegram bot token via [@BotFather](https://t.me/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:
|
||||
|
||||
```toml
|
||||
default_engine = "codex"
|
||||
transport = "telegram"
|
||||
|
||||
[transports.telegram]
|
||||
bot_token = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
|
||||
chat_id = 123456789
|
||||
```
|
||||
|
||||
Optional: split long final responses instead of trimming them:
|
||||
|
||||
```toml
|
||||
[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:
|
||||
|
||||
```sh
|
||||
cd ~/dev/happy-gadgets
|
||||
takopi init happy-gadgets
|
||||
```
|
||||
|
||||
This adds a project entry to your config (for example):
|
||||
|
||||
```toml
|
||||
[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:
|
||||
|
||||
```toml
|
||||
watch_config = true
|
||||
```
|
||||
|
||||
### Project-specific settings
|
||||
|
||||
Projects can override global defaults:
|
||||
|
||||
```toml
|
||||
[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:
|
||||
|
||||
```toml
|
||||
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
|
||||
|
||||
```toml
|
||||
[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:
|
||||
|
||||
```sh
|
||||
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:
|
||||
|
||||
```sh
|
||||
takopi chat-id --project happy-gadgets
|
||||
```
|
||||
|
||||
Send any message in the target chat. Takopi captures the `chat_id` and updates your config:
|
||||
|
||||
```toml
|
||||
[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:
|
||||
|
||||
```sh
|
||||
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
|
||||
|
||||
```toml
|
||||
[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:**
|
||||
|
||||
```toml
|
||||
[transports.telegram]
|
||||
chat_id = -1001234567890
|
||||
# show_resume_line = false
|
||||
|
||||
[transports.telegram.topics]
|
||||
enabled = true
|
||||
```
|
||||
|
||||
**Project chats:**
|
||||
|
||||
```toml
|
||||
[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:
|
||||
|
||||
```toml
|
||||
[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
|
||||
|
||||
```toml
|
||||
[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:
|
||||
|
||||
```toml
|
||||
# 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.
|
||||
- [Configuration](reference/config.md)
|
||||
- [Commands & directives](reference/commands-and-directives.md)
|
||||
- [Context resolution](reference/context-resolution.md)
|
||||
|
||||
Reference in New Issue
Block a user