UNPKG

@intellectronica/ruler

Version:

Ruler — apply the same rules to all coding agents

803 lines (584 loc) 30.6 kB
# Ruler: Centralise Your AI Coding Assistant Instructions <table style="width:100%"> <tr> <td style="vertical-align: top;"> <p> <a href="https://github.com/intellectronica/ruler/actions/workflows/ci.yml"><img src="https://github.com/intellectronica/ruler/actions/workflows/ci.yml/badge.svg" alt="CI"></a> <a href="https://www.npmjs.com/package/@intellectronica/ruler"><img src="https://badge.fury.io/js/%40intellectronica%2Fruler.svg" alt="npm version"></a> <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"> </p> <ul> <li><strong>GitHub</strong>: <a href="https://github.com/intellectronica/ruler">intellectronica/ruler</a></li> <li><strong>NPM</strong>: <a href="https://www.npmjs.com/package/@intellectronica/ruler">@intellectronica/ruler</a></li> </ul> <hr /> <p> <em>Animation by <a href="https://isaacflath.com/">Isaac Flath</a> of <strong><a href="https://elite-ai-assisted-coding.dev/">Elite AI-Assisted Coding</a></strong></em> ➡︎ </p> </td> <td style="vertical-align: top; width:33%;"> <img src="img/ruler-short.gif" alt="Ruler demo" style="width:300px; height:auto; display:block;" /> </td> </tr> </table> --- > **Beta Research Preview** > > - Please test this version carefully in your environment > - Report issues at https://github.com/intellectronica/ruler/issues ## Why Ruler? Managing instructions across multiple AI coding tools becomes complex as your team grows. Different agents (GitHub Copilot, Claude, Cursor, Aider, etc.) require their own configuration files, leading to: - **Inconsistent guidance** across AI tools - **Duplicated effort** maintaining multiple config files - **Context drift** as project requirements evolve - **Onboarding friction** for new AI tools - **Complex project structures** requiring context-specific instructions for different components Ruler solves this by providing a **single source of truth** for all your AI agent instructions, automatically distributing them to the right configuration files. With support for **nested rule loading**, Ruler can handle complex project structures with context-specific instructions for different components. ## Core Features - **Centralised Rule Management**: Store all AI instructions in a dedicated `.ruler/` directory using Markdown files - **Nested Rule Loading**: Support complex project structures with multiple `.ruler/` directories for context-specific instructions - **Automatic Distribution**: Ruler applies these rules to configuration files of supported AI agents - **Targeted Agent Configuration**: Fine-tune which agents are affected and their specific output paths via `ruler.toml` - **MCP Server Propagation**: Manage and distribute Model Context Protocol (MCP) server settings - **`.gitignore` Automation**: Keeps generated agent config files out of version control automatically - **Simple CLI**: Easy-to-use commands for initialising and applying configurations ## Supported AI Agents | Agent | Rules File(s) | MCP Configuration / Notes | | ---------------- | ------------------------------------------------ | ------------------------------------------------ | | AGENTS.md | `AGENTS.md` | (pseudo-agent ensuring root `AGENTS.md` exists) | | GitHub Copilot | `AGENTS.md` | `.vscode/mcp.json` | | Claude Code | `CLAUDE.md` | `.mcp.json` | | OpenAI Codex CLI | `AGENTS.md` | `.codex/config.toml` | | Jules | `AGENTS.md` | - | | Cursor | `.cursor/rules/ruler_cursor_instructions.mdc` | `.cursor/mcp.json` | | Windsurf | `.windsurf/rules/ruler_windsurf_instructions.md` | - | | Cline | `.clinerules` | - | | Crush | `CRUSH.md` | `.crush.json` | | Amp | `AGENTS.md` | - | | Amazon Q CLI | `.amazonq/rules/ruler_q_rules.md` | `.amazonq/mcp.json` | | Aider | `AGENTS.md`, `.aider.conf.yml` | `.mcp.json` | | Firebase Studio | `.idx/airules.md` | `.idx/mcp.json` | | Open Hands | `.openhands/microagents/repo.md` | `config.toml` | | Gemini CLI | `AGENTS.md` | `.gemini/settings.json` | | Junie | `.junie/guidelines.md` | - | | AugmentCode | `.augment/rules/ruler_augment_instructions.md` | - | | Kilo Code | `.kilocode/rules/ruler_kilocode_instructions.md` | `.kilocode/mcp.json` | | opencode | `AGENTS.md` | `opencode.json` | | Goose | `.goosehints` | - | | Qwen Code | `AGENTS.md` | `.qwen/settings.json` | | RooCode | `AGENTS.md` | `.roo/mcp.json` | | Zed | `AGENTS.md` | `.zed/settings.json` (project root, never $HOME) | | Trae AI | `.trae/rules/project_rules.md` | - | | Warp | `WARP.md` | - | | Kiro | `.kiro/steering/ruler_kiro_instructions.md` | - | | Firebender | `firebender.json` | - | ## Getting Started ### Installation **Global Installation (Recommended for CLI use):** ```bash npm install -g @intellectronica/ruler ``` **Using `npx` (for one-off commands):** ```bash npx @intellectronica/ruler apply ``` ### Project Initialisation 1. Navigate to your project's root directory 2. Run `ruler init` 3. This creates: - `.ruler/` directory - `.ruler/AGENTS.md`: The primary starter Markdown file for your rules - `.ruler/ruler.toml`: The main configuration file for Ruler (now contains sample MCP server sections; legacy `.ruler/mcp.json` no longer scaffolded) - (Optional legacy fallback) If you previously used `.ruler/instructions.md`, it is still respected when `AGENTS.md` is absent. (The prior runtime warning was removed.) Additionally, you can create a global configuration to use when no local `.ruler/` directory is found: ```bash ruler init --global ``` The global configuration will be created to `$XDG_CONFIG_HOME/ruler` (default: `~/.config/ruler`). ## Core Concepts ### The `.ruler/` Directory This is your central hub for all AI agent instructions: - **Primary File Order & Precedence**: 1. A repository root `AGENTS.md` (outside `.ruler/`) if present (highest precedence, prepended) 2. `.ruler/AGENTS.md` (new default starter file) 3. Legacy `.ruler/instructions.md` (only if `.ruler/AGENTS.md` absent; no longer emits a deprecation warning) 4. Remaining discovered `.md` files under `.ruler/` (and subdirectories) in sorted order - **Rule Files (`*.md`)**: Discovered recursively from `.ruler/` or `$XDG_CONFIG_HOME/ruler` and concatenated in the order above - **Concatenation Marker**: Each file's content is prepended with `--- Source: <relative_path_to_md_file> ---` for traceability - **`ruler.toml`**: Master configuration for Ruler's behavior, agent selection, and output paths - **`mcp.json`**: Shared MCP server settings This ordering lets you keep a short, high-impact root `AGENTS.md` (e.g. executive project summary) while housing detailed guidance inside `.ruler/`. ### Nested Rule Loading Ruler now supports **nested rule loading** with the `--nested` flag, enabling context-specific instructions for different parts of your project: ``` project/ ├── .ruler/ # Global project rules │ ├── AGENTS.md │ └── coding_style.md ├── src/ │ └── .ruler/ # Component-specific rules │ └── api_guidelines.md ├── tests/ │ └── .ruler/ # Test-specific rules │ └── testing_conventions.md └── docs/ └── .ruler/ # Documentation rules └── writing_style.md ``` **How it works:** - Discover all `.ruler/` directories in the project hierarchy - Load and concatenate rules from each directory in order - Enable with: `ruler apply --nested` **Perfect for:** - Monorepos with multiple services - Projects with distinct components (frontend/backend) - Teams needing different instructions for different areas - Complex codebases with varying standards ### Best Practices for Rule Files **Granularity**: Break down complex instructions into focused `.md` files: - `coding_style.md` - `api_conventions.md` - `project_architecture.md` - `security_guidelines.md` **Example rule file (`.ruler/python_guidelines.md`):** ```markdown # Python Project Guidelines ## General Style - Follow PEP 8 for all Python code - Use type hints for all function signatures and complex variables - Keep functions short and focused on a single task ## Error Handling - Use specific exception types rather than generic `Exception` - Log errors effectively with context ## Security - Always validate and sanitize user input - Be mindful of potential injection vulnerabilities ``` ## Usage: The `apply` Command ### Primary Command ```bash ruler apply [options] ``` The `apply` command looks for `.ruler/` in the current directory tree, reading the first match. If no such directory is found, it will look for a global configuration in `$XDG_CONFIG_HOME/ruler`. ### Options | Option | Description | | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--project-root <path>` | Path to your project's root (default: current directory) | | `--agents <agent1,agent2,...>` | Comma-separated list of agent names to target (agentsmd, aider, amazonqcli, amp, augmentcode, claude, cline, codex, copilot, crush, cursor, firebase, firebender, gemini-cli, goose, jules, junie, kilocode, kiro, opencode, openhands, qwen, roo, trae, warp, windsurf, zed) | | `--config <path>` | Path to a custom `ruler.toml` configuration file | | `--mcp` / `--with-mcp` | Enable applying MCP server configurations (default: true) | | `--no-mcp` | Disable applying MCP server configurations | | `--mcp-overwrite` | Overwrite native MCP config entirely instead of merging | | `--gitignore` | Enable automatic .gitignore updates (default: true) | | `--no-gitignore` | Disable automatic .gitignore updates | | `--nested` | Enable nested rule loading from nested .ruler directories (default: disabled) | | `--backup` | Enable/disable creation of .bak backup files (default: enabled) | | `--dry-run` | Preview changes without writing files | | `--local-only` | Do not look for configuration in `$XDG_CONFIG_HOME` | | `--verbose` / `-v` | Display detailed output during execution | ### Common Examples **Apply rules to all configured agents:** ```bash ruler apply ``` **Apply rules only to GitHub Copilot and Claude:** ```bash ruler apply --agents copilot,claude ``` **Apply rules only to Firebase Studio:** ```bash ruler apply --agents firebase ``` **Apply rules only to Warp:** ```bash ruler apply --agents warp ``` **Apply rules only to Trae AI:** ```bash ruler apply --agents trae ``` **Apply rules only to RooCode:** ```bash ruler apply --agents roo ``` **Use a specific configuration file:** ```bash ruler apply --config ./team-configs/ruler.frontend.toml ``` **Apply rules with verbose output:** ```bash ruler apply --verbose ``` **Apply rules but skip MCP and .gitignore updates:** ```bash ruler apply --no-mcp --no-gitignore ``` ## Usage: The `revert` Command The `revert` command safely undoes all changes made by `ruler apply`, restoring your project to its pre-ruler state. It intelligently restores files from backups (`.bak` files) when available, or removes generated files that didn't exist before. ### Why Revert is Needed When experimenting with different rule configurations or switching between projects, you may want to: - **Clean slate**: Remove all ruler-generated files to start fresh - **Restore originals**: Revert modified files back to their original state - **Selective cleanup**: Remove configurations for specific agents only - **Safe experimentation**: Try ruler without fear of permanent changes ### Primary Command ```bash ruler revert [options] ``` ### Options | Option | Description | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `--project-root <path>` | Path to your project's root (default: current directory) | | `--agents <agent1,agent2,...>` | Comma-separated list of agent names to revert (agentsmd, aider, amazonqcli, amp, augmentcode, claude, cline, codex, copilot, crush, cursor, firebase, firebender, gemini-cli, goose, jules, junie, kilocode, kiro, opencode, openhands, qwen, roo, trae, warp, windsurf, zed) | | `--config <path>` | Path to a custom `ruler.toml` configuration file | | `--keep-backups` | Keep backup files (.bak) after restoration (default: false) | | `--dry-run` | Preview changes without actually reverting files | | `--verbose` / `-v` | Display detailed output during execution | | `--local-only` | Only search for local .ruler directories, ignore global config | ### Common Examples **Revert all ruler changes:** ```bash ruler revert ``` **Preview what would be reverted (dry-run):** ```bash ruler revert --dry-run ``` **Revert only specific agents:** ```bash ruler revert --agents claude,copilot ``` **Revert with detailed output:** ```bash ruler revert --verbose ``` **Keep backup files after reverting:** ```bash ruler revert --keep-backups ``` ## Configuration (`ruler.toml`) in Detail ### Location Defaults to `.ruler/ruler.toml` in the project root. Override with `--config` CLI option. ### Complete Example ```toml # Default agents to run when --agents is not specified # Uses case-insensitive substring matching default_agents = ["copilot", "claude", "aider"] # --- Global MCP Server Configuration --- [mcp] # Enable/disable MCP propagation globally (default: true) enabled = true # Global merge strategy: 'merge' or 'overwrite' (default: 'merge') merge_strategy = "merge" # --- MCP Server Definitions --- [mcp_servers.filesystem] command = "npx" args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"] [mcp_servers.git] command = "npx" args = ["-y", "@modelcontextprotocol/server-git", "--repository", "."] [mcp_servers.remote_api] url = "https://api.example.com" [mcp_servers.remote_api.headers] Authorization = "Bearer your-token" # --- Global .gitignore Configuration --- [gitignore] # Enable/disable automatic .gitignore updates (default: true) enabled = true # --- Agent-Specific Configurations --- [agents.copilot] enabled = true [agents.claude] enabled = true output_path = "CLAUDE.md" [agents.aider] enabled = true output_path_instructions = "AGENTS.md" output_path_config = ".aider.conf.yml" # OpenAI Codex CLI agent and MCP config [agents.codex] enabled = true output_path = "AGENTS.md" output_path_config = ".codex/config.toml" # Agent-specific MCP configuration for Codex CLI [agents.codex.mcp] enabled = true merge_strategy = "merge" [agents.firebase] enabled = true output_path = ".idx/airules.md" [agents.gemini-cli] enabled = true [agents.jules] enabled = true [agents.junie] enabled = true output_path = ".junie/guidelines.md" # Agent-specific MCP configuration [agents.cursor.mcp] enabled = true merge_strategy = "merge" # Disable specific agents [agents.windsurf] enabled = false [agents.kilocode] enabled = true output_path = ".kilocode/rules/ruler_kilocode_instructions.md" [agents.warp] enabled = true output_path = "WARP.md" ``` ### Configuration Precedence 1. **CLI flags** (e.g., `--agents`, `--no-mcp`, `--mcp-overwrite`, `--no-gitignore`) 2. **Settings in `ruler.toml`** (`default_agents`, specific agent settings, global sections) 3. **Ruler's built-in defaults** (all agents enabled, standard output paths, MCP enabled with 'merge') ## MCP (Model Context Protocol) Server Configuration MCP provides broader context to AI models through server configurations. Ruler can manage and distribute these settings across compatible agents. ### TOML Configuration (Recommended) You can now define MCP servers directly in `ruler.toml` using the `[mcp_servers.<name>]` syntax: ```toml # Global MCP behavior [mcp] enabled = true merge_strategy = "merge" # or "overwrite" # Local (stdio) server [mcp_servers.filesystem] command = "npx" args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"] [mcp_servers.filesystem.env] API_KEY = "your-api-key" # Remote server [mcp_servers.search] url = "https://mcp.example.com" [mcp_servers.search.headers] Authorization = "Bearer your-token" "X-API-Version" = "v1" ``` ### Legacy `.ruler/mcp.json` (Deprecated) For backward compatibility, you can still use the JSON format; a warning is issued encouraging migration to TOML. The file is no longer created during `ruler init`. ```json { "mcpServers": { "filesystem": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-filesystem", "/path/to/project" ] }, "git": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-git", "--repository", "."] } } } ``` ### Configuration Precedence When both TOML and JSON configurations are present: 1. **TOML servers take precedence** over JSON servers with the same name 2. **Servers are merged** from both sources (unless using overwrite strategy) 3. **Deprecation warning** is shown encouraging migration to TOML (warning shown once per run) ### Server Types **Local/stdio servers** require a `command` field: ```toml [mcp_servers.local_server] command = "node" args = ["server.js"] [mcp_servers.local_server.env] DEBUG = "1" ``` **Remote servers** require a `url` field (headers optional; bearer Authorization token auto-extracted for OpenHands when possible): ```toml [mcp_servers.remote_server] url = "https://api.example.com" [mcp_servers.remote_server.headers] Authorization = "Bearer token" ``` Ruler uses this configuration with the `merge` (default) or `overwrite` strategy, controlled by `ruler.toml` or CLI flags. **Home Directory Safety:** Ruler never writes MCP configuration files outside your project root. Any historical references to user home directories (e.g. `~/.codeium/windsurf/mcp_config.json` or `~/.zed/settings.json`) have been removed; only project-local paths are targeted. **Note for OpenAI Codex CLI:** To apply the local Codex CLI MCP configuration, set the `CODEX_HOME` environment variable to your project’s `.codex` directory: ```bash export CODEX_HOME="$(pwd)/.codex" ``` ## `.gitignore` Integration Ruler automatically manages your `.gitignore` file to keep generated agent configuration files out of version control. ### How it Works - Creates or updates `.gitignore` in your project root - Adds paths to a managed block marked with `# START Ruler Generated Files` and `# END Ruler Generated Files` - Preserves existing content outside this block - Sorts paths alphabetically and uses relative POSIX-style paths ### Example `.gitignore` Section (sample - actual list depends on enabled agents) ```gitignore # Your existing rules node_modules/ *.log # START Ruler Generated Files .aider.conf.yml .clinerules .cursor/rules/ruler_cursor_instructions.mdc .windsurf/rules/ruler_windsurf_instructions.md AGENTS.md CLAUDE.md AGENTS.md # END Ruler Generated Files dist/ ``` ### Control Options - **CLI flags**: `--gitignore` or `--no-gitignore` - **Configuration**: `[gitignore].enabled` in `ruler.toml` - **Default**: enabled ## Practical Usage Scenarios ### Scenario 1: Getting Started Quickly ```bash # Initialize Ruler in your project cd your-project ruler init # Edit the generated files # - Add your coding guidelines to .ruler/AGENTS.md (or keep adding additional .md files) # - Customize .ruler/ruler.toml if needed # Apply rules to all AI agents ruler apply ``` ### Scenario 2: Complex Projects with Nested Rules For large projects with multiple components or services, use nested rule loading: ```bash # Set up nested .ruler directories mkdir -p src/.ruler tests/.ruler docs/.ruler # Add component-specific instructions echo "# API Design Guidelines" > src/.ruler/api_rules.md echo "# Testing Best Practices" > tests/.ruler/test_rules.md echo "# Documentation Standards" > docs/.ruler/docs_rules.md # Apply with nested loading ruler apply --nested --verbose ``` This creates context-specific instructions for different parts of your project while maintaining global rules in the root `.ruler/` directory. ### Scenario 3: Team Standardization 1. Create `.ruler/coding_standards.md`, `.ruler/api_usage.md` 2. Commit the `.ruler` directory to your repository 3. Team members pull changes and run `ruler apply` to update their local AI agent configurations ### Scenario 4: Project-Specific Context for AI 1. Detail your project's architecture in `.ruler/project_overview.md` 2. Describe primary data structures in `.ruler/data_models.md` 3. Run `ruler apply` to help AI tools provide more relevant suggestions ### Integration with NPM Scripts ```json { "scripts": { "ruler:apply": "ruler apply", "dev": "npm run ruler:apply && your_dev_command", "precommit": "npm run ruler:apply" } } ``` ### Integration with GitHub Actions ```yaml # .github/workflows/ruler-check.yml name: Check Ruler Configuration on: pull_request: paths: ['.ruler/**'] jobs: check-ruler: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '18' cache: 'npm' - name: Install Ruler run: npm install -g @intellectronica/ruler - name: Apply Ruler configuration run: ruler apply --no-gitignore - name: Check for uncommitted changes run: | if [[ -n $(git status --porcelain) ]]; then echo "::error::Ruler configuration is out of sync!" echo "Please run 'ruler apply' locally and commit the changes." exit 1 fi ``` ## Troubleshooting ### Common Issues **"Cannot find module" errors:** - Ensure Ruler is installed globally: `npm install -g @intellectronica/ruler` - Or use `npx @intellectronica/ruler` **Permission denied errors:** - On Unix systems, you may need `sudo` for global installation **Agent files not updating:** - Check if the agent is enabled in `ruler.toml` - Verify agent isn't excluded by `--agents` flag - Use `--verbose` to see detailed execution logs **Configuration validation errors:** - Ruler now validates `ruler.toml` format and will show specific error details - Check that all configuration values match the expected types and formats ### Debug Mode Use `--verbose` flag to see detailed execution logs: ```bash ruler apply --verbose ``` This shows: - Configuration loading details - Agent selection logic - File processing information - MCP configuration steps ## FAQ **Q: Can I use different rules for different agents?** A: Currently, all agents receive the same concatenated rules. For agent-specific instructions, include sections in your rule files like "## GitHub Copilot Specific" or "## Aider Configuration". **Q: How do I set up different instructions for different parts of my project?** A: Use the `--nested` flag with `ruler apply --nested`. This enables Ruler to discover and load rules from multiple `.ruler/` directories throughout your project hierarchy. Place component-specific instructions in `src/.ruler/`, test-specific rules in `tests/.ruler/`, etc., while keeping global rules in the root `.ruler/` directory. **Q: How do I temporarily disable Ruler for an agent?** A: Set `enabled = false` in `ruler.toml` under `[agents.agentname]`, or use `--agents` flag to specify only the agents you want. **Q: What happens to my existing agent configuration files?** A: Ruler creates backups with `.bak` extension before overwriting any existing files. **Q: Can I run Ruler in CI/CD pipelines?** A: Yes! Use `ruler apply --no-gitignore` in CI to avoid modifying `.gitignore`. See the GitHub Actions example above. **Q: How do I migrate from older versions using `instructions.md`?** A: Simply rename `.ruler/instructions.md` to `.ruler/AGENTS.md` (recommended). If you keep the legacy file and omit `AGENTS.md`, Ruler will still use it (without emitting the old deprecation warning). Having both causes `AGENTS.md` to take precedence; the legacy file is still concatenated afterward. **Q: How does OpenHands MCP propagation classify servers?** A: Local stdio servers become `stdio_servers`. Remote URLs containing `/sse` are classified as `sse_servers`; others become `shttp_servers`. Bearer tokens in an `Authorization` header are extracted into `api_key` where possible. **Q: Where is Zed configuration written now?** A: Ruler writes a `settings.json` in the project root (not the user home dir) and transforms MCP server definitions to Zed's `context_servers` format including `source: "custom"`. **Q: What changed about MCP initialization?** A: `ruler init` now only adds example MCP server sections to `ruler.toml` instead of creating `.ruler/mcp.json`. The JSON file is still consumed if present, but TOML servers win on name conflicts. **Q: Is Kiro supported?** A: Yes. Kiro receives concatenated rules at `.kiro/steering/ruler_kiro_instructions.md`. ## Development ### Setup ```bash git clone https://github.com/intellectronica/ruler.git cd ruler npm install npm run build ``` ### Testing ```bash # Run all tests npm test # Run tests with coverage npm run test:coverage # Run tests in watch mode npm run test:watch ``` ### Code Quality ```bash # Run linting npm run lint # Run formatting npm run format ``` ## Contributing Contributions are welcome! Please: 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests for new functionality 5. Ensure all tests pass 6. Submit a pull request For bugs and feature requests, please [open an issue](https://github.com/intellectronica/ruler/issues). ## License MIT --- © Eleanor Berger [ai.intellectronica.net](https://ai.intellectronica.net/)