Skip to content

GitHub Issues

This guide shows you how to connect Itervox to a GitHub repository so AI agents automatically pick up open issues and resolve them.

  • A GitHub repository (public or private)
  • A GitHub Personal Access Token (PAT) with the correct scopes (see below)
  • The itervox binary installed and available on your $PATH
  • The repository checked out locally

Itervox needs permission to read issues and create pull requests.

  1. Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens.
  2. Click Generate new token.
  3. Under Repository access, select Only select repositories and choose your target repo.
  4. Under Permissions, grant:
    • Issues — Read and write
    • Pull requests — Read and write
    • Contents — Read and write (required for agents that push branches)
  5. Click Generate token and copy it immediately.

If you prefer a classic token, create one with the repo scope at Settings → Developer settings → Personal access tokens → Tokens (classic).

Store the token in an environment variable:

Terminal window
export GITHUB_TOKEN="github_pat_xxxxxxxxxxxxxxxxxxxx"

Run the init command from the root of your repository:

Terminal window
itervox init --tracker github

This creates a WORKFLOW.md with YAML front matter and a default Liquid prompt template. Open the file and fill in the required fields.

GitHub Issues have a simpler state model than Linear: issues are either open or closed. Itervox maps these states directly.

---
tracker:
kind: github
api_key: $GITHUB_TOKEN # resolved from env at runtime
project_slug: owner/repo # GitHub "owner/repo" path
# Issues must be open to be dispatched; closed issues are terminal
active_states:
- open
# Itervox does not transition GitHub issue state automatically by default.
# Set completion_state to "closed" to close issues on success,
# or leave empty to leave them open until a human closes them.
completion_state: ""
terminal_states:
- closed
agent:
max_concurrent_agents: 3
polling:
interval_ms: 30000
---
You are an AI agent resolving GitHub issue #{{ issue.number }}: {{ issue.title }}.
{{ issue.description }}
Complete the task, push your changes to a new branch, and open a pull request.
FieldValueNotes
active_states["open"]Only open issues are dispatched
terminal_states["closed"]Closed issues are never re-dispatched
working_state(empty)GitHub has no intermediate states; leave empty
completion_state"closed" or ""Set to "closed" to auto-close issues on success
backlog_states[]Not applicable for GitHub

From the directory containing WORKFLOW.md:

Terminal window
itervox

Itervox polls the GitHub Issues API every interval_ms milliseconds and dispatches an agent for each open issue that does not already have a running worker.

Open the dashboard at http://localhost:8090 to monitor progress.

GitHub Issues has only two native states: open and closed. To get intermediate states (like “in progress”, “in review”), Itervox uses labels as state proxies.

When you set active_states: ["todo", "in-progress"], Itervox fetches open issues that have a todo or in-progress label. When it transitions state (e.g., on completion), it removes the old state label and adds the new one.

tracker:
active_states:
- todo
- in-progress
terminal_states:
- done
- closed
completion_state: done # adds "done" label when agent finishes
backlog_states:
- backlog # optional: enables the backlog panel in TUI/dashboard

Create these labels in your GitHub repository before running Itervox. Then assign the todo label to issues you want agents to pick up.

Itervox works with GitHub Issues + labels directly. It does not integrate with GitHub Projects v2 (the board/kanban feature). This means:

  • No column-based state management (cards don’t move between project board columns)
  • No project board filtering or views
  • The TUI/dashboard project picker is not available for GitHub (it’s a Linear-only feature)

If your team uses GitHub Projects for tracking, you can still use Itervox — just make sure your issues also have the correct state labels. Itervox reads labels, not board columns.

For GitHub Enterprise Server, set tracker.endpoint in your WORKFLOW.md:

tracker:
kind: github
endpoint: https://github.yourcompany.com/api/v3
api_key: $GITHUB_TOKEN
project_slug: org/repo

The Liquid prompt template has access to the full issue object, including its labels. You can use this to give agents specialised instructions based on how the issue is tagged.

---
tracker:
kind: github
api_key: $GITHUB_TOKEN
project_slug: owner/repo
active_states:
- open
terminal_states:
- closed
agent:
max_concurrent_agents: 5
---
You are an AI agent resolving GitHub issue #{{ issue.number }}: {{ issue.title }}.
{{ issue.description }}
{% if issue.labels contains "bug" %}
This is a **bug report**. Your priority is to:
1. Reproduce the bug with a failing test.
2. Fix the root cause.
3. Verify the fix passes all existing tests.
4. Open a pull request with a clear description of the fix.
{% elsif issue.labels contains "feature" %}
This is a **feature request**. Your priority is to:
1. Implement the feature as described.
2. Add appropriate tests.
3. Update documentation if needed.
4. Open a pull request.
{% else %}
Implement the changes described in the issue, add tests, and open a pull request.
{% endif %}
FieldDescription
issue.numberGitHub issue number
issue.titleIssue title
issue.descriptionIssue body text
issue.labelsArray of label names
issue.branch_nameBranch name created for this issue
issue.identifierSame as issue.number for GitHub

You can narrow which issues get dispatched by using specific labels in active_states. For example, set active_states: ["ready"] and only assign the ready label to issues you want agents to work on. Use the TUI or web dashboard to pause individual issues while you refine your workflow.

Set completion_state: closed to have Itervox close issues automatically when an agent finishes. Combine this with a pull-request merge hook so the issue closes only after the PR lands:

hooks:
after_run: ./scripts/close-issue-on-merge.sh

The GitHub API allows up to 5 000 authenticated requests per hour for fine-grained tokens. With the default 30-second polling interval and a small number of concurrent agents, you are well within limits. Lower interval_ms only if you need near-real-time dispatch.