Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/onenot8/issueLoop/llms.txt

Use this file to discover all available pages before exploring further.

IssueLoop needs somewhere to persist tickets between the triage step and the fix step — which may happen minutes, hours, or pipeline runs apart. Two backends are available: a local SQLite file that requires zero setup and is ideal for single-machine workflows, and a Supabase-hosted database for multi-process pipelines, parallel CI agents, or any scenario where more than one process needs to read and write tickets concurrently.

Local SQLite (default)

SQLite is the default backend. If you never call issueloop.use(), or if you call it without a database argument, IssueLoop creates data/issueloop.db in the IssueLoop working directory and applies the schema automatically on first connection — no migration tooling required.
import issueloop

issueloop.use(
    database="local",
    database_path="data/issueloop.db",  # optional — this is the default
)
The DB file is created with parents=True, so any missing parent directories are created automatically. Schema migrations are also applied at connection time: new columns (attempts, escalation_summary, proposed_fix, dispensed_at) are added with ALTER TABLE if they are missing, which means an existing database from an older version upgrades automatically. Tickets are dispensed in priority order. The dispense_next call (used by get_top_error) sorts candidates by this order before returning the first one:
PrioritySort key
blocking0
high1
normal2
low3
Within the same priority tier, tickets are ordered by created_at ascending — oldest first.

Supabase

Supabase provides a hosted Postgres database accessible over HTTP. Switch to it by changing the database argument; every other IssueLoop function works identically.
import issueloop

issueloop.use(database="supabase")
Install the extra dependency:
pip install "issueloop[supabase]"
Set the required environment variables. Copy .example.env to .env and fill in your project credentials:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-service-role-or-anon-key
IssueLoop calls load_dotenv() automatically when the Supabase backend initialises, so a .env file in your working directory is sufficient. If SUPABASE_URL or SUPABASE_KEY is missing at initialisation time, IssueLoop raises a RuntimeError with instructions. Create the tickets table using the SQL schema at sql/ticket_table.sql in the IssueLoop repository. Run it once against your Supabase project using the SQL editor or the Supabase CLI before your first run.

Retention and cleanup

IssueLoop does not grow the database indefinitely. The retention_days config option (default 30) controls how far back completed and failed tickets are kept. Pass it to issueloop.use():
issueloop.use(
    database="local",
    retention_days=14,
)
To trigger a cleanup manually:
# Delete done/failed tickets older than 30 days (uses retention_days config by default)
deleted = issueloop.cleanup(older_than_days=30)
print(f"Deleted {deleted} old tickets")

# Scope to a single repo
issueloop.cleanup(older_than_days=7, repo="myrepo")
To remove every ticket for a specific repo regardless of age or status:
removed = issueloop.purge_repo("myrepo")
print(f"Purged {removed} tickets for myrepo")

Database stats and export

Inspect the current state of the database without iterating over individual tickets:
stats = issueloop.get_database_stats("myrepo")
print(stats)
# {
#   "database": "local",
#   "total_bugs": 47,
#   "by_status": {
#     "pending": 12,
#     "in_progress": 3,
#     "done": 28,
#     "failed": 4
#   },
#   "db_size_bytes": 131072
# }
db_size_bytes is included when the local SQLite backend is active; it is omitted for Supabase. Export all tickets to a JSON file for backup or external reporting:
# Export to the default path: data/logs/bug_export.json
path = issueloop.export_bugs("myrepo")
print(f"Exported to {path}")

# Export to a custom path
issueloop.export_bugs("myrepo", path="backups/2024-01-15-myrepo.json")
The export file is a JSON array of ticket dicts in the same format returned by get_all_bugs.

Stale ticket reaping

When a ticket is dispensed via get_top_error, it is marked in_progress and its dispensed_at timestamp is recorded. If the worker that claimed the ticket crashes or times out before calling resolve or fail, the ticket remains stuck in in_progress indefinitely. reap_stale_bugs finds tickets that have been in_progress for longer than the given threshold and resets them to pending, making them available for the next get_top_error call:
# Reset any ticket in_progress for more than 30 minutes
reaped = issueloop.reap_stale_bugs(older_than_minutes=30)
print(f"Reaped {reaped} stale tickets")

# Scope to a single repo
issueloop.reap_stale_bugs(older_than_minutes=15, repo="myrepo")
Run reap_stale_bugs periodically — for example, at the start of each batch run — to ensure your queue does not fill up with stuck tickets.
When to use Supabase: switch from the local SQLite backend when you need any of the following:
  • Multi-process access — several CI agents running in parallel, each calling get_top_error, need a shared view of the queue so they do not claim the same ticket twice.
  • Persistent storage across machines — ephemeral CI runners that are torn down after each job cannot use a local file.
  • Backup and visibility — Supabase’s dashboard gives you a live table view of all tickets without running any IssueLoop commands.
For local development, single-machine automation, and getting started quickly, SQLite is simpler and has no dependencies beyond Python.

Build docs developers (and LLMs) love