Skip to content

About

AI-powered git diff analyser that delivers automated commit messages straight to Discord.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

gmd

Generate structured commit messages from a local git diff, using a Discord bot and the Groq API.

Python discord.py Groq Model


Table of Contents

  1. Overview
  2. Architecture
  3. Groq Integration
  4. Installation
  5. Usage
  6. Configuration Reference
  7. Troubleshooting
  8. Security
  9. Uninstall

Overview

gmd consists of two components:

  1. CLI (gmd): reads the uncommitted git diff in the current repository, splits it into chunks that fit Discord's message limit, and posts them to a channel through a webhook.
  2. Discord bot: monitors that channel, reassembles the chunks, sends the complete diff to Groq, and posts a formatted commit message as an embed.

Example output:

[mb1425] feat(robot): Add RobotArm class with pick-and-place functionality

- Implement RobotArm class to interface with CoppeliaSim
- Add methods for depth reading and pixel-to-robot conversion
- Include configuration handling and camera-to-robot transformation logic

Features

  • Commit messages in a consistent [shortcode] type(scope): Subject format
  • Line counts (+A/-R) computed in code rather than estimated by the model
  • Automatic chunking of large diffs to fit Discord's 2000-character limit
  • Retry handling for Discord rate limits (HTTP 429)
  • Idle flush: if the end signal is lost, the bot processes the buffered diff after 15 seconds
  • Automatic deletion of raw diff chunks from the channel
  • Mapping from git emails to shortcodes and Discord users through a YAML file
  • Errors are reported in the channel rather than failing silently

Architecture

flowchart LR
    Dev([Developer]) -->|runs gmd| CLI[diff_cli.py]
    CLI -->|reads diff| Git[(Git repository)]
    CLI -->|posts chunks and end signal| Discord{{Discord channel}}
    Discord -->|dispatches messages| Bot[diff_analyzer_bot.py]
    Bot -->|buffers chunks, deletes originals| Bot
    Bot -->|sends assembled diff| Groq[[Groq API]]
    Groq -->|returns JSON| Bot
    Bot -->|posts embed| Discord
    Cfg[config.yaml] -.-> CLI
    Cfg -.-> Bot
Loading

Processing sequence:

  1. gmd runs git diff, removes empty lines, and splits the output into chunks of up to 1980 characters.
  2. Each chunk is posted through the webhook, followed by a unique end marker: <<<GMD_END_OF_DIFF_7f3a>>>.
  3. The bot buffers chunks per webhook and deletes each message as it arrives.
  4. When the end marker arrives, or 15 seconds pass without a new chunk, the bot sends the full diff to Groq.
  5. The bot parses the response, applies formatting corrections, and posts the result as an embed.

Groq Integration

The bot uses the official asynchronous Groq Python SDK (AsyncGroq) and calls the chat completions endpoint with the openai/gpt-oss-20b model.

Request contents

Message Content
system Commit format rules, commit type priority order, and the required JSON output structure
user List of changed files, exact line counts, and the assembled diff

The diff is truncated to 24,000 characters before submission to remain within prompt limits. The file list and line counts are computed from the full diff, so the model is informed of every changed file even when truncation occurs.

Request parameters

Parameter Value Rationale
model openai/gpt-oss-20b Fast, low-cost reasoning model
temperature 0.2 Limits variation between runs
seed 42 Best-effort reproducibility
max_tokens 8192 Reasoning tokens count against this budget
reasoning_effort "low" Prevents the model from exhausting its budget on reasoning

Response handling

The model returns a JSON object containing the commit message. The bot then:

  1. Extracts the JSON block with a regular expression, falling back to field-level extraction if parsing fails.
  2. Replaces the line count with the value computed in code.
  3. Capitalises the first letter after the subject colon and after each bullet point.
  4. Removes any text after the last bullet point.
  5. Trims fields to Discord's embed size limits.

Commit type rules

The prompt selects the first matching type in the following order, which keeps classification consistent for mixed diffs:

Type Condition
feat The diff adds any new capability, function, option or behaviour
fix The diff mainly corrects incorrect behaviour and adds nothing new
refactor Code is restructured with no change in behaviour
docs Only documentation or comments changed
chore Only configuration, dependencies, build or tooling changed

Data handling: diffs are transmitted to Groq's API. Do not use gmd on code that may not be shared with a third-party service.


Installation

Prerequisites

  • Python 3.9 or newer
  • git, available on PATH
  • A Discord server in which you can create webhooks and add a bot
  • A Groq account

1. Clone the repository

git clone https://github.com/<your-username>/<your-repo>.git
cd <your-repo>

Expected layout:

.
├── src/
│   ├── diff_analyzer_bot.py   # Discord bot (runs on the server)
│   ├── diff_cli.py            # CLI (installed as `gmd`)
│   └── config_loader.py       # Shared YAML loader
├── config.example.yaml
├── install.sh
└── .env                       # created by you (bot secrets)

2. Install Python dependencies

pip install discord.py python-dotenv groq pyyaml requests

The CLI runs with the system python3, so requests and pyyaml must be installed for that interpreter as well.

