Manage your Cursor AI rules through dotfiles and build custom modes with keyboard shortcuts for automated workflows.
TL;DR
Keep your modular Cursor AI .mdc
rules inside your dotfiles repository for centralized rule management and consistent AI behavior across projects. Build powerful custom modes like a Git Committer to automate commit creation or the PR Reviewer to become your review buddy.
Table of Contents
- Why Version Control Cursor Rules?
- Dotfiles Structure for Cursor Rules
- Description Sections: Agent vs Auto-Attached
- Creating Custom Modes
- The Committer Mode: A Practical Example
- Real-World Workflow
- Summary
What are Cursor Rules?
Cursor rules are markdown files (.mdc
) that define how the Cursor AI assistant behaves. They contain instructions, context, and guidelines that shape the AI’s responses and actions within your development environment.
What are Custom Modes?
Custom modes in Cursor allow you to create specialized AI assistants with specific prompts, capabilities, and keybindings. They enable you to have different AI behaviors for different tasks like committing code, writing documentation, or debugging.
Enabling Custom Modes (Beta Feature)
- Open Cursor Settings (
Cmd+,
orCtrl+,
) - Navigate to the Features tab
- Scroll down to the Chat section
- Enable Custom Modes checkbox
Why use file imports in rules?
File imports allow you to modularize your rules, making them maintainable, reusable, and easier to organize. Instead of one massive rule file, you can use @import
and @import-if-<rule>
to have specialized rules for different languages, frameworks, or tasks.
Why Version Control Cursor Rules?
As developers, we customize our tools to match our workflow and preferences. Cursor AI rules are no different - they evolve over time as we discover better prompts, add new programming languages or refine our development practices.
Without version control, you’ll face these challenges:
- Inconsistency across machines: Different rule configurations on work vs personal laptops
- Lost optimizations: Accidentally overwriting a well-crafted rule without backup
- Rule drift: Gradual degradation of rule quality without tracking changes
- Setup overhead: Manual rule recreation when setting up new development environments
Version controlling your Cursor rules through dotfiles solves these problems by providing a centralized, trackable, and shareable configuration system.
Dotfiles Structure for Cursor Rules
Here’s a basic example of how I organize Cursor rules within my dotfiles repository:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/path/to/dotfiles/cursor/
├── rules.mdc # Main rules file
└── rules/ # Categorized rule modules
├── core
│ ├── code-style.mdc
│ └── general.mdc
├── language
│ ├── typescript.mdc
│ └── python.mdc
├── patterns
│ ├── api-design.mdc
│ └── error-handling.mdc
├── planning
│ ├── plan-generic.mdc
│ └── plan-specs.mdc
└── tools
├── git.mdc
└── kubernetes.mdc
The main rules.mdc
file serves as the entry point and imports specific rule modules by category:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Main Cursor Rules Configuration
## Core Development Rules
@import ./rules/core/code-style.mdc
@import ./rules/core/general.mdc
## Language-Specific Rules
@import-if-typescript ./rules/language/typescript.mdc
@import-if-python ./rules/language/python.mdc
## Planning & Content Rules
@import-if-plan ./rules/planning/plan-generic.mdc
@import-if-specs ./rules/planning/plan-specs.mdc
## Tool-Specific Rules
@import-if-git ./rules/tools/git.mdc
@import-if-kubernetes ./rules/tools/kubernetes.mdc
To symlink the managed rules into Cursor’s config folder:
1
2
3
4
5
# Symlink the root rules.mdc file
ln -sfn /path/to/your/dotfiles/cursor/rules.mdc $HOME/.cursor/rules.mdc
# Symlink the imported rules folder
ln -sfn /path/to/your/dotfiles/cursor/rules $HOME/.cursor/rules
This categorized structure provides several benefits:
- Clear organization: Rules are grouped by purpose and domain
- Easy navigation: Find relevant rules quickly by category
- Scalable structure: Add new categories as your workflow evolves
- Selective imports: Load only the rule categories you need for specific projects
Description Sections: Agent vs Auto-Attached
In Cursor rule files, the description section plays a crucial role in how rules are applied. Understanding the difference between agent-requested and auto-attached rules is essential:
Agent Requested Rules:
1
2
3
4
5
---
description: Git & Version Control
globs:
alwaysApply: false
---
Auto-Attached Rules with File Globs:
1
2
3
4
---
description: Enforces best practices for TypeScript development, including coding standards, performance considerations, and common pitfalls. This rule provides actionable guidance for developers to write clean, maintainable, and scalable TypeScript code.
globs: *.ts?(x)
---
Key differences:
- Agent Requested: Activated only when explicitly referenced or when using specific custom modes
- Auto-Attached: Automatically applied based on file patterns, ensuring consistent behavior, for example: auto-attached with
*.ts?(x)
file pattern match
This dual approach ensures rules are applied contextually - some rules work behind the scenes (auto-attached) while others are invoked for specific tasks (agent-requested).
Creating Custom Modes
Custom modes in Cursor allow you to create specialized AI assistants. They consist of:
- Prompt: The core instruction for the AI
- Capabilities: What actions the mode can perform (search, run commands, edit files)
- Model: Which AI model to use (Claude 4, GPT-4, etc..)
- Keybindings: Keyboard shortcuts for quick access
Custom modes are perfect for repetitive tasks that benefit from specialized AI behavior. Common examples include:
- 🚀 Committer: Specialized for creating git commits
- 👁️ Reviewer: Focused on code review and feedback
- 📝 Documenter: Dedicated to writing and updating documentation
- 🐛 Debugger: Expert at finding and fixing bugs
- 🧪 Tester: Specialized in writing comprehensive tests
The Committer Mode: A Practical Example
Let’s create a powerful “Committer” custom mode that streamlines the git commit process:
Rule definition: The git.mdc
rule that I’m using is quite verbose, I invite you to copy its content from here.
Setting Up the Custom Mode:
- Open Cursor Cascade Window (
Cmd+I
) - Navigate and click on the Agent dropdown
- Click “Add custom mode”
- Configure:
- Name:
Committer
- Prompt:
Follow the git.mdc Cursor rule to create a git commit. You must exclude files and folders specified in the cursor ignore file located in the repository.
- Actions: Enable only “Search” and “Run” (disable “Edit” and “MCP”)
- Model:
Claude Sonnet 4
- Keybinding:
Cmd+Shift+K
(orCtrl+Shift+K
on Windows/Linux)
- Name:
Real-World Workflow
Here’s how the Committer mode transforms the daily git workflow:
Traditional Approach (multiple steps, prone to errors):
1
2
3
4
5
6
7
8
9
10
11
12
13
# Check status
git status
# Add files (might forget some)
git add src/components/Button.tsx
git add src/components/Button.test.tsx
# Write commit message (inconsistent format)
git commit -m "updated button component"
# Realize you forgot something
git add src/types/Button.ts
git commit --amend -m "updated button component and types"
With Committer Mode (streamlined, consistent):
- Make your changes - Edit files as usual
- Use the keybinding - Press
Cmd+Shift+K
- Type simple instruction - “commit” or “commit and push”
- AI handles everything - The Committer mode will:
- Analyze all changes using
git status
- Respect
.cursorignore
exclusions - Suggest appropriate files to stage
- Generate a conventional commit message
- Execute the commit with proper formatting
- Analyze all changes using
Example Interaction:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Terminal session showing Committer mode in action
❯ # Working on a new feature...
❯ # Files modified: src/components/Button.tsx, src/types/Button.ts
❯ # Ready to commit - press Cmd+Shift+K
🤖 Committer AI: I'll analyze your changes and create a commit following the git.mdc rules.
🔍 Analyzing repository status...
✓ Found 3 modified files
✓ Checked .cursorignore exclusions
✓ Validated conventional commit format
📊 Changes detected:
M src/components/Button.tsx (+45 -12)
M src/components/Button.test.tsx (+28 -5)
A src/types/Button.ts (+15 -0)
🚫 Excluded files (per .cursorignore):
× node_modules/
× .env.local
× dist/
✨ Generated commit message:
┌─────────────────────────────────────────────────────────┐
│ feat(ui): enhance Button component with hover states │
│ │
│ - Add interactive hover animations and focus indicators │
│ - Implement comprehensive accessibility improvements │
│ - Add TypeScript interface for Button props │
│ - Expand test coverage for new interactive features │
└─────────────────────────────────────────────────────────┘
🎯 Ready to execute:
git add src/components/Button.tsx src/components/Button.test.tsx src/types/Button.ts
git commit -m "feat(ui): enhance Button component with hover states"
✅ Commit created successfully: a1b2c3d
3 files changed, 88 insertions(+), 17 deletions(-)
🚀 Tip: Type "commit and push" next time to also push to remote!
The AI provides transparency, follows your rules, and ensures consistency across all commits.
Summary
Hope you found this useful! Start small with one custom mode, iterate on your rules as you go, and gradually build your AI assistant toolkit. Your future self (and teammates) will definitely thank you.
It feels like Jarvis is creating commits for you, isn’t it? 😉
Please leave a comment, suggestion, or any other input you think is relevant to this post in the discussion below.
Thanks !
Discussion