Skip to content

owenob1/IssueMonitor-Python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IssueMonitor

Fetch, search, and retrieve GitHub issues — exported as LLM-friendly markdown, JSON, or compact agent format.

Features

  • Search issues by keyword using GitHub's Search API with full query syntax support
  • Fetch single issues by number with all comments included
  • Bulk fetch issues from any repo with date, state, and label filters
  • Watch mode — daemon that polls for new issues and comments on an interval
  • Three output formats — markdown, JSON, and a compact agent format optimised for LLM context windows
  • Flexible output — stdout, file, or custom path; pipe-friendly with --quiet
  • Auth-aware — works unauthenticated (60 req/hr) or with a token (5,000 req/hr)

Table of Contents

Quick Start

git clone https://github.com/owenob1/IssueMonitor-Python.git
cd IssueMonitor-Python

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# Search for issues matching a keyword
python -m issue_monitor --search "ECONNRESET timeout" --repo anthropics/claude-code

# Fetch a specific issue by number
python -m issue_monitor --issue 12345 --repo anthropics/claude-code

# Bulk fetch last 7 days (default)
python -m issue_monitor

Optionally copy .env.example to .env and add your GitHub token for higher rate limits (5,000 vs 60 requests/hour).

Installation

Prerequisites

  • Python 3.10+
  • Dependencies: PyGithub, rich, python-dateutil, python-dotenv

Setup

git clone https://github.com/owenob1/IssueMonitor-Python.git
cd IssueMonitor-Python

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Authentication

Method Rate Limit
Unauthenticated 60 requests/hour
With GITHUB_TOKEN 5,000 requests/hour

Token resolution order: --token flag > GITHUB_TOKEN env var > .env file > unauthenticated.

To set up a token:

  1. Go to GitHub Settings > Personal Access Tokens
  2. Generate a token with public_repo scope (or repo for private repos)
  3. Provide it via one of:
# .env file (recommended)
cp .env.example .env
# Edit .env and set GITHUB_TOKEN=ghp_xxx

# Environment variable
export GITHUB_TOKEN=ghp_xxx

# CLI flag
python -m issue_monitor --token ghp_xxx

Usage

Search Mode

Search issues by keyword using the GitHub Search API. Results are ranked by relevance. Defaults to --format agent --stdout.

# Basic search
python -m issue_monitor --search "rate limit" --repo anthropics/claude-code

# Limit results
python -m issue_monitor --search "crash" --repo vercel/next.js --limit 10

# Filter by state
python -m issue_monitor --search "memory leak" --repo facebook/react --state open

# Filter by label
python -m issue_monitor --search "timeout" --repo anthropics/claude-code --label bug

# Output as markdown instead
python -m issue_monitor --search "auth error" --repo anthropics/claude-code --format markdown

GitHub Search Syntax

The query is passed directly to the GitHub Search API. You can use any GitHub search qualifiers:

# Exact phrase
python -m issue_monitor --search '"connection reset"' --repo anthropics/claude-code

# Author filter
python -m issue_monitor --search "author:username bug" --repo anthropics/claude-code

# Date range (via GitHub syntax)
python -m issue_monitor --search "created:>2026-01-01 crash" --repo anthropics/claude-code

Get Issue Mode

Fetch a single issue by number with all comments. Defaults to --format agent --stdout. Returns an error if the number refers to a pull request.

python -m issue_monitor --issue 12345 --repo anthropics/claude-code

# Output as markdown
python -m issue_monitor --issue 12345 --repo anthropics/claude-code --format markdown

Bulk Fetch Mode

Fetch all issues from a time range. This is the default mode when neither --search nor --issue is specified. Defaults to --format markdown with file output.

# Target a repository
python -m issue_monitor --repo vercel/next.js
python -m issue_monitor --repo facebook/react

# Private repos require a token
python -m issue_monitor --repo myorg/private-repo --token ghp_xxx

# Date filtering
python -m issue_monitor --days 14
python -m issue_monitor --since 2026-01-01

# State and label filters
python -m issue_monitor --state open
python -m issue_monitor --label bug
python -m issue_monitor --label "bug,critical"

Watch Mode

Poll continuously for new issues and comments:

# Poll every 15 minutes (default)
python -m issue_monitor --watch

# Custom interval (30 minutes)
python -m issue_monitor --watch --interval 1800

# Run in background
nohup python -m issue_monitor --watch --quiet > monitor.log 2>&1 &