3. Obtain a Groq API key

  1. Sign in at console.groq.com.
  2. Open API Keys and select Create API Key.
  3. Copy the key. Groq keys begin with gsk_.

4. Create the Discord bot

  1. Open the Discord Developer Portal and select New Application.
  2. On the Bot tab, select Reset Token and copy the token.
  3. On the same tab, enable the following Privileged Gateway Intents:
    • Message Content Intent
    • Server Members Intent
  4. Under OAuth2 > URL Generator, select the bot scope and grant these permissions:
    • View Channel
    • Send Messages
    • Embed Links
    • Read Message History
    • Manage Messages (required to delete diff chunks)
  5. Open the generated URL and add the bot to your server.

5. Create the webhook and locate the channel ID

  1. In Discord, open User Settings > Advanced and enable Developer Mode.
  2. Right-click the target channel and select Copy Channel ID.
  3. Open Channel Settings > Integrations > Webhooks, create a webhook, and copy its URL.

6. Configure the application

Create a secrets file in the repository root:

# .env
DISCORD_TOKEN=your_discord_bot_token
GROQ_API_KEY=gsk_your_groq_key

Create the configuration file:

cp config.example.yaml config.yaml

Edit config.yaml:

discord:
  webhook_url: "https://discord.com/api/webhooks/ID/TOKEN"
  target_channel_id: 123456789012345678

cli:
  max_chunk_length: 1980
  delay_seconds: 1

users:
  jdoe:
    shortcode: "jdoe"
    discord_username: "JohnDoe"
    git_emails:
      - "john@example.com"
      - "john@work.com"

7. Protect secrets

Add the following to .gitignore before the first commit:

.env
config.yaml

The webhook URL allows anyone who holds it to post to your channel and must not be committed.

8. Install the CLI

chmod +x install.sh
./install.sh

The script copies the CLI, the config loader and config.yaml to ~/.gmd-tool and creates a gmd command in ~/.local/bin. If gmd is not found afterwards, add the following to your shell profile:

export PATH="$HOME/.local/bin:$PATH"

Note: gmd runs an installed copy of the code. After changing src/diff_cli.py, src/config_loader.py or config.yaml, run ./install.sh again.

9. Start the bot

python3 src/diff_analyzer_bot.py

Expected output:

Logged in as YourBot#1234 (ID: ...)
Monitoring and formatting channel ID: 123456789012345678

To keep the bot running after the terminal is closed, use tmux, screen, or a systemd service.


Usage

From any git repository with uncommitted changes:

gmd

The terminal prints Successfully generated commit message on discord, and the formatted result appears in the Discord channel shortly afterwards.

Note: gmd uses plain git diff, which includes unstaged changes only. Staged changes are not included.


Configuration Reference

config.yaml

Key Description
discord.webhook_url Webhook to which the CLI posts diff chunks
discord.target_channel_id Channel monitored by the bot
cli.max_chunk_length Maximum characters per webhook message (keep at or below 1980)
cli.delay_seconds Pause between chunks to avoid Discord rate limits
users.<key>.shortcode Short identifier used as the commit prefix, for example [jdoe]
users.<key>.discord_username Discord username mentioned in the result
users.<key>.git_emails All git email addresses that map to this user

If the git email is not listed under users, the shortcode resolves to UNKNOWN_USER.

Bot constants

Defined near the top of diff_analyzer_bot.py:

Constant Default Purpose
IDLE_FLUSH_SECONDS 15 Time to wait after the last chunk before processing without an end signal
MAX_DIFF_CHARS 24000 Maximum number of diff characters sent to Groq

Troubleshooting

Symptom Likely cause and resolution
Chunks disappear and nothing is posted The end signal was not received. Run ./install.sh again and confirm END_SIGNAL is identical in diff_cli.py and diff_analyzer_bot.py. The idle flush should still process the diff after 15 seconds
Chunks remain visible in the channel The bot lacks the Manage Messages permission
Error: config.yaml not found Copy config.example.yaml to config.yaml and run ./install.sh again
Error: Tokens are missing Confirm .env exists and defines DISCORD_TOKEN and GROQ_API_KEY
Bot cannot read messages or resolve users Enable Message Content Intent and Server Members Intent in the Developer Portal
gmd: command not found Add ~/.local/bin to PATH
Failed to send message to discord Verify the webhook URL. The HTTP error is printed above the message
Diff analysis failed in the channel The error is posted to Discord and the full traceback is written to the bot console
Duplicate or unexpected responses An earlier bot process is still running. Check ps aux | grep diff_analyzer_bot and stop duplicates
Incorrect line counts or missing changes The CLI strips blank added and removed lines, and diffs above MAX_DIFF_CHARS are truncated

Security

  • Keep .env and config.yaml out of version control.
  • Grant the bot only the permissions it requires.
  • Be aware that diffs are sent to Groq for processing.
  • If a secret is exposed, rotate it immediately: delete the webhook, reset the Discord bot token, and revoke the Groq API key. Removing a file in a later commit does not remove it from git history.

Uninstall

rm -rf ~/.gmd-tool ~/.local/bin/gmd

About

AI-powered git diff analyser that delivers automated commit messages straight to Discord.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Contributors

Languages