@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
@@ -1,55 +1,14 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.JulesAgent = void 0;
37
- const FileSystemUtils_1 = require("../core/FileSystemUtils");
38
- const path = __importStar(require("path"));
39
- class JulesAgent {
4
+ const AgentsMdAgent_1 = require("./AgentsMdAgent");
5
+ // Jules agent now simply inherits AgentsMdAgent behavior (idempotent AGENTS.md writes).
6
+ class JulesAgent extends AgentsMdAgent_1.AgentsMdAgent {
40
7
  getIdentifier() {
41
8
  return 'jules';
42
9
  }
43
10
  getName() {
44
11
  return 'Jules';
45
12
  }
46
- async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig) {
47
- const outputPath = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
48
- const absolutePath = path.resolve(projectRoot, outputPath);
49
- await (0, FileSystemUtils_1.writeGeneratedFile)(absolutePath, concatenatedRules);
50
- }
51
- getDefaultOutputPath(projectRoot) {
52
- return path.join(projectRoot, 'AGENTS.md');
53
- }
54
13
  }
55
14
  exports.JulesAgent = JulesAgent;
@@ -35,24 +35,17 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.JunieAgent = void 0;
37
37
  const path = __importStar(require("path"));
38
- const FileSystemUtils_1 = require("../core/FileSystemUtils");
38
+ const AbstractAgent_1 = require("./AbstractAgent");
39
39
  /**
40
40
  * JetBrains Junie agent adapter.
41
41
  */
42
- class JunieAgent {
42
+ class JunieAgent extends AbstractAgent_1.AbstractAgent {
43
43
  getIdentifier() {
44
44
  return 'junie';
45
45
  }
46
46
  getName() {
47
47
  return 'Junie';
48
48
  }
49
- async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, // eslint-disable-line @typescript-eslint/no-unused-vars
50
- agentConfig) {
51
- const output = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
52
- await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(output));
53
- await (0, FileSystemUtils_1.backupFile)(output);
54
- await (0, FileSystemUtils_1.writeGeneratedFile)(output, concatenatedRules);
55
- }
56
49
  getDefaultOutputPath(projectRoot) {
57
50
  return path.join(projectRoot, '.junie', 'guidelines.md');
58
51
  }
@@ -35,30 +35,29 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.KiloCodeAgent = void 0;
37
37
  const path = __importStar(require("path"));
38
- const FileSystemUtils_1 = require("../core/FileSystemUtils");
38
+ const AbstractAgent_1 = require("./AbstractAgent");
39
39
  /**
40
40
  * Kilo Code agent adapter.
41
41
  * Generates ruler_kilocode_instructions.md configuration file in .kilocode/rules/ directory.
42
42
  */
43
- class KiloCodeAgent {
43
+ class KiloCodeAgent extends AbstractAgent_1.AbstractAgent {
44
44
  getIdentifier() {
45
45
  return 'kilocode';
46
46
  }
47
47
  getName() {
48
48
  return 'Kilo Code';
49
49
  }
50
- async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, // eslint-disable-line @typescript-eslint/no-unused-vars
51
- agentConfig) {
52
- const output = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
53
- await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(output));
54
- await (0, FileSystemUtils_1.backupFile)(output);
55
- await (0, FileSystemUtils_1.writeGeneratedFile)(output, concatenatedRules);
56
- }
57
50
  getDefaultOutputPath(projectRoot) {
58
51
  return path.join(projectRoot, '.kilocode', 'rules', 'ruler_kilocode_instructions.md');
59
52
  }
60
53
  getMcpServerKey() {
61
54
  return 'mcpServers';
62
55
  }
56
+ supportsMcpStdio() {
57
+ return true;
58
+ }
59
+ supportsMcpRemote() {
60
+ return true;
61
+ }
63
62
  }
64
63
  exports.KiloCodeAgent = KiloCodeAgent;
