diff --git a/docs/overrides/.icons/takopi/takopi.svg b/docs/overrides/.icons/takopi/takopi.svg new file mode 100644 index 0000000..28d2156 --- /dev/null +++ b/docs/overrides/.icons/takopi/takopi.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/stylesheets/admonitions.css b/docs/stylesheets/admonitions.css new file mode 100644 index 0000000..3dda89d --- /dev/null +++ b/docs/stylesheets/admonitions.css @@ -0,0 +1,42 @@ +:root { + --md-admonition-icon--user: url('data:image/svg+xml;charset=utf-8,%3Csvg%20class%3D%22lucide%20lucide-user-round%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20%3E%20%3Ccircle%20cx%3D%2212%22%20cy%3D%228%22%20r%3D%225%22%20%2F%3E%20%3Cpath%20d%3D%22M20%2021a8%208%200%200%200-16%200%22%20%2F%3E%20%3C%2Fsvg%3E'); + --md-admonition-icon--takopi: var(--md-admonition-icon--info); + --md-admonition-color--user: #64dd17; + --md-admonition-color--takopi: #f4a5b8; + --md-admonition-bg-color--user: #64dd171a; + --md-admonition-bg-color--takopi: #f4a5b81a; +} + +.md-typeset .admonition.user, +.md-typeset details.user { + background-color: var(--md-admonition-bg-color--user); +} + +.md-typeset .admonition.takopi, +.md-typeset details.takopi { + background-color: var(--md-admonition-bg-color--takopi); +} + +.md-typeset .user > .admonition-title::before, +.md-typeset .user > summary::before { + background-color: var(--md-admonition-color--user); + -webkit-mask-image: var(--md-admonition-icon--user); + mask-image: var(--md-admonition-icon--user); +} + +.md-typeset .user > .admonition-title::after, +.md-typeset .user > summary::after { + color: var(--md-admonition-color--user); +} + +.md-typeset .takopi > .admonition-title::before, +.md-typeset .takopi > summary::before { + background-color: var(--md-admonition-color--takopi); + -webkit-mask-image: var(--md-admonition-icon--takopi); + mask-image: var(--md-admonition-icon--takopi); +} + +.md-typeset .takopi > .admonition-title::after, +.md-typeset .takopi > summary::after { + color: var(--md-admonition-color--takopi); +} diff --git a/docs/tutorials/first-run.md b/docs/tutorials/first-run.md index c0e1356..f5f4ce6 100644 --- a/docs/tutorials/first-run.md +++ b/docs/tutorials/first-run.md @@ -1,32 +1,186 @@ # First run -You’ll run Takopi in a repo, send a task from Telegram, and learn the basic controls. +This tutorial walks you through sending your first task, watching it execute, and learning the core interaction patterns. -## 1) Start Takopi in a repo +**What you'll learn:** How Takopi streams progress, how to continue conversations, and how to cancel a run. + +## 1. Start Takopi in a repo + +Takopi runs agent CLIs in your current directory. Navigate to a repo you want to work in: ```sh -cd ~/dev/your-repo +cd ~/dev/your-project takopi ``` -## 2) Send a message to your bot +Takopi keeps running in your terminal. In Telegram, your bot will post a startup message like: -Takopi streams progress in chat and posts a final message when the engine finishes. +!!! takopi "Takopi" + 🐙 takopi is ready -If you want to override the default engine for a single message, prefix the first line: + default: codex
+ agents: codex, claude
+ projects: none
+ working in: /Users/you/dev/your-project -``` -/codex explain this code -/claude refactor this module -``` +The engines/projects list reflects your setup. This tells you: -## 3) Continue or cancel +- Which engine is the default +- Which agents are available (and any missing ones) +- Which projects are registered +- Which directory Takopi will run in -- Continue the same thread by **replying** to any bot message that contains a resume line in the footer. -- Cancel an in-flight run by clicking the cancel button or replying to the progress message with `/cancel`. +!!! note "Takopi runs where you start it" + The agent will see files in your current directory. If you want to work on a different repo, stop Takopi (`Ctrl+C`) and restart it in that directory—or set up [projects](projects-and-branches.md) to switch repos from chat. + +## 2. Send a task + +Open Telegram and send a message to your bot: + +!!! user "You" + explain what this repo does + + +## 3. Watch progress stream + +Takopi immediately posts a progress message and updates it as the agent works: + +!!! takopi "Takopi" + starting · codex · 0s + +As the agent calls tools and makes progress, you'll see updates like: + +!!! takopi "Takopi" + working · codex · 12s · step 3 + + ✓ tool: read: readme.md
+ ✓ tool: read: docs/index.md
+ ✓ tool: read: src/takopi/runner.py + +The progress message is edited in-place. + +## 4. See the final answer + +When the agent finishes, Takopi sends a new message and replaces the progress message, so you get a notification. + + +!!! takopi "Takopi" + done · codex · 11s · step 5 + + Takopi is a Telegram bridge for AI coding agents (Codex, Claude Code, OpenCode, Pi). It lets you run agents from chat, manage multiple projects and git worktrees, stream progress (commands, file changes, elapsed time), and resume sessions from either chat or terminal. It also supports file transfer, group topics mapped to repo/branch contexts, and multiple engines via chat commands, with a plugin system for engines/transports/commands. + + codex resume 019bb89b-1b0b-7e90-96e4-c33181b49714 + + +That last line is the **resume line**—it's how Takopi knows which conversation to continue. + +## 5. Continue the conversation + +To follow up, **reply** to the bot's message: + +!!! takopi "Takopi" + done · codex · 11s · step 5 + + !!! user "You" + what command line arguments does it support? + +Takopi extracts the resume token from the message you replied to and continues the same agent session. The agent remembers everything from before. + +!!! takopi "Takopi" + done · codex · 47s · step 11 + + CLI Args + + - Global/auto-router (when you run just takopi): --version, --final-notify/--no-final-notify, --onboard/--no-onboard, --transport , --debug/--no-debug. This is the same option set used by engine subcommands. + - init [alias]: optional positional alias, plus --default to set the project as default_project. + - chat-id: --token , --project to store a captured chat id into the project config. + - plugins: --load/--no-load to validate plugin imports. + - Engine subcommands: one per engine id; built-ins are codex, claude, opencode, pi, plus any plugin engines. Each accepts --final-notify, --onboard, --transport, --debug. + + If you want, I can also summarize takopi --help output verbatim for your local build. + + codex resume 019bb89b-1b0b-7e90-96e4-c33181b49714 + +!!! tip "You can reply to any message with a resume line" + The resume line doesn't have to be in the most recent message. Reply to any earlier message to "branch" the conversation from that point. + +## 6. Cancel a run + +Sometimes you want to stop a run in progress—maybe you realize you asked the wrong question, or it's taking too long. + +While the progress message is showing, tap the **cancel** button or reply to it with: + +!!! takopi "Takopi" + working · codex · 12s · step 3 + + !!! user "You" + /cancel + +Takopi sends `SIGTERM` to the agent process and posts a cancelled status: + +!!! failure "" + cancelled · codex · 12s + + codex resume 019bb89b-1b0b-7e90-96e4-c33181b49714 + +If a resume token was already issued (and resume lines are enabled), it will still be included so you can continue from where it stopped. + +!!! note "Cancel only works on progress messages" + If the run already finished, there's nothing to cancel. Just send a new message or reply to continue. + +## 7. Try a different engine + +Want to use a different agent for one message? Prefix your message with `/`: + +!!! user "You" + /claude explain the error handling in this codebase + +This uses Claude Code for just this message. The resume line will show `claude --resume ...`, and replies will automatically use Claude. + +Available prefixes depend on what you have installed: `/codex`, `/claude`, `/opencode`, `/pi`. + +## What just happened + +Key points: + +- Takopi spawns the agent CLI as a subprocess +- The agent streams JSONL events (tool calls, progress, answer) +- Takopi renders these as an editable progress message +- When done, the progress message is replaced with the final answer +- The resume line lets you continue the conversation + +## The core loop + +You now know the three fundamental interactions: + +| Action | How | +|--------|-----| +| **Start** | Send a message to your bot | +| **Continue** | Reply to any message with a resume line | +| **Cancel** | Tap **cancel** on a progress message | + +Everything else in Takopi builds on this loop. + +## Troubleshooting + +**Progress message stuck on "starting" (or not updating)** + +The agent might be doing something slow (large repo scan, network call). Wait a bit, or `/cancel` and try a more specific prompt. + +**Agent CLI not found** + +The agent CLI isn't on your PATH. Install the CLI for the engine you're using (e.g., `npm install -g @openai/codex`) and make sure the install location is in your PATH. + +**Bot doesn't respond at all** + +Check that Takopi is still running in your terminal. You should also see a startup message ("takopi is ready") from the bot in Telegram. If not, restart it. + +**Resume doesn't work (starts a new conversation)** + +Make sure you're **replying** to a message, not sending a new one. The reply must be to a message that contains a resume line. ## Next -- [Projects](../how-to/projects.md) and [Worktrees](../how-to/worktrees.md) -- [Commands & directives](../reference/commands-and-directives.md) +You've mastered the basics. Next, let's set up projects so you can target specific repos and branches from anywhere. +[Projects and branches →](projects-and-branches.md) diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md index 2dfd18e..f16e856 100644 --- a/docs/tutorials/index.md +++ b/docs/tutorials/index.md @@ -1,41 +1,81 @@ # Tutorials -Tutorials are **step-by-step learning paths**. If you’re new, start here and follow them in order. +Tutorials walk you through Takopi step-by-step. Follow them in order if you're new. -If you already know what you want to do (e.g. “enable topics” or “fetch a file”), jump to **How-to**. +If you already know what you want ("enable topics", "use worktrees"), jump to **[How-to](../how-to/index.md)**. -## Before you start +## Prerequisites -You’ll need: +Before starting, make sure you have: -- A Telegram account + a bot token -- Python **3.14+** and `uv` -- At least one engine CLI on your `PATH`: `codex`, `claude`, `opencode`, or `pi` +- A **Telegram account** +- **Python 3.14+** and **uv** ([install uv](https://docs.astral.sh/uv/getting-started/installation/)) +- At least one agent CLI on your `PATH`: -## 1) Install and onboard +| Agent | Install | +|-------|---------| +| Codex | `npm install -g @openai/codex` | +| Claude Code | `npm install -g @anthropic-ai/claude-code` | +| OpenCode | `npm install -g opencode-ai@latest` | +| Pi | `npm install -g @mariozechner/pi-coding-agent` | -Get Takopi installed, create a bot token, capture your chat id, and pick a default engine. +You only need one to get started. Takopi auto-detects what's available. -- [Install & onboard](install-and-onboard.md) +## The tutorials -## 2) Your first run +### 1. Install and onboard -Run Takopi in a repo, send your first task from Telegram, and learn the two core controls: +Set up Takopi, create a Telegram bot, and generate your config. -- reply-to-continue (resume) -- cancel a run +**Time:** ~5 minutes -- [First run](first-run.md) +[Start here →](install-and-onboard.md) -## What to do next +### 2. First run -Once you can run tasks end-to-end, you’ll usually want: +Send your first task, watch it stream, and learn the core loop: run → continue → cancel. -- Register a repo as a **project alias**: [How-to: Projects](../how-to/projects.md) -- Run work on a branch in a dedicated **worktree**: [How-to: Worktrees](../how-to/worktrees.md) -- Keep long-running work organized in threads: [How-to: Topics](../how-to/topics.md) +**Time:** ~10 minutes -When you need exact knobs and defaults: +[Continue →](first-run.md) -- [Reference: Configuration](../reference/config.md) -- [Reference: Commands & directives](../reference/commands-and-directives.md) +### 3. Projects and branches + +Register a repo as a project so you can target it from anywhere. Run tasks on feature branches without leaving your main worktree. + +**Time:** ~10 minutes + +[Continue →](projects-and-branches.md) + +### 4. Multi-engine workflows + +Use different agents for different tasks. Set defaults per chat or topic. + +**Time:** ~5 minutes + +[Continue →](multi-engine.md) + +## What you'll build + +By the end of these tutorials, you'll have: + +``` +~/.takopi/takopi.toml +├── bot_token + chat_id configured +├── default_engine set +└── projects.your-repo registered +``` + +And you'll know how to: + +- Send tasks from Telegram and watch progress stream +- Continue conversations by replying +- Cancel runs mid-flight +- Target specific repos and branches +- Switch between agents on the fly + +## After the tutorials + +- **[How-to guides](../how-to/index.md)** — goal-oriented recipes (topics, file transfer, voice notes) +- **[Reference](../reference/index.md)** — exact config keys, commands, and contracts +- **[Explanation](../explanation/index.md)** — architecture and design rationale diff --git a/docs/tutorials/install-and-onboard.md b/docs/tutorials/install-and-onboard.md index d4e1feb..c372e34 100644 --- a/docs/tutorials/install-and-onboard.md +++ b/docs/tutorials/install-and-onboard.md @@ -1,56 +1,250 @@ -# Install & onboard +# Install and onboard -You’ll install Takopi, connect it to Telegram, and generate a working `takopi.toml`. +This tutorial walks you through installing Takopi, creating a Telegram bot, and generating your config file. -## Prerequisites +**What you'll have at the end:** A working `~/.takopi/takopi.toml` with your bot token, chat ID, and default engine. -- A Telegram account -- Python 3.14+ and `uv` -- At least one supported engine CLI on your `PATH` (`codex`, `claude`, `opencode`, or `pi`) +## 1. Install Python 3.14 and uv -## 1) Install Takopi +Install `uv`, the modern Python [package manager](https://docs.astral.sh/uv/): + +```sh +curl -LsSf https://astral.sh/uv/install.sh | sh +``` + +Install Python 3.14 with uv: + +```sh +uv python install 3.14 +``` + +## 2. Install Takopi ```sh uv tool install -U takopi ``` -## 2) Run onboarding +Verify it's installed: -Start Takopi: +```sh +takopi --version +``` + +You should see something like `0.17.1`. + +## 3. Install agent CLIs + +Takopi shells out to agent CLIs. Install the ones you plan to use (or install them all now): + +### Codex + +```sh +npm install -g @openai/codex +``` + +Takopi uses the official Codex CLI, so your existing ChatGPT subscription applies. Run `codex` and sign in with your ChatGPT account. + +### Claude Code + +```sh +npm install -g @anthropic-ai/claude-code +``` + +Takopi uses the official Claude CLI, so your existing Claude subscription applies. Run `claude` and log in with your Claude account. Takopi defaults to subscription billing unless you opt into API billing in config. + +### OpenCode + +```sh +npm install -g opencode-ai@latest +``` + +OpenCode supports logging in with Anthropic for your Claude subscription or with OpenAI for your ChatGPT subscription, and it can connect to 75+ providers via Models.dev (including local models). + +### Pi + +```sh +npm install -g @mariozechner/pi-coding-agent +``` + +Pi can authenticate via a provider login or use API billing. You can log in with Anthropic (Claude subscription), OpenAI (ChatGPT subscription), GitHub Copilot, Google Cloud Code Assist (Gemini CLI), or Antigravity (Gemini 3, Claude, GPT-OSS), or choose API billing instead. + +## 4. Run onboarding + +Start Takopi without a config file. It will detect this and launch the setup wizard: ```sh takopi ``` -If you want to re-run onboarding later: +You'll see something like: + +``` +welcome to takopi! + +let's set up your telegram bot. + +step 1: telegram bot setup + +? do you have a telegram bot token? (yes/no) +``` + +If you don't have a bot token yet, answer **n** and Takopi will show you the steps. + +## 5. Create a Telegram bot + +If you answered **n**, follow these steps (or skip to step 6 if you already have a token): + +1. Open Telegram and message [@BotFather](https://t.me/BotFather) +2. Send `/newbot` or use the mini app +3. Choose a display name (the obvious choice is "takopi") +4. Choose a username ending in `bot` (e.g., `my_takopi_bot`) + +BotFather will congratulate you on your new bot and will reply with your token: + +``` +Done! Congratulations on your new bot. You will find it at +t.me/my_takopi_bot. You can now add a description, about +section and profile picture for your bot, see /help for a +list of commands. + +Use this token to access the HTTP API: +123456789:ABCdefGHIjklMNOpqrsTUVwxyz + +Keep your token secure and store it safely, it can be used +by anyone to control your bot. +``` + +Copy the token (the `123456789:ABC...` part). + +!!! warning "Keep your token secret" + Anyone with your bot token can control your bot. Don't commit it to git or share it publicly. + +## 6. Enter your bot token + +Paste your token when prompted: + +``` +? paste your bot token: **** + validating... + connected to @my_takopi_bot +``` + +Takopi validates the token by calling the Telegram API. If it fails, double-check you copied the full token. + +## 7. Capture your chat ID + +Takopi needs to know which chat to send messages to. It will listen for a message from you: + +``` + send /start to @my_takopi_bot (works in groups too) + waiting... +``` + +Open Telegram and send `/start` (or any message) to your bot. Takopi will capture the chat: + +``` + got chat_id 123456789 from @yourusername + sent confirmation message +``` + +!!! tip "Using Takopi in a group" + You can also send a message in a group where the bot is a member. Takopi will capture that group's chat ID instead. This is useful if you want multiple people to share the same bot. + +## 8. Choose your default engine + +Takopi scans your PATH for installed agent CLIs: + +``` +step 2: agent cli tools + + agent status install command + ─────────────────────────────────────────── + codex ✓ installed + claude ✓ installed + opencode ✗ not found npm install -g opencode-ai@latest + pi ✗ not found npm install -g @mariozechner/pi-coding-agent + +? choose default agent: + ❯ codex + claude +``` + +Pick whichever you prefer. You can always switch engines per-message later. + +## 9. Save your config + +Takopi shows you a preview of what it will save: + +``` +step 3: save configuration + + ~/.takopi/takopi.toml + + default_engine = "codex" + transport = "telegram" + + [transports.telegram] + bot_token = "123456789:ABC..." + chat_id = 123456789 + +? save this config to ~/.takopi/takopi.toml? (yes/no) +``` + +Press **Enter** to save. You'll see: + +``` + config saved to ~/.takopi/takopi.toml + +setup complete. starting takopi... +``` + +Takopi is now running and listening for messages! + +## What just happened + +Your config file lives at `~/.takopi/takopi.toml`: + +```toml title="~/.takopi/takopi.toml" +default_engine = "codex" # new threads use this +transport = "telegram" # how Takopi talks to you + +[transports.telegram] +bot_token = "..." # your bot's API key +chat_id = 123456789 # where to send messages +``` + +This config file controls all of Takopi's behavior. You'll edit it directly for advanced features. + +## Re-running onboarding + +If you ever need to reconfigure: ```sh takopi --onboard ``` -The wizard walks you through: +This will prompt you to update your existing config (it won't overwrite without asking). -1. Creating a bot token via [@BotFather](https://t.me/BotFather) -2. Capturing your `chat_id` (it listens for a message from you) -3. Choosing a default engine +## Troubleshooting -Your configuration lives at `~/.takopi/takopi.toml`. +**"error: missing takopi config"** -## 3) Verify minimal config +Run `takopi` in a terminal with a TTY. The setup wizard only runs interactively. -After onboarding you should have something like: +**"failed to connect, check the token and try again"** -```toml -default_engine = "codex" -transport = "telegram" +Make sure you copied the full token from BotFather, including the numbers before the colon. -[transports.telegram] -bot_token = "123456789:ABCdefGHIjklMNOpqrsTUVwxyz" -chat_id = 123456789 -``` +**Bot doesn't respond to /start** + +If you're still in onboarding, your terminal should show "waiting...". If you accidentally closed it, run `takopi` again and restart the setup. + +**"error: already running"** + +You can only run one Takopi instance per bot token. Find and stop the other process, or remove the stale lock file at `~/.takopi/takopi.lock`. ## Next -- [First run](first-run.md) -- [Config reference](../reference/config.md) +Now that Takopi is configured, let's send your first task. +[First run →](first-run.md) diff --git a/docs/tutorials/multi-engine.md b/docs/tutorials/multi-engine.md new file mode 100644 index 0000000..4a6ceb6 --- /dev/null +++ b/docs/tutorials/multi-engine.md @@ -0,0 +1,212 @@ +# Multi-engine workflows + +This tutorial shows you how to use different agents for different tasks and set up defaults so you don't have to think about it. + +**What you'll learn:** Engine directives, persistent defaults, and when to use which agent. + +## Why multiple engines? + +Different agents have different strengths: + +| Agent | Good at | +|-------|---------| +| **Codex** | Fast edits, shell commands, quick fixes | +| **Claude Code** | Complex refactors, architecture, long context | +| **OpenCode** | Open-source alternative, local models | +| **Pi** | Conversational, explanations | + +You might want Codex for quick tasks and Claude for deep work—without manually specifying every time. + +## 1. One-off engine selection + +Prefix any message with `/`: + +!!! user "You" + /claude refactor this module to use dependency injection + +!!! user "You" + /codex add a --verbose flag to the CLI + +!!! user "You" + /pi explain how the event loop works in this codebase + +The engine only applies to that message. The response will have a resume line for that engine: + +!!! takopi "Takopi" + done · claude · 8s
+ claude --resume abc123 + +When you reply, Takopi sees `claude --resume` and automatically uses Claude—you don't need to repeat `/claude`. + +## 2. Engine + project + branch + +Directives combine. Order doesn't matter: + +!!! user "You" + /claude /happy-gadgets @feat/di refactor to use dependency injection + +Or: + +!!! user "You" + /happy-gadgets @feat/di /claude refactor to use dependency injection + +Both do the same thing: run Claude in the `happy-gadgets` project on the `feat/di` branch. + +!!! note "Directives are only parsed at the start" + Everything after the first non-directive word is the prompt. `/claude fix /this/path` uses Claude with prompt "fix /this/path"—it doesn't try to parse `/this` as a directive. + +## 3. Set a default engine for a chat + +Use `/agent set` to change the default for the current scope: + +!!! user "You" + /agent set claude + +Response: + +!!! takopi "Takopi" + chat default agent set to claude + +Now all new conversations in this chat use Claude (unless you explicitly override with `/codex`). + +Check the current default: + +!!! user "You" + /agent + +Example response: + +!!! takopi "Takopi" + agent: claude (chat default)
+ defaults: topic: none, chat: claude, project: none, global: codex
+ available: codex, claude, opencode, pi + +Clear it: + +!!! user "You" + /agent clear + +Response: + +!!! takopi "Takopi" + chat default agent cleared. + +## 4. Defaults in topics + +If you use Telegram forum topics, `/agent set` applies per-topic: + +!!! user "You" + topic: Backend work
+ /agent set claude + +!!! user "You" + topic: Quick fixes
+ /agent set codex + +Each topic remembers its own default. + +## 5. Per-project defaults + +Set a default engine in your project config: + +```toml +[projects.happy-gadgets] +path = "~/dev/happy-gadgets" +default_engine = "claude" +``` + +Now `/happy-gadgets` tasks default to Claude, even if your global default is Codex. + +## 6. Selection precedence + +When Takopi picks an engine, it checks (highest to lowest): + +1. **Resume line** — replying to `claude --resume ...` uses Claude +2. **Explicit directive** — `/codex ...` uses Codex +3. **Topic default** — `/agent set` in this forum topic +4. **Chat default** — `/agent set` in this chat +5. **Project default** — `default_engine` in project config +6. **Global default** — `default_engine` at the top of `takopi.toml` + +This means: resume lines always win, then explicit directives, then the most specific default applies. + +## 7. Practical patterns + +**Pattern: Quick questions vs. deep work** + +``` +# Global default for quick stuff +default_engine = "codex" + +# Project default for complex codebase +[projects.backend] +path = "~/dev/backend" +default_engine = "claude" +``` + +Simple messages go to Codex. `/backend` messages go to Claude. + +**Pattern: Topic per engine** + +Create forum topics like "Claude work" and "Codex tasks", then `/agent set` in each: + +!!! user "You" + topic: Claude deep-dives
+ /agent set claude + +!!! user "You" + topic: Quick Codex fixes
+ /agent set codex + +Drag tasks to the right topic and the engine follows. + +**Pattern: Override for specific tasks** + +Even with defaults, you can always override: + +!!! user "You" + /codex just add a print statement here + +Works regardless of what the default is. + +## Recap + +| Want to... | Do this | +|------------|---------| +| Use an engine once | `/claude ...` or `/codex ...` | +| Set default for chat | `/agent set claude` | +| Set default for topic | `/agent set ...` in the topic | +| Set default for project | `default_engine = "..."` in config | +| Set global default | `default_engine = "..."` at top of config | +| Check current default | `/agent` | +| Clear default | `/agent clear` | + +## You're done! + +That's the end of the tutorials. You now know how to: + +- ✅ Install and configure Takopi +- ✅ Send tasks and continue conversations +- ✅ Cancel runs mid-flight +- ✅ Target repos and branches from chat +- ✅ Use multiple engines effectively + +## Where to go next + +**Want to do something specific?** + +- [Enable forum topics](../how-to/topics.md) for organized threads +- [Transfer files](../how-to/file-transfer.md) between Telegram and your repo +- [Use voice notes](../how-to/voice-notes.md) to dictate tasks +- [Schedule tasks](../how-to/schedule-tasks.md) to run later + +**Want to understand the internals?** + +- [Architecture](../explanation/architecture.md) — how the pieces fit together +- [Routing and sessions](../explanation/routing-and-sessions.md) — how context resolution works +- [Specification](../reference/specification.md) — normative behavior contracts + +**Need exact syntax?** + +- [Commands & directives](../reference/commands-and-directives.md) +- [Configuration](../reference/config.md) diff --git a/docs/tutorials/projects-and-branches.md b/docs/tutorials/projects-and-branches.md new file mode 100644 index 0000000..332b0b8 --- /dev/null +++ b/docs/tutorials/projects-and-branches.md @@ -0,0 +1,201 @@ +# Projects and branches + +This tutorial shows you how to register repos as projects and run tasks on feature branches without switching directories. + +**What you'll learn:** How to target repos from anywhere with `/project`, and run on branches with `@branch`. + +## The problem + +So far, Takopi runs in whatever directory you started it. If you want to work on a different repo, you have to: + +1. Stop Takopi +2. `cd` to the other repo +3. Restart Takopi + +Projects fix this. Once you register a repo, you can target it from chat—even while Takopi is running elsewhere. + +## 1. Register a project + +Navigate to the repo and run `takopi init`: + +```sh +cd ~/dev/happy-gadgets +takopi init happy-gadgets +``` + +Output: + +``` +saved project 'happy-gadgets' to ~/.takopi/takopi.toml +``` + +This adds an entry to your config (Takopi also fills in defaults like `worktrees_dir`, `default_engine`, and sometimes `worktree_base`): + +```toml +[projects.happy-gadgets] +path = "~/dev/happy-gadgets" +``` + +!!! tip "Project aliases are also Telegram commands" + The alias becomes a `/command` you can use in chat. Keep them short and lowercase: `myapp`, `backend`, `docs`. + +## 2. Target a project from chat + +Now you can start Takopi from another repo. If you don't specify a project, Takopi runs in the directory where you launched it. + +```sh +cd ~/dev/your-project +takopi +``` + +And target the project by prefixing your message: + +!!! user "You" + /happy-gadgets explain the authentication flow + +Takopi runs the agent in `~/dev/happy-gadgets`, not your current directory. + +The response includes a context footer: + +!!! takopi "Takopi" + ctx: happy-gadgets
+ codex resume abc123 + +That `ctx:` line tells you which project is active. When you reply, Takopi automatically uses the same project—you don't need to repeat `/happy-gadgets`. + +## 3. Set up worktrees + +Worktrees let you run tasks on feature branches without touching your main checkout. Instead of `git checkout`, Takopi creates a separate directory for each branch. + +Add worktree config to your project: + +```toml +[projects.happy-gadgets] +path = "~/dev/happy-gadgets" +worktrees_dir = ".worktrees" # where branches go +worktree_base = "main" # base for new branches +``` + +!!! note "Ignore the worktrees directory" + Add `.worktrees/` to your global gitignore so it doesn't clutter `git status`: + ```sh + echo ".worktrees/" >> ~/.config/git/ignore + ``` + +## 4. Run on a branch + +Use `@branch` after the project: + +!!! user "You" + /happy-gadgets @feat/new-login add rate limiting to the login endpoint + +Takopi: +1. Checks if `.worktrees/feat/new-login` exists (and is a worktree) +2. If the branch exists locally, it adds a worktree for it +3. If the branch doesn't exist, it creates it from `worktree_base` (or the repo default) and adds the worktree +4. Runs the agent in that worktree + +The response shows both project and branch: + +!!! takopi "Takopi" + ctx: happy-gadgets @feat/new-login
+ codex resume xyz789 + +Replies stay on the same branch. Your main checkout is untouched. + +## 5. Context persistence + +Once you've set a context (via `/project @branch` or by replying), it sticks: + +!!! user "You" + /happy-gadgets @feat/new-login add tests + +!!! takopi "Takopi" + ctx: happy-gadgets @feat/new-login + +!!! user "reply to the bot's answer" + also add integration tests + +!!! takopi "Takopi" + ctx: happy-gadgets @feat/new-login + +The `ctx:` line in each message carries the context forward. + +## 6. Set a default project + +If you mostly work in one repo, set it as the default: + +```toml +default_project = "happy-gadgets" +``` + +Now messages without a `/project` prefix go to that repo: + +!!! user "You" + add a health check endpoint + +Goes to `happy-gadgets` automatically. + +## Putting it together + +Here's a typical workflow: + +```sh +takopi +``` + +!!! user "You" + /happy-gadgets review the error handling + +!!! user "You" + /happy-gadgets @feat/caching implement caching + +!!! takopi "Takopi" + ctx: happy-gadgets @feat/caching + + !!! user "You" + also add cache invalidation + +!!! user "You" + /backend @fix/memory-leak profile memory usage + +!!! user "You" + /happy-gadgets bump the version number + +All from the same Telegram chat, without restarting Takopi or changing directories. + +## Project config reference + +Full options for `[projects.]`: + +| Key | Default | Description | +|-----|---------|-------------| +| `path` | (required) | Repo root. Expands `~`. | +| `worktrees_dir` | `.worktrees` | Where branch worktrees are created (relative to the project path). | +| `worktree_base` | `null` | Base branch for new worktrees. If unset, Takopi uses `origin/HEAD`, the current branch, or `master`/`main` (in that order). | +| `default_engine` | `null` | Engine to use for this project (overrides global default). | +| `chat_id` | `null` | Bind a Telegram chat/group to this project. | + +## Troubleshooting + +**"unknown project"** + +Run `takopi init ` in the repo first. + +**Branch worktree not created** + +Make sure the worktrees directory (default `.worktrees`) is writable. If you've customized `worktrees_dir`, verify that path exists or can be created. + +**Context not carrying forward** + +Make sure you're **replying** to a message with a `ctx:` line. If you send a new message (not a reply), context resets unless you have a `default_project`. + +**Worktree conflicts with existing branch** + +If the branch already exists locally, Takopi uses it. For a fresh start, delete the worktree **and** the branch, or pick a new branch name. + +## Next + +You've got projects and branches working. The final tutorial covers using multiple engines effectively. + +[Multi-engine workflows →](multi-engine.md) diff --git a/zensical.toml b/zensical.toml index ca2333a..a758182 100644 --- a/zensical.toml +++ b/zensical.toml @@ -8,6 +8,7 @@ repo_name = "banteg/takopi" edit_uri = "edit/master/docs/" docs_dir = "docs" site_dir = "_site" +extra_css = ["stylesheets/admonitions.css"] nav = [ { "Home" = "index.md" }, @@ -15,6 +16,8 @@ nav = [ { "Overview" = "tutorials/index.md" }, { "Install & onboard" = "tutorials/install-and-onboard.md" }, { "First run" = "tutorials/first-run.md" }, + { "Projects & branches" = "tutorials/projects-and-branches.md" }, + { "Multi-engine" = "tutorials/multi-engine.md" }, ] }, { "How-to" = [ { "Overview" = "how-to/index.md" }, @@ -93,6 +96,7 @@ link = "https://t.me/+4VRTEKT_To0wMTUy" language = "en" logo = "assets/logo.svg" favicon = "assets/favicon.svg" +custom_dir = "docs/overrides" font.text = "Nunito" font.code = "Fira Code" features = [ @@ -113,6 +117,12 @@ features = [ [project.theme.icon] repo = "fontawesome/brands/github" +[project.theme.icon.admonition] +question = "fontawesome/solid/paper-plane" +info = "takopi/takopi" +user = "lucide/user-round" +takopi = "takopi/takopi" + [[project.theme.palette]] media = "(prefers-color-scheme)" toggle.icon = "lucide/sun-moon" @@ -142,6 +152,7 @@ toggle.name = "Switch to system preference" [project.markdown_extensions.pymdownx.emoji] emoji_index = "zensical.extensions.emoji.twemoji" emoji_generator = "zensical.extensions.emoji.to_svg" +options.custom_icons = ["docs/overrides/.icons"] [project.markdown_extensions.toc] permalink = true