View on GitHub

cat-github-watcher

cat-github-watcher

cat-github-watcher

PR monitoring tool for the automated implementation phase by GitHub Copilot

Japanese English Ask DeepWiki

Note: This document is largely AI-generated. It was generated by submitting an issue to an agent.

Status

| Item | Link | |——|——–| | 📊 GitHub Repository | cat2151/cat-github-watcher |

Overview

This is a Python tool that monitors the phases of Pull Requests where GitHub Copilot performs automated implementation, executing appropriate notifications and actions at the right time. It efficiently monitors PRs using the GraphQL API, targeting user-owned repositories of authenticated GitHub users.

Features

Architecture

This tool is a Python application modularized according to the Single Responsibility Principle (SRP).

Directory Structure

cat-github-watcher/
├── cat-github-watcher.py    # Entry point
├── src/
│   └── gh_pr_phase_monitor/
│       ├── colors.py         # ANSI color codes and coloring
│       ├── config.py         # Configuration loading and parsing
│       ├── github_client.py  # GitHub API integration
│       ├── phase_detector.py # PR phase detection logic
│       ├── comment_manager.py # Comment posting and verification
│       ├── pr_actions.py     # PR actions (Ready-up, browser launch)
│       └── main.py           # Main execution loop
└── tests/                    # Test files

Phase Detection Logic

The tool identifies the following four phases:

  1. phase1 (Draft state): When the PR is in Draft state and has review requests.
  2. phase2 (Addressing review comments): When copilot-pull-request-reviewer has posted review comments and corrections are needed.
  3. phase3 (Awaiting review): When copilot-swe-agent has completed corrections and is awaiting human review.
  4. LLM working (Coding agent in progress): When none of the above apply (e.g., Copilot is implementing).

Usage

Prerequisites

