routie dev init since i didn't adhere to any proper guidance up until now

This commit is contained in:
2026-04-29 22:27:29 -06:00
commit e1dabb71e2
15301 changed files with 3562618 additions and 0 deletions
@@ -0,0 +1,97 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractAgent = void 0;
const path = __importStar(require("path"));
const FileSystemUtils_1 = require("../core/FileSystemUtils");
/**
* Abstract base class for agents that write to a single configuration file.
* Implements common logic for applying ruler configuration.
*/
class AbstractAgent {
/**
* Applies the concatenated ruler rules to the agent's configuration.
* This implementation handles the common pattern of:
* 1. Determining the output path
* 2. Ensuring the parent directory exists
* 3. Backing up the existing file
* 4. Writing the new content
*/
async applyRulerConfig(concatenatedRules, projectRoot, _rulerMcpJson, agentConfig, backup = true) {
const output = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
const absolutePath = path.resolve(projectRoot, output);
await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(absolutePath));
if (backup) {
await (0, FileSystemUtils_1.backupFile)(absolutePath);
}
await (0, FileSystemUtils_1.writeGeneratedFile)(absolutePath, concatenatedRules);
}
/**
* Returns the specific key to be used for the server object in MCP JSON.
* Defaults to 'mcpServers' if not overridden.
*/
getMcpServerKey() {
return 'mcpServers';
}
/**
* Returns whether this agent supports MCP STDIO servers.
* Defaults to false if not overridden.
*/
supportsMcpStdio() {
return false;
}
/**
* Returns whether this agent supports MCP remote servers.
* Defaults to false if not overridden.
*/
supportsMcpRemote() {
return false;
}
/**
* Returns whether this agent supports MCP server timeout configuration.
* Defaults to false if not overridden.
*/
supportsMcpTimeout() {
return false;
}
/**
* Returns whether this agent has native skills support.
* Defaults to false if not overridden.
*/
supportsNativeSkills() {
return false;
}
}
exports.AbstractAgent = AbstractAgent;
@@ -0,0 +1,85 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AgentsMdAgent = void 0;
const path = __importStar(require("path"));
const fs_1 = require("fs");
const AbstractAgent_1 = require("./AbstractAgent");
const FileSystemUtils_1 = require("../core/FileSystemUtils");
/**
* Pseudo-agent that ensures the concatenated rules are written to root-level `AGENTS.md`.
* Does not participate in MCP propagation. Idempotent: only writes (and creates a backup)
* when content differs from existing file.
*/
class AgentsMdAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'agentsmd';
}
getName() {
return 'AgentsMd';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, 'AGENTS.md');
}
async applyRulerConfig(concatenatedRules, projectRoot, _rulerMcpJson, agentConfig, backup = true) {
const output = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
const absolutePath = path.resolve(projectRoot, output);
await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(absolutePath));
// Add marker comment to the content to identify it as generated
const contentWithMarker = `<!-- Generated by Ruler -->\n${concatenatedRules}`;
// Read existing content if present and skip write if identical
let existing = null;
try {
existing = await fs_1.promises.readFile(absolutePath, 'utf8');
}
catch {
existing = null;
}
if (existing !== null && existing === contentWithMarker) {
// No change; skip backup/write for idempotency
return;
}
// Backup (only if file existed and backup is enabled) then write new content
if (backup) {
await (0, FileSystemUtils_1.backupFile)(absolutePath);
}
await (0, FileSystemUtils_1.writeGeneratedFile)(absolutePath, contentWithMarker);
}
getMcpServerKey() {
// No MCP configuration for this pseudo-agent
return '';
}
}
exports.AgentsMdAgent = AgentsMdAgent;
+108
View File
@@ -0,0 +1,108 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AiderAgent = void 0;
const path = __importStar(require("path"));
const AgentsMdAgent_1 = require("./AgentsMdAgent");
const FileSystemUtils_1 = require("../core/FileSystemUtils");
const fs = __importStar(require("fs/promises"));
const yaml = __importStar(require("js-yaml"));
/**
* Aider agent adapter that uses AGENTS.md for instructions and .aider.conf.yml for configuration.
*/
class AiderAgent {
constructor() {
this.agentsMdAgent = new AgentsMdAgent_1.AgentsMdAgent();
}
getIdentifier() {
return 'aider';
}
getName() {
return 'Aider';
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig, backup = true) {
// First perform idempotent AGENTS.md write via composed AgentsMdAgent
await this.agentsMdAgent.applyRulerConfig(concatenatedRules, projectRoot, null, {
// Preserve explicit outputPath precedence semantics if provided.
outputPath: agentConfig?.outputPath ||
agentConfig?.outputPathInstructions ||
undefined,
}, backup);
// Now handle .aider.conf.yml configuration
const cfgPath = agentConfig?.outputPathConfig ??
this.getDefaultOutputPath(projectRoot).config;
let doc = {};
try {
await fs.access(cfgPath);
if (backup) {
await (0, FileSystemUtils_1.backupFile)(cfgPath);
}
const raw = await fs.readFile(cfgPath, 'utf8');
doc = (yaml.load(raw) || {});
}
catch {
doc = {};
}
if (!Array.isArray(doc.read)) {
doc.read = [];
}
// Determine the actual agents file path (AGENTS.md by default, or custom path)
const agentsPath = agentConfig?.outputPath ||
agentConfig?.outputPathInstructions ||
this.getDefaultOutputPath(projectRoot).instructions;
const name = path.basename(agentsPath);
if (!doc.read.includes(name)) {
doc.read.push(name);
}
const yamlStr = yaml.dump(doc);
await (0, FileSystemUtils_1.writeGeneratedFile)(cfgPath, yamlStr);
}
getDefaultOutputPath(projectRoot) {
return {
instructions: path.join(projectRoot, 'AGENTS.md'),
config: path.join(projectRoot, '.aider.conf.yml'),
};
}
getMcpServerKey() {
return this.agentsMdAgent.getMcpServerKey();
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
}
exports.AiderAgent = AiderAgent;
@@ -0,0 +1,103 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AmazonQCliAgent = void 0;
const path = __importStar(require("path"));
const fs_1 = require("fs");
const FileSystemUtils_1 = require("../core/FileSystemUtils");
const merge_1 = require("../mcp/merge");
/**
* Amazon Q CLI agent adapter.
*/
class AmazonQCliAgent {
getIdentifier() {
return 'amazonqcli';
}
getName() {
return 'Amazon Q CLI';
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig, backup = true) {
const outputPaths = this.getDefaultOutputPath(projectRoot);
const rulesPath = path.resolve(projectRoot, agentConfig?.outputPath ||
agentConfig?.outputPathInstructions ||
outputPaths['instructions']);
// Write rules file to .amazonq/rules/
await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(rulesPath));
if (backup) {
await (0, FileSystemUtils_1.backupFile)(rulesPath);
}
await (0, FileSystemUtils_1.writeGeneratedFile)(rulesPath, concatenatedRules);
// Handle MCP configuration if enabled and provided
const mcpEnabled = agentConfig?.mcp?.enabled ?? true;
if (mcpEnabled && rulerMcpJson) {
const mcpPath = path.resolve(projectRoot, agentConfig?.outputPathConfig ?? outputPaths['mcp']);
const mcpStrategy = agentConfig?.mcp?.strategy ?? 'merge';
await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(mcpPath));
let existingMcpConfig = {};
try {
const raw = await fs_1.promises.readFile(mcpPath, 'utf8');
existingMcpConfig = JSON.parse(raw);
}
catch (err) {
if (err.code !== 'ENOENT') {
throw err;
}
// File doesn't exist, start with empty config
}
// Merge the MCP configurations using the standard merge function
const mergedConfig = (0, merge_1.mergeMcp)(existingMcpConfig, rulerMcpJson, mcpStrategy, 'mcpServers');
if (backup) {
await (0, FileSystemUtils_1.backupFile)(mcpPath);
}
await (0, FileSystemUtils_1.writeGeneratedFile)(mcpPath, JSON.stringify(mergedConfig, null, 2));
}
}
getDefaultOutputPath(projectRoot) {
return {
instructions: path.join(projectRoot, '.amazonq', 'rules', 'ruler_q_rules.md'),
mcp: path.join(projectRoot, '.amazonq', 'mcp.json'),
};
}
getMcpServerKey() {
return 'mcpServers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
}
exports.AmazonQCliAgent = AmazonQCliAgent;
+16
View File
@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AmpAgent = void 0;
const AgentsMdAgent_1 = require("./AgentsMdAgent");
class AmpAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'amp';
}
getName() {
return 'Amp';
}
supportsNativeSkills() {
return true;
}
}
exports.AmpAgent = AmpAgent;
@@ -0,0 +1,56 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AntigravityAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
/**
* Antigravity agent adapter.
*/
class AntigravityAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'antigravity';
}
getName() {
return 'Antigravity';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.agent', 'rules', 'ruler.md');
}
supportsNativeSkills() {
return true;
}
}
exports.AntigravityAgent = AntigravityAgent;
@@ -0,0 +1,70 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AugmentCodeAgent = void 0;
const path = __importStar(require("path"));
const FileSystemUtils_1 = require("../core/FileSystemUtils");
/**
* AugmentCode agent adapter.
* Generates ruler_augment_instructions.md configuration file and updates VSCode settings.json with MCP server configuration.
*/
class AugmentCodeAgent {
getIdentifier() {
return 'augmentcode';
}
getName() {
return 'AugmentCode';
}
async applyRulerConfig(concatenatedRules, projectRoot, _rulerMcpJson, agentConfig, backup = true) {
const output = agentConfig?.outputPath ?? this.getDefaultOutputPath(projectRoot);
if (backup) {
await (0, FileSystemUtils_1.backupFile)(output);
}
await (0, FileSystemUtils_1.writeGeneratedFile)(output, concatenatedRules);
// AugmentCode does not support MCP servers
// MCP configuration is ignored for this agent
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.augment', 'rules', 'ruler_augment_instructions.md');
}
// AugmentCode does not support MCP servers
supportsMcpStdio() {
return false;
}
supportsMcpRemote() {
return false;
}
}
exports.AugmentCodeAgent = AugmentCodeAgent;
@@ -0,0 +1,62 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClaudeAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
/**
* Claude Code agent adapter.
*/
class ClaudeAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'claude';
}
getName() {
return 'Claude Code';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, 'CLAUDE.md');
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.ClaudeAgent = ClaudeAgent;
+53
View File
@@ -0,0 +1,53 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClineAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
/**
* Cline agent adapter.
*/
class ClineAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'cline';
}
getName() {
return 'Cline';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.clinerules');
}
}
exports.ClineAgent = ClineAgent;
@@ -0,0 +1,153 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodexCliAgent = void 0;
const path = __importStar(require("path"));
const fs_1 = require("fs");
const toml_1 = require("@iarna/toml");
const AgentsMdAgent_1 = require("./AgentsMdAgent");
const FileSystemUtils_1 = require("../core/FileSystemUtils");
const constants_1 = require("../constants");
/**
* OpenAI Codex CLI agent adapter.
*/
class CodexCliAgent {
constructor() {
this.agentsMdAgent = new AgentsMdAgent_1.AgentsMdAgent();
}
getIdentifier() {
return 'codex';
}
getName() {
return 'OpenAI Codex CLI';
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig, backup = true) {
// First perform idempotent AGENTS.md write via composed AgentsMdAgent
await this.agentsMdAgent.applyRulerConfig(concatenatedRules, projectRoot, null, {
// Preserve explicit outputPath precedence semantics if provided.
outputPath: agentConfig?.outputPath ||
agentConfig?.outputPathInstructions ||
undefined,
}, backup);
// Use proper path resolution from getDefaultOutputPath and agentConfig
const defaults = this.getDefaultOutputPath(projectRoot);
const mcpEnabled = agentConfig?.mcp?.enabled ?? true;
if (mcpEnabled && rulerMcpJson) {
// Apply MCP server filtering and transformation
const { filterMcpConfigForAgent } = await Promise.resolve().then(() => __importStar(require('../mcp/capabilities')));
const filteredMcpConfig = filterMcpConfigForAgent(rulerMcpJson, this);
if (!filteredMcpConfig) {
return; // No compatible servers found
}
const filteredRulerMcpJson = filteredMcpConfig;
// Determine the config file path using proper precedence
const configPath = agentConfig?.outputPathConfig ?? defaults.config;
// Ensure the parent directory exists
await fs_1.promises.mkdir(path.dirname(configPath), { recursive: true });
// Get the merge strategy
const strategy = agentConfig?.mcp?.strategy ?? 'merge';
// Extract MCP servers from filtered ruler config
const rulerServers = filteredRulerMcpJson.mcpServers || {};
// Read existing TOML config if it exists
let existingConfig = {};
try {
const existingContent = await fs_1.promises.readFile(configPath, 'utf8');
existingConfig = (0, toml_1.parse)(existingContent);
}
catch {
// File doesn't exist or can't be parsed, use empty config
}
// Create the updated config
const updatedConfig = { ...existingConfig };
// Initialize mcp_servers if it doesn't exist
if (!updatedConfig.mcp_servers) {
updatedConfig.mcp_servers = {};
}
if (strategy === 'overwrite') {
// For overwrite strategy, replace the entire mcp_servers section
updatedConfig.mcp_servers = {};
}
// Add the ruler servers
for (const [serverName, serverConfig] of Object.entries(rulerServers)) {
// Create a properly formatted MCP server entry
const mcpServer = {};
if (serverConfig.command) {
mcpServer.command = serverConfig.command;
}
if (serverConfig.url) {
mcpServer.url = serverConfig.url;
}
if (serverConfig.args) {
mcpServer.args = serverConfig.args;
}
// Format env as an inline table
if (serverConfig.env) {
mcpServer.env = serverConfig.env;
}
// Handle additional properties from remote server transformation
if (serverConfig.headers) {
mcpServer.headers = serverConfig.headers;
}
if (updatedConfig.mcp_servers) {
updatedConfig.mcp_servers[serverName] = mcpServer;
}
}
// Convert to TOML using structured objects
const finalConfig = { ...updatedConfig };
// @iarna/toml should handle the formatting properly
const tomlContent = (0, toml_1.stringify)(finalConfig);
await (0, FileSystemUtils_1.writeGeneratedFile)(configPath, tomlContent);
}
}
getDefaultOutputPath(projectRoot) {
return {
instructions: path.join(projectRoot, constants_1.DEFAULT_RULES_FILENAME),
config: path.join(projectRoot, '.codex', 'config.toml'),
};
}
getMcpServerKey() {
return 'mcp_servers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.CodexCliAgent = CodexCliAgent;
@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CopilotAgent = void 0;
const AgentsMdAgent_1 = require("./AgentsMdAgent");
/**
* GitHub Copilot agent adapter.
* Writes to AGENTS.md for both web-based GitHub Copilot and VS Code extension.
*/
class CopilotAgent {
constructor() {
this.agentsMdAgent = new AgentsMdAgent_1.AgentsMdAgent();
}
getIdentifier() {
return 'copilot';
}
getName() {
return 'GitHub Copilot';
}
/**
* Returns the default output path for AGENTS.md.
*/
getDefaultOutputPath(projectRoot) {
return this.agentsMdAgent.getDefaultOutputPath(projectRoot);
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig, backup = true) {
// Write to AGENTS.md using the existing AgentsMdAgent infrastructure
await this.agentsMdAgent.applyRulerConfig(concatenatedRules, projectRoot, null, // No MCP config needed for the instructions file
{
// Preserve explicit outputPath precedence semantics if provided
outputPath: agentConfig?.outputPath || agentConfig?.outputPathInstructions,
}, backup);
}
getMcpServerKey() {
return 'servers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.CopilotAgent = CopilotAgent;
+128
View File
@@ -0,0 +1,128 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.CrushAgent = void 0;
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
class CrushAgent {
getIdentifier() {
return 'crush';
}
getName() {
return 'Crush';
}
getDefaultOutputPath(projectRoot) {
return {
instructions: path.join(projectRoot, 'CRUSH.md'),
mcp: path.join(projectRoot, '.crush.json'),
};
}
/**
* Transform MCP server types for Crush compatibility.
* Crush expects "http" for HTTP servers and "sse" for SSE servers, not "remote".
*/
transformMcpServersForCrush(mcpServers) {
const transformedServers = {};
for (const [name, serverDef] of Object.entries(mcpServers)) {
if (serverDef && typeof serverDef === 'object') {
const server = serverDef;
const transformedServer = { ...server };
// Transform type: "remote" to appropriate Crush types
if (server.type === 'remote' &&
server.url &&
typeof server.url === 'string') {
const url = server.url;
// Check if URL suggests SSE (contains /sse path segment)
if (/\/sse(\/|$)/i.test(url)) {
transformedServer.type = 'sse';
}
else {
transformedServer.type = 'http';
}
}
transformedServers[name] = transformedServer;
}
else {
transformedServers[name] = serverDef;
}
}
return transformedServers;
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig) {
const outputPaths = this.getDefaultOutputPath(projectRoot);
const instructionsPath = agentConfig?.outputPathInstructions ?? outputPaths['instructions'];
const mcpPath = agentConfig?.outputPathConfig ?? outputPaths['mcp'];
await fs.writeFile(instructionsPath, concatenatedRules);
// Always transform from mcpServers ({ mcpServers: ... }) to { mcp: ... } for Crush
let finalMcpConfig = { mcp: {} };
try {
const existingMcpConfig = JSON.parse(await fs.readFile(mcpPath, 'utf-8'));
if (existingMcpConfig && typeof existingMcpConfig === 'object') {
const transformedServers = this.transformMcpServersForCrush((rulerMcpJson?.mcpServers ?? {}));
finalMcpConfig = {
...existingMcpConfig,
mcp: {
...(existingMcpConfig.mcp || {}),
...transformedServers,
},
};
}
else if (rulerMcpJson) {
const transformedServers = this.transformMcpServersForCrush((rulerMcpJson?.mcpServers ?? {}));
finalMcpConfig = {
mcp: transformedServers,
};
}
}
catch {
if (rulerMcpJson) {
const transformedServers = this.transformMcpServersForCrush((rulerMcpJson?.mcpServers ?? {}));
finalMcpConfig = {
mcp: transformedServers,
};
}
}
if (Object.keys(finalMcpConfig.mcp).length > 0) {
await fs.writeFile(mcpPath, JSON.stringify(finalMcpConfig, null, 2));
}
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
}
exports.CrushAgent = CrushAgent;
@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CursorAgent = void 0;
const AgentsMdAgent_1 = require("./AgentsMdAgent");
/**
* Cursor agent adapter.
* Leverages the standardized AGENTS.md approach supported natively by Cursor.
* See: https://docs.cursor.com/en/cli/using
*/
class CursorAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'cursor';
}
getName() {
return 'Cursor';
}
async applyRulerConfig(concatenatedRules, projectRoot, _rulerMcpJson, agentConfig, backup = true) {
// Write AGENTS.md via base class
// Cursor natively reads AGENTS.md from the project root
await super.applyRulerConfig(concatenatedRules, projectRoot, null, {
outputPath: agentConfig?.outputPath,
}, backup);
}
getMcpServerKey() {
return 'mcpServers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.CursorAgent = CursorAgent;
@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FactoryDroidAgent = void 0;
const AgentsMdAgent_1 = require("./AgentsMdAgent");
/**
* Factory Droid agent adapter.
* Uses the root-level AGENTS.md for instructions.
*/
class FactoryDroidAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'factory';
}
getName() {
return 'Factory Droid';
}
getMcpServerKey() {
return 'mcpServers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.FactoryDroidAgent = FactoryDroidAgent;
@@ -0,0 +1,61 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.FirebaseAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
/**
* Firebase Studio agent adapter.
*/
class FirebaseAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'firebase';
}
getName() {
return 'Firebase Studio';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.idx', 'airules.md');
}
// Firebase Studio (IDX) supports stdio MCP servers via .idx/mcp.json
supportsMcpStdio() {
return true;
}
// Remote MCP over HTTP/SSE is not documented for Firebase Studio yet
supportsMcpRemote() {
return false;
}
}
exports.FirebaseAgent = FirebaseAgent;
@@ -0,0 +1,205 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.FirebenderAgent = void 0;
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const FileSystemUtils_1 = require("../core/FileSystemUtils");
/**
* Firebender agent adapter.
*/
class FirebenderAgent {
/**
* Type guard function to safely check if an object is a FirebenderRule.
*/
isFirebenderRule(rule) {
return (typeof rule === 'object' &&
rule !== null &&
'filePathMatches' in rule &&
'rulesPaths' in rule &&
typeof rule.filePathMatches === 'string' &&
typeof rule.rulesPaths === 'string');
}
getIdentifier() {
return 'firebender';
}
getName() {
return 'Firebender';
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig, backup = true) {
const rulesPath = this.resolveOutputPath(projectRoot, agentConfig);
await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(rulesPath));
const firebenderConfig = await this.loadExistingConfig(rulesPath);
const newRules = this.createRulesFromConcatenatedRules(concatenatedRules, projectRoot);
firebenderConfig.rules.push(...newRules);
this.removeDuplicateRules(firebenderConfig);
const mcpEnabled = agentConfig?.mcp?.enabled ?? true;
if (mcpEnabled && rulerMcpJson) {
await this.handleMcpConfiguration(firebenderConfig, rulerMcpJson, agentConfig);
}
await this.saveConfig(rulesPath, firebenderConfig, backup);
}
resolveOutputPath(projectRoot, agentConfig) {
const outputPaths = this.getDefaultOutputPath(projectRoot);
const output = agentConfig?.outputPath ??
agentConfig?.outputPathInstructions ??
outputPaths['instructions'];
return path.resolve(projectRoot, output);
}
async loadExistingConfig(rulesPath) {
try {
const existingContent = await fs.promises.readFile(rulesPath, 'utf8');
const config = JSON.parse(existingContent);
if (!config.rules) {
config.rules = [];
}
return config;
}
catch (error) {
if (error &&
typeof error === 'object' &&
'code' in error &&
error.code === 'ENOENT') {
return { rules: [] };
}
console.warn(`Failed to read/parse existing firebender.json: ${error}`);
return { rules: [] };
}
}
createRulesFromConcatenatedRules(concatenatedRules, projectRoot) {
const filePaths = this.extractFilePathsFromRules(concatenatedRules, projectRoot);
if (filePaths.length > 0) {
return this.createRuleObjectsFromFilePaths(filePaths);
}
else {
return this.createRulesFromPlainText(concatenatedRules);
}
}
createRuleObjectsFromFilePaths(filePaths) {
return filePaths.map((filePath) => ({
filePathMatches: '**/*',
rulesPaths: filePath,
}));
}
createRulesFromPlainText(concatenatedRules) {
return concatenatedRules.split('\n').filter((rule) => rule.trim());
}
removeDuplicateRules(firebenderConfig) {
const seen = new Set();
firebenderConfig.rules = firebenderConfig.rules.filter((rule) => {
let key;
if (this.isFirebenderRule(rule)) {
const filePathMatchesPart = rule.filePathMatches;
const rulesPathsPart = rule.rulesPaths;
key = `${filePathMatchesPart}::${rulesPathsPart}`;
}
else {
key = String(rule);
}
if (seen.has(key)) {
return false;
}
seen.add(key);
return true;
});
}
async saveConfig(rulesPath, config, backup) {
const updatedContent = JSON.stringify(config, null, 2);
if (backup) {
await (0, FileSystemUtils_1.backupFile)(rulesPath);
}
await (0, FileSystemUtils_1.writeGeneratedFile)(rulesPath, updatedContent);
}
/**
* Handle MCP server configuration for Firebender.
* Merges or overwrites MCP servers in the firebender.json configuration based on strategy.
*/
async handleMcpConfiguration(firebenderConfig, rulerMcpJson, agentConfig) {
const strategy = agentConfig?.mcp?.strategy ?? 'merge';
const incomingServers = rulerMcpJson.mcpServers || {};
if (!firebenderConfig.mcpServers) {
firebenderConfig.mcpServers = {};
}
if (strategy === 'overwrite') {
firebenderConfig.mcpServers = { ...incomingServers };
}
else if (strategy === 'merge') {
const existingServers = firebenderConfig.mcpServers || {};
firebenderConfig.mcpServers = { ...existingServers, ...incomingServers };
}
}
getDefaultOutputPath(projectRoot) {
return {
instructions: path.join(projectRoot, 'firebender.json'),
mcp: path.join(projectRoot, 'firebender.json'),
};
}
getMcpServerKey() {
return 'mcpServers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
/**
* Extracts file paths from concatenated rules by parsing HTML source comments.
* @param concatenatedRules The concatenated rules string with HTML comments
* @param projectRoot The project root directory
* @returns Array of file paths relative to project root
*/
extractFilePathsFromRules(concatenatedRules, projectRoot) {
const sourceCommentRegex = /<!-- Source: (.+?) -->/g;
const filePaths = [];
let match;
while ((match = sourceCommentRegex.exec(concatenatedRules)) !== null) {
const relativePath = match[1];
const absolutePath = path.resolve(projectRoot, relativePath);
const normalizedProjectRoot = path.resolve(projectRoot);
// Ensure the absolutePath is within the project root (cross-platform compatible)
// This prevents path traversal attacks while handling Windows/Unix path differences
const isWithinProject = absolutePath.startsWith(normalizedProjectRoot) &&
(absolutePath.length === normalizedProjectRoot.length ||
absolutePath[normalizedProjectRoot.length] === path.sep);
if (isWithinProject) {
const projectRelativePath = path.relative(projectRoot, absolutePath);
filePaths.push(projectRelativePath);
}
}
return filePaths;
}
}
exports.FirebenderAgent = FirebenderAgent;
@@ -0,0 +1,120 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeminiCliAgent = void 0;
const path = __importStar(require("path"));
const fs_1 = require("fs");
const AgentsMdAgent_1 = require("./AgentsMdAgent");
class GeminiCliAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'gemini-cli';
}
getName() {
return 'Gemini CLI';
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig) {
// First, perform idempotent write of AGENTS.md via base class
await super.applyRulerConfig(concatenatedRules, projectRoot, null, {
outputPath: agentConfig?.outputPath,
});
// Prepare .gemini/settings.json with contextFileName and MCP configuration
const settingsPath = path.join(projectRoot, '.gemini', 'settings.json');
let existingSettings = {};
try {
const raw = await fs_1.promises.readFile(settingsPath, 'utf8');
existingSettings = JSON.parse(raw);
}
catch (err) {
if (err.code !== 'ENOENT') {
throw err;
}
}
const updated = {
...existingSettings,
contextFileName: 'AGENTS.md',
};
// Handle MCP server configuration if provided
const mcpEnabled = agentConfig?.mcp?.enabled ?? true;
if (mcpEnabled && rulerMcpJson) {
const strategy = agentConfig?.mcp?.strategy ?? 'merge';
// Gemini CLI (since v0.21.0) no longer accepts the "type" field in MCP server entries.
// Following the MCP spec update from Nov 25, 2025, the transport type is now inferred
// from the presence of specific keys (command/args -> stdio, url -> sse/http).
// Strip 'type' field from all incoming servers before merging.
const stripTypeField = (servers) => {
const cleaned = {};
for (const [name, def] of Object.entries(servers)) {
if (def && typeof def === 'object') {
const copy = { ...def };
delete copy.type;
cleaned[name] = copy;
}
else {
cleaned[name] = def;
}
}
return cleaned;
};
if (strategy === 'overwrite') {
// For overwrite, preserve existing settings except MCP servers
const incomingServers = rulerMcpJson.mcpServers || {};
updated[this.getMcpServerKey()] = stripTypeField(incomingServers);
}
else {
// For merge strategy, merge with existing MCP servers
const baseServers = existingSettings[this.getMcpServerKey()] || {};
const incomingServers = rulerMcpJson.mcpServers || {};
const mergedServers = { ...baseServers, ...incomingServers };
updated[this.getMcpServerKey()] = stripTypeField(mergedServers);
}
}
await fs_1.promises.mkdir(path.dirname(settingsPath), { recursive: true });
await fs_1.promises.writeFile(settingsPath, JSON.stringify(updated, null, 2));
}
// Ensure MCP merging uses the correct key for Gemini (.gemini/settings.json)
getMcpServerKey() {
return 'mcpServers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.GeminiCliAgent = GeminiCliAgent;
+61
View File
@@ -0,0 +1,61 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.GooseAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
/**
* Goose agent adapter for Block's Goose AI assistant.
* Propagates rules to .goosehints file.
*/
class GooseAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'goose';
}
getName() {
return 'Goose';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.goosehints');
}
getMcpServerKey() {
// Goose doesn't support MCP configuration via local config files
return '';
}
supportsNativeSkills() {
return true;
}
}
exports.GooseAgent = GooseAgent;
+2
View File
@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,54 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.JetBrainsAiAssistantAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
/**
* JetBrains AI Assistant agent adapter.
* Writes rules to .aiassistant/rules/AGENTS.md.
*/
class JetBrainsAiAssistantAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'jetbrains-ai';
}
getName() {
return 'JetBrains AI Assistant';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.aiassistant', 'rules', 'AGENTS.md');
}
}
exports.JetBrainsAiAssistantAgent = JetBrainsAiAssistantAgent;
+14
View File
@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JulesAgent = void 0;
const AgentsMdAgent_1 = require("./AgentsMdAgent");
// Jules agent now simply inherits AgentsMdAgent behavior (idempotent AGENTS.md writes).
class JulesAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'jules';
}
getName() {
return 'Jules';
}
}
exports.JulesAgent = JulesAgent;
+62
View File
@@ -0,0 +1,62 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.JunieAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
/**
* JetBrains Junie agent adapter.
*/
class JunieAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'junie';
}
getName() {
return 'Junie';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.junie', 'guidelines.md');
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.JunieAgent = JunieAgent;
@@ -0,0 +1,66 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.KiloCodeAgent = void 0;
const path = __importStar(require("path"));
const AgentsMdAgent_1 = require("./AgentsMdAgent");
/**
* Kilo Code agent adapter.
* Uses AGENTS.md for instructions and .kilocode/mcp.json for MCP configuration.
*/
class KiloCodeAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'kilocode';
}
getName() {
return 'Kilo Code';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, 'AGENTS.md');
}
getMcpServerKey() {
return 'mcpServers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.KiloCodeAgent = KiloCodeAgent;
+56
View File
@@ -0,0 +1,56 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.KiroAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
class KiroAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'kiro';
}
getName() {
return 'Kiro';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.kiro', 'steering', 'ruler_kiro_instructions.md');
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
}
exports.KiroAgent = KiroAgent;
@@ -0,0 +1,171 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.MistralVibeAgent = void 0;
const path = __importStar(require("path"));
const fs_1 = require("fs");
const toml_1 = require("@iarna/toml");
const AgentsMdAgent_1 = require("./AgentsMdAgent");
const FileSystemUtils_1 = require("../core/FileSystemUtils");
const constants_1 = require("../constants");
/**
* Mistral Vibe CLI agent adapter.
* Propagates rules to AGENTS.md and MCP servers to .vibe/config.toml.
*/
class MistralVibeAgent {
constructor() {
this.agentsMdAgent = new AgentsMdAgent_1.AgentsMdAgent();
}
getIdentifier() {
return 'mistral';
}
getName() {
return 'Mistral';
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig, backup = true) {
// First perform idempotent AGENTS.md write via composed AgentsMdAgent
await this.agentsMdAgent.applyRulerConfig(concatenatedRules, projectRoot, null, {
outputPath: agentConfig?.outputPath ||
agentConfig?.outputPathInstructions ||
undefined,
}, backup);
// Handle MCP configuration
const defaults = this.getDefaultOutputPath(projectRoot);
const mcpEnabled = agentConfig?.mcp?.enabled ?? true;
if (mcpEnabled && rulerMcpJson) {
// Apply MCP server filtering and transformation
const { filterMcpConfigForAgent } = await Promise.resolve().then(() => __importStar(require('../mcp/capabilities')));
const filteredMcpConfig = filterMcpConfigForAgent(rulerMcpJson, this);
if (!filteredMcpConfig) {
return; // No compatible servers found
}
const filteredRulerMcpJson = filteredMcpConfig;
// Determine the config file path
const configPath = agentConfig?.outputPathConfig ?? defaults.config;
// Ensure the parent directory exists
await fs_1.promises.mkdir(path.dirname(configPath), { recursive: true });
// Get the merge strategy
const strategy = agentConfig?.mcp?.strategy ?? 'merge';
// Transform ruler MCP servers to Vibe format
const rulerServers = filteredRulerMcpJson.mcpServers || {};
const vibeServers = [];
for (const [serverName, serverConfig] of Object.entries(rulerServers)) {
const vibeServer = {
name: serverName,
transport: this.determineTransport(serverConfig),
};
// Handle stdio servers
if (serverConfig.command) {
vibeServer.command = serverConfig.command;
if (serverConfig.args) {
vibeServer.args = serverConfig.args;
}
}
// Handle remote servers
if (serverConfig.url) {
vibeServer.url = serverConfig.url;
}
// Handle headers
if (serverConfig.headers) {
vibeServer.headers = serverConfig.headers;
}
// Handle env
if (serverConfig.env) {
vibeServer.env = serverConfig.env;
}
vibeServers.push(vibeServer);
}
// Read existing TOML config if it exists
let existingConfig = {};
try {
const existingContent = await fs_1.promises.readFile(configPath, 'utf8');
existingConfig = (0, toml_1.parse)(existingContent);
}
catch {
// File doesn't exist or can't be parsed, use empty config
}
// Create the updated config
const updatedConfig = { ...existingConfig };
if (strategy === 'overwrite') {
// For overwrite strategy, replace the entire mcp_servers array
updatedConfig.mcp_servers = vibeServers;
}
else {
// For merge strategy, merge by server name
const existingServers = updatedConfig.mcp_servers || [];
// Keep existing servers that aren't being overwritten by ruler
const mergedServers = existingServers.filter((s) => !rulerServers[s.name]);
// Add all ruler servers
mergedServers.push(...vibeServers);
updatedConfig.mcp_servers = mergedServers;
}
// Convert to TOML and write
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const tomlContent = (0, toml_1.stringify)(updatedConfig);
await (0, FileSystemUtils_1.writeGeneratedFile)(configPath, tomlContent);
}
}
/**
* Determines the transport type based on server configuration.
*/
determineTransport(server) {
if (server.command) {
return 'stdio';
}
if (server.url) {
// Default to http for remote servers
// Could potentially detect streamable-http based on URL patterns if needed
return 'http';
}
return 'stdio';
}
getDefaultOutputPath(projectRoot) {
return {
instructions: path.join(projectRoot, constants_1.DEFAULT_RULES_FILENAME),
config: path.join(projectRoot, '.vibe', 'config.toml'),
};
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true; // Mistral Vibe supports http and streamable-http transports
}
supportsNativeSkills() {
// Mistral Vibe supports native skills in .vibe/skills/
return true;
}
}
exports.MistralVibeAgent = MistralVibeAgent;
@@ -0,0 +1,105 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenCodeAgent = void 0;
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
class OpenCodeAgent {
getIdentifier() {
return 'opencode';
}
getName() {
return 'OpenCode';
}
getDefaultOutputPath(projectRoot) {
return {
instructions: path.join(projectRoot, 'AGENTS.md'),
mcp: path.join(projectRoot, 'opencode.json'),
};
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig) {
const outputPaths = this.getDefaultOutputPath(projectRoot);
const instructionsPath = path.resolve(projectRoot, agentConfig?.outputPathInstructions ?? outputPaths['instructions']);
const mcpPath = path.resolve(projectRoot, agentConfig?.outputPathConfig ?? outputPaths['mcp']);
await fs.writeFile(instructionsPath, concatenatedRules);
// Create OpenCode config with schema and MCP configuration
let finalMcpConfig = {
$schema: 'https://opencode.ai/config.json',
mcp: {},
};
try {
const existingMcpConfig = JSON.parse(await fs.readFile(mcpPath, 'utf-8'));
if (existingMcpConfig && typeof existingMcpConfig === 'object') {
finalMcpConfig = {
$schema: 'https://opencode.ai/config.json',
...existingMcpConfig,
mcp: {
...(existingMcpConfig.mcp || {}),
...(rulerMcpJson?.mcpServers ?? {}),
},
};
}
else if (rulerMcpJson) {
finalMcpConfig = {
$schema: 'https://opencode.ai/config.json',
mcp: (rulerMcpJson?.mcpServers ?? {}),
};
}
}
catch {
if (rulerMcpJson) {
finalMcpConfig = {
$schema: 'https://opencode.ai/config.json',
mcp: (rulerMcpJson?.mcpServers ?? {}),
};
}
}
// Always write the config file, even if MCP is empty
await fs.writeFile(mcpPath, JSON.stringify(finalMcpConfig, null, 2));
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsMcpTimeout() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.OpenCodeAgent = OpenCodeAgent;
@@ -0,0 +1,56 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenHandsAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
class OpenHandsAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'openhands';
}
getName() {
return 'Open Hands';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.openhands', 'microagents', 'repo.md');
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
}
exports.OpenHandsAgent = OpenHandsAgent;
+19
View File
@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PiAgent = void 0;
const AgentsMdAgent_1 = require("./AgentsMdAgent");
/**
* Pi Coding Agent adapter.
*/
class PiAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'pi';
}
getName() {
return 'Pi Coding Agent';
}
supportsNativeSkills() {
return true;
}
}
exports.PiAgent = PiAgent;
@@ -0,0 +1,82 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.QwenCodeAgent = void 0;
const path = __importStar(require("path"));
const fs_1 = require("fs");
const AgentsMdAgent_1 = require("./AgentsMdAgent");
class QwenCodeAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'qwen';
}
getName() {
return 'Qwen Code';
}
async applyRulerConfig(concatenatedRules, projectRoot, _rulerMcpJson, agentConfig) {
// First, perform idempotent write of AGENTS.md via base class
await super.applyRulerConfig(concatenatedRules, projectRoot, null, {
outputPath: agentConfig?.outputPath,
});
// Ensure .qwen/settings.json has contextFileName set to AGENTS.md
const settingsPath = path.join(projectRoot, '.qwen', 'settings.json');
let existingSettings = {};
try {
const raw = await fs_1.promises.readFile(settingsPath, 'utf8');
existingSettings = JSON.parse(raw);
}
catch (err) {
if (err.code !== 'ENOENT') {
throw err;
}
}
const updated = {
...existingSettings,
contextFileName: 'AGENTS.md',
};
await fs_1.promises.mkdir(path.dirname(settingsPath), { recursive: true });
await fs_1.promises.writeFile(settingsPath, JSON.stringify(updated, null, 2));
}
// Ensure MCP merging uses the correct key for Qwen Code (.qwen/settings.json)
getMcpServerKey() {
return 'mcpServers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
}
exports.QwenCodeAgent = QwenCodeAgent;
@@ -0,0 +1,142 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.RooCodeAgent = void 0;
const path = __importStar(require("path"));
const fs_1 = require("fs");
const AgentsMdAgent_1 = require("./AgentsMdAgent");
const FileSystemUtils_1 = require("../core/FileSystemUtils");
/**
* Agent for RooCode that writes to AGENTS.md and generates .roo/mcp.json
* with project-level MCP server configuration.
*/
class RooCodeAgent {
constructor() {
this.agentsMdAgent = new AgentsMdAgent_1.AgentsMdAgent();
}
getIdentifier() {
return 'roo';
}
getName() {
return 'RooCode';
}
getDefaultOutputPath(projectRoot) {
return {
instructions: path.join(projectRoot, 'AGENTS.md'),
mcp: path.join(projectRoot, '.roo', 'mcp.json'),
};
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig, backup = true) {
// First perform idempotent AGENTS.md write via composed AgentsMdAgent
await this.agentsMdAgent.applyRulerConfig(concatenatedRules, projectRoot, null, {
// Preserve explicit outputPath precedence semantics if provided.
outputPath: agentConfig?.outputPath ||
agentConfig?.outputPathInstructions ||
undefined,
}, backup);
// Now handle .roo/mcp.json configuration
const outputPaths = this.getDefaultOutputPath(projectRoot);
const mcpPath = path.resolve(projectRoot, agentConfig?.outputPathConfig ?? outputPaths['mcp']);
await (0, FileSystemUtils_1.ensureDirExists)(path.dirname(mcpPath));
// Create base structure with mcpServers
let finalMcpConfig = {
mcpServers: {},
};
// Try to read existing .roo/mcp.json
let existingConfig = {};
try {
const existingContent = await fs_1.promises.readFile(mcpPath, 'utf-8');
const parsed = JSON.parse(existingContent);
if (parsed && typeof parsed === 'object') {
existingConfig = parsed;
}
}
catch {
// File doesn't exist or invalid JSON - start fresh
existingConfig = {};
}
// Merge MCP servers if we have ruler config
if (rulerMcpJson?.mcpServers) {
const existingServers = existingConfig.mcpServers || {};
const newServers = rulerMcpJson.mcpServers;
// Shallow merge: new servers override existing with same name
finalMcpConfig = {
mcpServers: {
...existingServers,
...newServers,
},
};
}
else if (existingConfig.mcpServers) {
// Keep existing servers if no new ones to add
finalMcpConfig = {
mcpServers: existingConfig.mcpServers,
};
}
// If neither condition is met, finalMcpConfig remains { mcpServers: {} }
// Write the config file with pretty JSON (2 spaces)
const newContent = JSON.stringify(finalMcpConfig, null, 2);
// Check if content has changed for idempotency
let existingContent = null;
try {
existingContent = await fs_1.promises.readFile(mcpPath, 'utf8');
}
catch {
existingContent = null;
}
if (existingContent !== null && existingContent === newContent) {
// No change; skip backup/write for idempotency
return;
}
// Backup (only if file existed and backup is enabled) then write new content
if (backup) {
await (0, FileSystemUtils_1.backupFile)(mcpPath);
}
await (0, FileSystemUtils_1.writeGeneratedFile)(mcpPath, newContent);
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
getMcpServerKey() {
return 'mcpServers';
}
supportsNativeSkills() {
return true;
}
}
exports.RooCodeAgent = RooCodeAgent;
+54
View File
@@ -0,0 +1,54 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TraeAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
/**
* Trae AI agent adapter.
* Generates project_rules.md configuration file.
*/
class TraeAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'trae';
}
getName() {
return 'Trae AI';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, '.trae', 'rules', 'project_rules.md');
}
}
exports.TraeAgent = TraeAgent;
+61
View File
@@ -0,0 +1,61 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.WarpAgent = void 0;
const path = __importStar(require("path"));
const AbstractAgent_1 = require("./AbstractAgent");
/**
* Warp Agent Mode adapter.
* Generates WARP.md configuration file in the project root.
*/
class WarpAgent extends AbstractAgent_1.AbstractAgent {
getIdentifier() {
return 'warp';
}
getName() {
return 'Warp';
}
getDefaultOutputPath(projectRoot) {
return path.join(projectRoot, 'WARP.md');
}
// Warp does not support MCP servers
supportsMcpStdio() {
return false;
}
supportsMcpRemote() {
return false;
}
}
exports.WarpAgent = WarpAgent;
@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WindsurfAgent = void 0;
const AgentsMdAgent_1 = require("./AgentsMdAgent");
/**
* Windsurf agent adapter.
* Now uses AGENTS.md format like other agents.
*/
class WindsurfAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'windsurf';
}
getName() {
return 'Windsurf';
}
// Windsurf supports MCP configuration
getMcpServerKey() {
return 'mcpServers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
supportsNativeSkills() {
return true;
}
}
exports.WindsurfAgent = WindsurfAgent;
+132
View File
@@ -0,0 +1,132 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZedAgent = void 0;
const path = __importStar(require("path"));
const fs_1 = require("fs");
const AgentsMdAgent_1 = require("./AgentsMdAgent");
/**
* Zed editor agent adapter.
* Inherits from AgentsMdAgent to write instructions to AGENTS.md and handles
* MCP server configuration in .zed/settings.json at the project root.
*/
class ZedAgent extends AgentsMdAgent_1.AgentsMdAgent {
getIdentifier() {
return 'zed';
}
getName() {
return 'Zed';
}
async applyRulerConfig(concatenatedRules, projectRoot, rulerMcpJson, agentConfig) {
// First, perform idempotent AGENTS.md write via base class
await super.applyRulerConfig(concatenatedRules, projectRoot, null, {
outputPath: agentConfig?.outputPath,
});
// Handle MCP server configuration if enabled and provided
const mcpEnabled = agentConfig?.mcp?.enabled ?? true;
if (mcpEnabled && rulerMcpJson) {
const zedSettingsPath = path.join(projectRoot, '.zed', 'settings.json');
// Read existing settings
let existingSettings = {};
try {
const content = await fs_1.promises.readFile(zedSettingsPath, 'utf8');
existingSettings = JSON.parse(content);
}
catch (error) {
if (error.code !== 'ENOENT') {
throw error;
}
// File doesn't exist, use empty settings
}
// Get the merge strategy
const strategy = agentConfig?.mcp?.strategy ?? 'merge';
// Handle merging based on strategy
let mergedSettings;
if (strategy === 'overwrite') {
// For overwrite, preserve all existing settings except MCP servers
mergedSettings = { ...existingSettings };
// Extract incoming MCP servers and transform them for Zed format
const incomingServers = rulerMcpJson.mcpServers || {};
const transformedServers = {};
for (const [serverName, serverConfig] of Object.entries(incomingServers)) {
transformedServers[serverName] = this.transformMcpServerForZed(serverConfig);
}
// Replace MCP servers completely
mergedSettings[this.getMcpServerKey()] = transformedServers;
}
else {
// For merge strategy, preserve all existing settings
const baseServers = existingSettings[this.getMcpServerKey()] || {};
const incomingServers = rulerMcpJson.mcpServers || {};
// Transform incoming servers for Zed format
const transformedIncomingServers = {};
for (const [serverName, serverConfig] of Object.entries(incomingServers)) {
transformedIncomingServers[serverName] =
this.transformMcpServerForZed(serverConfig);
}
const mergedServers = { ...baseServers, ...transformedIncomingServers };
mergedSettings = {
...existingSettings,
[this.getMcpServerKey()]: mergedServers,
};
}
// Write updated settings
await fs_1.promises.mkdir(path.dirname(zedSettingsPath), { recursive: true });
await fs_1.promises.writeFile(zedSettingsPath, JSON.stringify(mergedSettings, null, 2));
}
}
getMcpServerKey() {
return 'context_servers';
}
supportsMcpStdio() {
return true;
}
supportsMcpRemote() {
return true;
}
/**
* Transform MCP server configuration from ruler format to Zed format.
* Converts "type": "stdio" to "source": "custom" and preserves other fields.
*/
transformMcpServerForZed(rulerServer) {
const transformedServer = { ...rulerServer };
// Remove "type" field if present
delete transformedServer.type;
// Add "source": "custom" as required by Zed
transformedServer.source = 'custom';
return transformedServer;
}
}
exports.ZedAgent = ZedAgent;
@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAgentOutputPaths = getAgentOutputPaths;
/**
* Gets all output paths for an agent, taking into account any config overrides.
*/
function getAgentOutputPaths(agent, projectRoot, agentConfig) {
const paths = [];
const defaults = agent.getDefaultOutputPath(projectRoot);
if (typeof defaults === 'string') {
// Single output path (most agents)
const actualPath = agentConfig?.outputPath ?? defaults;
paths.push(actualPath);
}
else {
// Multiple output paths (e.g., AiderAgent)
const defaultPaths = defaults;
// Handle instructions path
if ('instructions' in defaultPaths) {
const instructionsPath = agentConfig?.outputPathInstructions ?? defaultPaths.instructions;
paths.push(instructionsPath);
}
// Handle config path
if ('config' in defaultPaths) {
const configPath = agentConfig?.outputPathConfig ?? defaultPaths.config;
paths.push(configPath);
}
// Handle any other paths in the default paths record
for (const [key, defaultPath] of Object.entries(defaultPaths)) {
if (key !== 'instructions' && key !== 'config') {
// For unknown path types, use the default since we don't have specific config overrides
paths.push(defaultPath);
}
}
}
return paths;
}
+87
View File
@@ -0,0 +1,87 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.allAgents = exports.AbstractAgent = void 0;
exports.getAgentIdentifiersForCliHelp = getAgentIdentifiersForCliHelp;
const AbstractAgent_1 = require("./AbstractAgent");
Object.defineProperty(exports, "AbstractAgent", { enumerable: true, get: function () { return AbstractAgent_1.AbstractAgent; } });
const CopilotAgent_1 = require("./CopilotAgent");
const ClaudeAgent_1 = require("./ClaudeAgent");
const CodexCliAgent_1 = require("./CodexCliAgent");
const CursorAgent_1 = require("./CursorAgent");
const WindsurfAgent_1 = require("./WindsurfAgent");
const ClineAgent_1 = require("./ClineAgent");
const AiderAgent_1 = require("./AiderAgent");
const FirebaseAgent_1 = require("./FirebaseAgent");
const OpenHandsAgent_1 = require("./OpenHandsAgent");
const GeminiCliAgent_1 = require("./GeminiCliAgent");
const JulesAgent_1 = require("./JulesAgent");
const JunieAgent_1 = require("./JunieAgent");
const AugmentCodeAgent_1 = require("./AugmentCodeAgent");
const KiloCodeAgent_1 = require("./KiloCodeAgent");
const OpenCodeAgent_1 = require("./OpenCodeAgent");
const CrushAgent_1 = require("./CrushAgent");
const GooseAgent_1 = require("./GooseAgent");
const AmpAgent_1 = require("./AmpAgent");
const ZedAgent_1 = require("./ZedAgent");
const AgentsMdAgent_1 = require("./AgentsMdAgent");
const QwenCodeAgent_1 = require("./QwenCodeAgent");
const KiroAgent_1 = require("./KiroAgent");
const WarpAgent_1 = require("./WarpAgent");
const RooCodeAgent_1 = require("./RooCodeAgent");
const TraeAgent_1 = require("./TraeAgent");
const AmazonQCliAgent_1 = require("./AmazonQCliAgent");
const FirebenderAgent_1 = require("./FirebenderAgent");
const FactoryDroidAgent_1 = require("./FactoryDroidAgent");
const AntigravityAgent_1 = require("./AntigravityAgent");
const MistralVibeAgent_1 = require("./MistralVibeAgent");
const PiAgent_1 = require("./PiAgent");
const JetBrainsAiAssistantAgent_1 = require("./JetBrainsAiAssistantAgent");
exports.allAgents = [
new CopilotAgent_1.CopilotAgent(),
new ClaudeAgent_1.ClaudeAgent(),
new CodexCliAgent_1.CodexCliAgent(),
new CursorAgent_1.CursorAgent(),
new WindsurfAgent_1.WindsurfAgent(),
new ClineAgent_1.ClineAgent(),
new AiderAgent_1.AiderAgent(),
new FirebaseAgent_1.FirebaseAgent(),
new OpenHandsAgent_1.OpenHandsAgent(),
new GeminiCliAgent_1.GeminiCliAgent(),
new JulesAgent_1.JulesAgent(),
new JunieAgent_1.JunieAgent(),
new AugmentCodeAgent_1.AugmentCodeAgent(),
new KiloCodeAgent_1.KiloCodeAgent(),
new OpenCodeAgent_1.OpenCodeAgent(),
new GooseAgent_1.GooseAgent(),
new CrushAgent_1.CrushAgent(),
new AmpAgent_1.AmpAgent(),
new ZedAgent_1.ZedAgent(),
new QwenCodeAgent_1.QwenCodeAgent(),
new AgentsMdAgent_1.AgentsMdAgent(),
new KiroAgent_1.KiroAgent(),
new WarpAgent_1.WarpAgent(),
new RooCodeAgent_1.RooCodeAgent(),
new TraeAgent_1.TraeAgent(),
new AmazonQCliAgent_1.AmazonQCliAgent(),
new FirebenderAgent_1.FirebenderAgent(),
new FactoryDroidAgent_1.FactoryDroidAgent(),
new AntigravityAgent_1.AntigravityAgent(),
new MistralVibeAgent_1.MistralVibeAgent(),
new PiAgent_1.PiAgent(),
new JetBrainsAiAssistantAgent_1.JetBrainsAiAssistantAgent(),
];
/**
* Generates a comma-separated list of agent identifiers for CLI help text.
* Returns identifiers in alphabetical order, with 'agentsmd' always first.
*/
function getAgentIdentifiersForCliHelp() {
const identifiers = exports.allAgents.map((agent) => agent.getIdentifier());
const sorted = identifiers.sort();
// Ensure agentsmd is first (it should already be first alphabetically, but let's be explicit)
const agentsMdIndex = sorted.indexOf('agentsmd');
if (agentsMdIndex > 0) {
const agentsmd = sorted.splice(agentsMdIndex, 1)[0];
sorted.unshift(agentsmd);
}
return sorted.join(', ');
}