# Configuration teabot reads a single YAML file, by default `$XDG_CONFIG_HOME/teabot/config.yaml` (i.e. `~/.config/teabot/config.yaml`). Override the path with `--config/-c`. Generate a starting point with [`teabot config init`](config.md), and validate the effective settings with `teabot config show`. ## Top-level keys | Key | Default | Description | |-----|---------|-------------| | `gitea_url` | `https://git.unkin.net` | Base URL of the Gitea instance to poll. | | `repos` | *(required)* | List of `owner/name` repositories to watch. | | `poll_interval` | `60s` | Delay between poll cycles (Go duration). | | `max_concurrent` | `2` | Maximum job containers running at once. | | `job_timeout` | `30m` | Per-session wall-clock timeout. | | `job_image` | `git.unkin.net/unkin/agent-dev:latest` | Container image each session runs in. | | `container_home` | `/home/agent` | Home dir inside `job_image` (mount target). | | `claude_config_dir` | `~/.claude` | Host dir with Claude Code credentials. | | `anthropic_api_key` | *(unset)* | If set, injected as `ANTHROPIC_API_KEY`. | | `anthropic_base_url` | *(unset)* | If set, injected as `ANTHROPIC_BASE_URL`. | | `state_dir` | `~/.local/state/teabot` | Where processed-event state is persisted. | | `personalities` | *(required)* | Bot identities (see below). | `~` and `~/` are expanded in path-valued keys. ## Personalities A personality is a distinct Gitea bot account. teabot must be able to act as different identities — e.g. an implementer that opens PRs and a separate reviewer that critiques them — so each personality points at its **own tea config file** rather than sharing your personal `~/.config/tea/config.yml`. ```yaml personalities: - name: implementer tea_config: ~/.config/teabot/tea-implementer.yml role: implementer # implementer | reviewer | both git_name: Teabot Implementer git_email: teabot-implementer@unkin.net - name: reviewer tea_config: ~/.config/teabot/tea-reviewer.yml role: reviewer git_name: Teabot Reviewer git_email: teabot-reviewer@unkin.net ``` | Field | Description | |-------|-------------| | `name` | Label used in logs and prompts. | | `tea_config` | Path to a `tea` config.yml holding this bot's login. teabot reads the API token + username from it and mounts it into the job container. | | `role` | `implementer` (issues), `reviewer` (pull requests), or `both`. Defaults to `both`. | | `git_name` / `git_email` | Commit identity set inside the container. | Create each tea config with the normal tea workflow, pointing `HOME`/ `XDG_CONFIG_HOME` at a scratch dir so it lands somewhere dedicated, or copy an existing `config.yml` and edit the token. The file format is exactly tea's own: ```yaml logins: - name: teabot-implementer url: https://git.unkin.net token: default: true user: teabot-implementer ``` teabot picks the login whose `url` matches `gitea_url`, else the `default`, else the first. The `user` field is the bot's username — teabot uses it for **loop prevention** (it never reacts to events authored by any personality's username). At least one personality must be able to implement and at least one to review, or config validation fails. ## Claude credentials By default teabot uses your Claude **subscription** auth: it copies `claude_config_dir` (default `~/.claude`) into a per-job scratch dir and mounts that copy read-write into the container, so the session can refresh tokens without ever mutating your real config. Alternatively set `anthropic_api_key` (and optionally `anthropic_base_url` for a gateway such as LiteLLM). When present these are injected as environment variables and take precedence over the mounted subscription credentials. ## SELinux This host is Fedora, so Docker bind mounts are relabelled with `:z`. teabot does this automatically. If you run under a different security model, the relabel suffix is a field on `DockerRunner` (`SELinuxLabel`). ## A note on comment follow-ups teabot only continues comment threads on issues/PRs it **acted on** itself (opened a PR for, or reviewed). A comment on an unrelated thread is recorded but ignored. Combined with loop prevention (bot-authored comments are skipped), this means teabot will not, for example, keep answering an issue it decided not to implement — it engages a thread only after it has taken an action there.