@intellectronica/ruler 0.3.41 → 0.3.42

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 (94) hide show
  1. package/README.md +40 -28
  2. package/dist/agents/AbstractAgent.d.ts +53 -0
  3. package/dist/agents/AgentsMdAgent.d.ts +14 -0
  4. package/dist/agents/AiderAgent.d.ts +14 -0
  5. package/dist/agents/AiderAgent.js +3 -1
  6. package/dist/agents/AmazonQCliAgent.d.ts +13 -0
  7. package/dist/agents/AmpAgent.d.ts +6 -0
  8. package/dist/agents/AntigravityAgent.d.ts +10 -0
  9. package/dist/agents/AugmentCodeAgent.d.ts +13 -0
  10. package/dist/agents/ClaudeAgent.d.ts +13 -0
  11. package/dist/agents/ClineAgent.d.ts +9 -0
  12. package/dist/agents/CodexCliAgent.d.ts +31 -0
  13. package/dist/agents/CopilotAgent.d.ts +20 -0
  14. package/dist/agents/CrushAgent.d.ts +14 -0
  15. package/dist/agents/CrushAgent.js +5 -2
  16. package/dist/agents/CursorAgent.d.ts +17 -0
  17. package/dist/agents/FactoryDroidAgent.d.ts +13 -0
  18. package/dist/agents/FirebaseAgent.d.ts +11 -0
  19. package/dist/agents/FirebenderAgent.d.ts +36 -0
  20. package/dist/agents/GeminiCliAgent.d.ts +11 -0
  21. package/dist/agents/GeminiCliAgent.js +2 -2
  22. package/dist/agents/GooseAgent.d.ts +12 -0
  23. package/dist/agents/IAgent.d.ts +72 -0
  24. package/dist/agents/JetBrainsAiAssistantAgent.d.ts +10 -0
  25. package/dist/agents/JulesAgent.d.ts +5 -0
  26. package/dist/agents/JunieAgent.d.ts +12 -0
  27. package/dist/agents/KiloCodeAgent.d.ts +14 -0
  28. package/dist/agents/KiroAgent.d.ts +8 -0
  29. package/dist/agents/MistralVibeAgent.d.ts +31 -0
  30. package/dist/agents/OpenCodeAgent.d.ts +11 -0
  31. package/dist/agents/OpenCodeAgent.js +14 -9
  32. package/dist/agents/OpenHandsAgent.d.ts +8 -0
  33. package/dist/agents/PiAgent.d.ts +9 -0
  34. package/dist/agents/QwenCodeAgent.d.ts +10 -0
  35. package/dist/agents/QwenCodeAgent.js +2 -2
  36. package/dist/agents/RooCodeAgent.d.ts +16 -0
  37. package/dist/agents/TraeAgent.d.ts +10 -0
  38. package/dist/agents/WarpAgent.d.ts +12 -0
  39. package/dist/agents/WindsurfAgent.d.ts +13 -0
  40. package/dist/agents/ZedAgent.d.ts +21 -0
  41. package/dist/agents/ZedAgent.js +5 -2
  42. package/dist/agents/agent-utils.d.ts +5 -0
  43. package/dist/agents/agent-utils.js +8 -5
  44. package/dist/agents/index.d.ts +9 -0
  45. package/dist/cli/commands.d.ts +4 -0
  46. package/dist/cli/commands.js +1 -2
  47. package/dist/cli/handlers.d.ts +41 -0
  48. package/dist/cli/handlers.js +75 -59
  49. package/dist/cli/index.d.ts +2 -0
  50. package/dist/constants.d.ts +35 -0
  51. package/dist/core/ConfigLoader.d.ts +57 -0
  52. package/dist/core/ConfigLoader.js +106 -39
  53. package/dist/core/FileSystemUtils.d.ts +51 -0
  54. package/dist/core/FileSystemUtils.js +37 -17
  55. package/dist/core/GitignoreUtils.d.ts +15 -0
  56. package/dist/core/GitignoreUtils.js +32 -1
  57. package/dist/core/RuleProcessor.d.ts +8 -0
  58. package/dist/core/SkillsProcessor.d.ts +127 -0
  59. package/dist/core/SkillsProcessor.js +104 -218
  60. package/dist/core/SkillsUtils.d.ts +26 -0
  61. package/dist/core/SubagentsProcessor.d.ts +38 -0
  62. package/dist/core/SubagentsUtils.d.ts +34 -0
  63. package/dist/core/UnifiedConfigLoader.d.ts +10 -0
  64. package/dist/core/UnifiedConfigLoader.js +61 -31
  65. package/dist/core/UnifiedConfigTypes.d.ts +95 -0
  66. package/dist/core/agent-selection.d.ts +12 -0
  67. package/dist/core/agent-selection.js +11 -3
  68. package/dist/core/apply-engine.d.ts +69 -0
  69. package/dist/core/apply-engine.js +57 -50
  70. package/dist/core/config-utils.d.ts +14 -0
  71. package/dist/core/config-utils.js +9 -3
  72. package/dist/core/hash.d.ts +2 -0
  73. package/dist/core/path-utils.d.ts +1 -0
  74. package/dist/core/path-utils.js +42 -0
  75. package/dist/core/revert-engine.d.ts +36 -0
  76. package/dist/core/revert-engine.js +70 -9
  77. package/dist/lib.d.ts +13 -0
  78. package/dist/lib.js +16 -3
  79. package/dist/mcp/capabilities.d.ts +20 -0
  80. package/dist/mcp/merge.d.ts +10 -0
  81. package/dist/mcp/merge.js +19 -1
  82. package/dist/mcp/propagateOpenCodeMcp.d.ts +2 -0
  83. package/dist/mcp/propagateOpenCodeMcp.js +21 -9
  84. package/dist/mcp/propagateOpenHandsMcp.d.ts +2 -0
  85. package/dist/mcp/propagateOpenHandsMcp.js +31 -15
  86. package/dist/mcp/validate.d.ts +7 -0
  87. package/dist/mcp/validate.js +6 -1
  88. package/dist/paths/mcp.d.ts +8 -0
  89. package/dist/paths/mcp.js +33 -4
  90. package/dist/revert.d.ts +6 -0
  91. package/dist/revert.js +39 -27
  92. package/dist/types.d.ts +87 -0
  93. package/dist/vscode/settings.d.ts +40 -0
  94. package/package.json +6 -4
