Tracker: GitHub Issues¶
Use this when your tickets are GitHub Issues. The simplest setup overall — same provider for code and tickets, one token, one webhook secret. The example is the fictional TodoList product on github.com/acme-org.
In the studio¶
Configuration for a server lives in the database and you edit it in the dashboard: switch the left rail to Configuration and work down the catalogs. The order matters, because each entry references the one before it: Secrets (names only), then Agents, then Repositories, then a Tracker, then a Project that wires them together. References are picked from dropdowns, so a project can't point at something that doesn't exist, and the drawer keeps Create disabled until every reference resolves.
GitHub specifics: pick type github on the tracker and the form asks for the repository URL (the repo whose issues are the tickets) and the auth secret. Trigger statuses and open states stay empty for GitHub, since issues are open or closed and the routing happens on labels. The "Default pipeline" field sets what an issue runs when no label in the tracker's label map matched.
The full tour is on The Config studio; what follows is the same wiring written as YAML, which is what the CLI reads directly and what agent-smith config import takes.
The same thing as YAML¶
# yaml-language-server: $schema=https://raw.githubusercontent.com/holgerleichsenring/agent-smith/main/config/agentsmith.schema.json
agents:
default-openai:
type: openai
models:
scout: { model: gpt-4.1-mini }
primary: { model: gpt-4.1 }
planning: { model: gpt-4.1 }
summarization: { model: gpt-4.1-mini }
repos:
todolist-api:
type: github
url: https://github.com/acme-org/todolist-api
auth: github_token
todolist-worker:
type: github
url: https://github.com/acme-org/todolist-worker
auth: github_token
todolist-web:
type: github
url: https://github.com/acme-org/todolist-web
auth: github_token
trackers:
acme-issues:
type: github
url: https://github.com/acme-org/todolist-api # the repo whose issues are the tickets
auth: github_token
open_states: [open]
done_status: closed
default_pipeline: code
projects:
github-todolist:
agent: default-openai
tracker: acme-issues
repos: [todolist-api, todolist-worker, todolist-web]
github_trigger:
project_resolution:
strategy: tag # an issue labelled todolist routes here
value: todolist
trigger_statuses: [open]
done_status: closed
pipeline_from_label:
agent-smith:bug: code
agent-smith:feature: code
agent-smith:security-scan: security-scan
secrets:
openai_api_key: ${OPENAI_API_KEY}
github_token: ${GITHUB_TOKEN}
GitHub-specific things to notice:
urlon the tracker is a repository — GitHub has no Azure-DevOps-style project concept. Issues belong to a repo, so the tracker names the one repo whose issues Agent Smith reads and writes.open_states: [open]+done_status: closed— GitHub Issues are binary, open or closed. There's no in-between state.project_resolution.strategy: tag— a label on the issue picks the project. The agent still touches all repos inprojects.X.reposduring the run; the resolution is about which project to wake up, not which repo to change. Therepostrategy (route by the repo the issue was filed in) only works for a project with exactly one repo; see Project resolution.work_item_kindsdoes nothing here — GitHub issues have no type to pick, so the tracker ignores it.
The tracker owns the workflow: open_states, done_status, failed_status, trigger_statuses (falls back to open_states) and pipeline_from_label can all sit on the tracker block, inherited by every project routed to it. A project then only declares its resolution:
trackers:
acme-issues:
type: github
url: https://github.com/acme-org/todolist-api
auth: github_token
open_states: [open]
done_status: closed
pipeline_from_label:
agent-smith:bug: code
agent-smith:feature: code
projects:
github-todolist:
agent: default-openai
tracker: acme-issues
repos: [todolist-api, todolist-worker, todolist-web]
resolution:
tag: todolist
The explicit github_trigger: block from the full config works too and overrides the tracker field by field — use it when one project needs its own comment_keyword or a different label map.
Skills need no configuration: they ship embedded in the release; a skills: block is only an override for skills development or air-gap mirrors (see Skills catalog).
Authentication¶
Use a fine-grained Personal Access Token with these repository permissions: Contents (Read & Write), Pull requests (Read & Write), Issues (Read & Write).
The tracker and the repos read the token through the secret their auth names (github_token: ${GITHUB_TOKEN}), for API calls and for clone and push alike, so a repo of another owner can carry a token of its own.
How tickets reach Agent Smith¶
- Webhook (preferred). One webhook per repo, or one org-level webhook. The server listens on port 8081; point the webhook at
POST /webhook/github(or the genericPOST /webhook— the platform is auto-detected from the headers). Verification is HMAC via theX-Hub-Signature-256header, checked against theGITHUB_WEBHOOK_SECRETenvironment variable on the server process — there is no secret key in the config. See Webhooks: GitHub. - Polling. Add
polling: { enabled: true, interval_seconds: 60 }to the tracker when webhooks can't reach the server. - Manual CLI.
agent-smith code --ticket 54 --project github-todolist.
What gets written back to the ticket¶
The database is the system of record; the issue state and labels are a best-effort projection of it.
When a run finishes:
- Issue gets closed (state →
closed). - A new comment with the PR URLs and the run id.
- The
agent-smith:donelabel gets added;agent-smith:in-progressremoved. - PRs whose verification came back red are opened as drafts.
When a run fails, the issue moves to failed_status if configured (with GitHub's binary open/closed model that usually means it stays open), the agent-smith:failed label gets added, and a comment carries the error. The run lifecycle (pending / enqueued / in-progress / done / failed, plus waiting and shortfall) is carried as agent-smith:* labels, the same as on every tracker. A label_names: map on the tracker renames them if your repo already uses its own words.
When the PR opens, Agent Smith uses the Closes #54 linkage so GitHub auto-closes the issue if the PR merges. That's belt-and-suspenders — the framework also closes the issue explicitly via the API in the WriteRunResult step.
When an issue is too thin to act on (title-only, or the run needs a decision), Agent Smith doesn't guess: it posts its open questions as an issue comment and parks the issue in needs_clarification_status (settable on the tracker or the project). Answering resumes the run — see Spec dialogue.
Cross-repo issues¶
GitHub Issues belong to one repo, but a TodoList ticket may need changes in all three repos (todolist-api, todolist-worker, todolist-web). The convention: file the issue in the repo the tracker points at, and label it for the project. The Agent Smith run touches every repo it needs to, opens one PR per repo, and cross-links them in each PR's body.