feat(cli): add takopi config subcommand (#153)
This commit is contained in:
+151
-26
@@ -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"
|
||||
```
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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"]`.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user