teabot watches Gitea repos and dispatches one-shot Claude Code sessions in Docker containers to work issues and review PRs, acting as configurable bot personalities. Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
4.3 KiB
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, 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.
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:
logins:
- name: teabot-implementer
url: https://git.unkin.net
token: <bot-api-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.