creatrip-agent-rules-builder
Version:
Unified converter for AI coding agent rules across Cursor, Windsurf, and Claude
193 lines • 9.2 kB
JavaScript
;
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;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildRules = buildRules;
const chalk_1 = __importDefault(require("chalk"));
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const parser_1 = require("./parser");
const cursor_1 = require("./generators/cursor");
const windsurf_1 = require("./generators/windsurf");
const claude_1 = require("./generators/claude");
function findAgentRulesFiles(dir) {
const gitignorePath = path.join(dir, ".gitignore");
let gitignorePatterns = [];
if (fs.existsSync(gitignorePath)) {
const gitignoreContent = fs.readFileSync(gitignorePath, "utf8");
gitignorePatterns = gitignoreContent
.split("\n")
.map((line) => line.trim())
.filter((line) => line && !line.startsWith("#"));
}
const defaultIgnorePatterns = [
"node_modules",
".git",
"dist",
"build",
"out",
".next",
".nuxt",
"coverage",
".nyc_output",
];
const allIgnorePatterns = [
...new Set([...defaultIgnorePatterns, ...gitignorePatterns]),
];
function shouldIgnoreDir(dirPath) {
const dirName = path.basename(dirPath);
const relativePath = path.relative(dir, dirPath);
return allIgnorePatterns.some((pattern) => {
// /sub-app/ 같은 절대 경로 패턴 (슬래시로 끝남)
if (pattern.startsWith("/") && pattern.endsWith("/")) {
const cleanPattern = pattern.slice(1, -1);
return (relativePath === cleanPattern ||
relativePath.startsWith(cleanPattern + "/"));
}
// /sub-app 같은 절대 경로 패턴 (슬래시로 끝나지 않음)
if (pattern.startsWith("/")) {
const cleanPattern = pattern.slice(1);
return (relativePath === cleanPattern ||
relativePath.startsWith(cleanPattern + "/"));
}
// sub-app/ 같은 상대 경로 패턴
if (pattern.endsWith("/")) {
const cleanPattern = pattern.slice(0, -1);
return (dirName === cleanPattern ||
relativePath === cleanPattern ||
relativePath.startsWith(cleanPattern + "/"));
}
// 단순 이름 패턴
return dirName === pattern || relativePath === pattern;
});
}
function searchRecursively(currentDir) {
const results = [];
try {
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(currentDir, entry.name);
if (entry.isDirectory()) {
if (!shouldIgnoreDir(fullPath)) {
results.push(...searchRecursively(fullPath));
}
}
else if (entry.name === "AGENTS.md") {
results.push(currentDir);
}
}
}
catch (error) {
// 권한 문제 등으로 읽을 수 없는 디렉토리는 무시
}
return results;
}
return searchRecursively(dir);
}
function processRulesFile(filePath, showDetails = true) {
const baseDir = path.dirname(filePath);
if (showDetails) {
console.log(chalk_1.default.gray(`처리 중: ${filePath}`));
}
const parsedContent = (0, parser_1.parseAgentRulesFile)(filePath);
(0, cursor_1.generateCursorRules)(parsedContent, baseDir);
(0, windsurf_1.generateWindsurfRules)(parsedContent, baseDir);
(0, claude_1.generateClaudeRules)(parsedContent, baseDir);
}
async function buildRules(options) {
console.log(chalk_1.default.blue("🚀 Agent Rules Builder"));
// -f와 -r 옵션 동시 사용 체크
if (options.file && options.recursive) {
console.error(chalk_1.default.red.bold("❌ 오류: -f(--file)와 -r(--recursive) 옵션은 동시에 사용할 수 없습니다"));
console.log(chalk_1.default.yellow("\n💡 사용법:"));
console.log(chalk_1.default.gray("특정 파일 처리: agent-rules build -f YOUR_FILE.md"));
console.log(chalk_1.default.gray("재귀 처리: agent-rules build -r"));
process.exit(1);
}
try {
if (options.recursive) {
const startDir = process.cwd();
console.log(chalk_1.default.gray(`재귀 탐색 시작: ${startDir}`));
const agentRulesFiles = findAgentRulesFiles(startDir);
if (agentRulesFiles.length === 0) {
console.log(chalk_1.default.yellow("⚠️ AGENTS.md 파일을 찾을 수 없습니다"));
return;
}
console.log(chalk_1.default.yellow(`📝 ${agentRulesFiles.length}개 위치에서 AGENTS.md 발견\n`));
for (const filePath of agentRulesFiles) {
const relativePath = path.relative(startDir, filePath) || ".";
console.log(chalk_1.default.cyan(`📁 /${relativePath}`));
processRulesFile(path.join(filePath, "AGENTS.md"), false);
console.log(chalk_1.default.green(` ✅ Cursor 규칙 생성 완료`));
console.log(chalk_1.default.green(` ✅ Windsurf 규칙 생성 완료`));
console.log(chalk_1.default.green(` ✅ Claude 규칙 생성 완료`));
console.log(""); // 위치 간 구분
}
console.log("========================================");
console.log(chalk_1.default.green.bold(`🎉 ${agentRulesFiles.length}개 위치에서 모든 규칙 파일이 생성되었습니다!`));
}
else {
const filePath = options.file || (0, parser_1.getDefaultRulesFilePath)();
const baseDir = path.dirname(filePath);
console.log(chalk_1.default.gray(`입력 파일: ${filePath}`));
console.log(chalk_1.default.gray(`출력 디렉토리: ${baseDir}`));
console.log(chalk_1.default.yellow("📝 파일 파싱 중..."));
const parsedContent = (0, parser_1.parseAgentRulesFile)(filePath);
console.log(chalk_1.default.yellow("🔄 변환 중..."));
(0, cursor_1.generateCursorRules)(parsedContent, baseDir);
console.log(chalk_1.default.green(`✅ Cursor 규칙 생성 완료`));
(0, windsurf_1.generateWindsurfRules)(parsedContent, baseDir);
console.log(chalk_1.default.green(`✅ Windsurf 규칙 생성 완료`));
(0, claude_1.generateClaudeRules)(parsedContent, baseDir);
console.log(chalk_1.default.green(`✅ Claude 규칙 생성 완료`));
console.log(chalk_1.default.green.bold("\n🎉 모든 규칙 파일이 성공적으로 생성되었습니다!"));
}
}
catch (error) {
console.error(chalk_1.default.red.bold("❌ 오류 발생:"));
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
if (error instanceof Error &&
error.message.includes("파일을 찾을 수 없습니다")) {
console.log(chalk_1.default.yellow("\n💡 사용법:"));
console.log(chalk_1.default.gray("1. AGENTS.md 파일을 생성하세요"));
console.log(chalk_1.default.gray("2. agent-rules build 명령어를 실행하세요"));
console.log(chalk_1.default.gray("3. 또는 agent-rules build --file YOUR_FILE.md로 다른 파일을 지정하세요"));
}
process.exit(1);
}
}
//# sourceMappingURL=build.js.map