Setup

  1. Clone this repository:
    git clone https://github.com/cat2151/cat-github-watcher.git
    cd cat-github-watcher
    
  2. Create a configuration file (optional):
    cp config.toml.example config.toml
    
  3. Edit config.toml to configure monitoring intervals, execution modes, ntfy.sh notifications, Copilot auto-assignment, and auto-merging (optional):
    # Check interval (e.g., "30s", "1m", "5m", "1h", "1d")
    interval = "1m"
       
    # Upper limit on the number of issues to display from repositories without PRs
    # Default is 10, but can be changed to any positive number (e.g., 5, 15, 20)
    issue_display_limit = 10
       
    # Timeout duration for no state change
    # If the state of all PRs (each PR's phase) does not change for this duration,
    # the monitoring interval switches to power-saving mode (reduced_frequency_interval below).
    # Set to an empty string "" to disable.
    # Supported formats: "30s", "1m", "5m", "30m", "1h", "1d"
    # Default: "30m" (30 minutes - stability priority)
    no_change_timeout = "30m"
       
    # Monitoring interval in power-saving mode
    # If no state change is detected during the no_change_timeout period,
    # the monitoring interval switches to this interval to reduce API usage.
    # When a change is detected, it returns to the regular monitoring interval.
    # Supported formats: "30s", "1m", "5m", "30m", "1h", "1d"
    # Default: "1h" (1 hour)
    reduced_frequency_interval = "1h"
       
    # Verbose mode - display detailed configuration information
    # If enabled, all settings are displayed on startup, and per-repository settings are also displayed during execution.
    # Useful for detecting configuration errors.
    # Default: false
    verbose = false
       
    # Execution control flags - only configurable within the [[rulesets]] section
    # Global flags are no longer supported
    # To apply settings to all repositories, use 'repositories = ["all"]'
       
    # Ruleset configuration example:
    # [[rulesets]]
    # name = "Default for all repositories - dry-run mode"
    # repositories = ["all"]  # "all" matches all repositories
    # enable_execution_phase1_to_phase2 = false  # set to true to make draft PRs ready
    # enable_execution_phase2_to_phase3 = false  # set to true to post phase2 comment
    # enable_execution_phase3_send_ntfy = false  # set to true to send ntfy notification
    # enable_execution_phase3_to_merge = false   # set to true to merge phase3 PR
       
    # [[rulesets]]
    # name = "Simple: automatically assign good first issues to Copilot"
    # repositories = ["my-repo"]
    # assign_good_first_old = true  # This is enough! The [assign_to_copilot] section is not needed.
    #                               # Default behavior: open issue in browser for manual assignment.
       
    # ntfy.sh notification settings (optional)
    # Notifications include a clickable action button to open the PR.
    [ntfy]
    enabled = false  # set to true to enable notifications
    topic = "<Enter your ntfy.sh topic name here>"  # This topic can be read/written by anyone, so please use an unguessable string.
    message = "PR is ready for review: {url}"  # Message template
    priority = 4  # Notification priority (1=lowest, 3=default, 4=high, 5=highest)
    all_phase3_message = "All PRs are now in phase3 (ready for review)"  # Message when all PRs enter phase3
       
    # Phase3 Auto-merge settings (optional)
    # Automatically merges the PR when it reaches phase3 (awaiting review).
    # Before merging, the comment defined below will be posted to the PR.
    # After successful merge, the feature branch will be automatically deleted.
    # IMPORTANT: For safety, this feature is disabled by default.
    # You must explicitly enable it by setting enable_execution_phase3_to_merge = true in the rulesets for each repository.
    # IMPORTANT: If auto-merge is enabled, the comment field must be explicitly configured.
    [phase3_merge]
    comment = "The agent determines that review comments have been addressed. Under the user's responsibility, user review will be omitted. Merging the PR."  # Comment to post before merging (required when auto-merge is enabled)
    automated = false  # set to true to click merge button via browser automation
    wait_seconds = 10  # Wait time in seconds after browser launch, before clicking the button
    debug_dir = "debug_screenshots"  # Directory to save debug information on image recognition failure (default: "debug_screenshots")
       
    # Automatically assign issues to Copilot (completely optional! This entire section is optional)
    # 
    # Simple usage: just set assign_good_first_old = true in rulesets (see example above)
    # Define this section only if you want to customize the default behavior.
    # 
    # Assignment behavior is controlled by ruleset flags:
    # - assign_good_first_old: Assigns the oldest "good first issue" (by issue number, default: false)
    # - assign_old: Assigns the oldest issue (by issue number, any label, default: false)
    # If both are true, "good first issue" is prioritized.
    # 
    # Default behavior (if this section is not defined):
    # - Automatically clicks buttons via browser automation
    # - Uses PyAutoGUI
    # - wait_seconds = 10
    # 
    # REQUIRED: PyAutoGUI installation is required (pip install pyautogui pillow)
    # 
    # IMPORTANT: For safety, this feature is disabled by default.
    # You must explicitly enable it by specifying assign_good_first_old or assign_old in the rulesets for each repository.
    [assign_to_copilot]
    wait_seconds = 10  # Wait time in seconds after browser launch, before clicking the button
    debug_dir = "debug_screenshots"  # Directory to save debug information on image recognition failure (default: "debug_screenshots")
    
  4. Prepare Button Screenshots (only if using automation):

    If you use automation features (automated = true or enabling assign_to_copilot / phase3_merge), screenshots of the buttons PyAutoGUI needs to click are required.

    Required Screenshots:

    For automated issue assignment (assign_to_copilot feature):

    • assign_to_copilot.png - Screenshot of the “Assign to Copilot” button
    • assign.png - Screenshot of the “Assign” button

    For automated PR merging (if automated = true for phase3_merge feature):

    • merge_pull_request.png - Screenshot of the “Merge pull request” button
    • confirm_merge.png - Screenshot of the “Confirm merge” button
    • delete_branch.png - Screenshot of the “Delete branch” button (optional)

    How to Take Screenshots:

    a. Open a GitHub issue or PR in your browser. b. Find the button you want to automate. c. Take a screenshot of only the button (not the entire screen). d. Save it as a PNG file in the screenshots directory. e. Use the exact filenames listed above.

    Tips:

    • Screenshots should include only the button, with a small margin.
    • Use your OS’s screenshot tool (Windows: Snipping Tool, Mac: Cmd+Shift+4).
    • Ensure the button is clearly visible and not obscured.
    • If the button’s appearance changes (e.g., due to theme changes), you’ll need to update the screenshots.
    • Use the confidence setting to adjust image recognition reliability (due to DPI scaling or themes).

    Automated Debug Information Saving:

    • If image recognition fails, debug information is automatically saved.
    • Save location: debug_screenshots/ directory (default).
    • Contents saved:
      • Screenshot (full screen at time of failure): {button_name}_fail_{timestamp}.png
      • Failure information JSON: {button_name}_fail_{timestamp}.json
        • Button name, timestamp, confidence threshold, screenshot path, template image path.
    • The debug directory can be changed in the settings: debug_dir option (within the assign_to_copilot or phase3_merge sections).

    Important Requirements:

    • You must already be logged in to GitHub in your default browser.
    • Automation uses existing browser sessions (it does not perform new authentication).
    • Ensure the correct GitHub window/tab is focused and visible on screen when a button is clicked.
    • If multiple GitHub pages are open, the first found button will be clicked.

    Create Screenshot Directory:

    mkdir screenshots
    
  5. Install PyAutoGUI (only if using automation):

    pip install -r requirements-automation.txt
    

    または

    pip install pyautogui pillow
    