Behaviour:

  • First run fetches the last --days of issues
  • Subsequent polls fetch only issues updated since the last poll
  • State is persisted to output/.state.json (survives restarts)
  • Each poll writes to output/issues-latest.{md,json}
  • Daily snapshots are saved as output/issues-YYYY-MM-DD.{md,json}
  • Handles rate limits automatically (waits for reset)
  • Shuts down cleanly on SIGINT/SIGTERM

Output Formats

Format Description Best for
agent Compact markdown with truncated bodies (~500 chars) and latest comment preview (~200 chars) LLM context windows, AI agents
json Full structured data with all fields Programmatic processing, piping to jq
markdown Full readable markdown with complete bodies and all comments Human reading, reports, file output

Auto-defaults by mode:

Mode Default format Default output
--search agent stdout
--issue agent stdout
Bulk fetch markdown file

Override any default with --format and --stdout/--output.

Output Options

# stdout (default for search/issue modes)
python -m issue_monitor --search "error" --repo owner/repo

# File output (default for bulk fetch)
python -m issue_monitor

# Custom output path
python -m issue_monitor --output /path/to/issues.md

# Force stdout for bulk fetch
python -m issue_monitor --stdout

# Pipe JSON through jq
python -m issue_monitor --format json --stdout | jq '.issues | length'

# Suppress Rich progress output (logs still go to stderr)
python -m issue_monitor --quiet --stdout

CLI Reference

Flag Default Description
--repo anthropics/claude-code Target GitHub repository (owner/repo)
--search -- Search issues by keyword (GitHub Search API)
--issue -- Fetch a single issue by number
--limit 25 Max search results (1-100)
--days 7 Fetch issues from last N days (positive integer)
--since -- ISO 8601 date (alternative to --days)
--state all Filter: open, closed, all
--label -- Comma-separated label filter
--output output/issues-YYYY-MM-DD.md Output file path
--stdout false Print to stdout instead of file
--format markdown Output format: markdown, json, agent
--token $GITHUB_TOKEN GitHub personal access token
--quiet, -q false Suppress Rich progress output
--watch false Daemon mode: poll for updates
--interval 900 Poll interval in seconds (positive integer)

Mutual exclusivity:

  • --search and --issue cannot be combined
  • --search and --watch cannot be combined
  • --issue and --watch cannot be combined
  • --issue and --days/--since cannot be combined

Auto-defaults: --search and --issue default to --format agent --stdout unless explicitly overridden.

Examples

Agent Subprocess Call

# Search for relevant issues, parse JSON output
result=$(python -m issue_monitor --search "connection timeout" --repo anthropics/claude-code --format json --quiet)
echo "$result" | jq '.issues[0].title'

# Get a specific issue for context
python -m issue_monitor --issue 456 --repo anthropics/claude-code --quiet

Cron Job

# Daily at 6am
0 6 * * * cd /path/to/IssueMonitor-Python && .venv/bin/python -m issue_monitor --days 7 --quiet

GitHub Actions

- name: Fetch recent issues
  run: python -m issue_monitor --days 7 --format json --output issues.json
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

LLM Context Injection

# Pipe markdown to an LLM tool
python -m issue_monitor --stdout | your-llm-tool process

# Filter JSON to bugs only
python -m issue_monitor --format json --stdout \
  | jq '.issues[] | select(.labels | contains(["bug"]))'

Project Structure

issue_monitor/
  __init__.py       # Package marker
  __main__.py       # python -m entry point
  models.py         # Dataclasses, constants
  github.py         # API interaction, search, concurrent comment fetching
  formatting.py     # Markdown/JSON output, file writing
  watcher.py        # Daemon mode, state persistence
  cli.py            # Argument parsing, main()
scripts/
  fetch_issues.py   # Backwards-compatible shim
output/             # Generated files (gitignored, created on demand)

Troubleshooting

Rate Limit Exceeded

403: rate limit exceeded

Add a GitHub token — see Authentication.

Private Repo Access Denied

404 Not Found or 403 Forbidden

Ensure your token has repo scope and you have access to the repository.

ModuleNotFoundError

ModuleNotFoundError: No module named 'github'

Activate the virtual environment and install dependencies:

source .venv/bin/activate
pip install -r requirements.txt

Licence

MIT

About

CLI tool to fetch GitHub issues and comments for LLM processing

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages