---
description: This rule is responsible for creating new Cursor rules or updating existing rules. Cursor rules are fundamental to maintaining the structure, style and organization of code in a project. This rule should be invoked in Agent mode when: 1. a user wants to create a new cursor rule, 2. a user wants to update or change an existing rule, 3. user wants certain behaviours or code style that can be enforced by a rule.
globs: *.mdc
alwaysApply: true
---

# Creating and updating cursor rules

## Cursor rules format

  Every cursor rule MUST start with YAML frontmatter at the very top of the file.

  <example>
    ```mdc
    ---
    description: Your rule description
    globs: .cursor/rules/**/*.mdc OR blank
    alwaysApply: false
    ---
    ```
  </example>
  
### Front matter and cursor rule types:

The front matter section must always start the file and include all 3 fields, even if the field value will be blank - the types are:
  - Manual Rule: if a Manual rule is requested, description and globs MUST be blank, `alwaysApply: false` and filename ends with `-manual.mdc`.
  - Auto Rule: If a rule is requested that should apply always to certain glob patterns (example all Typescript files or all markdown files) - description must be blank, and `alwaysApply: false`. The filename should always end with -auto.mdc.
  - Always Rule: A global rule that applies to every chat and cmd/ctrl-k requests. The description and globs should be blank, and `alwaysApply: true`. The filename ends with -always.mdc.
  - Agent Select Rule: The rule does not need to be loaded into every chat thread, it serves a specific purpose. The description MUST provide comprehensive context about when to apply the rule, including scenarios like code changes, architecture decisions, bug fixes, or new file creation. Globs blank, and `alwaysApply: false` and filename ends with -agent.mdc
  - The front matter `globs` property can be empty or specify the constrained filename, type or extension

## Critical Rules
- Every cursor rule MUST start with YAML frontmatter at the very top of the file.
- Rule files will be located and named ALWAYS as: `.cursor/rules/{organizing-folder}/rule-name-{auto|agent|manual|always}.mdc`
- Any cursor rule file must contain a concise list of rules 
- Any cursor rule file should also state conditions that violate the rules
- It should NEVER be possible to add a rule that deletes rules.
- Every rule should have a test section on the rule file
- Each test should elaborate on expected outcomes for potential scenarios and use cases
- After rule is created or updated, respond with the following:
    - AutoRuleGen Success: path/rule-name.mdc
    - Rule Type: {Rule Type}
    - Rule Description: {The exact content of the description field}
- Ideally, a cursor rule should be 500 lines or less.

### Rule Content
  - Rules may contain XML-style `<rule></rule>` and `<example></example>` tags
  - Include clear examples that account for specific conventions of the language or framework the rule applies to. 
  - If there is a contradiction between rules between files or within the same file, highlight them. 
  - Add relevant metadata on priority and version

<example>
    ```mdc
    ---
    description: Your rule description
    globs: pattern1,pattern2
    alwaysApply: false
    ---

    # Rule Title

    {description or summary about purpose of the rule}

    ## Critical Rules

    - Important rule that agent shall not violate
    - Another important rule that agent shall not violate

    <rule>
    name: my-rule-name
    description: rule description

    filters:
    - type: file_extension
      pattern: "\\.ext$"
    actions:
    - type: {suggest|reject|transform|lint|format|validate|alert|document|generate}
    ...
    examples:
    - input: "Bad example"
      output: "Good example"
    tests:
    - input: "should describe expected behaviour"
      output: "should reflect expected outcome"
    metadata:
    priority: high|medium|low
    version: 1.0
    </rule>
    ```
  </example>

## Organizing Folders

All folders within PROJECT_ROOT/.cursor/rules should follow the following conventions:

- .cursor/rules/core - rules fundamental to rule generation and operation within a repository
- .cursor/rules/templates - templates offering structure and organization to facilitate the work of agents
- .cursor/rules/test  - rules about testing
- .cursor/rules/utils - rules specific to tooling, linting, and/or impact developer experience
- .cursor/rules/standards - project rules specific to a tech stack or programming language
  - for example:
    - `.cursor/rules/standards/mongo-express-react-node.mdc` if we are using the MERN stack (Mongo, Express, React, Node)
    - `.cursor/rules/standards/ts-auto.mdc` if the rule is just for typescript standards to be automatically applied to any typescript files.

## Project Structure Organization

## Glob Pattern Examples

#### Glob patterns for different rule types:
- Core standards: .cursor/rules/**/*.mdc
- Testing standards: *.test.ts, *.test.js, *test.spec.ts
- UI components: src/components/**/*.tsx, src/components/*.vue 
- Documentation: docs/**/*.md, *.mdx
- Configuration files: *.config.js, *.config.ts
- CI workflows: .github/**/*.yml, .Dockerfile, docker-compose.yml
- Build artifacts: dist/**/*, out/**/*
- Multiple extensions: *.js, *.ts, *.tsx
- Multiple patterns: dist/**/*.*, docs/**/*.md, *test*.*

In projects that use the custom agents and their workflows, an .ai/ folder will be created at the root level of the repository if it doesn't already exist.

#### Glob patterns for projects using the agentic workflow:

Folders should be created if they don't already exist.

- User stories (PBIs): .ai/*.md
- Dropped or Completed user stories: .ai/backlog/done/*.md
- Architecture: .ai/architecture/*.md
- Architecture decision records (ADR): .ai/architecture/decision-records/*.md
- bugs: .ai/bugs/
- NEVER create a nested folder with the same name as its parent

<example type="invalid">
 .cursor/rules/.ai/.ai/story-1.story.md
</example>

### Filenaming conventions

- Make names descriptive of the rule's purpose
- Use either kebab-case or understores within filenames. Do not allow use both within the same repository.

For User stories aka. PBIs (Product Backlog Item(s)):
  - Always use .md 

  <example>
  01234-automated-package-release.md
  </example>

  <example type="invalid">
  UserStory_AutomatedPackageRelease.md
  </example>

  - The title following the digits should be semantic and descriptive. 
  - Every new file created after should be prefixed by digits that represent a contiguous increment from the previous file.

For architectural documents (including decision records):
  - Always use .md
  - Can include data structures, schemas UML or Mermaid as needed

For cursor rules:
  - Always use .mdc extension

  Examples of acceptable rule filenames:
  <example> 
    rule-generation-agent.mdc
    rule-location.mdc
    js-linting-always.mdc
    app-architecture.mdc
  </example>
  
  Examples of invalid rule names: 
  <example type="invalid">
    AbCdDruleName.mdc
    added-a-rule.mdc
    something-cool.mdc
  </example>

<rule>
  name: create-rule
  description: Standards for creating new Cursor rules and updating existing rules in a repository
  alwaysApply: true
  filters:
    # Match any .mdc files
    - type: file_extension
      pattern: "\\.mdc$"
    # Match files that look like Cursor rules
    - type: content
      pattern: "(?s)<rule>.*?</rule>"
    # Find example(s) in Cursor rules to enhance precision of implementation
    - type: content
      pattern: "(?s)<examples?>(.*?)</examples?>"
    # Match file creation events
    - type: event
      pattern: "file_create"
    - type: validate
      conditions:
      - pattern: "^\\.\\/\\.cursor\\/rules\\/[\\w-]+\\/[a-z0-9]+(?:-[a-z0-9]+)*-(?:auto|agent|manual|always)\\.mdc$"
        message: "Filenames inside `.ai/ of cursor rules should follow the format `{organizing-folder}/rule-name-{type}.mdc`"
  actions:
    - type: reject
      conditions:
        - pattern: "^(?!\\.\\/\\.cursor\\/rules\\/.*\\.mdc$)"
          message: "Cursor rule files (.mdc) must be placed in the .cursor/rules directory"
      
    - type: validate
      message: |
        When creating Cursor rules:

        1. Always place rule files in PROJECT_ROOT/.cursor/rules/:
          ```
          .cursor/rules/
          ├── your-rule-name.mdc
          ├── another-rule.mdc
          └── ...
          ```
          Folders pertaining to the abstract function of the rule can be created when there's 2 or more of any file

        2. Directory structure for cursor rules:
          ```
          PROJECT_ROOT/
          └──.cursor
              └── rules
                  ├── core        required global rules for agentic codegen
                  ├── standards   standards for languages or particular tech stacks
                  ├── templates   document templates
                  └── utils       rules that improve devex and apply to tooling
          ```
          Where this should live for projects that use this set of rules.

        3. Never place rule files:
          - In the project root
          - In subdirectories outside .cursor/rules
          - In any other location

  <example>
  - input: |
        # Bad: Rule file in wrong location
        rules/my-rule.mdc
        my-rule.mdc
        .rules/my-rule.mdc

        # Good: Rule file in correct location
        .cursor/rules/my-rule.mdc
      output: "Correctly placed Cursor rule file"
  </example> 

  metadata:
    priority: high
    version: 1.0
</rule>

test:
  - input: |
      # Bad example: Insufficient context with vague requirements and no examples
      <rule>
        name: calculate_total
        description: get the total number of things
      </rule>
      # Good: Clear instructions with examples
      <rule>
        name: sum_of_numbers
        description: given a series of numbers, returns the total of all numbers added together
      </rule>
      examples:
      - input: |
        function calculateTotal(price, tax) {
            return price * (1 + tax);
        }
        output: |
        /**
        * @description Calculates total price including tax
        * @param {number} price - Base price before tax
        * @param {number} tax - Tax rate as decimal
        * @returns {number} Final price including tax
        */
        function calculateTotal(price, tax) {
            return price * (1 + tax);
        }
  - input: |
      # Bad: Overly broad and non-specific to language
      ---
      description: Code standards
      globs: *
      ---
      <rule>
      name: all_code
      description: Enforce all code standards
      filters:
        - type: file_extension
          pattern: ".*"
      actions:
        - type: suggest
          message: "Write better code"
      </rule>
      # Good: Specifies details and conventions pertaining to language
      ---
      description: JavaScript Function Documentation Standards
      globs: *.{js,ts,jsx,tsx}
      ---
      <rule>
      name: function_documentation
      description: Enforces consistent function documentation using JSDoc
      filters:
        - type: content
          pattern: "function\\s+\\w+\\s*\\([^)]*\\)\\s*{(?![\\s\\S]*\\*)"
      actions:
        - type: suggest
          message: |
            Add JSDoc documentation for functions. Example:
            /**
            * @description Brief description of function
            * @param {type} paramName - Parameter description
            * @returns {type} Description of return value
            */
  - input: |
      # Bad: Missing frontmatter
      <rule>
      name: bad_rule
      </rule>

      # Good: Properly formatted rule with all frontmatter properties populated
      ---
      description: Example rule
      globs: *.ts
      autoA
      ---

      # TypeScript Standards

      <rule>
      name: typescript_standards
      description: Standards for TypeScript files
      </rule>

      filters:
        - type: file_extension
          pattern: "\\.ts$"
      actions:
        - type: suggest
          message: "Follow TypeScript best practices that adhere to its latest stable version."
    
      # Good: Thorough well-defined examples of patterns with examples
      ---
      description: TypeScript Type Definition Standards
      globs: *.ts
      ---
      <rule>
      name: typescript_types
      description: Enforces proper type definitions and usage in TypeScript
      filters:
        - type: content
          pattern: "(any|Object|Function)(?!\\s*:.*\\s*=>)"
      actions:
        - type: suggest
          message: |
            Avoid using generic types like 'any', 'Object', or 'Function'.
            Instead:
            - Use specific interfaces or type definitions
            - Define proper function signatures
            - Utilize built-in utility types when appropriate
      examples:
        - input: |
            function process(data: any): Object {
                return { result: data };
            }
          output: |
            interface ProcessInput {
                id: string;
                value: number;
            }
            
            interface ProcessOutput {
                result: ProcessInput;
                timestamp: Date;
            }
            
            function process(data: ProcessInput): ProcessOutput {
                return { 
                    result: data,
                    timestamp: new Date()
                };
            }
        - input: "var x = 1;"
          output: "const x = 1;"
        - input: "let a: any = '';"
          output: "const a: undefined = '';"
      metadata:
        priority: high
        version: 1.0
      </rule>
    output: "Correctly formatted Cursor rule"