Run

Start the tool to begin monitoring:

python3 cat-github-watcher.py [config.toml]

Or, run directly as a Python module:

python3 -m src.gh_pr_phase_monitor.main [config.toml]

Workflow

  1. Start: When the tool is launched, it begins monitoring user-owned repositories of the authenticated GitHub user.
  2. PR Detection: Automatically detects repositories with open PRs.
  3. Phase Determination: Determines the phase of each PR (phase1/2/3, LLM working).
  4. Action Execution:
    • phase1: Default is Dry-run (if enable_execution_phase1_to_phase2 = true in rulesets, Draft PR is changed to Ready state).
    • phase2: Default is Dry-run (if enable_execution_phase2_to_phase3 = true in rulesets, posts a comment asking Copilot to apply changes).
    • phase3: Opens the PR page in the browser.
      • If enable_execution_phase3_send_ntfy = true in rulesets, also sends an ntfy.sh notification.
      • If enable_execution_phase3_to_merge = true in rulesets, automatically merges the PR (using global [phase3_merge] settings).
    • LLM working: Waits (if all PRs are in this state, displays issues from repositories with no open PRs).
  5. Automated Issue Assignment: If all PRs are “LLM working” and there are repositories with no open PRs:
    • If assign_good_first_old = true in rulesets, automatically assigns the oldest “good first issue” (by issue number).
    • If assign_old = true in rulesets, automatically assigns the oldest issue (by issue number, any label).
    • If both are true, “good first issue” is prioritized.
    • Default behavior: Automatically clicks buttons with PyAutoGUI (the [assign_to_copilot] section is not needed).
    • Required: PyAutoGUI installation and button screenshot preparation are necessary.
  6. Repeat: Continues monitoring at the configured interval.
    • If no state change occurs for the duration set by no_change_timeout, it automatically switches to power-saving mode (reduced_frequency_interval) to reduce API usage.
    • When a change is detected, it returns to the normal monitoring interval.

Dry-run Mode

By default, the tool operates in Dry-run Mode and does not execute actual actions, allowing you to safely verify its operation.

To enable actual actions, set the following flags to true in the [[rulesets]] section of config.toml.

[[rulesets]]
name = "Enable automation for specific repository"
repositories = ["test-repo"]  # or ["all"] for all repositories
enable_execution_phase1_to_phase2 = true  # Make Draft PR ready
enable_execution_phase2_to_phase3 = true  # Post Phase2 comment
enable_execution_phase3_send_ntfy = true  # Send ntfy notification
enable_execution_phase3_to_merge = true   # Merge Phase3 PR
assign_good_first_old = true              # Auto-assign good first issue

Stopping

You can stop monitoring with Ctrl+C.

Caveats

Tests

The project includes a test suite using pytest:

pytest tests/

License

MIT License - See the LICENSE file for details.

Note: The English README.md is automatically generated from README.ja.md by GitHub Actions using Gemini’s translation.

Big Brother is watching your repositories. Now it’s the cat. 🐱