package/README.md CHANGED
@@ -18,7 +18,7 @@
18
18
  </p>
19
19
  </td>
20
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;" />
21
+ <img src="https://raw.githubusercontent.com/intellectronica/ruler/main/img/ruler-short.gif" alt="Ruler demo" style="width:300px; height:auto; display:block;" />
22
22
  </td>
23
23
  </tr>
24
24
  </table>
@@ -80,7 +80,7 @@ Ruler solves this by providing a **single source of truth** for all your AI agen
80
80
  | Goose | `.goosehints` | - | `.agents/skills/` | - |
81
81
  | Qwen Code | `AGENTS.md` | `.qwen/settings.json` | - | - |
82
82
  | RooCode | `AGENTS.md` | `.roo/mcp.json` | `.roo/skills/` | - |
83
- | Zed | `AGENTS.md` | `.zed/settings.json` (project root, never $HOME) | - | - |
83
+ | Zed | `AGENTS.md` | `.zed/settings.json` (project root, never $HOME) | `.agents/skills/` | - |
84
84
  | Trae AI | `.trae/rules/project_rules.md` | - | - | - |
85
85
  | Warp | `WARP.md` | - | - | - |
86
86
  | Kiro | `.kiro/steering/ruler_kiro_instructions.md` | `.kiro/settings/mcp.json` | - | - |
@@ -224,32 +224,32 @@ project/
224
224
  ruler apply [options]
225
225
  ```
226
226
 
227
- 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`.
227
+ The `apply` command searches upward from `--project-root` (default: current directory) for the nearest `.ruler/` directory. If no local `.ruler/` directory is found, it falls back to `$XDG_CONFIG_HOME/ruler`.
228
228
 
229
229
  ### Options
230
230
 
