@intellectronica/ruler 0.2.19 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +281 -62
  2. package/dist/agents/AbstractAgent.js +82 -0
  3. package/dist/agents/AgentsMdAgent.js +84 -0
  4. package/dist/agents/AiderAgent.js +29 -9
  5. package/dist/agents/AmpAgent.js +2 -44
  6. package/dist/agents/AugmentCodeAgent.js +10 -12
  7. package/dist/agents/ClaudeAgent.js +9 -9
  8. package/dist/agents/ClineAgent.js +3 -9
  9. package/dist/agents/CodexCliAgent.js +27 -21
  10. package/dist/agents/CopilotAgent.js +9 -10
  11. package/dist/agents/CrushAgent.js +6 -0
  12. package/dist/agents/CursorAgent.js +13 -5
  13. package/dist/agents/FirebaseAgent.js +2 -8
  14. package/dist/agents/GeminiCliAgent.js +31 -22
  15. package/dist/agents/GooseAgent.js +2 -10
  16. package/dist/agents/JulesAgent.js +3 -44
  17. package/dist/agents/JunieAgent.js +2 -9
  18. package/dist/agents/KiloCodeAgent.js +8 -9
  19. package/dist/agents/KiroAgent.js +50 -0
  20. package/dist/agents/OpenCodeAgent.js +50 -11
  21. package/dist/agents/OpenHandsAgent.js +8 -9
  22. package/dist/agents/QwenCodeAgent.js +83 -0
  23. package/dist/agents/WarpAgent.js +61 -0
  24. package/dist/agents/WindsurfAgent.js +16 -5
  25. package/dist/agents/ZedAgent.js +132 -0
  26. package/dist/agents/agent-utils.js +37 -0
  27. package/dist/agents/index.js +53 -0
  28. package/dist/cli/commands.js +53 -242
  29. package/dist/cli/handlers.js +181 -0
  30. package/dist/constants.js +9 -2
  31. package/dist/core/ConfigLoader.js +4 -1
  32. package/dist/core/FileSystemUtils.js +123 -4
  33. package/dist/core/RuleProcessor.js +15 -3
  34. package/dist/core/UnifiedConfigLoader.js +364 -0
  35. package/dist/core/UnifiedConfigTypes.js +2 -0
  36. package/dist/core/agent-selection.js +52 -0
  37. package/dist/core/apply-engine.js +416 -0
  38. package/dist/core/config-utils.js +30 -0
  39. package/dist/core/hash.js +24 -0
  40. package/dist/core/revert-engine.js +413 -0
  41. package/dist/lib.js +46 -329
  42. package/dist/mcp/capabilities.js +51 -0
  43. package/dist/mcp/propagateOpenCodeMcp.js +30 -31
  44. package/dist/mcp/propagateOpenHandsMcp.js +101 -17
  45. package/dist/paths/mcp.js +7 -3
  46. package/dist/revert.js +96 -481
  47. package/package.json +2 -1
package/README.md CHANGED
@@ -1,11 +1,27 @@
1
1
  # Ruler: Centralise Your AI Coding Assistant Instructions
2
2
 
