8 min read

Building a VS Code Extension for AI-Powered Git Commit Messages

Learn how to create a VS Code extension that generates Git commit messages using Hugging Face's AI models, complete with Git integration and a user-friendly interface.

TypeScriptVS CodeGitHugging FaceAI

Writing good Git commit messages can be tedious, especially when you’re deep in a coding session. In this post, I’ll walk you through building a VS Code extension called `git-commit-ai` that uses Hugging Face’s AI to suggest commit messages based on your staged changes. It’s got Git integration, a slick UI, and customizable styles—let’s dive in!

It’s still a work in progress, works fine with small changes, but the foundation is there. Stay tuned for updates! 🚀

Why This Extension?

Manually crafting commit messages takes time, and tools like Git’s `-m` flag don’t help with inspiration. By tapping into Hugging Face’s free Inference API, we can automate this with AI. Plus, integrating it into VS Code means it’s right where developers live.

Implementation

Here’s how I built `git-commit-ai`, broken into manageable steps. We’ll use TypeScript, the VS Code API, and Hugging Face’s AI.

Step 1: Project Setup

Start by scaffolding a VS Code extension with Yeoman and installing dependencies.

bash
npm install -g yo generator-code
yo code
# Choose: New Extension (TypeScript), Name: git-commit-ai
cd git-commit-ai
npm install --save axios @types/node child-process-promise

Step 2: Git Integration

It will fetch staged changes using `git diff --staged`, running it in the workspace folder to ensure context.

typescript
import { execSync } from 'child_process';
import * as vscode from 'vscode';

export class GitService {
  static getStagedDiff(): string {
    const workspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
    if (!workspaceFolder) throw new Error('No workspace folder open');
    return execSync('git diff --staged', { cwd: workspaceFolder, encoding: 'utf8' });
  }

  static commit(message: string): void {
    const workspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
    if (!workspaceFolder) throw new Error('No workspace folder open');
    execSync(`git commit -m "${message}"`, { cwd: workspaceFolder, encoding: 'utf8' });
  }
}

Step 3: AI Integration with Hugging Face

Next, it will call the Hugging Face API to generate a commit message based on the diff, parsing it to extract the clean output.

typescript
import axios from 'axios';
import * as vscode from 'vscode';

export class AIService {
  private static readonly ENDPOINT = 'https://api-inference.huggingface.co/models/mistralai/Mixtral-8x7B-Instruct-v0.1';

  static async generateCommitMessage(diff: string, style: 'conventional' | 'casual' | 'detailed'): Promise<string[]> {
    const prompt = `Given this code diff, generate a single Git commit message in the specified style. Output the message in this exact format: [message]. Strictly follow the style instruction and include no other text.
Style: ${style === 'casual' ? 'Use a relaxed, conversational tone (e.g., "Yo, added some cool stuff!")' : style === 'conventional' ? 'Use Conventional Commits format' : 'Provide a detailed description'}
Diff:
${diff}`;

    const response = await axios.post(this.ENDPOINT, { inputs: prompt, parameters: { max_new_tokens: 100 } }, {
      headers: { Authorization: `Bearer ${process.env.HF_API_TOKEN}` }
    });

    const generatedText = response.data[0]?.generated_text || '';
    const match = generatedText.match(/\[(.*?)\]/s);
    const message = match?.[1] || 'Default commit message';
    return [message];
  }
}

Step 4: User Interface

It will display suggestions in a Quick Pick modal, letting users approve, edit, or regenerate.

typescript
import * as vscode from 'vscode';
import { GitService } from './git';
import { AIService } from './ai';

export function activate(context: vscode.ExtensionContext) {
  context.subscriptions.push(vscode.commands.registerCommand('git-commit-ai.suggestCommit', async () => {
    const diff = GitService.getStagedDiff();
    if (!diff.trim()) {
      vscode.window.showWarningMessage('No staged changes found');
      return;
    }

    const suggestions = await AIService.generateCommitMessage(diff, 'casual');
    const action = await vscode.window.showQuickPick([
      ...suggestions.map(msg => ({ label: msg, message: msg })),
      { label: 'Regenerate', description: 'Get new suggestions' },
      { label: 'Custom', description: 'Write your own message' }
    ], { placeHolder: 'Select a commit message or action' });

    if (!action) return;
    if (action.label === 'Regenerate') {
      vscode.commands.executeCommand('git-commit-ai.suggestCommit');
      return;
    }

    let finalMessage = action.label === 'Custom' ? await vscode.window.showInputBox({ value: suggestions[0] }) : 'message' in action ? action.message : suggestions[0];
    if (finalMessage) GitService.commit(finalMessage);
  }));
}

Configuration

Users need to configure the API token and commit style in VS Code settings.

json
{
  "gitCommitAI.apiToken": "your-hugging-face-token",
  "gitCommitAI.commitStyle": "casual"
}

Publishing to the Marketplace

After testing, package and publish it with `vsce`. Don’t forget to set your publisher ID in `package.json`! and upload it to visual studio marketplace I'll do a post on that or already have so check it out

bash
npm install -g vsce
vsce package
vsce publish --pat your-marketplace-pat

Conclusion

The `git-commit-ai` extension streamlines committing by leveraging AI to suggest messages tailored to your changes. It’s a fun blend of Git, VS Code, and AI—perfect for developers who want to save time and keep their commit history lively. Try it out and let me know how it works for you! if you have any question reach out to me in one of my socials and I will try to help