231
- | Option | Description |
232
- | ------------------------------ | ---------------------------------------------------------------------- |
233
- | `--project-root <path>` | Project root path (default: current directory). |
234
- | `--agents <agent1,agent2,...>` | Comma-separated agent names to target (see supported list below). |
235
- | `--config <path>` | Custom `ruler.toml` path. |
236
- | `--mcp` / `--with-mcp` | Enable applying MCP server configurations (default: true). |
237
- | `--no-mcp` | Disable applying MCP server configurations. |
238
- | `--mcp-overwrite` | Overwrite native MCP config instead of merging. |
239
- | `--gitignore` | Enable automatic .gitignore updates (default: true). |
240
- | `--no-gitignore` | Disable automatic .gitignore updates. |
241
- | `--gitignore-local` | Write managed ignore entries to `.git/info/exclude` instead. |
242
- | `--nested` | Enable nested rule loading (default: inherit from config or disabled). |
243
- | `--no-nested` | Disable nested rule loading even if `nested = true` in config. |
244
- | `--backup` | Enable creation of `.bak` backup files (default: enabled). |
245
- | `--no-backup` | Disable creation of `.bak` backup files. |
246
- | `--skills` | Enable skills support (experimental, default: enabled). |
247
- | `--no-skills` | Disable skills support. |
248
- | `--subagents` | Enable subagents support (experimental, default: disabled). |
249
- | `--no-subagents` | Disable subagents support. |
250
- | `--dry-run` | Preview changes without writing files. |
251
- | `--local-only` | Skip `$XDG_CONFIG_HOME` when looking for configuration. |
252
- | `--verbose` / `-v` | Display detailed output during execution. |
231
+ | Option | Description |
232
+ | ------------------------------ | ------------------------------------------------------------------------- |
233
+ | `--project-root <path>` | Project root path (default: current directory). |
234
+ | `--agents <agent1,agent2,...>` | Comma-separated agent names to target (see supported list below). |
235
+ | `--config <path>` | Custom `ruler.toml` path. |
236
+ | `--mcp` / `--with-mcp` | Enable applying MCP server configurations (default: true). |
237
+ | `--no-mcp` | Disable applying MCP server configurations. |
238
+ | `--mcp-overwrite` | Overwrite native MCP config instead of merging. |
239
+ | `--gitignore` | Enable automatic .gitignore updates (default: true). |
240
+ | `--no-gitignore` | Disable automatic .gitignore updates. |
241
+ | `--gitignore-local` | Write managed ignore entries to `.git/info/exclude` instead. |
242
+ | `--nested` | Enable nested rule loading (default: inherit from config or disabled). |
243
+ | `--no-nested` | Disable nested rule loading even if `nested = true` in config. |
244
+ | `--backup` | Enable creation of `.bak` backup files (default: from config or enabled). |
245
+ | `--no-backup` | Disable creation of `.bak` backup files. |
246
+ | `--skills` | Enable skills support (experimental, default: enabled). |
247
+ | `--no-skills` | Disable skills support. |
248
+ | `--subagents` | Enable subagents support (experimental, default: disabled). |
249
+ | `--no-subagents` | Disable subagents support. |
250
+ | `--dry-run` | Preview changes without writing files. |
251
+ | `--local-only` | Skip `$XDG_CONFIG_HOME` when looking for configuration. |
252
+ | `--verbose` / `-v` | Display detailed output during execution. |
253
253
 
254
254
  ### Common Examples
255
255
 
@@ -412,6 +412,11 @@ enabled = true
412
412
  # Write managed entries to .git/info/exclude instead of .gitignore (default: false)
413
413
  local = false
414
414
 
415
+ # --- Backup Configuration ---
416
+ [backup]
417
+ # Enable/disable creation of .bak backup files (default: true)
418
+ enabled = true
419
+
415
420
  # --- Agent-Specific Configurations ---
416
421
  [agents.copilot]
417
422
  enabled = true
@@ -592,6 +597,7 @@ Skills are specialized knowledge packages that extend AI agent capabilities with
592
597
  - **Pi Coding Agent**: `.pi/skills/`
593
598
  - **Goose**: `.agents/skills/`
594
599
  - **Amp**: `.agents/skills/` (shared with Goose)
600
+ - **Zed**: `.agents/skills/` (shared with Goose)
595
601
  - **Antigravity**: `.agent/skills/`
596
602
  - **Factory Droid**: `.factory/skills/`
597
603
  - **Mistral Vibe**: `.vibe/skills/`
@@ -658,7 +664,7 @@ When skills support is enabled and gitignore integration is active, Ruler automa
658
664
  - `.codex/skills/` (for OpenAI Codex CLI)
659
665
  - `.opencode/skills/` (for OpenCode)
660
666
  - `.pi/skills/` (for Pi Coding Agent)
661
- - `.agents/skills/` (for Goose and Amp)
667
+ - `.agents/skills/` (for Goose, Amp, and Zed)
662
668
  - `.agent/skills/` (for Antigravity)
663
669
  - `.factory/skills/` (for Factory Droid)
664
670
  - `.vibe/skills/` (for Mistral Vibe)
@@ -719,7 +725,7 @@ ruler apply
719
725
  # - OpenAI Codex CLI: .codex/skills/my-skill/
720
726
  # - OpenCode: .opencode/skills/my-skill/
721
727
  # - Pi Coding Agent: .pi/skills/my-skill/
722
- # - Goose & Amp: .agents/skills/my-skill/
728
+ # - Goose, Amp & Zed: .agents/skills/my-skill/
723
729
  # - Antigravity: .agent/skills/my-skill/
