feat(commands): add AI git commit message generator

Add comprehensive slash command for generating conventional commit
messages using AI. The command analyzes staged git changes and creates
well-structured commit messages following best practices.

Features:
- Conventional commit format (type, scope, description)
- Interactive message editing and regeneration
- Context-aware analysis of git diffs
- Learning from existing commit history style
- Support for custom type and scope hints
- Multi-step workflow with user confirmation

Command supports multiple usage patterns:
- Basic: /git-commit-msg
- With hints: /git-commit-msg fix
- With context: /git-commit-msg "feat(api)"

Also updates command README with documentation for the new command.

🤖 Generated with Claude Code
This commit is contained in:
windyboy
2026-01-05 21:38:47 +08:00
parent 8e3943f064
commit 79de88d25c
9 changed files with 446 additions and 3 deletions
+10
View File
@@ -54,6 +54,16 @@ Create a comprehensive synthesis of the week's work.
Best for: Weekly reviews, pattern recognition Best for: Weekly reviews, pattern recognition
### 💬 git-commit-msg
AI-generated conventional commit messages from staged changes.
```
/git-commit-msg
```
Best for: Creating meaningful commit messages, maintaining clean git history
## Creating Custom Commands ## Creating Custom Commands
1. Create a new `.md` file in this directory 1. Create a new `.md` file in this directory
+320
View File
@@ -0,0 +1,320 @@
---
allowed-tools: Bash, AskUserQuestion
description: AI-generated git commit messages from staged changes
argument-hint: [optional: type or scope hint]
---
# AI Git Commit Message Generator
Analyzes your staged git changes and generates a well-structured conventional commit message using AI. Perfect for creating meaningful, consistent commit messages that follow best practices.
## Task
Review staged changes, analyze the modifications, and generate a descriptive conventional commit message that accurately describes what was changed and why.
## Process
### 1. **Check Git Status**
First, verify there are changes to commit:
```bash
git status
```
If no changes are staged, check if there are unstaged changes:
- If yes: Ask user if they want to stage all changes
- If no: Exit with message "No changes to commit"
### 2. **Review Changes**
Show detailed diff of staged changes:
```bash
# Show staged changes
git diff --cached --stat
git diff --cached
```
Also check recent commits for context on commit message style:
```bash
git log --oneline -5
```
### 3. **Analyze Changes**
Examine the diff output to understand:
- **What changed**: Files modified, added, or deleted
- **Scope**: Which modules/components are affected
- **Type**: Is this a feature, fix, refactor, docs, etc.?
- **Impact**: Breaking changes, new functionality, bug fixes
- **Details**: Specific changes worth mentioning
### 4. **Generate Commit Message**
Create a conventional commit message following this format:
```
<type>(<scope>): <short summary>
<detailed description>
<footer>
```
**Type Options:**
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `style`: Code style/formatting (no logic change)
- `refactor`: Code restructuring (no feature change)
- `perf`: Performance improvement
- `test`: Adding or updating tests
- `chore`: Build process, dependencies, tooling
- `ci`: CI/CD configuration changes
- `revert`: Reverting previous changes
**Message Structure:**
- **Subject line**: Max 72 characters, imperative mood ("add" not "added")
- **Body** (optional): Explain what and why (not how)
- **Footer** (optional): Breaking changes, issue references
**Example:**
```
feat(auth): add OAuth2 login flow
Implement OAuth2 authentication with Google and GitHub providers.
Users can now log in using their existing accounts, improving
onboarding experience and security.
- Add OAuth2 client configuration
- Create provider-specific callback handlers
- Update login UI with social login buttons
- Add user account linking logic
Closes #123
```
### 5. **Present Options**
Show the generated commit message to the user with options:
```
📝 Generated Commit Message:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[Generated message here]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Options:
1. Use this message (recommended)
2. Edit message
3. Generate alternative version
4. Cancel commit
```
Use AskUserQuestion to get user's choice.
### 6. **Commit Changes**
Based on user selection:
**Option 1 - Use as-is:**
```bash
git commit -m "$(cat <<'EOF'
[Generated message]
🤖 Generated with Claude Code
EOF
)"
```
**Option 2 - Edit:**
- Ask user for modifications
- Show revised message
- Confirm before committing
**Option 3 - Regenerate:**
- Ask for guidance (e.g., "focus more on why", "simpler message")
- Generate new version
- Show options again
**Option 4 - Cancel:**
- Exit without committing
- Changes remain staged
### 7. **Confirm Success**
After committing:
```bash
git log -1 --pretty=format:"%h - %s"
git status
```
Show commit hash and updated status to confirm success.
## Arguments
**Optional user input:**
- Type hint: `fix`, `feat`, `docs`, etc.
- Scope hint: `auth`, `api`, `ui`, etc.
- Custom context: "this fixes the login timeout issue"
## Example Usage
```bash
# Auto-generate from staged changes
/git-commit-msg
# Provide type hint
/git-commit-msg fix
# Provide type and scope
/git-commit-msg "feat(api)"
# Provide context
/git-commit-msg "fixing the auth timeout bug mentioned in #234"
```
## Output Example
```
🔍 Analyzing staged changes...
📊 Changes Summary:
src/auth/oauth.ts | 45 +++++++++++++++++++++++++++-
src/components/Login.tsx | 23 +++++++++++---
tests/auth.test.ts | 18 +++++++++++
3 files changed, 81 insertions(+), 5 deletions(-)
📝 Generated Commit Message:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
feat(auth): add OAuth2 social login integration
Implement OAuth2 authentication with Google and GitHub providers
to improve user onboarding and security.
- Add OAuth2 client configuration
- Create provider callback handlers
- Update login UI with social buttons
- Add comprehensive auth tests
Closes #234
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Committed successfully: a7f3b2c
```
## Best Practices
**Subject Line:**
- Use imperative mood: "add" not "added" or "adds"
- Don't end with a period
- Keep under 72 characters
- Be specific but concise
**Body:**
- Explain **what** and **why**, not **how**
- Wrap at 72 characters per line
- Use bullet points for multiple changes
- Reference issues when relevant
**Scope:**
- Use specific module/component names
- Keep consistent with codebase conventions
- Omit if change affects multiple areas
**Common Patterns:**
- `feat(api): add user search endpoint`
- `fix(ui): resolve mobile menu overflow issue`
- `docs(readme): update installation instructions`
- `refactor(auth): simplify token validation logic`
- `perf(db): optimize query performance with indexes`
- `test(api): add integration tests for auth flow`
## Smart Features
**Context Awareness:**
- Learn from existing commit history style
- Detect breaking changes automatically
- Identify issue references in branch names
- Suggest appropriate scope from file paths
**Safety:**
- Show full diff before committing
- Allow message editing
- Confirm before finalizing
- Never auto-push (commit locally only)
**Quality Checks:**
- Validate conventional commit format
- Check subject line length
- Ensure meaningful description
- Verify scope accuracy
## Configuration
Can be customized for your project:
- Custom commit types
- Required/optional scope
- Footer format (issue tracking)
- Additional validation rules
## Integration with Git Plugin
This skill is designed to work seamlessly with Obsidian git plugins:
- Generates messages compatible with all git workflows
- Works with staging area from any git client
- Commits stay in local history until you push
- No changes to your git configuration
## Tips
- **Stage selectively**: Use `git add -p` for partial file commits
- **Commit atomically**: One logical change per commit
- **Reference issues**: Use "Closes #123" in footer
- **Breaking changes**: Start body with "BREAKING CHANGE:"
- **Co-authors**: Add in footer: `Co-authored-by: Name <email>`
## Troubleshooting
**"No changes staged":**
- Run `git add <files>` first, or let skill stage changes for you
**"Generated message too generic":**
- Select "Generate alternative" and provide more context
- Check that changes have meaningful diffs
**"Wrong commit type detected":**
- Provide type hint as argument: `/git-commit-msg fix`
**"Commit message too long":**
- Skill will automatically wrap at 72 characters
- Complex changes will use multi-line body
## Advanced Usage
**Multi-file changes:**
```bash
# Skill will group related changes and create comprehensive message
git add src/auth/*.ts src/components/Login.tsx
/git-commit-msg
```
**Partial commits:**
```bash
# Stage specific hunks
git add -p src/complex-file.ts
/git-commit-msg "focusing on the bug fix part"
```
**Amending commits:**
```bash
# After running the skill, if you need to amend:
git commit --amend
# Edit the AI-generated message as needed
```
---
**Pro tip**: Use this skill consistently to build a clean, professional git history that makes code review and debugging much easier!
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+102
View File
@@ -284,6 +284,108 @@
"pattern": "06_Metadata/Obsidian-Plugins-Manual.md", "pattern": "06_Metadata/Obsidian-Plugins-Manual.md",
"approvedAt": 1767608585967, "approvedAt": 1767608585967,
"scope": "always" "scope": "always"
},
{
"toolName": "Bash",
"pattern": "git remote remove origin 2>&1 || echo \"no origin to remove\"",
"approvedAt": 1767616810536,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "pnpm install",
"approvedAt": 1767616837185,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "mkdir -p 00_Inbox 01_Projects 02_Areas 03_Resources 04_Archive 05_Attachments/Organized 06_Metadata/Reference 06_Metadata/Plans 06_Metadata/Templates && echo \"Folders created successfully\"",
"approvedAt": 1767617713953,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "cat > \"01_Projects/README.md\" << 'EOF'\n# Projects\n\n**Purpose:** Time-bound initiatives with clear completion criteria.\n\n## What is a Project?\n\nA project has:\n- A specific goal or deliverable\n- A clear end date or completion criteria\n- Multiple tasks or actions\n\nExamples: Writing a paper, launching a product, planning an event, learning a new skill\n\n## Recommended Structure\n\nFor each project folder, create:\n- `Research/` - Source materials and references\n- `Drafts/` - Work in progress\n- `Output/` - Final deliverables\n- `README.md` - Project objectives, timeline, and status\n\n## Project Lifecycle\n\n1. **Start:** Create folder with subfolders and README\n2. **During:** Keep all related materials in the project folder\n3. **Complete:** Create summary note, then move to `04_Archive/`\n\n## Tips\n\n- Link to relevant Areas and Resources\n- Commit regularly to track progress with git\n- Review weekly to check status and next actions\nEOF\necho \"Created 01_Projects/README.md\"",
"approvedAt": 1767618086311,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "cat > \"04_Archive/README.md\" << 'EOF'\n# Archive\n\n**Purpose:** Completed or inactive items from Projects and Areas.\n\n## What Gets Archived\n\n- **Completed projects** - Move entire project folder here\n- **Inactive areas** - Areas you're no longer maintaining\n- **Old resources** - Outdated reference materials (use sparingly)\n\n## Archive Structure\n\nMaintain the same folder structure:\n- `Projects/` - Completed project folders\n- `Areas/` - Inactive areas\n- `Resources/` - Outdated resources (if needed)\n\n## Before Archiving a Project\n\n1. Create a project summary note with:\n - What was accomplished\n - Key learnings\n - Links to important outputs\n2. Update related Area notes\n3. Move the entire project folder here\n\n## Maintenance\n\n- Review quarterly to see what can be deleted\n- Some archived items may be reactivated\n- Keep the archive organized (mirror active structure)\n\n## Tips\n\n- Don't archive too aggressively - keep valuable reference material\n- Use git history to track when things were archived\n- Archived doesn't mean forgotten - you can still search and reference\nEOF\necho \"Created 04_Archive/README.md\"",
"approvedAt": 1767618088747,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "cat > \"05_Attachments/README.md\" << 'EOF'\n# Attachments\n\n**Purpose:** Storage for all non-text files (images, PDFs, videos, audio).\n\n## Organization\n\n- **Root (05_Attachments/)** - Unprocessed attachments\n- **Organized/** - Files that have been properly named and referenced\n\n## Naming Convention\n\nUse descriptive names that indicate the related note:\n- `[RelatedNote]_[Description].[ext]`\n- Example: `ProjectAlpha_Architecture_Diagram.png`\n- Example: `BookNotes_Thinking_Fast_Slow_Cover.jpg`\n\n## Helper Scripts\n\n```bash\npnpm attachments:list # List unprocessed files\npnpm attachments:organized # Count organized files\npnpm attachments:orphans # Find unreferenced files\npnpm attachments:update-links # Update links after moving\n```\n\n## Processing Workflow\n\n1. Files initially land in `05_Attachments/`\n2. Rename with descriptive names\n3. Reference in notes using `![[filename.ext]]`\n4. Move to `Organized/` subfolder\n5. Update any links if paths change\n\n## Tips\n\n- Process attachments regularly (don't let them pile up)\n- Use consistent naming patterns\n- Delete duplicates and unused files\n- Consider using Gemini Vision to analyze images\nEOF\necho \"Created 05_Attachments/README.md\"",
"approvedAt": 1767618090058,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "cat package.json | grep -A 30 '\"scripts\"'",
"approvedAt": 1767618132102,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "mkdir -p .claude && echo '{\"user\":{\"name\":\"\",\"publicProfile\":false},\"organizationMethod\":\"PARA\",\"primaryUses\":[\"research\",\"writing\",\"project-management\",\"daily-notes\"],\"tools\":{\"geminiVision\":false,\"firecrawl\":true},\"weeklyReview\":true,\"importedAt\":\"2026-01-05\",\"lastUpdated\":\"2026-01-05\"}' > .claude/vault-config.json && cat .claude/vault-config.json",
"approvedAt": 1767618135787,
"scope": "always"
},
{
"toolName": "Write",
"pattern": "D:\\tmp\\vault\\my-vault\\CLAUDE.md",
"approvedAt": 1767618385844,
"scope": "always"
},
{
"toolName": "Write",
"pattern": "D:\\tmp\\vault\\my-vault\\WEEKLY_REVIEW.md",
"approvedAt": 1767618388814,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "test -f \"D:\\tmp\\vault\\my-vault\\.gitignore\" && echo \"exists\" || echo \"not found\"",
"approvedAt": 1767618406650,
"scope": "always"
},
{
"toolName": "Edit",
"pattern": "D:\\tmp\\vault\\my-vault\\.gitignore",
"approvedAt": 1767618439421,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "pnpm vault:stats",
"approvedAt": 1767618580628,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "git add CLAUDE.md WEEKLY_REVIEW.md .gitignore .claude/vault-config.json 01_Projects/README.md 02_Areas/README.md 03_Resources/README.md 04_Archive/README.md 05_Attachments/README.md pnpm-lock.yaml",
"approvedAt": 1767618604305,
"scope": "always"
},
{
"toolName": "Bash",
"pattern": "git commit -m \"$(cat <<'EOF'\nInitial vault setup with PARA structure\n\n- Created CLAUDE.md configuration file\n- Created WEEKLY_REVIEW.md template\n- Set up PARA folder structure (Projects, Areas, Resources, Archive)\n- Created README files for each main folder\n- Configured .gitignore for vault files\n- Saved vault configuration to .claude/vault-config.json\n\nGenerated with Claude Code\nCo-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>\nEOF\n)\"",
"approvedAt": 1767618611184,
"scope": "always"
},
{
"toolName": "Write",
"pattern": ".claude/commands/git-commit-msg.md",
"approvedAt": 1767619909039,
"scope": "always"
},
{
"toolName": "Edit",
"pattern": ".claude/commands/README.md",
"approvedAt": 1767619920589,
"scope": "always"
} }
], ],
"excludedTags": [], "excludedTags": [],
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"activeConversationId": "conv-1767607708938-lh0h0m9vo", "activeConversationId": "conv-1767620030117-cqj3f0arx",
"lastEnvHash": "", "lastEnvHash": "",
"lastClaudeModel": "sonnet", "lastClaudeModel": "sonnet",
"lastCustomModel": "" "lastCustomModel": ""
+1 -1
View File
@@ -1 +1 @@
{"history":{"2026-01-05":{"words":0,"characters":0,"sentences":0,"pages":0,"files":0,"footnotes":0,"citations":0,"totalWords":713710,"totalCharacters":4194148,"totalSentences":15884,"totalFootnotes":15,"totalCitations":4,"totalPages":2378.800000000001}},"modifiedFiles":{}} {"history":{"2026-01-05":{"words":0,"characters":0,"sentences":0,"pages":0,"files":0,"footnotes":0,"citations":0,"totalWords":715315,"totalCharacters":4209751,"totalSentences":15845,"totalFootnotes":15,"totalCitations":4,"totalPages":2384.000000000001}},"modifiedFiles":{}}