3
- [![CI](https://github.com/intellectronica/ruler/actions/workflows/ci.yml/badge.svg)](https://github.com/intellectronica/ruler/actions/workflows/ci.yml)
4
- [![npm version](https://badge.fury.io/js/%40intellectronica%2Fruler.svg)](https://badge.fury.io/js/%40intellectronica%2Fruler)
5
- ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
6
-
7
- - **GitHub**: [intellectronica/ruler](https://github.com/intellectronica/ruler)
8
- - **NPM**: [@intellectronica/ruler](https://www.npmjs.com/package/@intellectronica/ruler)
3
+ <table style="width:100%">
4
+ <tr>
5
+ <td style="vertical-align: top;">
6
+ <p>
7
+ <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>
8
+ <a href="https://www.npmjs.com/package/@intellectronica/ruler"><img src="https://badge.fury.io/js/%40intellectronica%2Fruler.svg" alt="npm version"></a>
9
+ <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT">
10
+ </p>
11
+ <ul>
12
+ <li><strong>GitHub</strong>: <a href="https://github.com/intellectronica/ruler">intellectronica/ruler</a></li>
13
+ <li><strong>NPM</strong>: <a href="https://www.npmjs.com/package/@intellectronica/ruler">@intellectronica/ruler</a></li>
14
+ </ul>
15
+ <hr />
16
+ <p>
17
+ <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> ➡︎
18
+ </p>
19
+ </td>
20
+ <td style="vertical-align: top; width:33%;">
21
+ <img src="img/ruler-short.gif" alt="Ruler demo" style="width:300px; height:auto; display:block;" />
22
+ </td>
23
+ </tr>
24
+ </table>
9
25
 
10
26
  ---
11
27
 
@@ -22,12 +38,14 @@ Managing instructions across multiple AI coding tools becomes complex as your te
22
38
  - **Duplicated effort** maintaining multiple config files
23
39
  - **Context drift** as project requirements evolve
24
40
  - **Onboarding friction** for new AI tools
41
+ - **Complex project structures** requiring context-specific instructions for different components
25
42
 
26
- Ruler solves this by providing a **single source of truth** for all your AI agent instructions, automatically distributing them to the right configuration files.
43
+ 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.
27
44
 
28
45
  ## Core Features
29
46
 
30
47
  - **Centralised Rule Management**: Store all AI instructions in a dedicated `.ruler/` directory using Markdown files
48
+ - **Nested Rule Loading**: Support complex project structures with multiple `.ruler/` directories for context-specific instructions
31
49
  - **Automatic Distribution**: Ruler applies these rules to configuration files of supported AI agents
32
50
  - **Targeted Agent Configuration**: Fine-tune which agents are affected and their specific output paths via `ruler.toml`
33
51
  - **MCP Server Propagation**: Manage and distribute Model Context Protocol (MCP) server settings
@@ -36,25 +54,30 @@ Ruler solves this by providing a **single source of truth** for all your AI agen
36
54
 
37
55
  ## Supported AI Agents
38
56
 
39
- | Agent | Rules File(s) | MCP Configuration |
40
- | ---------------- | ------------------------------------------------ | --------------------------------------------------- |
41
- | GitHub Copilot | `.github/copilot-instructions.md` | `.vscode/mcp.json` |
42
- | Claude Code | `CLAUDE.md` | `.mcp.json` |
43
- | OpenAI Codex CLI | `AGENTS.md` | `.codex/config.toml`, `~/.codex/config.json` |
44
- | Jules | `AGENTS.md` | - |
45
- | Cursor | `.cursor/rules/ruler_cursor_instructions.mdc` | `.cursor/mcp.json`, `~/.cursor/mcp.json` |
46
- | Windsurf | `.windsurf/rules/ruler_windsurf_instructions.md` | `~/.codeium/windsurf/mcp_config.json` |
47
- | Cline | `.clinerules` | - |
48
- | Amp | `AGENT.md` | - |
49
- | Aider | `ruler_aider_instructions.md`, `.aider.conf.yml` | `.mcp.json` |
50
- | Firebase Studio | `.idx/airules.md` | - |
51
- | Open Hands | `.openhands/microagents/repo.md` | `.openhands/config.toml` |
52
- | Gemini CLI | `GEMINI.md` | `.gemini/settings.json` |
53
- | Junie | `.junie/guidelines.md` | - |
54
- | AugmentCode | `.augment/rules/ruler_augment_instructions.md` | `.vscode/settings.json` |
55
- | Kilo Code | `.kilocode/rules/ruler_kilocode_instructions.md` | `.kilocode/mcp.json` |
56
- | OpenCode | `AGENTS.md` | `opencode.json`, `~/.config/opencode/opencode.json` |
57
- | Goose | `.goosehints` | - |
57
+ | Agent | Rules File(s) | MCP Configuration / Notes |
58
+ | ---------------- | ------------------------------------------------ | ------------------------------------------------ |
59
+ | AGENTS.md | `AGENTS.md` | (pseudo-agent ensuring root `AGENTS.md` exists) |
60
+ | GitHub Copilot | `.github/copilot-instructions.md` | `.vscode/mcp.json` |
61
+ | Claude Code | `CLAUDE.md` | `.mcp.json` |
62
+ | OpenAI Codex CLI | `AGENTS.md` | `.codex/config.toml` |
63
+ | Jules | `AGENTS.md` | - |
64
+ | Cursor | `.cursor/rules/ruler_cursor_instructions.mdc` | `.cursor/mcp.json` |
65
+ | Windsurf | `.windsurf/rules/ruler_windsurf_instructions.md` | - |
66
+ | Cline | `.clinerules` | - |
67
+ | Amp | `AGENTS.md` | - |
68
+ | Aider | `AGENTS.md`, `.aider.conf.yml` | `.mcp.json` |
69
+ | Firebase Studio | `.idx/airules.md` | - |
70
+ | Open Hands | `.openhands/microagents/repo.md` | `.openhands/config.toml` |
71
+ | Gemini CLI | `AGENTS.md` | `.gemini/settings.json` |
72
+ | Junie | `.junie/guidelines.md` | - |
73
+ | AugmentCode | `.augment/rules/ruler_augment_instructions.md` | `.vscode/settings.json` |
74
+ | Kilo Code | `.kilocode/rules/ruler_kilocode_instructions.md` | `.kilocode/mcp.json` |
75
+ | opencode | `AGENTS.md` | `opencode.json` |
76
+ | Goose | `.goosehints` | - |
77
+ | Qwen Code | `AGENTS.md` | `.qwen/settings.json` |
78
+ | Zed | `AGENTS.md` | `.zed/settings.json` (project root, never $HOME) |
79
+ | Warp | `WARP.md` | - |
80
+ | Kiro | `.kiro/steering/ruler_kiro_instructions.md` | - |
58
81
 
59
82
  ## Getting Started
60
83
 
@@ -81,10 +104,10 @@ npx @intellectronica/ruler apply
81
104
  1. Navigate to your project's root directory
82
105
  2. Run `ruler init`
83
106
  3. This creates:
84
- - `.ruler/` directory
85
- - `.ruler/instructions.md`: A starter Markdown file for your rules
86
- - `.ruler/ruler.toml`: The main configuration file for Ruler
87
- - `.ruler/mcp.json`: An example MCP server configuration
107
+ - `.ruler/` directory
108
+ - `.ruler/AGENTS.md`: The primary starter Markdown file for your rules
109
+ - `.ruler/ruler.toml`: The main configuration file for Ruler (now contains sample MCP server sections; legacy `.ruler/mcp.json` no longer scaffolded)
110
+ - (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.)
88
111
 
89
112
  Additionally, you can create a global configuration to use when no local `.ruler/` directory is found:
90
113
 
@@ -100,11 +123,51 @@ The global configuration will be created to `$XDG_CONFIG_HOME/ruler` (default: `
100
123
 
101
124
  This is your central hub for all AI agent instructions:
102
125
 
103
- - **Rule Files (`*.md`)**: Discovered recursively from `.ruler/` or `$XDG_CONFIG_HOME/ruler` and alphabetically concatenated
126
+ - **Primary File Order & Precedence**:
127
+ 1. A repository root `AGENTS.md` (outside `.ruler/`) if present (highest precedence, prepended)
128
+ 2. `.ruler/AGENTS.md` (new default starter file)
129
+ 3. Legacy `.ruler/instructions.md` (only if `.ruler/AGENTS.md` absent; no longer emits a deprecation warning)
130
+ 4. Remaining discovered `.md` files under `.ruler/` (and subdirectories) in sorted order
131
+ - **Rule Files (`*.md`)**: Discovered recursively from `.ruler/` or `$XDG_CONFIG_HOME/ruler` and concatenated in the order above
104
132
  - **Concatenation Marker**: Each file's content is prepended with `--- Source: <relative_path_to_md_file> ---` for traceability
105
133
  - **`ruler.toml`**: Master configuration for Ruler's behavior, agent selection, and output paths
106
134
  - **`mcp.json`**: Shared MCP server settings
107
135
 
136
+ This ordering lets you keep a short, high-impact root `AGENTS.md` (e.g. executive project summary) while housing detailed guidance inside `.ruler/`.
137
+
138
+ ### Nested Rule Loading
139
+
140
+ Ruler now supports **nested rule loading** with the `--nested` flag, enabling context-specific instructions for different parts of your project:
141
+
142
+ ```
143
+ project/
144
+ ├── .ruler/ # Global project rules
145
+ │ ├── AGENTS.md
146
+ │ └── coding_style.md
147
+ ├── src/
148
+ │ └── .ruler/ # Component-specific rules
149
+ │ └── api_guidelines.md
150
+ ├── tests/
151
+ │ └── .ruler/ # Test-specific rules
152
+ │ └── testing_conventions.md
153
+ └── docs/
154
+ └── .ruler/ # Documentation rules
155
+ └── writing_style.md
156
+ ```
157
+
158
+ **How it works:**
159
+
160
+ - Discover all `.ruler/` directories in the project hierarchy
161
+ - Load and concatenate rules from each directory in order
162
+ - Enable with: `ruler apply --nested`
163
+
164
+ **Perfect for:**
165
+
166
+ - Monorepos with multiple services
167
+ - Projects with distinct components (frontend/backend)
168
+ - Teams needing different instructions for different areas
169
+ - Complex codebases with varying standards
170
+
108
171
  ### Best Practices for Rule Files
109
172
 
110
173
  **Granularity**: Break down complex instructions into focused `.md` files:
@@ -148,18 +211,18 @@ The `apply` command looks for `.ruler/` in the current directory tree, reading t
148
211
 
149
212
  ### Options
150
213
 
151
- | Option | Description |
152
- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
153
- | `--project-root <path>` | Path to your project's root (default: current directory) |
154
- | `--agents <agent1,agent2,...>` | Comma-separated list of agent names to target (amp, copilot, claude, codex, cursor, windsurf, cline, aider, firebase, gemini-cli, junie, augmentcode, kilocode) |
155
- | `--config <path>` | Path to a custom `ruler.toml` configuration file |
156
- | `--mcp` / `--with-mcp` | Enable applying MCP server configurations (default: true) |
157
- | `--no-mcp` | Disable applying MCP server configurations |
158
- | `--mcp-overwrite` | Overwrite native MCP config entirely instead of merging |
159
- | `--gitignore` | Enable automatic .gitignore updates (default: true) |
160
- | `--no-gitignore` | Disable automatic .gitignore updates |
161
- | `--local-only` | Do not look for configuration in `$XDG_CONFIG_HOME` |
162
- | `--verbose` / `-v` | Display detailed output during execution |
214
+ | Option | Description |
215
+ | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
216
+ | `--project-root <path>` | Path to your project's root (default: current directory) |
217
+ | `--agents <agent1,agent2,...>` | Comma-separated list of agent names to target (agentsmd, amp, copilot, claude, codex, cursor, windsurf, cline, aider, firebase, gemini-cli, junie, augmentcode, kilocode, warp) |
218
+ | `--config <path>` | Path to a custom `ruler.toml` configuration file |
219
+ | `--mcp` / `--with-mcp` | Enable applying MCP server configurations (default: true) |
220
+ | `--no-mcp` | Disable applying MCP server configurations |
221
+ | `--mcp-overwrite` | Overwrite native MCP config entirely instead of merging |
222
+ | `--gitignore` | Enable automatic .gitignore updates (default: true) |
223
+ | `--no-gitignore` | Disable automatic .gitignore updates |
224
+ | `--local-only` | Do not look for configuration in `$XDG_CONFIG_HOME` |
225
+ | `--verbose` / `-v` | Display detailed output during execution |
163
226
 
164
227
  ### Common Examples
165
228
 
@@ -181,6 +244,12 @@ ruler apply --agents copilot,claude
181
244
  ruler apply --agents firebase
182
245
  ```
183
246
 
247
+ **Apply rules only to Warp:**
248
+
249
+ ```bash
250
+ ruler apply --agents warp
251
+ ```
252
+
184
253
  **Use a specific configuration file:**
185
254
 
186
255
  ```bash
@@ -220,15 +289,15 @@ ruler revert [options]
220
289
 
221
290
  ### Options
222
291
 
223
- | Option | Description |
224
- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
225
- | `--project-root <path>` | Path to your project's root (default: current directory) |
226
- | `--agents <agent1,agent2,...>` | Comma-separated list of agent names to revert (amp, copilot, claude, codex, cursor, windsurf, cline, aider, firebase, gemini-cli, junie, kilocode, opencode) |
227
- | `--config <path>` | Path to a custom `ruler.toml` configuration file |
228
- | `--keep-backups` | Keep backup files (.bak) after restoration (default: false) |
229
- | `--dry-run` | Preview changes without actually reverting files |
230
- | `--verbose` / `-v` | Display detailed output during execution |
231
- | `--local-only` | Only search for local .ruler directories, ignore global config |
292
+ | Option | Description |
293
+ | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
294
+ | `--project-root <path>` | Path to your project's root (default: current directory) |
295
+ | `--agents <agent1,agent2,...>` | Comma-separated list of agent names to revert (agentsmd, amp, copilot, claude, codex, cursor, windsurf, cline, aider, firebase, gemini-cli, junie, kilocode, opencode, warp) |
296
+ | `--config <path>` | Path to a custom `ruler.toml` configuration file |
297
+ | `--keep-backups` | Keep backup files (.bak) after restoration (default: false) |
298
+ | `--dry-run` | Preview changes without actually reverting files |
299
+ | `--verbose` / `-v` | Display detailed output during execution |
300
+ | `--local-only` | Only search for local .ruler directories, ignore global config |
232
301
 
233
302
  ### Common Examples
234
303
 
@@ -282,6 +351,21 @@ enabled = true
282
351
  # Global merge strategy: 'merge' or 'overwrite' (default: 'merge')
283
352
  merge_strategy = "merge"
284
353
 
354
+ # --- MCP Server Definitions ---
355
+ [mcp_servers.filesystem]
356
+ command = "npx"
357
+ args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"]
358
+
359
+ [mcp_servers.git]
360
+ command = "npx"
361
+ args = ["-y", "@modelcontextprotocol/server-git", "--repository", "."]
362
+
363
+ [mcp_servers.remote_api]
364
+ url = "https://api.example.com"
365
+
366
+ [mcp_servers.remote_api.headers]
367
+ Authorization = "Bearer your-token"
368
+
285
369
  # --- Global .gitignore Configuration ---
286
370
  [gitignore]
287
371
  # Enable/disable automatic .gitignore updates (default: true)
@@ -298,7 +382,7 @@ output_path = "CLAUDE.md"
298
382
 
299
383
  [agents.aider]
300
384
  enabled = true
301
- output_path_instructions = "ruler_aider_instructions.md"
385
+ output_path_instructions = "AGENTS.md"
302
386
  output_path_config = ".aider.conf.yml"
303
387
 
304
388
  # OpenAI Codex CLI agent and MCP config
@@ -338,6 +422,10 @@ enabled = false
338
422
  [agents.kilocode]
339
423
  enabled = true
340
424
  output_path = ".kilocode/rules/ruler_kilocode_instructions.md"
425
+
426
+ [agents.warp]
427
+ enabled = true
428
+ output_path = "WARP.md"
341
429
  ```
342
430
 
343
431
  ### Configuration Precedence
@@ -350,9 +438,36 @@ output_path = ".kilocode/rules/ruler_kilocode_instructions.md"
350
438
 
351
439
  MCP provides broader context to AI models through server configurations. Ruler can manage and distribute these settings across compatible agents.
352
440
 
353
- ### `.ruler/mcp.json`
441
+ ### TOML Configuration (Recommended)
354
442
 
355
- Define your project's MCP servers:
443
+ You can now define MCP servers directly in `ruler.toml` using the `[mcp_servers.<name>]` syntax:
444
+
445
+ ```toml
446
+ # Global MCP behavior
447
+ [mcp]
448
+ enabled = true
449
+ merge_strategy = "merge" # or "overwrite"
450
+
451
+ # Local (stdio) server
452
+ [mcp_servers.filesystem]
453
+ command = "npx"
454
+ args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"]
455
+
456
+ [mcp_servers.filesystem.env]
457
+ API_KEY = "your-api-key"
458
+
459
+ # Remote server
460
+ [mcp_servers.search]
461
+ url = "https://mcp.example.com"
462
+
463
+ [mcp_servers.search.headers]
464
+ Authorization = "Bearer your-token"
465
+ "X-API-Version" = "v1"
466
+ ```
467
+
468
+ ### Legacy `.ruler/mcp.json` (Deprecated)
469
+
470
+ 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`.
356
471
 
357
472
  ```json
358
473
  {
@@ -373,10 +488,42 @@ Define your project's MCP servers:
373
488
  }
374
489
  ```
375
490
 
491
+ ### Configuration Precedence
492
+
493
+ When both TOML and JSON configurations are present:
494
+
495
+ 1. **TOML servers take precedence** over JSON servers with the same name
496
+ 2. **Servers are merged** from both sources (unless using overwrite strategy)
497
+ 3. **Deprecation warning** is shown encouraging migration to TOML (warning shown once per run)
498
+
499
+ ### Server Types
376
500
 
377
- Ruler uses this file with the `merge` (default) or `overwrite` strategy, controlled by `ruler.toml` or CLI flags.
501
+ **Local/stdio servers** require a `command` field:
502
+
503
+ ```toml
504
+ [mcp_servers.local_server]
505
+ command = "node"
506
+ args = ["server.js"]
507
+
508
+ [mcp_servers.local_server.env]
509
+ DEBUG = "1"
510
+ ```
511
+
512
+ **Remote servers** require a `url` field (headers optional; bearer Authorization token auto-extracted for OpenHands when possible):
513
+ ```toml
514
+ [mcp_servers.remote_server]
515
+ url = "https://api.example.com"
516
+
517
+ [mcp_servers.remote_server.headers]
518
+ Authorization = "Bearer token"
519
+ ```
520
+
521
+ Ruler uses this configuration with the `merge` (default) or `overwrite` strategy, controlled by `ruler.toml` or CLI flags.
522
+
523
+ **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.
378
524
 
379
525
  **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:
526
+
380
527
  ```bash
381
528
  export CODEX_HOME="$(pwd)/.codex"
382
529
  ```
@@ -392,7 +539,7 @@ Ruler automatically manages your `.gitignore` file to keep generated agent confi
392
539
  - Preserves existing content outside this block
393
540
  - Sorts paths alphabetically and uses relative POSIX-style paths
394
541
 
395
- ### Example `.gitignore` Section
542
+ ### Example `.gitignore` Section (sample - actual list depends on enabled agents)
396
543
 
397
544
  ```gitignore
398
545
  # Your existing rules
@@ -407,7 +554,7 @@ node_modules/
407
554
  .windsurf/rules/ruler_windsurf_instructions.md
408
555
  AGENTS.md
409
556
  CLAUDE.md
410
- ruler_aider_instructions.md
557
+ AGENTS.md
411
558
  # END Ruler Generated Files
412
559
 
413
560
  dist/
@@ -429,14 +576,33 @@ cd your-project
429
576
  ruler init
430
577
 
431
578
  # Edit the generated files
432
- # - Add your coding guidelines to .ruler/instructions.md
579
+ # - Add your coding guidelines to .ruler/AGENTS.md (or keep adding additional .md files)
433
580
  # - Customize .ruler/ruler.toml if needed
434
581
 
435
582
  # Apply rules to all AI agents
436
583
  ruler apply
437
584
  ```
438
585
 
439
- ### Scenario 2: Team Standardization
586
+ ### Scenario 2: Complex Projects with Nested Rules
587
+
588
+ For large projects with multiple components or services, use nested rule loading:
589
+
590
+ ```bash
591
+ # Set up nested .ruler directories
592
+ mkdir -p src/.ruler tests/.ruler docs/.ruler
593
+
594
+ # Add component-specific instructions
595
+ echo "# API Design Guidelines" > src/.ruler/api_rules.md
596
+ echo "# Testing Best Practices" > tests/.ruler/test_rules.md
597
+ echo "# Documentation Standards" > docs/.ruler/docs_rules.md
598
+
599
+ # Apply with nested loading
600
+ ruler apply --nested --verbose
601
+ ```
602
+
603
+ This creates context-specific instructions for different parts of your project while maintaining global rules in the root `.ruler/` directory.
604
+
605
+ ### Scenario 3: Team Standardization
440
606
 
441
607
  1. Create `.ruler/coding_standards.md`, `.ruler/api_usage.md`
442
608
  2. Commit the `.ruler` directory to your repository
@@ -538,6 +704,9 @@ This shows:
538
704
  **Q: Can I use different rules for different agents?**
539
705
  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".
540
706
 
707
+ **Q: How do I set up different instructions for different parts of my project?**
708
+ 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.
709
+
541
710
  **Q: How do I temporarily disable Ruler for an agent?**
542
711
  A: Set `enabled = false` in `ruler.toml` under `[agents.agentname]`, or use `--agents` flag to specify only the agents you want.
543
712
 
@@ -547,8 +716,20 @@ A: Ruler creates backups with `.bak` extension before overwriting any existing f
547
716
  **Q: Can I run Ruler in CI/CD pipelines?**
548
717
  A: Yes! Use `ruler apply --no-gitignore` in CI to avoid modifying `.gitignore`. See the GitHub Actions example above.
549
718
 
550
- **Q: How do I migrate from version 0.1.x to 0.2.0?**
551
- A: Version 0.2.0 is backward compatible. Your existing `.ruler/` directory and `ruler.toml` will continue to work. New features like verbose logging and improved error messages are opt-in.
719
+ **Q: How do I migrate from older versions using `instructions.md`?**
720
+ 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.
721
+
722
+ **Q: How does OpenHands MCP propagation classify servers?**
723
+ 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.
724
+
725
+ **Q: Where is Zed configuration written now?**
726
+ 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"`.
727
+
728
+ **Q: What changed about MCP initialization?**
729
+ 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.
730
+
731
+ **Q: Is Kiro supported?**
732
+ A: Yes. Kiro receives concatenated rules at `.kiro/steering/ruler_kiro_instructions.md`.
552
733
 
553
734
  ## Development
554
735
 
@@ -603,5 +784,43 @@ MIT
603
784
 
604
785
  ---
605
786
 
787
+ ## Development and Testing
788
+
789
+ ### Running Tests
790
+
791
+ The project includes comprehensive test coverage with unit, integration, and end-to-end tests:
792
+
793
+ ```bash
794
+ # Run all tests
795
+ npm test
796
+
797
+ # Run with coverage
798
+ npm run test:coverage
799
+
800
+ # Run integration tests specifically
801
+ npm run test:integration
802
+
803
+ # Run tests in watch mode
804
+ npm run test:watch
805
+ ```
806
+
807
+ ### Integration Testing
808
+
809
+ The project includes comprehensive integration tests that validate the complete CLI workflow:
810
+
811
+ - **`npm run test:integration`**: Runs a full end-to-end integration test that:
812
+ 1. Creates a temporary test directory
813
+ 2. Runs `ruler init` to set up the initial structure
814
+ 3. Creates custom `ruler.toml` with MCP servers (both stdio and remote)
815
+ 4. Creates sample `AGENTS.md` and additional markdown files for concatenation
816
+ 5. Runs `ruler apply` to generate all agent configuration files
817
+ 6. Inspects and validates all generated files contain expected content
818
+ 7. Outputs the content of all generated files for manual verification
819
+ 8. Validates MCP server configurations were properly applied
820
+
821
+ This integration test ensures the entire CLI workflow functions correctly and can be used for manual testing or CI validation.
822
+
823
+ ---
824
+
606
825
  © Eleanor Berger
607
826
  [ai.intellectronica.net](https://ai.intellectronica.net/)
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.AbstractAgent = void 0;
37
+ const path = __importStar(require("path"));
38
+ const FileSystemUtils_1 = require("../core/FileSystemUtils");
39
+ /**
40
+ * Abstract base class for agents that write to a single configuration file.
41
+ * Implements common logic for applying ruler configuration.
42
+ */
43
+ class AbstractAgent {
44
+ /**
45
+ * Applies the concatenated ruler rules to the agent's configuration.
46
+ * This implementation handles the common pattern of:
47
+ * 1. Determining the output path
48
+ * 2. Ensuring the parent directory exists
49
+ * 3. Backing up the existing file
50
+ * 4. Writing the new content
51
+ */
52
+ async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, // eslint-disable-line @typescript-eslint/no-unused-vars
53
+ agentConfig) {
54
+ const output = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
55
+ const absolutePath = path.resolve(projectRoot, output);
56
+ await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(absolutePath));
57
+ await (0, FileSystemUtils_1.backupFile)(absolutePath);
58
+ await (0, FileSystemUtils_1.writeGeneratedFile)(absolutePath, concatenatedRules);
59
+ }
60
+ /**
61
+ * Returns the specific key to be used for the server object in MCP JSON.
62
+ * Defaults to 'mcpServers' if not overridden.
63
+ */
64
+ getMcpServerKey() {
65
+ return 'mcpServers';
66
+ }
67
+ /**
68
+ * Returns whether this agent supports MCP STDIO servers.
69
+ * Defaults to false if not overridden.
70
+ */
71
+ supportsMcpStdio() {
72
+ return false;
73
+ }
74
+ /**
75
+ * Returns whether this agent supports MCP remote servers.
76
+ * Defaults to false if not overridden.
77
+ */
78
+ supportsMcpRemote() {
79
+ return false;
80
+ }
81
+ }
82
+ exports.AbstractAgent = AbstractAgent;