Claude/Code/How To/Create Git Commit Tool
Properties
- tags
- Diataxis/How To
How to use Claude/Code to build a CLI/Tool to create a git/commit according to a convention
Goal
- Create a standalone command-line tool that generates git commits following the Conventional Commits specification based on prompts stored independently of the script.
- The tool should work independently of Claude Code and can be used in any development workflow.
Preconditions
Approach Options
Procedure: Option 1 - Python CLI with llm-cli
1. Set up the development environment
2. Create the CLI structure
- Create the main CLI module:
- python
# conventional_commit_tool/cli.py import click import os from pathlib import Path from .commit_generator import ConventionalCommitGenerator command option'--prompt-file''-p' help='Path to file containing commit prompt' option'--prompt''-m' help='Direct commit prompt text' option'--dry-run'is_flag=True help='Show commit message without executing' option'--scope''-s' help='Optional scope for the commit' def main(prompt_file, prompt, dry_run, scope): """Generate conventional commits using LLM.""" generator = ConventionalCommitGenerator() if prompt_file: with open(prompt_file, 'r') as f: prompt_text = f.read().strip() elif prompt: prompt_text = prompt else: click.echo("Error: Must provide either --prompt-file or --prompt") return commit_msg = generator.generate_commit(prompt_text, scope) if dry_run: click.echo("Generated commit message:") click.echo(commit_msg) else: # Execute git commit os.system(f'git commit -m "{commit_msg}"') if __name__ == '__main__': main()
- Create the main CLI module:
3. Create the commit generator
- python
# conventional_commit_tool/commit_generator.py import anthropic import os from typing import Optional class ConventionalCommitGenerator: def __init__(self): self.client = anthropic.Anthropic( api_key=os.getenv('ANTHROPIC_API_KEY') ) def generate_commit(self, prompt: str, scope: Optional[str] = None) -> str: system_prompt = self._get_system_prompt() user_prompt = f""" Generate a conventional commit message for the following changes: {prompt} """ if scope: user_prompt += f"\n\nScope: {scope}" response = self.client.messages.create( model="claude-3-5-sonnet-20241022", max_tokens=150, system=system_prompt, messages=[{"role": "user", "content": user_prompt}] ) return response.content[0].text.strip() def _get_system_prompt(self) -> str: return """ You are a git commit message generator that follows the Conventional Commits specification. The commit message should be structured as follows: <type>[optional scope]: <description> Types: - feat: A new feature - fix: A bug fix - docs: Documentation only changes - style: Changes that do not affect the meaning of the code - refactor: A code change that neither fixes a bug nor adds a feature - perf: A code change that improves performance - test: Adding missing tests or correcting existing tests - chore: Changes to the build process or auxiliary tools Rules: 1. Use the imperative mood ("add" not "added" or "adds") 2. Don't capitalize the first letter 3. No dot (.) at the end 4. Keep the description under 72 characters 5. If scope is provided, include it in brackets Examples: - feat(auth): add OAuth2 authentication - fix(api): resolve user data retrieval issue - docs: update README with installation steps - refactor: simplify user validation logic """
4. Create prompt templates
5. Install and test the tool
6. Make it globally available
Procedure: Option 2 - Node.js CLI with oclif
1. Initialize oclif project
2. Add dependencies
3. Create the main command
- typescript
// src/commands/generate.ts import {Command, Flags} from '@oclif/core' import Anthropic from '@anthropic-ai/sdk' import * as fs from 'fs' import {execSync} from 'child_process' export default class Generate extends Command { static description = 'Generate conventional commit message' static flags = { 'prompt-file': Flags.string({ char: 'p', description: 'Path to file containing commit prompt', }), prompt: Flags.string({ char: 'm', description: 'Direct commit prompt text', }), 'dry-run': Flags.boolean({ description: 'Show commit message without executing', }), scope: Flags.string({ char: 's', description: 'Optional scope for the commit', }), } async run() { const {flags} = await this.parse(Generate) const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY, }) let promptText: string if (flags['prompt-file']) { promptText = fs.readFileSync(flags['prompt-file'], 'utf8').trim() } else if (flags.prompt) { promptText = flags.prompt } else { this.error('Must provide either --prompt-file or --prompt') } const systemPrompt = this.getSystemPrompt() const userPrompt = this.buildUserPrompt(promptText, flags.scope) const response = await anthropic.messages.create({ model: 'claude-3-5-sonnet-20241022', max_tokens: 150, system: systemPrompt, messages: [{role: 'user', content: userPrompt}], }) const commitMsg = response.content[0].text.trim() if (flags['dry-run']) { this.log('Generated commit message:') this.log(commitMsg) } else { execSync(`git commit -m "${commitMsg}"`, {stdio: 'inherit'}) } } private getSystemPrompt(): string { return `You are a git commit message generator that follows the Conventional Commits specification. The commit message should be structured as follows: <type>[optional scope]: <description> Types: - feat: A new feature - fix: A bug fix - docs: Documentation only changes - style: Changes that do not affect the meaning of the code - refactor: A code change that neither fixes a bug nor adds a feature - perf: A code change that improves performance - test: Adding missing tests or correcting existing tests - chore: Changes to the build process or auxiliary tools Rules: 1. Use the imperative mood ("add" not "added" or "adds") 2. Don't capitalize the first letter 3. No dot (.) at the end 4. Keep the description under 72 characters 5. If scope is provided, include it in brackets` } private buildUserPrompt(prompt: string, scope?: string): string { let userPrompt = `Generate a conventional commit message for the following changes: ${prompt}` if (scope) { userPrompt += `\n\nScope: ${scope}` } return userPrompt } }
4. Build and install
Procedure: Option 3 - Claude Code-assisted development
Usage Examples
Integration with Development Workflow
Troubleshooting
References