BORN TO POISON / 410,757,864,530 DEAD CLANKERS
u/Bruhtopiest — 7 days ago
Here's a python script that will write the git commits for you using a local model. Written for LMStudio but could easily be modified for vLLM, open router, or corpo models.
import os
import subprocess
import urllib.request
import urllib.error
import json
import sys
BASE_DIR = r"C:\ai"
LM_STUDIO_URL = "http://localhost:1234/v1"
def check_lm_studio():
print("[*] Pinging LM Studio server...")
try:
# Hit the models endpoint to see what is loaded
req = urllib.request.Request(f"{LM_STUDIO_URL}/models")
with urllib.request.urlopen(req, timeout=3) as response:
data = json.loads(response.read().decode('utf-8'))
models = [m['id'] for m in data.get('data', [])]
if not models:
print("[!] Connected to LM Studio, but no model is currently loaded!")
print(" Please load a model in LM Studio and try again.")
return None
print(f"[+] Connected! Active model: {models[0]}")
if len(models) > 1:
print(f" (Found {len(models)} models, defaulting to {models[0]})")
return models[0]
except urllib.error.URLError as e:
print("\n[!] Could not connect to LM Studio (WinError 10061).")
print(" 1. Open LM Studio.")
print(" 2. Go to the Local Server tab (↔️ icon).")
print(" 3. Click 'Start Server' on port 1234.")
return None
def find_git_repos():
repos = []
try:
for item in os.listdir(BASE_DIR):
item_path = os.path.join(BASE_DIR, item)
if os.path.isdir(item_path) and os.path.isdir(os.path.join(item_path, ".git")):
repos.append(item_path)
except Exception as e:
print(f"[!] Error scanning directory: {e}")
return repos
def select_repo(repos):
if not repos:
print(f"[!] No Git repositories found in {BASE_DIR}.")
sys.exit(0)
print("\n=== Select a Project ===")
for i, repo in enumerate(repos):
print(f"[{i + 1}] {os.path.basename(repo)}")
while True:
try:
choice = input(f"\nSelect a project (1-{len(repos)}) or 'q' to quit: ").strip()
if choice.lower() == 'q':
sys.exit(0)
index = int(choice) - 1
if 0 <= index < len(repos):
return repos[index]
except ValueError:
pass
print("[!] Invalid selection. Please enter a valid number.")
def get_staged_diff(repo_path):
repo_name = os.path.basename(repo_path)
print(f"\n[*] Extracting staged changes from '{repo_name}'...")
result = subprocess.run(['git', '-C', repo_path, 'diff', '--cached'], capture_output=True, text=True)
return result.stdout.strip()
def generate_commit_message(diff, model_id):
print("[*] Generating commit summary and description...")
url = f"{LM_STUDIO_URL}/chat/completions"
headers = {"Content-Type": "application/json"}
system_prompt = (
"You are an expert software engineer. Write a conventional commit message based on the git diff. "
"You must include a short summary line, followed by a blank line, followed by a description body.\n\n"
"Rules:\n"
"- Stylistic preference: 'say more with less'. Keep the description concise, punchy, and feature-highlighted.\n"
"- Format:\n<type>(<scope>): <summary>\n\n- <description point 1>\n- <description point 2>\n"
"- Do not include markdown code blocks, introductory text, or quotes. Output only the raw commit text."
)
data = {
"model": model_id,
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": diff}
],
"temperature": 0.3,
"max_tokens": 200
}
try:
req = urllib.request.Request(url, data=json.dumps(data).encode('utf-8'), headers=headers)
with urllib.request.urlopen(req) as response:
result = json.loads(response.read().decode('utf-8'))
return result['choices'][0]['message']['content'].strip()
except Exception as e:
print(f"\n[!] Generation failed: {e}")
sys.exit(1)
def main():
print("========================================")
print(" AI Commit Message Generator ")
print("========================================\n")
# Step 1: Ensure LM Studio is awake and get the active model
active_model = check_lm_studio()
if not active_model:
input("\nPress Enter to exit...")
sys.exit(1)
# Step 2: Select Project
repos = find_git_repos()
selected_repo = select_repo(repos)
# Step 3: Get Diff
diff = get_staged_diff(selected_repo)
if not diff:
print(f"\n[!] No staged changes found in {os.path.basename(selected_repo)}.")
print("[!] Stage your files in GitKraken first, then run this tool again.")
input("\nPress Enter to exit...")
sys.exit(0)
print(f"[*] Found {len(diff.splitlines())} lines of staged changes.")
# Step 4: Generate
commit_msg = generate_commit_message(diff, active_model)
print("\n========================================")
print(commit_msg)
print("========================================\n")
# Step 5: Copy to Clipboard
try:
subprocess.run('clip', input=commit_msg, text=True, check=True, shell=True)
print("[Success] Commit message copied to your clipboard!")
except Exception as e:
print(f"[Note] Could not auto-copy to clipboard: {e}")
input("\nPress Enter to close...")
if __name__ == "__main__":
main()