724
730
  # - Factory Droid: .factory/skills/my-skill/
725
731
  # - Mistral Vibe: .vibe/skills/my-skill/
@@ -909,6 +915,12 @@ dist/
909
915
  - **Configuration**: `[gitignore].enabled` and `[gitignore].local` in `ruler.toml`
910
916
  - **Default**: enabled
911
917
 
918
+ ### Backup Control
919
+
920
+ - **CLI flags**: `--backup`, `--no-backup`
921
+ - **Configuration**: `[backup].enabled` in `ruler.toml`
922
+ - **Default**: enabled
923
+
912
924
  ## Practical Usage Scenarios
913
925
 
914
926
  ### Scenario 1: Getting Started Quickly
@@ -1079,7 +1091,7 @@ A: Simply rename `.ruler/instructions.md` to `.ruler/AGENTS.md` (recommended). I
1079
1091
  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.
1080
1092
 
1081
1093
  **Q: Where is Zed configuration written now?**
1082
- 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"`.
1094
+ A: Ruler writes `.zed/settings.json` inside the project root (not the user home dir) and transforms MCP server definitions to Zed's `context_servers` format including `source: "custom"`.
1083
1095
 
1084
1096
  **Q: What changed about MCP initialization?**
1085
1097
  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.
@@ -0,0 +1,53 @@
1
+ import { IAgent, IAgentConfig } from './IAgent';
2
+ /**
3
+ * Abstract base class for agents that write to a single configuration file.
4
+ * Implements common logic for applying ruler configuration.
5
+ */
6
+ export declare abstract class AbstractAgent implements IAgent {
7
+ /**
8
+ * Returns the lowercase identifier of the agent.
9
+ */
10
+ abstract getIdentifier(): string;
11
+ /**
12
+ * Returns the display name of the agent.
13
+ */
14
+ abstract getName(): string;
15
+ /**
16
+ * Returns the default output path for this agent given the project root.
17
+ */
18
+ abstract getDefaultOutputPath(projectRoot: string): string;
19
+ /**
20
+ * Applies the concatenated ruler rules to the agent's configuration.
21
+ * This implementation handles the common pattern of:
22
+ * 1. Determining the output path
23
+ * 2. Ensuring the parent directory exists
24
+ * 3. Backing up the existing file
25
+ * 4. Writing the new content
26
+ */
27
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, _rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
28
+ /**
29
+ * Returns the specific key to be used for the server object in MCP JSON.
30
+ * Defaults to 'mcpServers' if not overridden.
31
+ */
32
+ getMcpServerKey(): string;
33
+ /**
34
+ * Returns whether this agent supports MCP STDIO servers.
35
+ * Defaults to false if not overridden.
36
+ */
37
+ supportsMcpStdio(): boolean;
38
+ /**
39
+ * Returns whether this agent supports MCP remote servers.
40
+ * Defaults to false if not overridden.
41
+ */
42
+ supportsMcpRemote(): boolean;
43
+ /**
44
+ * Returns whether this agent supports MCP server timeout configuration.
45
+ * Defaults to false if not overridden.
46
+ */
47
+ supportsMcpTimeout(): boolean;
48
+ /**
49
+ * Returns whether this agent has native skills support.
50
+ * Defaults to false if not overridden.
51
+ */
52
+ supportsNativeSkills(): boolean;
53
+ }
@@ -0,0 +1,14 @@
1
+ import { AbstractAgent } from './AbstractAgent';
2
+ import { IAgentConfig } from './IAgent';
3
+ /**
4
+ * Pseudo-agent that ensures the concatenated rules are written to root-level `AGENTS.md`.
5
+ * Does not participate in MCP propagation. Idempotent: only writes (and creates a backup)
6
+ * when content differs from existing file.
7
+ */
8
+ export declare class AgentsMdAgent extends AbstractAgent {
9
+ getIdentifier(): string;
10
+ getName(): string;
11
+ getDefaultOutputPath(projectRoot: string): string;
12
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, _rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
13
+ getMcpServerKey(): string;
14
+ }
@@ -0,0 +1,14 @@
1
+ import { IAgent, IAgentConfig } from './IAgent';
2
+ /**
3
+ * Aider agent adapter that uses AGENTS.md for instructions and .aider.conf.yml for configuration.
4
+ */
5
+ export declare class AiderAgent implements IAgent {
6
+ private agentsMdAgent;
7
+ getIdentifier(): string;
8
+ getName(): string;
9
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
10
+ getDefaultOutputPath(projectRoot: string): Record<string, string>;
11
+ getMcpServerKey(): string;
12
+ supportsMcpStdio(): boolean;
13
+ supportsMcpRemote(): boolean;
14
+ }
@@ -82,7 +82,9 @@ class AiderAgent {
82
82
  const agentsPath = agentConfig?.outputPath ||
83
83
  agentConfig?.outputPathInstructions ||
84
84
  this.getDefaultOutputPath(projectRoot).instructions;
85
- const name = path.basename(agentsPath);
85
+ const name = path
86
+ .relative(projectRoot, path.resolve(projectRoot, agentsPath))
87
+ .replace(/\\/g, '/');
86
88
  if (!doc.read.includes(name)) {
87
89
  doc.read.push(name);
88
90
  }
@@ -0,0 +1,13 @@
1
+ import { IAgent, IAgentConfig } from './IAgent';
2
+ /**
3
+ * Amazon Q CLI agent adapter.
4
+ */
5
+ export declare class AmazonQCliAgent implements IAgent {
6
+ getIdentifier(): string;
7
+ getName(): string;
8
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
9
+ getDefaultOutputPath(projectRoot: string): Record<string, string>;
10
+ getMcpServerKey(): string;
11
+ supportsMcpStdio(): boolean;
12
+ supportsMcpRemote(): boolean;
13
+ }
@@ -0,0 +1,6 @@
1
+ import { AgentsMdAgent } from './AgentsMdAgent';
2
+ export declare class AmpAgent extends AgentsMdAgent {
3
+ getIdentifier(): string;
4
+ getName(): string;
5
+ supportsNativeSkills(): boolean;
6
+ }
@@ -0,0 +1,10 @@
1
+ import { AbstractAgent } from './AbstractAgent';
2
+ /**
3
+ * Antigravity agent adapter.
4
+ */
5
+ export declare class AntigravityAgent extends AbstractAgent {
6
+ getIdentifier(): string;
7
+ getName(): string;
8
+ getDefaultOutputPath(projectRoot: string): string;
9
+ supportsNativeSkills(): boolean;
10
+ }
@@ -0,0 +1,13 @@
1
+ import { IAgent, IAgentConfig } from './IAgent';
2
+ /**
3
+ * AugmentCode agent adapter.
4
+ * Generates ruler_augment_instructions.md configuration file and updates VSCode settings.json with MCP server configuration.
5
+ */
6
+ export declare class AugmentCodeAgent implements IAgent {
7
+ getIdentifier(): string;
8
+ getName(): string;
9
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, _rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
10
+ getDefaultOutputPath(projectRoot: string): string;
11
+ supportsMcpStdio(): boolean;
12
+ supportsMcpRemote(): boolean;
13
+ }
@@ -0,0 +1,13 @@
1
+ import { AbstractAgent } from './AbstractAgent';
2
+ /**
3
+ * Claude Code agent adapter.
4
+ */
5
+ export declare class ClaudeAgent extends AbstractAgent {
6
+ getIdentifier(): string;
7
+ getName(): string;
8
+ getDefaultOutputPath(projectRoot: string): string;
9
+ supportsMcpStdio(): boolean;
10
+ supportsMcpRemote(): boolean;
11
+ supportsNativeSkills(): boolean;
12
+ supportsNativeSubagents(): boolean;
13
+ }
@@ -0,0 +1,9 @@
1
+ import { AbstractAgent } from './AbstractAgent';
2
+ /**
3
+ * Cline agent adapter.
4
+ */
5
+ export declare class ClineAgent extends AbstractAgent {
6
+ getIdentifier(): string;
7
+ getName(): string;
8
+ getDefaultOutputPath(projectRoot: string): string;
9
+ }
@@ -0,0 +1,31 @@
1
+ import { IAgent, IAgentConfig } from './IAgent';
2
+ /**
3
+ * MCP server definition for Codex CLI (stdio uses command, remote uses url).
4
+ */
5
+ interface McpServer {
6
+ command?: string;
7
+ args?: string[];
8
+ env?: Record<string, string>;
9
+ url?: string;
10
+ headers?: Record<string, string>;
11
+ [key: string]: any;
12
+ }
13
+ interface RulerMcp {
14
+ mcpServers?: Record<string, McpServer>;
15
+ }
16
+ /**
17
+ * OpenAI Codex CLI agent adapter.
18
+ */
19
+ export declare class CodexCliAgent implements IAgent {
20
+ private agentsMdAgent;
21
+ getIdentifier(): string;
22
+ getName(): string;
23
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, rulerMcpJson: RulerMcp | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
24
+ getDefaultOutputPath(projectRoot: string): Record<string, string>;
25
+ getMcpServerKey(): string;
26
+ supportsMcpStdio(): boolean;
27
+ supportsMcpRemote(): boolean;
28
+ supportsNativeSkills(): boolean;
29
+ supportsNativeSubagents(): boolean;
30
+ }
31
+ export {};
@@ -0,0 +1,20 @@
1
+ import { IAgent, IAgentConfig } from './IAgent';
2
+ /**
3
+ * GitHub Copilot agent adapter.
4
+ * Writes to AGENTS.md for both web-based GitHub Copilot and VS Code extension.
5
+ */
6
+ export declare class CopilotAgent implements IAgent {
7
+ private agentsMdAgent;
8
+ getIdentifier(): string;
9
+ getName(): string;
10
+ /**
11
+ * Returns the default output path for AGENTS.md.
12
+ */
13
+ getDefaultOutputPath(projectRoot: string): string;
14
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
15
+ getMcpServerKey(): string;
16
+ supportsMcpStdio(): boolean;
17
+ supportsMcpRemote(): boolean;
18
+ supportsNativeSkills(): boolean;
19
+ supportsNativeSubagents(): boolean;
20
+ }
@@ -0,0 +1,14 @@
1
+ import { IAgent, IAgentConfig } from './IAgent';
2
+ export declare class CrushAgent implements IAgent {
3
+ getIdentifier(): string;
4
+ getName(): string;
5
+ getDefaultOutputPath(projectRoot: string): Record<string, string>;
6
+ /**
7
+ * Transform MCP server types for Crush compatibility.
8
+ * Crush expects "http" for HTTP servers and "sse" for SSE servers, not "remote".
9
+ */
10
+ private transformMcpServersForCrush;
11
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig): Promise<void>;
12
+ supportsMcpStdio(): boolean;
13
+ supportsMcpRemote(): boolean;
14
+ }
@@ -82,11 +82,14 @@ class CrushAgent {
82
82
  }
83
83
  async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig) {
84
84
  const outputPaths = this.getDefaultOutputPath(projectRoot);
85
- const instructionsPath = agentConfig?.outputPathInstructions ?? outputPaths['instructions'];
85
+ const instructionsPath = agentConfig?.outputPath ??
86
+ agentConfig?.outputPathInstructions ??
87
+ outputPaths['instructions'];
86
88
  const mcpPath = agentConfig?.outputPathConfig ?? outputPaths['mcp'];
87
89
  await fs.writeFile(instructionsPath, concatenatedRules);
88
90
  // Always transform from mcpServers ({ mcpServers: ... }) to { mcp: ... } for Crush
89
91
  let finalMcpConfig = { mcp: {} };
92
+ const strategy = agentConfig?.mcp?.strategy ?? 'merge';
90
93
  try {
91
94
  const existingMcpConfig = JSON.parse(await fs.readFile(mcpPath, 'utf-8'));
92
95
  if (existingMcpConfig && typeof existingMcpConfig === 'object') {
@@ -94,7 +97,7 @@ class CrushAgent {
94
97
  finalMcpConfig = {
95
98
  ...existingMcpConfig,
96
99
  mcp: {
97
- ...(existingMcpConfig.mcp || {}),
100
+ ...(strategy === 'merge' ? existingMcpConfig.mcp || {} : {}),
98
101
  ...transformedServers,
99
102
  },
100
103
  };
@@ -0,0 +1,17 @@
1
+ import { IAgentConfig } from './IAgent';
2
+ import { AgentsMdAgent } from './AgentsMdAgent';
3
+ /**
4
+ * Cursor agent adapter.
5
+ * Leverages the standardized AGENTS.md approach supported natively by Cursor.
6
+ * See: https://docs.cursor.com/en/cli/using
7
+ */
8
+ export declare class CursorAgent extends AgentsMdAgent {
9
+ getIdentifier(): string;
10
+ getName(): string;
11
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, _rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
12
+ getMcpServerKey(): string;
13
+ supportsMcpStdio(): boolean;
14
+ supportsMcpRemote(): boolean;
15
+ supportsNativeSkills(): boolean;
16
+ supportsNativeSubagents(): boolean;
17
+ }
@@ -0,0 +1,13 @@
1
+ import { AgentsMdAgent } from './AgentsMdAgent';
2
+ /**
3
+ * Factory Droid agent adapter.
4
+ * Uses the root-level AGENTS.md for instructions.
5
+ */
6
+ export declare class FactoryDroidAgent extends AgentsMdAgent {
7
+ getIdentifier(): string;
8
+ getName(): string;
9
+ getMcpServerKey(): string;
10
+ supportsMcpStdio(): boolean;
11
+ supportsMcpRemote(): boolean;
12
+ supportsNativeSkills(): boolean;
13
+ }
@@ -0,0 +1,11 @@
1
+ import { AbstractAgent } from './AbstractAgent';
2
+ /**
3
+ * Firebase Studio agent adapter.
4
+ */
5
+ export declare class FirebaseAgent extends AbstractAgent {
6
+ getIdentifier(): string;
7
+ getName(): string;
8
+ getDefaultOutputPath(projectRoot: string): string;
9
+ supportsMcpStdio(): boolean;
10
+ supportsMcpRemote(): boolean;
11
+ }
@@ -0,0 +1,36 @@
1
+ import { IAgent, IAgentConfig } from './IAgent';
2
+ /**
3
+ * Firebender agent adapter.
4
+ */
5
+ export declare class FirebenderAgent implements IAgent {
6
+ /**
7
+ * Type guard function to safely check if an object is a FirebenderRule.
8
+ */
9
+ private isFirebenderRule;
10
+ getIdentifier(): string;
11
+ getName(): string;
12
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
13
+ private resolveOutputPath;
14
+ private loadExistingConfig;
15
+ private createRulesFromConcatenatedRules;
16
+ private createRuleObjectsFromFilePaths;
17
+ private createRulesFromPlainText;
18
+ private removeDuplicateRules;
19
+ private saveConfig;
20
+ /**
21
+ * Handle MCP server configuration for Firebender.
22
+ * Merges or overwrites MCP servers in the firebender.json configuration based on strategy.
23
+ */
24
+ private handleMcpConfiguration;
25
+ getDefaultOutputPath(projectRoot: string): Record<string, string>;
26
+ getMcpServerKey(): string;
27
+ supportsMcpStdio(): boolean;
28
+ supportsMcpRemote(): boolean;
29
+ /**
30
+ * Extracts file paths from concatenated rules by parsing HTML source comments.
31
+ * @param concatenatedRules The concatenated rules string with HTML comments
32
+ * @param projectRoot The project root directory
33
+ * @returns Array of file paths relative to project root
34
+ */
35
+ private extractFilePathsFromRules;
36
+ }
@@ -0,0 +1,11 @@
1
+ import { IAgentConfig } from './IAgent';
2
+ import { AgentsMdAgent } from './AgentsMdAgent';
3
+ export declare class GeminiCliAgent extends AgentsMdAgent {
4
+ getIdentifier(): string;
5
+ getName(): string;
6
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
7
+ getMcpServerKey(): string;
8
+ supportsMcpStdio(): boolean;
9
+ supportsMcpRemote(): boolean;
10
+ supportsNativeSkills(): boolean;
11
+ }
@@ -44,11 +44,11 @@ class GeminiCliAgent extends AgentsMdAgent_1.AgentsMdAgent {
44
44
  getName() {
45
45
  return 'Gemini CLI';
46
46
  }
47
- async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig) {
47
+ async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig, backup = true) {
48
48
  // First, perform idempotent write of AGENTS.md via base class
49
49
  await super.applyRulerConfig(concatenatedRules, projectRoot, null, {
50
50
  outputPath: agentConfig?.outputPath,
51
- });
51
+ }, backup);
52
52
  // Prepare .gemini/settings.json with contextFileName and MCP configuration
53
53
  const settingsPath = path.join(projectRoot, '.gemini', 'settings.json');
54
54
  let existingSettings = {};
@@ -0,0 +1,12 @@
1
+ import { AbstractAgent } from './AbstractAgent';
2
+ /**
3
+ * Goose agent adapter for Block's Goose AI assistant.
4
+ * Propagates rules to .goosehints file.
5
+ */
6
+ export declare class GooseAgent extends AbstractAgent {
7
+ getIdentifier(): string;
8
+ getName(): string;
9
+ getDefaultOutputPath(projectRoot: string): string;
10
+ getMcpServerKey(): string;
11
+ supportsNativeSkills(): boolean;
12
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Interface defining an AI agent configuration adapter.
3
+ */
4
+ import { McpConfig } from '../types';
5
+ /**
6
+ * Configuration overrides for a specific agent.
7
+ */
8
+ export interface IAgentConfig {
9
+ /** Explicit enable/disable agent */
10
+ enabled?: boolean;
11
+ /** Override for primary output path */
12
+ outputPath?: string;
13
+ /** Override for Aider instruction file path */
14
+ outputPathInstructions?: string;
15
+ /** Override for Aider config file path */
16
+ outputPathConfig?: string;
17
+ /** MCP propagation config for this agent. */
18
+ mcp?: McpConfig;
19
+ }
20
+ export interface IAgent {
21
+ /**
22
+ * Returns the lowercase identifier of the agent (e.g., "copilot", "claude", "aider").
23
+ */
24
+ getIdentifier(): string;
25
+ /**
26
+ * Returns the display name of the agent.
27
+ */
28
+ getName(): string;
29
+ /**
30
+ * Applies the concatenated ruler rules to the agent's configuration.
31
+ * @param concatenatedRules The combined rules text
32
+ * @param projectRoot The root directory of the project
33
+ */
34
+ applyRulerConfig(concatenatedRules: string, projectRoot: string, rulerMcpJson: Record<string, unknown> | null, agentConfig?: IAgentConfig, backup?: boolean): Promise<void>;
35
+ /**
36
+ * Returns the default output path(s) for this agent given the project root.
37
+ */
38
+ getDefaultOutputPath(projectRoot: string): string | Record<string, string>;
39
+ /**
40
+ * Returns the specific key to be used for the server object in MCP JSON.
41
+ * Defaults to 'mcpServers' if not implemented.
42
+ */
43
+ getMcpServerKey?(): string;
44
+ /**
45
+ * Returns whether this agent supports MCP STDIO servers.
46
+ * Defaults to false if not implemented.
47
+ */
48
+ supportsMcpStdio?(): boolean;
49
+ /**
50
+ * Returns whether this agent supports MCP remote servers.
51
+ * Defaults to false if not implemented.
52
+ */
53
+ supportsMcpRemote?(): boolean;
54
+ /**
55
+ * Returns whether this agent supports MCP server timeout configuration.
56
+ * Defaults to false if not implemented.
57
+ */
58
+ supportsMcpTimeout?(): boolean;
59
+ /**
60
+ * Returns whether this agent has native skills support (like Claude Code).
61
+ * When true, skills are copied directly to the agent's skills directory.
62
+ * Defaults to false if not implemented.
63
+ */
64
+ supportsNativeSkills?(): boolean;
65
+ /**
66
+ * Returns whether this agent has native subagent support (like Claude Code,
67
+ * Cursor, Codex CLI, GitHub Copilot). When true, subagent definitions from
68
+ * `.ruler/agents/` are propagated to the agent's native subagent location.
69
+ * Defaults to false if not implemented.
70
+ */
71
+ supportsNativeSubagents?(): boolean;
72
+ }
@@ -0,0 +1,10 @@
1
+ import { AbstractAgent } from './AbstractAgent';
2
+ /**
3
+ * JetBrains AI Assistant agent adapter.
4
+ * Writes rules to .aiassistant/rules/AGENTS.md.
5
+ */
6
+ export declare class JetBrainsAiAssistantAgent extends AbstractAgent {
7
+ getIdentifier(): string;
8
+ getName(): string;
9
+ getDefaultOutputPath(projectRoot: string): string;
10
+ }
@@ -0,0 +1,5 @@
1
+ import { AgentsMdAgent } from './AgentsMdAgent';
2
+ export declare class JulesAgent extends AgentsMdAgent {
3
+ getIdentifier(): string;
4
+ getName(): string;
5
+ }
@@ -0,0 +1,12 @@
1
+ import { AbstractAgent } from './AbstractAgent';
2
+ /**
3
+ * JetBrains Junie agent adapter.
4
+ */
5
+ export declare class JunieAgent extends AbstractAgent {
6
+ getIdentifier(): string;
7
+ getName(): string;
8
+ getDefaultOutputPath(projectRoot: string): string;
9
+ supportsMcpStdio(): boolean;
10
+ supportsMcpRemote(): boolean;
11
+ supportsNativeSkills(): boolean;
12
+ }
@@ -0,0 +1,14 @@
1
+ import { AgentsMdAgent } from './AgentsMdAgent';
2
+ /**
3
+ * Kilo Code agent adapter.
4
+ * Uses AGENTS.md for instructions and .kilocode/mcp.json for MCP configuration.
5
+ */
6
+ export declare class KiloCodeAgent extends AgentsMdAgent {
7
+ getIdentifier(): string;
8
+ getName(): string;
9
+ getDefaultOutputPath(projectRoot: string): string;
10
+ getMcpServerKey(): string;
11
+ supportsMcpStdio(): boolean;
12
+ supportsMcpRemote(): boolean;
13
+ supportsNativeSkills(): boolean;
14
+ }