Cursor Rules Sync Script
December 14, 2025 · View on GitHub
Syncs the .cursor directory from the source repository to all other projects in ~/PycharmProjects/. Uses path-based syncing with ID-based file matching for handling renames and updates.
Overview
The script manages one-way synchronization of Cursor rules and prompts across multiple projects. Source directory is ~/PycharmProjects/cursor-rules-and-prompts/.cursor. Destination directories are all other directories in ~/PycharmProjects/ that have both a .cursor directory and a .include file.
Note: The fetch-cursor-rules.sh script is deprecated and no longer used. All synchronization is handled by sync-cursor.sh.
See: sync-cursor.sh
Features
- One-way sync: Source → Destinations only (no bidirectional sync)
- Path-based syncing: Uses
.includefile to specify what to sync (no interactive mode selection) - ID-based matching: Matches files by unique ID in frontmatter, handles renames and ID updates
- Recursive directory inclusion: Automatically includes all subdirectories when a directory pattern is specified
- Single configuration file: Uses
.includefile (replaces.syncignoreand.syncinclude) - Orphaned file cleanup: Removes files in destinations that no longer exist in source
- Specific directory sync: Can sync to a single directory by passing it as an argument
Setup
To run the script from any directory, add an alias to ~/.zshrc:
# Cursor rules sync script
alias sync-cursor="~/PycharmProjects/cursor-rules-and-prompts/sync-cursor.sh"
After adding the alias, reload your shell configuration:
source ~/.zshrc
Now you can run sync-cursor from any directory.
Usage
Sync to All Destinations
Run from any directory:
sync-cursor
Or run directly with the full path:
~/PycharmProjects/cursor-rules-and-prompts/sync-cursor.sh
The script will:
- Find all directories in
~/PycharmProjects/(excluding source) - Only sync to directories that have both
.cursor/directory and.includefile - Skip directories without
.cursor/or without.includefile (with warnings)
Sync to Specific Directory
Pass the directory path as an argument:
sync-cursor /path/to/specific/project
The script will:
- Validate that the directory exists and has
.cursor/directory - Check for
.includefile - Sync only to that directory
How It Works
1. Destination Detection
The script automatically detects destination directories:
- All directories in
~/PycharmProjects/(excluding source:cursor-rules-and-prompts) - Requirement: Directory must have both
.cursor/directory and.includefile - Directories without
.cursor/are skipped with info message - Directories without
.includefile (or empty.include) are skipped with warning
2. Pattern Processing
The script reads patterns from .include files:
- Source
.include:~/PycharmProjects/cursor-rules-and-prompts/.cursor/.include - Destination
.include:{destination}/.cursor/.include - Patterns from both files are combined
- Patterns without
!prefix are inclusions - Patterns with
!prefix are exclusions
3. Pattern Expansion
For directory patterns (ending with /), the script automatically generates recursive patterns:
prompts/→ includesprompts/,prompts/*,prompts/*/,prompts/*/*/, etc. (up to 20 levels deep)- This ensures all subdirectories are included recursively
4. File Synchronization
Uses rsync with the generated include/exclude patterns:
- Whitelist mode: If include patterns exist, only those are synced
- Blacklist mode: If only exclude patterns exist, everything except those is synced
- Normal mode: If no patterns, syncs everything (except
.includefile itself) - Uses
--deleteto remove files not in source
5. ID-Based Matching
After rsync completes, the script processes ID-based matching:
- Extracts unique
idfrom frontmatter of each file - Matches files by ID first, then falls back to filename
- Handles file renames: if source file has same ID but different name, renames target file
- Handles ID updates: if filename same but ID changed, updates the file
- Cleans up orphaned files: removes files in destination whose IDs no longer exist in source
ID-Based File Matching
How It Works
Each rule and prompt file should have a unique id in its frontmatter:
---
id: rule-academic-copyright-and-genericity
alwaysApply: true
description: Copyright and genericity guidelines
author: Himel Das
---
The script uses this ID to:
- Match files across locations: Even if filename changes, same ID = same file
- Handle renames: If source file is renamed but ID stays same, target file is renamed
- Detect ID changes: If filename same but ID changes, file is updated
- Clean up orphans: Files in destination with IDs not in source are removed
ID Format
- Rules:
rule-{category}-{filename-without-ext}- Example:
rule-academic-copyright-and-genericity
- Example:
- Prompts:
prompt-{filename-without-ext}- Example:
prompt-architecture-diagram-generation
- Example:
Fallback Behavior
If a file doesn't have an ID:
- Script falls back to filename-based matching
- File is still synced, but rename detection won't work
.include File
The .include file replaces both .syncignore and .syncinclude. It uses a single file where:
- Patterns without
!are inclusions (whitelist) - Patterns with
!prefix are exclusions (blacklist) - Similar to
.gitignorebut inverted (inclusions are default)
Location
- Source:
~/PycharmProjects/cursor-rules-and-prompts/.cursor/.include - Destination:
{destination}/.cursor/.include - Patterns from both files are combined
Pattern Syntax
pattern- Include this pattern!pattern- Exclude this pattern# comment- Comments (lines starting with#are ignored)- Empty lines are ignored
- Directory patterns ending with
/are recursively expanded
Examples
Include only rules and prompts:
# Include rules directory (recursively)
rules/
# Include prompts directory (recursively)
prompts/
Include specific subdirectories:
# Include only specific rule categories
rules/academic/
rules/documentation/
# Include prompts
prompts/
# Exclude a specific subdirectory
!rules/academic/old/
Include with exclusions:
# Include rules but exclude old rules
rules/
!rules/old/
!rules/deprecated/
# Include prompts but exclude specific files
prompts/
!prompts/temp.md
Exclude patterns only (blacklist mode):
# Exclude temporary files
!*.tmp
!*.log
!temp/
!backup/
Recursive Directory Inclusion
When you specify a directory pattern (ending with /), all subdirectories are automatically included:
# This includes:
# - prompts/
# - prompts/html-to-markdown/
# - prompts/html-to-markdown/subdir/
# - All files at any depth
prompts/
The script generates patterns up to 20 levels deep automatically.
Pattern Conflicts
If the same pattern appears in both include and exclude:
- Include takes precedence (warning is logged)
- Example:
rules/and!rules/→rules/is included
Important Notes
- The
.includefile itself is never synced (always excluded) - If no
.includefile exists or it's empty, the directory is skipped with a warning - Both source and destination
.includefiles are read and combined - Patterns are relative to
.cursor/directory
File Processing Flow
- Read
.includefiles (source + destination) - Parse patterns (inclusions and exclusions)
- Expand directory patterns (recursive inclusion)
- Run rsync with generated patterns
- Build ID mappings (source and destination)
- Process ID matching (handle renames, updates)
- Cleanup orphaned files (remove files not in source)
Error Handling
- Exits if source directory doesn't exist
- Skips destinations without
.cursor/directory (with info message) - Skips destinations without
.includefile (with warning) - Continues processing even if individual destinations fail
- Logs warnings for pattern conflicts
- Handles missing ID gracefully (falls back to filename)
Output
The script provides colored output:
- Blue [INFO]: General information and progress
- Green [SUCCESS]: Successful operations
- Yellow [WARNING]: Warnings (e.g., missing
.includefiles, pattern conflicts) - Red [ERROR]: Errors that stop execution
Progress messages show: Synced to X/Y destinations after each successful sync.
Requirements
rsync- For file synchronizationbash- Shell interpreterawk,grep,sed- Text processing (standard Unix tools)
Example Workflow
-
Create
.includefile in source:~/PycharmProjects/cursor-rules-and-prompts/.cursor/.includerules/ prompts/ -
Create
.includefile in destination:~/PycharmProjects/my-project/.cursor/.includerules/academic/ prompts/ -
Run sync:
sync-cursor -
Script will:
- Read both
.includefiles - Combine patterns (rules/, prompts/, rules/academic/)
- Sync matching files from source to destination
- Process ID-based matching (handle renames)
- Clean up orphaned files
- Read both
Deprecated Scripts
fetch-cursor-rules.sh
The fetch-cursor-rules.sh script is deprecated and no longer used. All functionality has been migrated to sync-cursor.sh. The new script provides:
- Better ID-based matching
- Simpler configuration (single
.includefile) - Path-based syncing (no interactive prompts)
- Recursive directory inclusion
- Improved error handling
If you have any references to fetch-cursor-rules.sh, please update them to use sync-cursor.sh instead.
Migration from Old Scripts
If you were using the old scripts, here's what changed:
From fetch-cursor-rules.sh
- No longer needed: The script is deprecated
- Use:
sync-cursor.shinstead - Configuration: Create
.includefile instead of using GitHub repository
From Old sync-cursor.sh (with .syncignore/.syncinclude)
- Combine files: Merge
.syncignoreand.syncincludeinto single.includefile - Add exclusions: Prefix exclusion patterns with
! - Remove interactive prompts: No more "sync only rules?" prompt - it's path-based now
- Remove meta.json: Version tracking is no longer used
Example Migration
Old .syncinclude:
rules/
prompts/
Old .syncignore:
*.tmp
backup/
New .include:
rules/
prompts/
!*.tmp
!backup/
Troubleshooting
Directory Not Syncing
Problem: Directory has .cursor/ but nothing is syncing.
Solution:
- Check if
.includefile exists in.cursor/directory - Check if
.includefile has non-empty, non-comment lines - Script will warn if
.includeis missing or empty
Subdirectories Not Included
Problem: Added prompts/ but subdirectories like prompts/html-to-markdown/ are not syncing.
Solution:
- Ensure pattern ends with
/(e.g.,prompts/notprompts) - Script automatically expands directory patterns recursively
- Check that subdirectories aren't excluded by
!patterns
Files Not Renaming
Problem: File renamed in source but still has old name in destination.
Solution:
- Ensure both source and destination files have
idin frontmatter - Check that IDs match between source and destination
- Script uses ID-based matching for renames
Orphaned Files Not Removed
Problem: Files deleted in source still exist in destination.
Solution:
- Ensure files have
idin frontmatter - Script only removes files with IDs that no longer exist in source
- Files without IDs won't be automatically cleaned up