creatrip-agent-rules-builder
Version:
Unified converter for AI coding agent rules across Cursor, Windsurf, and Claude
196 lines • 8.97 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCICommand = createCICommand;
const commander_1 = require("commander");
const chalk_1 = __importDefault(require("chalk"));
const verifiers_1 = require("../verifiers");
const build_1 = require("../build");
function createCICommand() {
const command = new commander_1.Command("ci");
command
.description("스마트 동기화: 자동으로 검증하고 필요시 빌드 실행")
.option("-r, --recursive", "하위 디렉토리를 재귀적으로 처리")
.option("--json", "JSON 형식으로 결과 출력")
.action(async (options) => {
const isRecursive = options.recursive || false;
const isJson = options.json || false;
try {
const result = await runCI(isRecursive, isJson);
if (isJson) {
console.log(JSON.stringify(result, null, 2));
}
process.exit(result.status === "pass" ? 0 : 1);
}
catch (error) {
if (!isJson) {
console.error(chalk_1.default.red(`오류: ${error instanceof Error ? error.message : "알 수 없는 오류"}`));
}
process.exit(1);
}
});
return command;
}
async function runCI(isRecursive, isJson) {
const rootPath = process.cwd();
if (!isJson) {
console.log(chalk_1.default.blue("🔍 일관성 검증 중..."));
}
// 1단계: 검증
const verifyResult = await (0, verifiers_1.verifyAgents)(rootPath, "json", isRecursive);
const ciResult = {
status: "pass",
summary: {
total: 0,
synced: 0,
autoBuild: 0,
needsReview: 0,
},
message: "",
};
const needsReviewList = [];
// 각 위치별로 처리
for (const location of verifyResult.locations) {
ciResult.summary.total++;
if (location.status === "pass") {
// 이미 동기화됨
ciResult.summary.synced++;
if (!isJson) {
const relativePath = location.path.replace(rootPath, "") || "/";
if (isRecursive) {
console.log(chalk_1.default.green(`📁 ${relativePath}`));
console.log(chalk_1.default.green(" ✅ 동기화됨"));
}
}
}
else {
// 패턴에 따라 처리
switch (location.diagnosis?.pattern) {
case "all_outdated":
// 자동 빌드 실행
if (!isJson) {
const relativePath = location.path.replace(rootPath, "") || "/";
if (isRecursive) {
console.log(chalk_1.default.cyan(`📁 ${relativePath}`));
console.log(chalk_1.default.yellow(" ⚠️ 오래됨 → 자동 빌드"));
}
else {
console.log(chalk_1.default.yellow("⚠️ 모든 파일이 오래됨 (AGENTS.md가 더 최신)"));
console.log(chalk_1.default.blue("🔨 자동으로 빌드를 실행합니다..."));
}
}
// 빌드 실행
await buildRulesForLocation(location.path, isJson);
ciResult.summary.autoBuild++;
if (!isJson) {
if (isRecursive) {
console.log(chalk_1.default.green(" ✅ 빌드 완료"));
}
else {
console.log(chalk_1.default.green("✅ 빌드 완료 - 모든 파일이 동기화되었습니다"));
}
}
break;
case "single_diverged":
case "multiple_diverged":
// 수동 검토 필요
ciResult.status = "fail";
ciResult.summary.needsReview++;
const relativePath = location.path.replace(rootPath, "") || "/";
needsReviewList.push({
path: relativePath,
issue: location.diagnosis.pattern,
files: location.diagnosis.diverged,
});
if (!isJson) {
if (isRecursive) {
console.log(chalk_1.default.red(`📁 ${relativePath}`));
if (location.diagnosis.pattern === "single_diverged") {
console.log(chalk_1.default.red(` ❌ ${location.diagnosis.diverged?.[0]} 파일 수동 편집 감지`));
}
else {
console.log(chalk_1.default.red(` ❌ 여러 파일 수동 편집 감지`));
}
}
else {
if (location.diagnosis.pattern === "single_diverged") {
console.log(chalk_1.default.red(`❌ ${location.diagnosis.diverged?.[0]} 파일에 수동 편집 감지`));
console.log("");
console.log(chalk_1.default.yellow("수동 검토가 필요합니다:"));
console.log(chalk_1.default.yellow(`- ${location.diagnosis.diverged?.[0]} 파일이 직접 수정되었습니다`));
console.log(chalk_1.default.yellow("- AGENTS.md를 수정하려던 것이 아닌지 확인하세요"));
}
else {
console.log(chalk_1.default.red("❌ 여러 파일에서 수동 편집 감지"));
console.log("");
console.log(chalk_1.default.yellow("수동 검토가 필요합니다:"));
location.diagnosis.diverged?.forEach((file) => {
console.log(chalk_1.default.yellow(`- ${file} 파일이 직접 수정됨`));
});
}
}
}
break;
}
}
if (!isJson && isRecursive) {
console.log(""); // 위치 간 구분
}
}
// 결과 메시지 설정
if (ciResult.status === "pass") {
if (ciResult.summary.autoBuild > 0) {
ciResult.message = `Auto-build completed for ${ciResult.summary.autoBuild} location(s)`;
}
else {
ciResult.message = "All files are already synchronized";
}
if (!isJson) {
if (isRecursive) {
console.log("========================================");
console.log(chalk_1.default.green(`📊 요약: ${ciResult.summary.total}개 위치 모두 동기화됨`));
if (ciResult.summary.autoBuild > 0) {
console.log(chalk_1.default.green(` (${ciResult.summary.autoBuild}개 자동 빌드됨)`));
}
}
else if (ciResult.summary.autoBuild === 0) {
console.log(chalk_1.default.green("✅ 이미 모든 파일이 동기화되어 있습니다"));
}
}
}
else {
ciResult.needsReview = needsReviewList;
ciResult.message = `Manual review required for ${ciResult.summary.needsReview} location(s)`;
if (!isJson && isRecursive) {
console.log("========================================");
console.log(chalk_1.default.yellow(`📊 요약: ${ciResult.summary.total}개 위치 중 ${ciResult.summary.needsReview}개 수동 검토 필요`));
console.log(chalk_1.default.red("❌ CI 실패: 수동 검토가 필요한 파일이 있습니다"));
console.log("");
console.log(chalk_1.default.yellow("문제 위치:"));
needsReviewList.forEach((item) => {
console.log(chalk_1.default.yellow(`- ${item.path}: ${item.files?.join(", ")} 파일 수동 편집`));
});
}
}
return ciResult;
}
async function buildRulesForLocation(locationPath, isJson) {
// build.ts의 로직 재사용
const options = {
file: `${locationPath}/AGENTS.md`,
};
// 빌드 실행 (출력 억제)
const originalLog = console.log;
if (isJson) {
console.log = () => { }; // JSON 모드에서는 출력 억제
}
try {
await (0, build_1.buildRules)(options);
}
finally {
console.log = originalLog;
}
}
//# sourceMappingURL=ci.js.map