@@ -0,0 +1,50 @@
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.KiroAgent = void 0;
37
+ const path = __importStar(require("path"));
38
+ const AbstractAgent_1 = require("./AbstractAgent");
39
+ class KiroAgent extends AbstractAgent_1.AbstractAgent {
40
+ getIdentifier() {
41
+ return 'kiro';
42
+ }
43
+ getName() {
44
+ return 'Kiro';
45
+ }
46
+ getDefaultOutputPath(projectRoot) {
47
+ return path.join(projectRoot, '.kiro', 'steering', 'ruler_kiro_instructions.md');
48
+ }
49
+ }
50
+ exports.KiroAgent = KiroAgent;
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.OpenCodeAgent = void 0;
37
- const FileSystemUtils_1 = require("../core/FileSystemUtils");
37
+ const fs = __importStar(require("fs/promises"));
38
38
  const path = __importStar(require("path"));
39
39
  class OpenCodeAgent {
40
40
  getIdentifier() {
@@ -43,18 +43,57 @@ class OpenCodeAgent {
43
43
  getName() {
44
44
  return 'OpenCode';
45
45
  }
46
- async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, // eslint-disable-line @typescript-eslint/no-unused-vars
47
- agentConfig) {
48
- const outputPath = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
49
- const absolutePath = path.resolve(projectRoot, outputPath);
50
- await (0, FileSystemUtils_1.backupFile)(absolutePath);
51
- await (0, FileSystemUtils_1.writeGeneratedFile)(absolutePath, concatenatedRules);
52
- }
53
46
  getDefaultOutputPath(projectRoot) {
54
- return path.join(projectRoot, 'AGENTS.md');
47
+ return {
48
+ instructions: path.join(projectRoot, 'AGENTS.md'),
49
+ mcp: path.join(projectRoot, 'opencode.json'),
50
+ };
51
+ }
52
+ async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig) {
53
+ const outputPaths = this.getDefaultOutputPath(projectRoot);
54
+ const instructionsPath = path.resolve(projectRoot, agentConfig?.outputPathInstructions ?? outputPaths['instructions']);
55
+ const mcpPath = path.resolve(projectRoot, agentConfig?.outputPathConfig ?? outputPaths['mcp']);
56
+ await fs.writeFile(instructionsPath, concatenatedRules);
57
+ // Create OpenCode config with schema and MCP configuration
58
+ let finalMcpConfig = {
59
+ $schema: 'https://opencode.ai/config.json',
60
+ mcp: {},
61
+ };
62
+ try {
63
+ const existingMcpConfig = JSON.parse(await fs.readFile(mcpPath, 'utf-8'));
64
+ if (existingMcpConfig && typeof existingMcpConfig === 'object') {
65
+ finalMcpConfig = {
66
+ $schema: 'https://opencode.ai/config.json',
67
+ ...existingMcpConfig,
68
+ mcp: {
69
+ ...(existingMcpConfig.mcp || {}),
70
+ ...(rulerMcpJson?.mcpServers ?? {}),
71
+ },
72
+ };
73
+ }
74
+ else if (rulerMcpJson) {
75
+ finalMcpConfig = {
76
+ $schema: 'https://opencode.ai/config.json',
77
+ mcp: (rulerMcpJson?.mcpServers ?? {}),
78
+ };
79
+ }
80
+ }
81
+ catch {
82
+ if (rulerMcpJson) {
83
+ finalMcpConfig = {
84
+ $schema: 'https://opencode.ai/config.json',
85
+ mcp: (rulerMcpJson?.mcpServers ?? {}),
86
+ };
87
+ }
88
+ }
89
+ // Always write the config file, even if MCP is empty
90
+ await fs.writeFile(mcpPath, JSON.stringify(finalMcpConfig, null, 2));
91
+ }
92
+ supportsMcpStdio() {
93
+ return true;
55
94
  }
56
- getMcpServerKey() {
57
- return 'mcp';
95
+ supportsMcpRemote() {
96
+ return true;
58
97
  }
59
98
  }
60
99
  exports.OpenCodeAgent = OpenCodeAgent;
@@ -35,23 +35,22 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.OpenHandsAgent = void 0;
37
37
  const path = __importStar(require("path"));
38
- const FileSystemUtils_1 = require("../core/FileSystemUtils");
39
- class OpenHandsAgent {
38
+ const AbstractAgent_1 = require("./AbstractAgent");
39
+ class OpenHandsAgent extends AbstractAgent_1.AbstractAgent {
40
40
  getIdentifier() {
41
41
  return 'openhands';
42
42
  }
43
43
  getName() {
44
44
  return 'Open Hands';
45
45
  }
46
- async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, // eslint-disable-line @typescript-eslint/no-unused-vars
47
- agentConfig) {
48
- const output = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
49
- await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(output));
50
- await (0, FileSystemUtils_1.backupFile)(output);
51
- await (0, FileSystemUtils_1.writeGeneratedFile)(output, concatenatedRules);
52
- }
53
46
  getDefaultOutputPath(projectRoot) {
54
47
  return path.join(projectRoot, '.openhands', 'microagents', 'repo.md');
55
48
  }
49
+ supportsMcpStdio() {
50
+ return true;
51
+ }
52
+ supportsMcpRemote() {
53
+ return true;
54
+ }
56
55
  }
57
56
  exports.OpenHandsAgent = OpenHandsAgent;
@@ -0,0 +1,83 @@
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.QwenCodeAgent = void 0;
37
+ const path = __importStar(require("path"));
38
+ const fs_1 = require("fs");
39
+ const AgentsMdAgent_1 = require("./AgentsMdAgent");
40
+ class QwenCodeAgent extends AgentsMdAgent_1.AgentsMdAgent {
41
+ getIdentifier() {
42
+ return 'qwen';
43
+ }
44
+ getName() {
45
+ return 'Qwen Code';
46
+ }
47
+ async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, // eslint-disable-line @typescript-eslint/no-unused-vars
48
+ agentConfig) {
49
+ // First, perform idempotent write of AGENTS.md via base class
50
+ await super.applyRulerConfig(concatenatedRules, projectRoot, null, {
51
+ outputPath: agentConfig?.outputPath,
52
+ });
53
+ // Ensure .qwen/settings.json has contextFileName set to AGENTS.md
54
+ const settingsPath = path.join(projectRoot, '.qwen', 'settings.json');
55
+ let existingSettings = {};
56
+ try {
57
+ const raw = await fs_1.promises.readFile(settingsPath, 'utf8');
58
+ existingSettings = JSON.parse(raw);
59
+ }
60
+ catch (err) {
61
+ if (err.code !== 'ENOENT') {
62
+ throw err;
63
+ }
64
+ }
65
+ const updated = {
66
+ ...existingSettings,
67
+ contextFileName: 'AGENTS.md',
68
+ };
69
+ await fs_1.promises.mkdir(path.dirname(settingsPath), { recursive: true });
70
+ await fs_1.promises.writeFile(settingsPath, JSON.stringify(updated, null, 2));
71
+ }
72
+ // Ensure MCP merging uses the correct key for Qwen Code (.qwen/settings.json)
73
+ getMcpServerKey() {
74
+ return 'mcpServers';
75
+ }
76
+ supportsMcpStdio() {
77
+ return true;
78
+ }
79
+ supportsMcpRemote() {
80
+ return true;
81
+ }
82
+ }
83
+ exports.QwenCodeAgent = QwenCodeAgent;
@@ -0,0 +1,61 @@
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.WarpAgent = void 0;
37
+ const path = __importStar(require("path"));
38
+ const AbstractAgent_1 = require("./AbstractAgent");
39
+ /**
40
+ * Warp Agent Mode adapter.
41
+ * Generates WARP.md configuration file in the project root.
42
+ */
43
+ class WarpAgent extends AbstractAgent_1.AbstractAgent {
44
+ getIdentifier() {
45
+ return 'warp';
46
+ }
47
+ getName() {
48
+ return 'Warp';
49
+ }
50
+ getDefaultOutputPath(projectRoot) {
51
+ return path.join(projectRoot, 'WARP.md');
52
+ }
53
+ // Warp does not support MCP servers
54
+ supportsMcpStdio() {
55
+ return false;
56
+ }
57
+ supportsMcpRemote() {
58
+ return false;
59
+ }
60
+ }
61
+ exports.WarpAgent = WarpAgent;
@@ -35,11 +35,12 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.WindsurfAgent = void 0;
37
37
  const path = __importStar(require("path"));
38
+ const AbstractAgent_1 = require("./AbstractAgent");
38
39
  const FileSystemUtils_1 = require("../core/FileSystemUtils");
39
40
  /**
40
- * Windsurf agent adapter (stub implementation).
41
+ * Windsurf agent adapter.
41
42
  */
42
- class WindsurfAgent {
43
+ class WindsurfAgent extends AbstractAgent_1.AbstractAgent {
43
44
  getIdentifier() {
44
45
  return 'windsurf';
45
46
  }
@@ -49,12 +50,22 @@ class WindsurfAgent {
49
50
  async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, // eslint-disable-line @typescript-eslint/no-unused-vars
50
51
  agentConfig) {
51
52
  const output = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
52
- await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(output));
53
- await (0, FileSystemUtils_1.backupFile)(output);
54
- await (0, FileSystemUtils_1.writeGeneratedFile)(output, concatenatedRules);
53
+ const absolutePath = path.resolve(projectRoot, output);
54
+ // Windsurf expects a YAML front-matter block with a `trigger` flag.
55
+ const frontMatter = ['---', 'trigger: always_on', '---', ''].join('\n');
56
+ const content = `${frontMatter}${concatenatedRules.trimStart()}`;
57
+ await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(absolutePath));
58
+ await (0, FileSystemUtils_1.backupFile)(absolutePath);
59
+ await (0, FileSystemUtils_1.writeGeneratedFile)(absolutePath, content);
55
60
  }
56
61
  getDefaultOutputPath(projectRoot) {
57
62
  return path.join(projectRoot, '.windsurf', 'rules', 'ruler_windsurf_instructions.md');
58
63
  }
64
+ supportsMcpStdio() {
65
+ return true;
66
+ }
67
+ supportsMcpRemote() {
68
+ return true;
69
+ }
59
70
  }
60
71
  exports.WindsurfAgent = WindsurfAgent;
@@ -0,0 +1,132 @@
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.ZedAgent = void 0;
37
+ const path = __importStar(require("path"));
38
+ const fs_1 = require("fs");
39
+ const AgentsMdAgent_1 = require("./AgentsMdAgent");
40
+ /**
41
+ * Zed editor agent adapter.
42
+ * Inherits from AgentsMdAgent to write instructions to AGENTS.md and handles
43
+ * MCP server configuration in .zed/settings.json at the project root.
44
+ */
45
+ class ZedAgent extends AgentsMdAgent_1.AgentsMdAgent {
46
+ getIdentifier() {
47
+ return 'zed';
48
+ }
49
+ getName() {
50
+ return 'Zed';
51
+ }
52
+ async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig) {
53
+ // First, perform idempotent AGENTS.md write via base class
54
+ await super.applyRulerConfig(concatenatedRules, projectRoot, null, {
55
+ outputPath: agentConfig?.outputPath,
56
+ });
57
+ // Handle MCP server configuration if enabled and provided
58
+ const mcpEnabled = agentConfig?.mcp?.enabled ?? true;
59
+ if (mcpEnabled && rulerMcpJson) {
60
+ const zedSettingsPath = path.join(projectRoot, '.zed', 'settings.json');
61
+ // Read existing settings
62
+ let existingSettings = {};
63
+ try {
64
+ const content = await fs_1.promises.readFile(zedSettingsPath, 'utf8');
65
+ existingSettings = JSON.parse(content);
66
+ }
67
+ catch (error) {
68
+ if (error.code !== 'ENOENT') {
69
+ throw error;
70
+ }
71
+ // File doesn't exist, use empty settings
72
+ }
73
+ // Get the merge strategy
74
+ const strategy = agentConfig?.mcp?.strategy ?? 'merge';
75
+ // Handle merging based on strategy
76
+ let mergedSettings;
77
+ if (strategy === 'overwrite') {
78
+ // For overwrite, preserve all existing settings except MCP servers
79
+ mergedSettings = { ...existingSettings };
80
+ // Extract incoming MCP servers and transform them for Zed format
81
+ const incomingServers = rulerMcpJson.mcpServers || {};
82
+ const transformedServers = {};
83
+ for (const [serverName, serverConfig] of Object.entries(incomingServers)) {
84
+ transformedServers[serverName] = this.transformMcpServerForZed(serverConfig);
85
+ }
86
+ // Replace MCP servers completely
87
+ mergedSettings[this.getMcpServerKey()] = transformedServers;
88
+ }
89
+ else {
90
+ // For merge strategy, preserve all existing settings
91
+ const baseServers = existingSettings[this.getMcpServerKey()] || {};
92
+ const incomingServers = rulerMcpJson.mcpServers || {};
93
+ // Transform incoming servers for Zed format
94
+ const transformedIncomingServers = {};
95
+ for (const [serverName, serverConfig] of Object.entries(incomingServers)) {
96
+ transformedIncomingServers[serverName] =
97
+ this.transformMcpServerForZed(serverConfig);
98
+ }
99
+ const mergedServers = { ...baseServers, ...transformedIncomingServers };
100
+ mergedSettings = {
101
+ ...existingSettings,
102
+ [this.getMcpServerKey()]: mergedServers,
103
+ };
104
+ }
105
+ // Write updated settings
106
+ await fs_1.promises.mkdir(path.dirname(zedSettingsPath), { recursive: true });
107
+ await fs_1.promises.writeFile(zedSettingsPath, JSON.stringify(mergedSettings, null, 2));
108
+ }
109
+ }
110
+ getMcpServerKey() {
111
+ return 'context_servers';
112
+ }
113
+ supportsMcpStdio() {
114
+ return true;
115
+ }
116
+ supportsMcpRemote() {
117
+ return true;
118
+ }
119
+ /**
120
+ * Transform MCP server configuration from ruler format to Zed format.
121
+ * Converts "type": "stdio" to "source": "custom" and preserves other fields.
122
+ */
123
+ transformMcpServerForZed(rulerServer) {
124
+ const transformedServer = { ...rulerServer };
125
+ // Remove "type" field if present
126
+ delete transformedServer.type;
127
+ // Add "source": "custom" as required by Zed
128
+ transformedServer.source = 'custom';
129
+ return transformedServer;
130
+ }
131
+ }
132
+ exports.ZedAgent = ZedAgent;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAgentOutputPaths = getAgentOutputPaths;
4
+ /**
5
+ * Gets all output paths for an agent, taking into account any config overrides.
6
+ */
7
+ function getAgentOutputPaths(agent, projectRoot, agentConfig) {
8
+ const paths = [];
9
+ const defaults = agent.getDefaultOutputPath(projectRoot);
10
+ if (typeof defaults === 'string') {
11
+ // Single output path (most agents)
12
+ const actualPath = agentConfig?.outputPath ?? defaults;
13
+ paths.push(actualPath);
14
+ }
15
+ else {
16
+ // Multiple output paths (e.g., AiderAgent)
17
+ const defaultPaths = defaults;
18
+ // Handle instructions path
19
+ if ('instructions' in defaultPaths) {
20
+ const instructionsPath = agentConfig?.outputPathInstructions ?? defaultPaths.instructions;
21
+ paths.push(instructionsPath);
22
+ }
23
+ // Handle config path
24
+ if ('config' in defaultPaths) {
25
+ const configPath = agentConfig?.outputPathConfig ?? defaultPaths.config;
26
+ paths.push(configPath);
27
+ }
28
+ // Handle any other paths in the default paths record
29
+ for (const [key, defaultPath] of Object.entries(defaultPaths)) {
30
+ if (key !== 'instructions' && key !== 'config') {
31
+ // For unknown path types, use the default since we don't have specific config overrides
32
+ paths.push(defaultPath);
33
+ }
34
+ }
35
+ }
36
+ return paths;
37
+ }