feat(cli): add takopi config subcommand (#153)

This commit is contained in:
banteg
2026-01-16 11:28:06 +04:00
committed by GitHub
parent dec93019b1
commit 92b33c5181
25 changed files with 1248 additions and 246 deletions
+12 -4
View File
@@ -51,10 +51,18 @@ Rules:
Plugin visibility can be restricted via:
```toml
[plugins]
enabled = ["takopi-engine-acme", "takopi-transport-slack"]
```
=== "takopi config"
```sh
takopi config set plugins.enabled '["takopi-engine-acme", "takopi-transport-slack"]'
```
=== "toml"
```toml
[plugins]
enabled = ["takopi-engine-acme", "takopi-transport-slack"]
```
When set, Takopi filters by **distribution name** (package metadata), not by entrypoint name.
This lets you:
+24 -8
View File
@@ -9,10 +9,18 @@ Chat sessions store one resume token per engine per chat (per sender in group ch
If you chose **handoff** during onboarding and want to switch to chat mode:
```toml
[transports.telegram]
session_mode = "chat" # stateless | chat
```
=== "takopi config"
```sh
takopi config set transports.telegram.session_mode "chat"
```
=== "toml"
```toml
[transports.telegram]
session_mode = "chat" # stateless | chat
```
With `session_mode = "chat"`, new messages in the chat continue the current thread automatically.
@@ -32,10 +40,18 @@ Chat sessions do not remove reply-to-continue. If resume lines are visible, you
If you prefer a cleaner chat, hide resume lines:
```toml
[transports.telegram]
show_resume_line = false
```
=== "takopi config"
```sh
takopi config set transports.telegram.show_resume_line false
```
=== "toml"
```toml
[transports.telegram]
show_resume_line = false
```
## How it behaves in groups
+22 -10
View File
@@ -4,15 +4,28 @@ Upload files into the active repo/worktree or fetch files back into Telegram.
## Enable file transfer
```toml
[transports.telegram.files]
enabled = true
auto_put = true
auto_put_mode = "upload" # upload | prompt
uploads_dir = "incoming"
allowed_user_ids = [123456789]
deny_globs = [".git/**", ".env", ".envrc", "**/*.pem", "**/.ssh/**"]
```
=== "takopi config"
```sh
takopi config set transports.telegram.files.enabled true
takopi config set transports.telegram.files.auto_put true
takopi config set transports.telegram.files.auto_put_mode "upload"
takopi config set transports.telegram.files.uploads_dir "incoming"
takopi config set transports.telegram.files.allowed_user_ids "[123456789]"
takopi config set transports.telegram.files.deny_globs '[".git/**", ".env", ".envrc", "**/*.pem", "**/.ssh/**"]'
```
=== "toml"
```toml
[transports.telegram.files]
enabled = true
auto_put = true
auto_put_mode = "upload" # upload | prompt
uploads_dir = "incoming"
allowed_user_ids = [123456789]
deny_globs = [".git/**", ".env", ".envrc", "**/*.pem", "**/.ssh/**"]
```
Notes:
@@ -56,4 +69,3 @@ Directories are zipped automatically.
- [Commands & directives](../reference/commands-and-directives.md)
- [Config reference](../reference/config.md)
+52 -18
View File
@@ -11,10 +11,18 @@ takopi init happy-gadgets
This adds a project to your config:
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
```
=== "takopi config"
```sh
takopi config set projects.happy-gadgets.path "~/dev/happy-gadgets"
```
=== "toml"
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
```
## Target a project from chat
@@ -28,30 +36,56 @@ Send:
Projects can override global defaults:
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
default_engine = "claude"
worktrees_dir = ".worktrees"
worktree_base = "master"
```
=== "takopi config"
```sh
takopi config set projects.happy-gadgets.path "~/dev/happy-gadgets"
takopi config set projects.happy-gadgets.default_engine "claude"
takopi config set projects.happy-gadgets.worktrees_dir ".worktrees"
takopi config set projects.happy-gadgets.worktree_base "master"
```
=== "toml"
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
default_engine = "claude"
worktrees_dir = ".worktrees"
worktree_base = "master"
```
If you expect to edit config while Takopi is running, enable hot reload:
```toml
watch_config = true
```
=== "takopi config"
```sh
takopi config set watch_config true
```
=== "toml"
```toml
watch_config = true
```
## Set a default project
If you mostly work in one repo:
```toml
default_project = "happy-gadgets"
```
=== "takopi config"
```sh
takopi config set default_project "happy-gadgets"
```
=== "toml"
```toml
default_project = "happy-gadgets"
```
## Related
- [Context resolution](../reference/context-resolution.md)
- [Worktrees](worktrees.md)
+14 -6
View File
@@ -12,11 +12,20 @@ takopi chat-id --project happy-gadgets
Then 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
```
=== "takopi config"
```sh
takopi config set projects.happy-gadgets.path "~/dev/happy-gadgets"
takopi config set projects.happy-gadgets.chat_id -1001234567890
```
=== "toml"
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
chat_id = -1001234567890
```
Messages from that chat now default to the project.
@@ -36,4 +45,3 @@ takopi chat-id
- [Topics](topics.md)
- [Context resolution](../reference/context-resolution.md)
+14 -5
View File
@@ -27,11 +27,20 @@ Topics bind Telegram **forum threads** to a project/branch context. Each topic k
## Enable topics
```toml
[transports.telegram.topics]
enabled = true
scope = "auto" # auto | main | projects | all
```
=== "takopi config"
```sh
takopi config set transports.telegram.topics.enabled true
takopi config set transports.telegram.topics.scope "auto"
```
=== "toml"
```toml
[transports.telegram.topics]
enabled = true
scope = "auto" # auto | main | projects | all
```
### Scope explained
+14 -6
View File
@@ -4,11 +4,20 @@ Enable transcription so voice notes become normal text runs.
## Enable transcription
```toml
[transports.telegram]
voice_transcription = true
voice_transcription_model = "gpt-4o-mini-transcribe" # optional
```
=== "takopi config"
```sh
takopi config set transports.telegram.voice_transcription true
takopi config set transports.telegram.voice_transcription_model "gpt-4o-mini-transcribe"
```
=== "toml"
```toml
[transports.telegram]
voice_transcription = true
voice_transcription_model = "gpt-4o-mini-transcribe" # optional
```
Set `OPENAI_API_KEY` in your environment (uses OpenAIs transcription API).
@@ -24,4 +33,3 @@ If transcription fails, youll get an error message and the run is skipped.
## Related
- [Config reference](../reference/config.md)
+16 -7
View File
@@ -6,12 +6,22 @@ Use `@branch` to run tasks in a dedicated git worktree for that branch.
Add a `worktrees_dir` (and optionally a base branch) to the project:
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
worktrees_dir = ".worktrees" # relative to project path
worktree_base = "master" # base branch for new worktrees
```
=== "takopi config"
```sh
takopi config set projects.happy-gadgets.path "~/dev/happy-gadgets"
takopi config set projects.happy-gadgets.worktrees_dir ".worktrees"
takopi config set projects.happy-gadgets.worktree_base "master"
```
=== "toml"
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
worktrees_dir = ".worktrees" # relative to project path
worktree_base = "master" # base branch for new worktrees
```
## Run in a branch worktree
@@ -39,4 +49,3 @@ When you reply, this context carries forward (you usually dont need to repeat
## Related
- [Context resolution](../reference/context-resolution.md)
+36 -12
View File
@@ -52,10 +52,18 @@ BACKEND = EngineBackend(
Engine config is a raw table in `takopi.toml`:
```toml
[myengine]
model = "..."
```
=== "takopi config"
```sh
takopi config set myengine.model "..."
```
=== "toml"
```toml
[myengine]
model = "..."
```
## Transport backend plugin
@@ -92,19 +100,35 @@ BACKEND = MyCommand()
Configure under `[plugins.<id>]`:
```toml
[plugins.hello]
greeting = "hello"
```
=== "takopi config"
```sh
takopi config set plugins.hello.greeting "hello"
```
=== "toml"
```toml
[plugins.hello]
greeting = "hello"
```
The parsed dict is available as `ctx.plugin_config` in `handle()`.
## Enable/disable installed plugins
```toml
[plugins]
enabled = ["takopi-transport-slack", "takopi-engine-acme"]
```
=== "takopi config"
```sh
takopi config set plugins.enabled '["takopi-transport-slack", "takopi-engine-acme"]'
```
=== "toml"
```toml
[plugins]
enabled = ["takopi-transport-slack", "takopi-engine-acme"]
```
- `enabled = []` (default) means “load all installed plugins”.
- If non-empty, only distributions with matching names are visible.
+151 -26
View File
@@ -4,9 +4,17 @@ Takopi reads configuration from `~/.takopi/takopi.toml`.
If you expect to edit config while Takopi is running, set:
```toml
watch_config = true
```
=== "takopi config"
```sh
takopi config set watch_config true
```
=== "toml"
```toml
watch_config = true
```
## Top-level keys
@@ -19,11 +27,20 @@ watch_config = true
## `transports.telegram`
```toml
[transports.telegram]
bot_token = "..."
chat_id = 123
```
=== "takopi config"
```sh
takopi config set transports.telegram.bot_token "..."
takopi config set transports.telegram.chat_id 123
```
=== "toml"
```toml
[transports.telegram]
bot_token = "..."
chat_id = 123
```
| Key | Type | Default | Notes |
|-----|------|---------|-------|
@@ -62,14 +79,26 @@ File size limits (not configurable):
## `projects.<alias>`
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
worktrees_dir = ".worktrees"
default_engine = "claude"
worktree_base = "master"
chat_id = -1001234567890
```
=== "takopi config"
```sh
takopi config set projects.happy-gadgets.path "~/dev/happy-gadgets"
takopi config set projects.happy-gadgets.worktrees_dir ".worktrees"
takopi config set projects.happy-gadgets.default_engine "claude"
takopi config set projects.happy-gadgets.worktree_base "master"
takopi config set projects.happy-gadgets.chat_id -1001234567890
```
=== "toml"
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
worktrees_dir = ".worktrees"
default_engine = "claude"
worktree_base = "master"
chat_id = -1001234567890
```
| Key | Type | Default | Notes |
|-----|------|---------|-------|
@@ -85,10 +114,18 @@ Legacy config note: top-level `bot_token` / `chat_id` are auto-migrated into `[t
### `plugins.enabled`
```toml
[plugins]
enabled = ["takopi-transport-slack", "takopi-engine-acme"]
```
=== "takopi config"
```sh
takopi config set plugins.enabled '["takopi-transport-slack", "takopi-engine-acme"]'
```
=== "toml"
```toml
[plugins]
enabled = ["takopi-transport-slack", "takopi-engine-acme"]
```
- `enabled = []` (default) means “load all installed plugins”.
- If non-empty, only distributions with matching names are visible (case-insensitive).
@@ -99,11 +136,99 @@ Plugin-specific configuration lives under `[plugins.<id>]` and is passed to comm
## Engine-specific config tables
Engines can have top-level config tables keyed by engine id, for example:
Engines use **top-level tables** keyed by engine id. Built-in engines are listed
here; plugin engines should document their own keys.
```toml
[codex]
model = "..."
```
### `codex`
The shape is engine-defined.
| Key | Type | Default | Notes |
|-----|------|---------|-------|
| `extra_args` | string[] | `["-c", "notify=[]"]` | Extra CLI args for `codex` (exec-only flags are rejected). |
| `profile` | string | (unset) | Passed as `--profile <name>` and used as the session title. |
=== "takopi config"
```sh
takopi config set codex.extra_args '["-c", "notify=[]"]'
takopi config set codex.profile "work"
```
=== "toml"
```toml
[codex]
extra_args = ["-c", "notify=[]"]
profile = "work"
```
### `claude`
| Key | Type | Default | Notes |
|-----|------|---------|-------|
| `model` | string | (unset) | Optional model override. |
| `allowed_tools` | string[] | `["Bash", "Read", "Edit", "Write"]` | Auto-approve tool rules. |
| `dangerously_skip_permissions` | bool | `false` | Skip Claude permissions prompts. |
| `use_api_billing` | bool | `false` | Keep `ANTHROPIC_API_KEY` for API billing. |
=== "takopi config"
```sh
takopi config set claude.model "claude-sonnet-4-5-20250929"
takopi config set claude.allowed_tools '["Bash", "Read", "Edit", "Write"]'
takopi config set claude.dangerously_skip_permissions false
takopi config set claude.use_api_billing false
```
=== "toml"
```toml
[claude]
model = "claude-sonnet-4-5-20250929"
allowed_tools = ["Bash", "Read", "Edit", "Write"]
dangerously_skip_permissions = false
use_api_billing = false
```
### `pi`
| Key | Type | Default | Notes |
|-----|------|---------|-------|
| `model` | string | (unset) | Passed as `--model`. |
| `provider` | string | (unset) | Passed as `--provider`. |
| `extra_args` | string[] | `[]` | Extra CLI args for `pi`. |
=== "takopi config"
```sh
takopi config set pi.model "..."
takopi config set pi.provider "..."
takopi config set pi.extra_args "[]"
```
=== "toml"
```toml
[pi]
model = "..."
provider = "..."
extra_args = []
```
### `opencode`
| Key | Type | Default | Notes |
|-----|------|---------|-------|
| `model` | string | (unset) | Optional model override. |
=== "takopi config"
```sh
takopi config set opencode.model "claude-sonnet"
```
=== "toml"
```toml
[opencode]
model = "claude-sonnet"
```
+31 -14
View File
@@ -18,22 +18,39 @@ worktree-based runs via `@branch`.
All config lives in `~/.takopi/takopi.toml`.
See [Config](config.md) for the full reference.
```toml
default_engine = "codex" # optional
default_project = "z80" # optional
transport = "telegram" # optional, defaults to "telegram"
=== "takopi config"
[transports.telegram]
bot_token = "..." # required
chat_id = 123 # required
```sh
takopi config set default_engine "codex"
takopi config set default_project "z80"
takopi config set transport "telegram"
takopi config set transports.telegram.bot_token "..."
takopi config set transports.telegram.chat_id 123
takopi config set projects.z80.path "~/dev/z80"
takopi config set projects.z80.worktrees_dir ".worktrees"
takopi config set projects.z80.default_engine "codex"
takopi config set projects.z80.worktree_base "master"
takopi config set projects.z80.chat_id -123
```
[projects.z80]
path = "~/dev/z80" # required (repo root)
worktrees_dir = ".worktrees" # optional, default ".worktrees"
default_engine = "codex" # optional, per-project override
worktree_base = "master" # optional, base for new branches
chat_id = -123 # optional, project chat id
```
=== "toml"
```toml
default_engine = "codex" # optional
default_project = "z80" # optional
transport = "telegram" # optional, defaults to "telegram"
[transports.telegram]
bot_token = "..." # required
chat_id = 123 # required
[projects.z80]
path = "~/dev/z80" # required (repo root)
worktrees_dir = ".worktrees" # optional, default ".worktrees"
default_engine = "codex" # optional, per-project override
worktree_base = "master" # optional, base for new branches
chat_id = -123 # optional, project chat id
```
Legacy config note: top-level `bot_token` / `chat_id` are auto-migrated into
`[transports.telegram]` on startup.
+21 -9
View File
@@ -68,17 +68,29 @@ Add a new optional `[claude]` section.
Recommended v1 schema:
```toml
# ~/.takopi/takopi.toml
=== "takopi config"
default_engine = "claude"
```sh
takopi config set default_engine "claude"
takopi config set claude.model "claude-sonnet-4-5-20250929"
takopi config set claude.allowed_tools '["Bash", "Read", "Edit", "Write"]'
takopi config set claude.dangerously_skip_permissions false
takopi config set claude.use_api_billing false
```
[claude]
model = "claude-sonnet-4-5-20250929" # optional (Claude Code supports model override in settings too)
allowed_tools = ["Bash", "Read", "Edit", "Write"] # optional but strongly recommended for automation
dangerously_skip_permissions = false # optional (high risk; prefer sandbox use only)
use_api_billing = false # optional (keep ANTHROPIC_API_KEY for API billing)
```
=== "toml"
```toml
# ~/.takopi/takopi.toml
default_engine = "claude"
[claude]
model = "claude-sonnet-4-5-20250929" # optional (Claude Code supports model override in settings too)
allowed_tools = ["Bash", "Read", "Edit", "Write"] # optional but strongly recommended for automation
dangerously_skip_permissions = false # optional (high risk; prefer sandbox use only)
use_api_billing = false # optional (keep ANTHROPIC_API_KEY for API billing)
```
Notes:
+19 -8
View File
@@ -210,15 +210,26 @@ Claude runner implementation summary (no Takopi domain model changes):
A minimal TOML config for Claude:
```toml
[claude]
# model: opus | sonnet | haiku
model = "sonnet"
=== "takopi config"
allowed_tools = ["Bash", "Read", "Edit", "Write", "WebSearch"]
dangerously_skip_permissions = false
use_api_billing = false
```
```sh
takopi config set claude.model "sonnet"
takopi config set claude.allowed_tools '["Bash", "Read", "Edit", "Write", "WebSearch"]'
takopi config set claude.dangerously_skip_permissions false
takopi config set claude.use_api_billing false
```
=== "toml"
```toml
[claude]
# model: opus | sonnet | haiku
model = "sonnet"
allowed_tools = ["Bash", "Read", "Edit", "Write", "WebSearch"]
dangerously_skip_permissions = false
use_api_billing = false
```
Takopi only maps these keys to Claude CLI flags; other options should be configured in Claude Code settings.
If `allowed_tools` is omitted, Takopi defaults to `["Bash", "Read", "Edit", "Write"]`.
+12 -4
View File
@@ -13,10 +13,18 @@ npm i -g opencode-ai@latest
Add to your `takopi.toml`:
```toml
[opencode]
model = "claude-sonnet" # optional
```
=== "takopi config"
```sh
takopi config set opencode.model "claude-sonnet"
```
=== "toml"
```toml
[opencode]
model = "claude-sonnet" # optional
```
## Usage
+19 -8
View File
@@ -58,16 +58,27 @@ Add a new optional `[pi]` section.
Recommended schema:
```toml
# ~/.takopi/takopi.toml
=== "takopi config"
default_engine = "pi"
```sh
takopi config set default_engine "pi"
takopi config set pi.model "..."
takopi config set pi.provider "..."
takopi config set pi.extra_args "[]"
```
[pi]
model = "..." # optional; passed as --model
provider = "..." # optional; passed as --provider
extra_args = [] # optional list of strings, appended verbatim
```
=== "toml"
```toml
# ~/.takopi/takopi.toml
default_engine = "pi"
[pi]
model = "..." # optional; passed as --model
provider = "..." # optional; passed as --provider
extra_args = [] # optional list of strings, appended verbatim
```
Notes:
+16 -6
View File
@@ -144,11 +144,21 @@ transformation.
A minimal TOML config for Pi:
```toml
[pi]
model = "..."
provider = "..."
extra_args = []
```
=== "takopi config"
```sh
takopi config set pi.model "..."
takopi config set pi.provider "..."
takopi config set pi.extra_args "[]"
```
=== "toml"
```toml
[pi]
model = "..."
provider = "..."
extra_args = []
```
Use `extra_args` for any Pi CLI flags not explicitly mapped.
+63 -20
View File
@@ -28,10 +28,19 @@ directive pipeline as typed text.
Configuration (under `[transports.telegram]`):
```toml
voice_transcription = true
voice_transcription_model = "gpt-4o-mini-transcribe" # optional
```
=== "takopi config"
```sh
takopi config set transports.telegram.voice_transcription true
takopi config set transports.telegram.voice_transcription_model "gpt-4o-mini-transcribe"
```
=== "toml"
```toml
voice_transcription = true
voice_transcription_model = "gpt-4o-mini-transcribe" # optional
```
Set `OPENAI_API_KEY` in the environment. If transcription is enabled but the API key
is missing or the audio download fails, takopi replies with a short error and skips
@@ -88,9 +97,17 @@ Behavior:
Configuration (under `[transports.telegram]`):
```toml
forward_coalesce_s = 1.0 # set 0 to disable the delay
```
=== "takopi config"
```sh
takopi config set transports.telegram.forward_coalesce_s 1.0
```
=== "toml"
```toml
forward_coalesce_s = 1.0 # set 0 to disable the delay
```
## Chat sessions (optional)
@@ -100,10 +117,19 @@ use chat mode with auto-resume enabled.
Configuration (under `[transports.telegram]`):
```toml
show_resume_line = true # set false to hide resume lines
session_mode = "chat" # or "stateless"
```
=== "takopi config"
```sh
takopi config set transports.telegram.show_resume_line true
takopi config set transports.telegram.session_mode "chat"
```
=== "toml"
```toml
show_resume_line = true # set false to hide resume lines
session_mode = "chat" # or "stateless"
```
Behavior:
@@ -124,10 +150,18 @@ By default, takopi trims long final responses to ~3500 characters to stay under
Telegram's 4096 character limit after entity parsing. You can opt into splitting
instead:
```toml
[transports.telegram]
message_overflow = "split" # trim | split
```
=== "takopi config"
```sh
takopi config set transports.telegram.message_overflow "split"
```
=== "toml"
```toml
[transports.telegram]
message_overflow = "split" # trim | split
```
Split mode sends multiple messages. Each chunk includes the footer; follow-up
chunks add a "continued (N/M)" header.
@@ -140,11 +174,20 @@ topic, so replies keep the right context even after restarts.
Configuration (under `[transports.telegram]`):
```toml
[transports.telegram.topics]
enabled = true
scope = "auto" # auto | main | projects | all
```
=== "takopi config"
```sh
takopi config set transports.telegram.topics.enabled true
takopi config set transports.telegram.topics.scope "auto"
```
=== "toml"
```toml
[transports.telegram.topics]
enabled = true
scope = "auto" # auto | main | projects | all
```
Requirements:
+26 -9
View File
@@ -57,11 +57,20 @@ To continue the same session, **reply** to a message with a resume line:
You can manually change these settings in your config file:
```toml
[transports.telegram]
session_mode = "chat" # "chat" or "stateless"
show_resume_line = false # true or false
```
=== "takopi config"
```sh
takopi config set transports.telegram.session_mode "chat"
takopi config set transports.telegram.show_resume_line false
```
=== "toml"
```toml
[transports.telegram]
session_mode = "chat" # "chat" or "stateless"
show_resume_line = false # true or false
```
Or re-run onboarding to pick a different workflow:
@@ -76,10 +85,18 @@ Resume lines are still shown when no project context is set, so replies can bran
If you prefer always-visible resume lines, set:
```toml
[transports.telegram]
show_resume_line = true
```
=== "takopi config"
```sh
takopi config set transports.telegram.show_resume_line true
```
=== "toml"
```toml
[transports.telegram]
show_resume_line = true
```
## Reply-to-continue still works
+81 -36
View File
@@ -268,54 +268,99 @@ Your config file lives at `~/.takopi/takopi.toml`. The exact contents depend on
=== "assistant"
```toml title="~/.takopi/takopi.toml"
default_engine = "codex"
transport = "telegram"
=== "takopi config"
[transports.telegram]
bot_token = "..."
chat_id = 123456789
session_mode = "chat" # auto-resume
show_resume_line = false # cleaner chat
```sh
takopi config set default_engine "codex"
takopi config set transport "telegram"
takopi config set transports.telegram.bot_token "..."
takopi config set transports.telegram.chat_id 123456789
takopi config set transports.telegram.session_mode "chat"
takopi config set transports.telegram.show_resume_line false
takopi config set transports.telegram.topics.enabled false
takopi config set transports.telegram.topics.scope "auto"
```
[transports.telegram.topics]
enabled = false
scope = "auto"
```
=== "toml"
```toml title="~/.takopi/takopi.toml"
default_engine = "codex"
transport = "telegram"
[transports.telegram]
bot_token = "..."
chat_id = 123456789
session_mode = "chat" # auto-resume
show_resume_line = false # cleaner chat
[transports.telegram.topics]
enabled = false
scope = "auto"
```
=== "workspace"
```toml title="~/.takopi/takopi.toml"
default_engine = "codex"
transport = "telegram"
=== "takopi config"
[transports.telegram]
bot_token = "..."
chat_id = -1001234567890 # forum group
session_mode = "chat"
show_resume_line = false
```sh
takopi config set default_engine "codex"
takopi config set transport "telegram"
takopi config set transports.telegram.bot_token "..."
takopi config set transports.telegram.chat_id -1001234567890
takopi config set transports.telegram.session_mode "chat"
takopi config set transports.telegram.show_resume_line false
takopi config set transports.telegram.topics.enabled true
takopi config set transports.telegram.topics.scope "auto"
```
[transports.telegram.topics]
enabled = true # topics on
scope = "auto"
```
=== "toml"
```toml title="~/.takopi/takopi.toml"
default_engine = "codex"
transport = "telegram"
[transports.telegram]
bot_token = "..."
chat_id = -1001234567890 # forum group
session_mode = "chat"
show_resume_line = false
[transports.telegram.topics]
enabled = true # topics on
scope = "auto"
```
=== "handoff"
```toml title="~/.takopi/takopi.toml"
default_engine = "codex"
transport = "telegram"
=== "takopi config"
[transports.telegram]
bot_token = "..."
chat_id = 123456789
session_mode = "stateless" # reply-to-continue
show_resume_line = true # always show resume lines
```sh
takopi config set default_engine "codex"
takopi config set transport "telegram"
takopi config set transports.telegram.bot_token "..."
takopi config set transports.telegram.chat_id 123456789
takopi config set transports.telegram.session_mode "stateless"
takopi config set transports.telegram.show_resume_line true
takopi config set transports.telegram.topics.enabled false
takopi config set transports.telegram.topics.scope "auto"
```
[transports.telegram.topics]
enabled = false
scope = "auto"
```
=== "toml"
```toml title="~/.takopi/takopi.toml"
default_engine = "codex"
transport = "telegram"
[transports.telegram]
bot_token = "..."
chat_id = 123456789
session_mode = "stateless" # reply-to-continue
show_resume_line = true # always show resume lines
[transports.telegram.topics]
enabled = false
scope = "auto"
```
This config file controls all of Takopi's behavior. You can edit it directly to change settings or add advanced features.
+35 -13
View File
@@ -109,11 +109,20 @@ Each topic remembers its own default.
Set a default engine in your project config:
```toml
[projects.happy-gadgets]
path = "~/dev/happy-gadgets"
default_engine = "claude"
```
=== "takopi config"
```sh
takopi config set projects.happy-gadgets.path "~/dev/happy-gadgets"
takopi config set projects.happy-gadgets.default_engine "claude"
```
=== "toml"
```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.
@@ -144,15 +153,28 @@ This means: resume lines always win, then explicit directives, then the most spe
**Pattern: Quick questions vs. deep work**
```
# Global default for quick stuff
default_engine = "codex"
=== "takopi config"
# Project default for complex codebase
[projects.backend]
path = "~/dev/backend"
default_engine = "claude"
```
```sh
# Global default for quick stuff
takopi config set default_engine "codex"
# Project default for complex codebase
takopi config set projects.backend.path "~/dev/backend"
takopi config set projects.backend.default_engine "claude"
```
=== "toml"
```toml
# 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.
+39 -13
View File
@@ -31,10 +31,18 @@ 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"
```
=== "takopi config"
```sh
takopi config set projects.happy-gadgets.path "~/dev/happy-gadgets"
```
=== "toml"
```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`.
@@ -69,12 +77,22 @@ Worktrees let you run tasks on feature branches without touching your main check
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
```
=== "takopi config"
```sh
takopi config set projects.happy-gadgets.path "~/dev/happy-gadgets"
takopi config set projects.happy-gadgets.worktrees_dir ".worktrees"
takopi config set projects.happy-gadgets.worktree_base "main"
```
=== "toml"
```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`:
@@ -125,9 +143,17 @@ The `ctx:` line in each message carries the context forward.
If you mostly work in one repo, set it as the default:
```toml
default_project = "happy-gadgets"
```
=== "takopi config"
```sh
takopi config set default_project "happy-gadgets"
```
=== "toml"
```toml
default_project = "happy-gadgets"
```
Now messages without a `/project` prefix go to that repo: