Skip to content

Latest commit

 

History

History

github

README.md

GitHub Integration Scripts

Scripts for integrating GitHub context and repository management into AI agent workflows.

⚠️ Self-merge / Greptile / PR-monitoring toolchain — READ BEFORE BUILDING

If you're about to build PR monitoring, a Greptile review loop ("greploop"), self-merge logic, a stale-PR sweep, or a Greptile score check — it already exists here. This toolchain is shared across agents (Alice, Bob) and is hardened for scale. Don't rebuild a parallel; use or extend these. (Origin of this note: 2026-06 an agent rebuilt greploop + a sweep + a score parser that all already existed. See scripts/workflow/read-the-task-before-reinvestigating patterns.)

The canonical flow — drive a PR to merge ("greploop"):

Step Tool Notes
Discover stalled PRs activity-gate.sh (has a Greptile score sweep) · pr-queue-health.py event-driven; surfaces low-scored / stuck PRs
Trigger / re-trigger review greptile-helper.sh (anti-spam: flock, ack-detect, max-retriggers) · pr-greptile-trigger.py (batch) NEVER post raw @greptileai review
Read the score signal greptile-merge-signal.py (summary score ≥ threshold + "Safe to merge") reusable; default 5/5
Address findings, push (agent session) fix the code
Resolve addressed threads resolve-greptile-threads.py the resolveReviewThread mutation; fix-first; resolves Greptile-bot threads only
Gate the merge self-merge-check.py CI green + a clean machine review + no unresolved threads + score floor (SELF_MERGE_MIN_GREPTILE_SCORE, default 5/5) + category/sensitive-path filter
Merge self-merge-if-eligible.sh / pr-address-wait-and-merge.sh (Bob) bounded poll-budget wait → merge

Greptile is not the only accepted reviewer. On repos Greptile does not cover, the gate was unsatisfiable ("Greptile review not found"). self-merge-check.py now also accepts the self-hosted reviewer's <!-- bob-ai-review {…} --> summary marker — but only at full strength: 5/5, at the current head SHA, with an undegraded consensus record, non-abstaining, and posted by the authenticated user. Anything less falls back to requiring Greptile. It is an OR, never a replacement: when Greptile has reviewed, the path is byte-for-byte what it always was and the marker is not even fetched. Kill switch: SELF_MERGE_ACCEPT_AI_REVIEW=0. The strictness is tuned for recall, not precision — a false finding only lowers the score and costs a wasted round, whereas a missed bug produces a clean score and an unreviewed merge.

Robustness patterns (tuned at scale — reuse, don't reinvent):

  • Rate limits: gate on github-rate-limit-health.sh (GH_RATE_LIMIT_HELPER; self-merge-check.py defers with exit 76). Re-check before expensive sub-steps, not just at cycle start.
  • Fewer API calls: fetch Greptile review data ONCE per PR and reuse (see self-merge-check.py's _fetch_greptile_review_data passed to both helpers). Don't spawn a per-PR subprocess that re-fetches.
  • Caching: key Greptile status by PR head-SHA — unchanged PRs skip the fetch.
  • Pagination: paginate reviewThreads (avoids silently undercounting unresolved threads).
  • GraphQL attribution: wrap GraphQL calls for consumption accounting.

See also: knowledge/research/2026-06-12-monitoring-robustness-alice-vs-bob.md (Alice repo) and the greploop skill (greptileai/skills, MIT) for the upstream pattern this implements.

Scripts

context-gh.sh

Generates comprehensive GitHub context for AI agent conversations, reducing the need for manual tool calls during autonomous operation.

Features:

  • GitHub notifications (unread, with type and reason)
  • Open issues in agent workspace repository
  • Multi-repository CI status checking
  • Open PRs across all repositories
  • Recent PRs in current repository

Usage:

./scripts/github/context-gh.sh

Requirements:

  • gh (GitHub CLI) installed and authenticated
  • Repository list configured in repo-status.sh

Output: Markdown-formatted sections that can be included in agent context via gptme.toml's context_cmd.

repo-status.sh

Check CI status across multiple repositories to catch failing builds before pushing changes.

Features:

  • Quick status check for multiple repos
  • Color-coded output (✓ passing, ✗ failing, ⚠ other states)
  • Workflow URL display for failing builds
  • Configurable repository list

Usage:

./scripts/github/repo-status.sh

Configuration: Pass repositories as arguments (format: owner/repo:Label or just owner/repo):

./scripts/github/repo-status.sh gptme/gptme:gptme gptme/gptme-rag:gptme-rag

Or set GH_USER environment variable to customize user for PR checking:

export GH_USER=myusername
./scripts/github/repo-status.sh

Default behavior (no arguments): Checks gptme ecosystem repos.

Requirements:

  • gh (GitHub CLI) installed and authenticated

activity-gate.sh

Lightweight pre-check that scans GitHub for actionable activity before spawning an expensive LLM session. Uses state-tracked timestamps to avoid re-reporting old items.

Without this gate, monitoring services can waste hundreds of LLM sessions per week on empty runs. In Bob's deployment, this gate prevents ~97% of NOOP monitoring runs.

Checks performed:

  • PR updates (new comments, reviews — excluding self-authored)
  • CI failures (state-change tracked, dedup by conclusion hash)
  • Merge conflicts (always reported until resolved)
  • Merge readiness (CLEAN status + acceptable Greptile score)
  • GitHub notifications (filtered for actionable reasons)
  • Greptile score sweep (finds low-scored PRs needing code fixes)
  • Assigned issues (issues assigned to the configured author)
  • Master branch CI failures (CI regressions on the main branch)

Exit codes:

  • 0 = actionable work found (items printed to stdout)
  • 1 = no actionable work found
  • 2 = usage error

Usage:

# Basic usage
activity-gate.sh --author MyBot --org myorg

# With extra repos outside the org
activity-gate.sh --author MyBot --org myorg --repo OtherOrg/repo

# JSONL output for structured processing
activity-gate.sh --author MyBot --org myorg --format jsonl

# Custom state directory (default: /tmp/github-activity-gate-state)
activity-gate.sh --author MyBot --org myorg --state-dir /tmp/my-state

# Use as a gate before spawning a session
if work=$(./activity-gate.sh --author MyBot --org myorg); then
    echo "Work found, spawning session..."
    echo "$work"
else
    echo "Nothing to do, skipping."
fi

State tracking: Each check type uses files in the state directory to remember what it last reported. On first run, all items are seeded (state created) but NOT reported — only changes after the first run trigger output. This prevents a flood of items on initial setup.

Integration pattern (project monitoring):

# In your monitoring script:
ACTIVITY_GATE="$WORKSPACE/gptme-contrib/scripts/github/activity-gate.sh"
STATE_DIR="/tmp/my-agent-monitoring-state"

# Use a pending state dir so crashes don't lose state
PENDING_STATE_DIR="${STATE_DIR}-pending"
mkdir -p "$STATE_DIR" "$PENDING_STATE_DIR"
rsync -a --delete "$STATE_DIR/" "$PENDING_STATE_DIR/"

gate_exit=0
work=$("$ACTIVITY_GATE" --author "$AUTHOR" --org "$ORG" \
    --state-dir "$PENDING_STATE_DIR" --format jsonl) || gate_exit=$?
if [ "$gate_exit" -eq 2 ]; then
    echo "Error: activity-gate.sh usage error (check AUTHOR/ORG/STATE_DIR are set)" >&2
    exit 2
elif [ "$gate_exit" -ne 0 ]; then
    echo "No work found, skipping session."
    exit 0
fi

# Promote state only after successful session — uncomment after your session call:
# rsync -a "$PENDING_STATE_DIR/" "$STATE_DIR/"
# Without this, all items re-emit every run (state is never committed).

Requirements:

  • gh (GitHub CLI) installed and authenticated
  • jq for JSONL output parsing

greptile-helper.sh

Safe Greptile review trigger with anti-spam guards (flock, age guard, max re-triggers, fail-safe cooldown). Always use this instead of posting raw @greptileai review comments.

Usage:

# Trigger a review (safe — checks guards first)
bash scripts/github/greptile-helper.sh trigger OWNER/REPO PR_NUMBER

# Check review status
bash scripts/github/greptile-helper.sh status OWNER/REPO PR_NUMBER

Requirements:

  • gh (GitHub CLI) installed and authenticated
  • Greptile GitHub app installed on the target repository

check-notifications.sh

Fetch and format unread GitHub notifications for agent context injection.

Usage:

./scripts/github/check-notifications.sh

Integration with gptme

These scripts are designed to be integrated into gptme agent workflows:

  1. Dynamic Context: Include context-gh.sh in your agent's main context.sh script:

    # In your agent's scripts/context.sh
    ./gptme-contrib/scripts/github/context-gh.sh

    Or use directly in gptme.toml (less common):

    context_cmd = "gptme-contrib/scripts/github/context-gh.sh"
  2. Pre-Push Checks: Run repo-status.sh before pushing to ensure CI health:

    ./scripts/github/repo-status.sh && git push
  3. Autonomous Operations: Include GitHub context automatically in agent prompts to reduce exploratory tool calls.

  4. Project Monitoring Gate: Use activity-gate.sh to prevent wasted LLM sessions:

    # In your monitoring timer/service script
    if work=$(./gptme-contrib/scripts/github/activity-gate.sh \
        --author MyAgent --org myorg --format jsonl); then
        # Spawn LLM session with $work as context
        echo "$work" | your-agent-harness
    fi

Benefits

  • Reduced Tool Calls: GitHub context is served upfront instead of requiring multiple API calls
  • Faster Decision Making: Agent can see notifications, issues, and CI status immediately
  • Better Coordination: Agent aware of open issues and PRs without manual checking
  • CI Health Awareness: Catch failing builds before adding more changes

pr-greptile-trigger.py

Batch-trigger safe Greptile re-review requests for open PRs.

Scans open PRs authored by the authenticated user, identifies which ones need a re-review because new commits landed since the last Greptile review, and routes triggers through greptile-helper.sh. Never triggers initial reviews — Greptile auto-reviews new PRs.

Features:

  • Safe re-review triggering (no spam — uses greptile-helper.sh guards)
  • Configurable repo list via GREPTILE_REPOS env var or --repo flag
  • Dry-run mode by default (use --execute to actually trigger)
  • Status overview mode (--status)
  • Filter PRs by author via --author (default: authenticated user)

Usage:

# Show what would be triggered (dry-run)
python3 scripts/github/pr-greptile-trigger.py

# Actually trigger re-reviews
python3 scripts/github/pr-greptile-trigger.py --execute

# Show review status for all open PRs
python3 scripts/github/pr-greptile-trigger.py --status

# Scan a specific repo
python3 scripts/github/pr-greptile-trigger.py --repo gptme/gptme

# Use custom repo list
GREPTILE_REPOS=myorg/repo1,myorg/repo2 python3 scripts/github/pr-greptile-trigger.py

# Filter by a specific author (useful in shared CI contexts)
python3 scripts/github/pr-greptile-trigger.py --author mybot

Requirements:

  • gh (GitHub CLI) installed and authenticated
  • greptile-helper.sh in the same directory

self-merge-check.py

Evaluates whether a PR is eligible for autonomous agent self-merge.

Applies a conservative policy: CI must be green, Greptile must have reviewed with no unresolved threads, and changed files must fall into a low-risk category (tests, docs, lessons, internal tooling, task metadata). Sensitive/infra paths immediately disqualify.

Features:

  • Auto-detects workspace repo from git remote (override with --workspace-repo or WORKSPACE_REPO)
  • Cross-repo PRs disqualified when workspace repo is set (clear WORKSPACE_REPO to disable)
  • JSON output mode for scripting
  • Detailed per-check reasoning

Usage:

# Check a PR by URL
python3 scripts/github/self-merge-check.py https://github.com/owner/repo/pull/123

# Check by repo and number
python3 scripts/github/self-merge-check.py --repo gptme/gptme 456

# JSON output for scripting
python3 scripts/github/self-merge-check.py --json https://github.com/owner/repo/pull/123

# Allow cross-repo merges (clear workspace repo restriction)
WORKSPACE_REPO="" python3 scripts/github/self-merge-check.py https://github.com/gptme/gptme/pull/456

# Override workspace repo detection
python3 scripts/github/self-merge-check.py --workspace-repo myorg/myrepo <pr-url>

Exit codes: 0 = eligible, 1 = not eligible, 2 = error

Requirements:

  • gh (GitHub CLI) installed and authenticated
  • Greptile installed on the target repo for review checking

greptile-merge-signal.py

Evaluates whether a Greptile summary comment is strong enough for fast-path merge use: allowlisted bot login + "Safe to merge" + score ≥ threshold (default 5/5). A reusable score signal — self-merge-check.py wires it in as the score floor so resolving threads alone can't merge a low-scored PR. Parse failure does not block (the thread/category gates still apply).

python3 scripts/github/greptile-merge-signal.py --repo owner/repo 123   # JSON; exit 0 eligible, 1 not

resolve-greptile-threads.py

Resolves addressed Greptile review threads via the resolveReviewThread GraphQL mutation — the gap that blocks self-merge-check.py (it requires no unresolved threads, but we reply to nitpicks rather than resolve them, so the deterministic merge path never fires on nitpick-laden PRs). Call it after addressing findings (fix-first), or with --outdated-only for the conservative "code changed since the comment" heuristic. Safety: only ever resolves Greptile-bot-authored threads — never touches human threads. Paginates reviewThreads so it can't silently undercount; per-thread resolve failures are non-fatal (the loop continues).

# Dry-run first — list what would be resolved
python3 scripts/github/resolve-greptile-threads.py owner/repo#123 --dry-run

# Resolve all addressed Greptile threads (JSON summary on stdout, progress on stderr)
python3 scripts/github/resolve-greptile-threads.py owner/repo#123 --json

# Conservative: only resolve threads whose code changed since the comment
python3 scripts/github/resolve-greptile-threads.py owner/repo 123 --outdated-only

Exit codes: 0 = ok (prints count resolved), 2 = arg/gh error.

Related