rulesync 0.54.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +401 -210
- package/dist/index.js +399 -208
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1012,6 +1012,36 @@ function mergeWithCliOptions(config, cliOptions) {
|
|
|
1012
1012
|
return merged;
|
|
1013
1013
|
}
|
|
1014
1014
|
|
|
1015
|
+
// src/utils/error.ts
|
|
1016
|
+
function getErrorMessage(error) {
|
|
1017
|
+
return error instanceof Error ? error.message : String(error);
|
|
1018
|
+
}
|
|
1019
|
+
function formatErrorWithContext(error, context) {
|
|
1020
|
+
const errorMessage = getErrorMessage(error);
|
|
1021
|
+
return `${context}: ${errorMessage}`;
|
|
1022
|
+
}
|
|
1023
|
+
function createErrorResult(error, context) {
|
|
1024
|
+
const errorMessage = context ? formatErrorWithContext(error, context) : getErrorMessage(error);
|
|
1025
|
+
return {
|
|
1026
|
+
success: false,
|
|
1027
|
+
error: errorMessage
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
function createSuccessResult(result) {
|
|
1031
|
+
return {
|
|
1032
|
+
success: true,
|
|
1033
|
+
result
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
async function safeAsyncOperation(operation, errorContext) {
|
|
1037
|
+
try {
|
|
1038
|
+
const result = await operation();
|
|
1039
|
+
return createSuccessResult(result);
|
|
1040
|
+
} catch (error) {
|
|
1041
|
+
return createErrorResult(error, errorContext);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1015
1045
|
// src/utils/file.ts
|
|
1016
1046
|
var import_promises2 = require("fs/promises");
|
|
1017
1047
|
var import_node_path = require("path");
|
|
@@ -1022,6 +1052,9 @@ async function ensureDir(dirPath) {
|
|
|
1022
1052
|
await (0, import_promises2.mkdir)(dirPath, { recursive: true });
|
|
1023
1053
|
}
|
|
1024
1054
|
}
|
|
1055
|
+
function resolvePath(relativePath, baseDir) {
|
|
1056
|
+
return baseDir ? (0, import_node_path.join)(baseDir, relativePath) : relativePath;
|
|
1057
|
+
}
|
|
1025
1058
|
async function readFileContent(filepath) {
|
|
1026
1059
|
return (0, import_promises2.readFile)(filepath, "utf-8");
|
|
1027
1060
|
}
|
|
@@ -1949,7 +1982,7 @@ function filterIgnoredFiles(files, ignorePatterns) {
|
|
|
1949
1982
|
|
|
1950
1983
|
// src/generators/rules/shared-helpers.ts
|
|
1951
1984
|
function resolveOutputDir(config, tool, baseDir) {
|
|
1952
|
-
return
|
|
1985
|
+
return resolvePath(config.outputPaths[tool], baseDir);
|
|
1953
1986
|
}
|
|
1954
1987
|
function createOutputsArray() {
|
|
1955
1988
|
return [];
|
|
@@ -1976,7 +2009,7 @@ async function generateRulesConfig(rules, config, generatorConfig, baseDir) {
|
|
|
1976
2009
|
}
|
|
1977
2010
|
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
1978
2011
|
if (ignorePatterns.patterns.length > 0) {
|
|
1979
|
-
const ignorePath =
|
|
2012
|
+
const ignorePath = resolvePath(generatorConfig.ignoreFileName, baseDir);
|
|
1980
2013
|
const ignoreContent = generateIgnoreFile2(ignorePatterns.patterns, generatorConfig.tool);
|
|
1981
2014
|
outputs.push({
|
|
1982
2015
|
tool: generatorConfig.tool,
|
|
@@ -1994,7 +2027,10 @@ async function generateComplexRules(rules, config, generatorConfig, baseDir) {
|
|
|
1994
2027
|
if (generatorConfig.generateDetailContent && generatorConfig.detailSubDir) {
|
|
1995
2028
|
for (const rule of detailRules) {
|
|
1996
2029
|
const content = generatorConfig.generateDetailContent(rule);
|
|
1997
|
-
const filepath =
|
|
2030
|
+
const filepath = resolvePath(
|
|
2031
|
+
(0, import_node_path5.join)(generatorConfig.detailSubDir, `${rule.filename}.md`),
|
|
2032
|
+
baseDir
|
|
2033
|
+
);
|
|
1998
2034
|
outputs.push({
|
|
1999
2035
|
tool: generatorConfig.tool,
|
|
2000
2036
|
filepath,
|
|
@@ -2004,7 +2040,7 @@ async function generateComplexRules(rules, config, generatorConfig, baseDir) {
|
|
|
2004
2040
|
}
|
|
2005
2041
|
if (generatorConfig.generateRootContent && generatorConfig.rootFilePath) {
|
|
2006
2042
|
const rootContent = generatorConfig.generateRootContent(rootRule, detailRules, baseDir);
|
|
2007
|
-
const rootFilepath =
|
|
2043
|
+
const rootFilepath = resolvePath(generatorConfig.rootFilePath, baseDir);
|
|
2008
2044
|
outputs.push({
|
|
2009
2045
|
tool: generatorConfig.tool,
|
|
2010
2046
|
filepath: rootFilepath,
|
|
@@ -2013,7 +2049,7 @@ async function generateComplexRules(rules, config, generatorConfig, baseDir) {
|
|
|
2013
2049
|
}
|
|
2014
2050
|
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
2015
2051
|
if (ignorePatterns.patterns.length > 0) {
|
|
2016
|
-
const ignorePath =
|
|
2052
|
+
const ignorePath = resolvePath(generatorConfig.ignoreFileName, baseDir);
|
|
2017
2053
|
const ignoreContent = generateIgnoreFile2(ignorePatterns.patterns, generatorConfig.tool);
|
|
2018
2054
|
outputs.push({
|
|
2019
2055
|
tool: generatorConfig.tool,
|
|
@@ -2118,30 +2154,22 @@ function generateLegacyGuidelinesFile(allRules) {
|
|
|
2118
2154
|
// src/generators/rules/claudecode.ts
|
|
2119
2155
|
var import_node_path7 = require("path");
|
|
2120
2156
|
async function generateClaudecodeConfig(rules, config, baseDir) {
|
|
2121
|
-
const
|
|
2122
|
-
const rootRules = rules.filter((r) => r.frontmatter.root === true);
|
|
2123
|
-
const detailRules = rules.filter((r) => r.frontmatter.root === false);
|
|
2124
|
-
const claudeMdContent = generateClaudeMarkdown(rootRules, detailRules);
|
|
2125
|
-
const claudeOutputDir = baseDir ? (0, import_node_path7.join)(baseDir, config.outputPaths.claudecode) : config.outputPaths.claudecode;
|
|
2126
|
-
outputs.push({
|
|
2157
|
+
const generatorConfig = {
|
|
2127
2158
|
tool: "claudecode",
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
await updateClaudeSettings(settingsPath, ignorePatterns.patterns);
|
|
2143
|
-
}
|
|
2144
|
-
return outputs;
|
|
2159
|
+
fileExtension: ".md",
|
|
2160
|
+
ignoreFileName: ".aiignore",
|
|
2161
|
+
generateContent: generateMemoryFile,
|
|
2162
|
+
generateRootContent: (rootRule, detailRules) => generateClaudeMarkdown(rootRule ? [rootRule] : [], detailRules),
|
|
2163
|
+
rootFilePath: "CLAUDE.md",
|
|
2164
|
+
generateDetailContent: generateMemoryFile,
|
|
2165
|
+
detailSubDir: ".claude/memories",
|
|
2166
|
+
updateAdditionalConfig: async (ignorePatterns, baseDir2) => {
|
|
2167
|
+
const settingsPath = resolvePath((0, import_node_path7.join)(".claude", "settings.json"), baseDir2);
|
|
2168
|
+
await updateClaudeSettings(settingsPath, ignorePatterns);
|
|
2169
|
+
return [];
|
|
2170
|
+
}
|
|
2171
|
+
};
|
|
2172
|
+
return generateComplexRules(rules, config, generatorConfig, baseDir);
|
|
2145
2173
|
}
|
|
2146
2174
|
function generateClaudeMarkdown(rootRules, detailRules) {
|
|
2147
2175
|
const lines = [];
|
|
@@ -2201,54 +2229,222 @@ async function updateClaudeSettings(settingsPath, ignorePatterns) {
|
|
|
2201
2229
|
console.log(`\u2705 Updated Claude Code settings: ${settingsPath}`);
|
|
2202
2230
|
}
|
|
2203
2231
|
|
|
2204
|
-
// src/generators/rules/
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2232
|
+
// src/generators/rules/generator-registry.ts
|
|
2233
|
+
var import_node_path8 = require("path");
|
|
2234
|
+
var GENERATOR_REGISTRY = {
|
|
2235
|
+
// Simple generators - generate one file per rule
|
|
2236
|
+
cline: {
|
|
2237
|
+
type: "simple",
|
|
2238
|
+
tool: "cline",
|
|
2239
|
+
fileExtension: ".md",
|
|
2240
|
+
ignoreFileName: ".clineignore",
|
|
2241
|
+
generateContent: (rule) => rule.content.trim()
|
|
2242
|
+
},
|
|
2243
|
+
roo: {
|
|
2244
|
+
type: "simple",
|
|
2245
|
+
tool: "roo",
|
|
2246
|
+
fileExtension: ".md",
|
|
2247
|
+
ignoreFileName: ".rooignore",
|
|
2248
|
+
generateContent: (rule) => rule.content.trim()
|
|
2249
|
+
},
|
|
2250
|
+
kiro: {
|
|
2251
|
+
type: "simple",
|
|
2252
|
+
tool: "kiro",
|
|
2253
|
+
fileExtension: ".md",
|
|
2254
|
+
ignoreFileName: ".kiroignore",
|
|
2255
|
+
generateContent: (rule) => rule.content.trim()
|
|
2256
|
+
},
|
|
2257
|
+
augmentcode: {
|
|
2258
|
+
type: "simple",
|
|
2259
|
+
tool: "augmentcode",
|
|
2260
|
+
fileExtension: ".md",
|
|
2261
|
+
ignoreFileName: ".aiignore",
|
|
2262
|
+
generateContent: (rule) => rule.content.trim()
|
|
2263
|
+
},
|
|
2264
|
+
"augmentcode-legacy": {
|
|
2265
|
+
type: "simple",
|
|
2266
|
+
tool: "augmentcode-legacy",
|
|
2267
|
+
fileExtension: ".md",
|
|
2268
|
+
ignoreFileName: ".aiignore",
|
|
2269
|
+
generateContent: (rule) => rule.content.trim()
|
|
2270
|
+
},
|
|
2271
|
+
// Complex generators with custom content formatting
|
|
2272
|
+
copilot: {
|
|
2273
|
+
type: "simple",
|
|
2274
|
+
tool: "copilot",
|
|
2275
|
+
fileExtension: ".instructions.md",
|
|
2276
|
+
ignoreFileName: ".copilotignore",
|
|
2277
|
+
generateContent: (rule) => {
|
|
2278
|
+
const lines = [];
|
|
2279
|
+
lines.push("---");
|
|
2280
|
+
lines.push(`description: "${rule.frontmatter.description}"`);
|
|
2281
|
+
if (rule.frontmatter.globs.length > 0) {
|
|
2282
|
+
lines.push(`applyTo: "${rule.frontmatter.globs.join(", ")}"`);
|
|
2283
|
+
} else {
|
|
2284
|
+
lines.push('applyTo: "**"');
|
|
2285
|
+
}
|
|
2286
|
+
lines.push("---");
|
|
2287
|
+
lines.push(rule.content);
|
|
2288
|
+
return lines.join("\n");
|
|
2214
2289
|
},
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
}
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2290
|
+
pathResolver: (rule, outputDir) => {
|
|
2291
|
+
const baseFilename = rule.filename.replace(/\.md$/, "");
|
|
2292
|
+
return (0, import_node_path8.join)(outputDir, `${baseFilename}.instructions.md`);
|
|
2293
|
+
}
|
|
2294
|
+
},
|
|
2295
|
+
cursor: {
|
|
2296
|
+
type: "simple",
|
|
2297
|
+
tool: "cursor",
|
|
2298
|
+
fileExtension: ".md",
|
|
2299
|
+
ignoreFileName: ".cursorignore",
|
|
2300
|
+
generateContent: (rule) => rule.content.trim()
|
|
2301
|
+
},
|
|
2302
|
+
codexcli: {
|
|
2303
|
+
type: "simple",
|
|
2222
2304
|
tool: "codexcli",
|
|
2223
2305
|
fileExtension: ".md",
|
|
2224
2306
|
ignoreFileName: ".codexignore",
|
|
2225
|
-
generateContent:
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2307
|
+
generateContent: (rule) => rule.content.trim()
|
|
2308
|
+
},
|
|
2309
|
+
// Complex generators with root + detail pattern
|
|
2310
|
+
claudecode: {
|
|
2311
|
+
type: "complex",
|
|
2312
|
+
tool: "claudecode",
|
|
2313
|
+
fileExtension: ".md",
|
|
2314
|
+
ignoreFileName: ".aiignore",
|
|
2315
|
+
generateContent: (rule) => {
|
|
2316
|
+
const lines = [];
|
|
2317
|
+
if (rule.frontmatter.description) {
|
|
2318
|
+
lines.push(`# ${rule.frontmatter.description}
|
|
2319
|
+
`);
|
|
2229
2320
|
}
|
|
2230
|
-
|
|
2321
|
+
lines.push(rule.content.trim());
|
|
2322
|
+
return lines.join("\n");
|
|
2231
2323
|
}
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
}
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2324
|
+
// NOTE: Claude Code specific logic is handled in the actual generator file
|
|
2325
|
+
// due to complex settings.json manipulation requirements
|
|
2326
|
+
},
|
|
2327
|
+
geminicli: {
|
|
2328
|
+
type: "complex",
|
|
2329
|
+
tool: "geminicli",
|
|
2330
|
+
fileExtension: ".md",
|
|
2331
|
+
ignoreFileName: ".aiexclude",
|
|
2332
|
+
generateContent: (rule) => {
|
|
2333
|
+
const lines = [];
|
|
2334
|
+
if (rule.frontmatter.description) {
|
|
2335
|
+
lines.push(`# ${rule.frontmatter.description}
|
|
2336
|
+
`);
|
|
2337
|
+
}
|
|
2338
|
+
lines.push(rule.content.trim());
|
|
2339
|
+
return lines.join("\n");
|
|
2241
2340
|
}
|
|
2341
|
+
// Complex generation handled by existing generator
|
|
2342
|
+
},
|
|
2343
|
+
junie: {
|
|
2344
|
+
type: "complex",
|
|
2345
|
+
tool: "junie",
|
|
2346
|
+
fileExtension: ".md",
|
|
2347
|
+
ignoreFileName: ".aiignore",
|
|
2348
|
+
generateContent: (rule) => {
|
|
2349
|
+
const lines = [];
|
|
2350
|
+
if (rule.frontmatter.description) {
|
|
2351
|
+
lines.push(`# ${rule.frontmatter.description}
|
|
2352
|
+
`);
|
|
2353
|
+
}
|
|
2354
|
+
lines.push(rule.content.trim());
|
|
2355
|
+
return lines.join("\n");
|
|
2356
|
+
}
|
|
2357
|
+
// Complex generation handled by existing generator
|
|
2242
2358
|
}
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2359
|
+
};
|
|
2360
|
+
async function generateFromRegistry(tool, rules, config, baseDir) {
|
|
2361
|
+
const generatorConfig = GENERATOR_REGISTRY[tool];
|
|
2362
|
+
if (!generatorConfig) {
|
|
2363
|
+
throw new Error(`No generator configuration found for tool: ${tool}`);
|
|
2364
|
+
}
|
|
2365
|
+
if (generatorConfig.type === "simple") {
|
|
2366
|
+
const ruleConfig = {
|
|
2367
|
+
tool: generatorConfig.tool,
|
|
2368
|
+
fileExtension: generatorConfig.fileExtension,
|
|
2369
|
+
ignoreFileName: generatorConfig.ignoreFileName,
|
|
2370
|
+
generateContent: generatorConfig.generateContent,
|
|
2371
|
+
...generatorConfig.pathResolver && { pathResolver: generatorConfig.pathResolver }
|
|
2372
|
+
};
|
|
2373
|
+
return generateRulesConfig(rules, config, ruleConfig, baseDir);
|
|
2374
|
+
} else {
|
|
2375
|
+
const enhancedConfig = {
|
|
2376
|
+
tool: generatorConfig.tool,
|
|
2377
|
+
fileExtension: generatorConfig.fileExtension,
|
|
2378
|
+
ignoreFileName: generatorConfig.ignoreFileName,
|
|
2379
|
+
generateContent: generatorConfig.generateContent,
|
|
2380
|
+
...generatorConfig.generateRootContent && {
|
|
2381
|
+
generateRootContent: generatorConfig.generateRootContent
|
|
2382
|
+
},
|
|
2383
|
+
...generatorConfig.rootFilePath && { rootFilePath: generatorConfig.rootFilePath },
|
|
2384
|
+
...generatorConfig.generateDetailContent && {
|
|
2385
|
+
generateDetailContent: generatorConfig.generateDetailContent
|
|
2386
|
+
},
|
|
2387
|
+
...generatorConfig.detailSubDir && { detailSubDir: generatorConfig.detailSubDir },
|
|
2388
|
+
...generatorConfig.updateAdditionalConfig && {
|
|
2389
|
+
updateAdditionalConfig: generatorConfig.updateAdditionalConfig
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2392
|
+
return generateComplexRules(rules, config, enhancedConfig, baseDir);
|
|
2246
2393
|
}
|
|
2247
|
-
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
// src/generators/rules/cline.ts
|
|
2397
|
+
async function generateClineConfig(rules, config, baseDir) {
|
|
2398
|
+
return generateFromRegistry("cline", rules, config, baseDir);
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
// src/generators/rules/codexcli.ts
|
|
2402
|
+
async function generateCodexConfig(rules, config, baseDir) {
|
|
2403
|
+
const outputs = [];
|
|
2404
|
+
if (rules.length === 0) {
|
|
2405
|
+
return outputs;
|
|
2406
|
+
}
|
|
2407
|
+
const sortedRules = [...rules].sort((a, b) => {
|
|
2408
|
+
if (a.frontmatter.root === true && b.frontmatter.root !== true) return -1;
|
|
2409
|
+
if (a.frontmatter.root !== true && b.frontmatter.root === true) return 1;
|
|
2410
|
+
return 0;
|
|
2411
|
+
});
|
|
2412
|
+
const concatenatedContent = generateConcatenatedCodexContent(sortedRules);
|
|
2413
|
+
if (concatenatedContent.trim()) {
|
|
2414
|
+
const outputDir = resolveOutputDir(config, "codexcli", baseDir);
|
|
2415
|
+
const filepath = `${outputDir}/codex.md`;
|
|
2416
|
+
outputs.push({
|
|
2417
|
+
tool: "codexcli",
|
|
2418
|
+
filepath,
|
|
2419
|
+
content: concatenatedContent
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
2423
|
+
if (ignorePatterns.patterns.length > 0) {
|
|
2424
|
+
const ignorePath = resolvePath(".codexignore", baseDir);
|
|
2425
|
+
const ignoreContent = generateIgnoreFile2(ignorePatterns.patterns, "codexcli");
|
|
2426
|
+
outputs.push({
|
|
2427
|
+
tool: "codexcli",
|
|
2428
|
+
filepath: ignorePath,
|
|
2429
|
+
content: ignoreContent
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2432
|
+
return outputs;
|
|
2433
|
+
}
|
|
2434
|
+
function generateConcatenatedCodexContent(rules) {
|
|
2435
|
+
const sections = [];
|
|
2436
|
+
for (const rule of rules) {
|
|
2437
|
+
const content = rule.content.trim();
|
|
2438
|
+
if (!content) {
|
|
2439
|
+
continue;
|
|
2440
|
+
}
|
|
2441
|
+
sections.push(content);
|
|
2442
|
+
}
|
|
2443
|
+
return sections.join("\n\n---\n\n");
|
|
2248
2444
|
}
|
|
2249
2445
|
|
|
2250
2446
|
// src/generators/rules/copilot.ts
|
|
2251
|
-
var
|
|
2447
|
+
var import_node_path9 = require("path");
|
|
2252
2448
|
async function generateCopilotConfig(rules, config, baseDir) {
|
|
2253
2449
|
return generateComplexRulesConfig(
|
|
2254
2450
|
rules,
|
|
@@ -2260,7 +2456,7 @@ async function generateCopilotConfig(rules, config, baseDir) {
|
|
|
2260
2456
|
generateContent: generateCopilotMarkdown,
|
|
2261
2457
|
getOutputPath: (rule, outputDir) => {
|
|
2262
2458
|
const baseFilename = rule.filename.replace(/\.md$/, "");
|
|
2263
|
-
return (0,
|
|
2459
|
+
return (0, import_node_path9.join)(outputDir, `${baseFilename}.instructions.md`);
|
|
2264
2460
|
}
|
|
2265
2461
|
},
|
|
2266
2462
|
baseDir
|
|
@@ -2281,7 +2477,7 @@ function generateCopilotMarkdown(rule) {
|
|
|
2281
2477
|
}
|
|
2282
2478
|
|
|
2283
2479
|
// src/generators/rules/cursor.ts
|
|
2284
|
-
var
|
|
2480
|
+
var import_node_path10 = require("path");
|
|
2285
2481
|
async function generateCursorConfig(rules, config, baseDir) {
|
|
2286
2482
|
return generateComplexRulesConfig(
|
|
2287
2483
|
rules,
|
|
@@ -2292,7 +2488,7 @@ async function generateCursorConfig(rules, config, baseDir) {
|
|
|
2292
2488
|
ignoreFileName: ".cursorignore",
|
|
2293
2489
|
generateContent: generateCursorMarkdown,
|
|
2294
2490
|
getOutputPath: (rule, outputDir) => {
|
|
2295
|
-
return (0,
|
|
2491
|
+
return (0, import_node_path10.join)(outputDir, `${rule.filename}.mdc`);
|
|
2296
2492
|
}
|
|
2297
2493
|
},
|
|
2298
2494
|
baseDir
|
|
@@ -2421,38 +2617,13 @@ function generateGuidelinesMarkdown(rootRule, detailRules) {
|
|
|
2421
2617
|
}
|
|
2422
2618
|
|
|
2423
2619
|
// src/generators/rules/kiro.ts
|
|
2424
|
-
var import_node_path10 = require("path");
|
|
2425
2620
|
async function generateKiroConfig(rules, config, baseDir) {
|
|
2426
|
-
|
|
2427
|
-
for (const rule of rules) {
|
|
2428
|
-
const content = generateKiroMarkdown(rule);
|
|
2429
|
-
const outputDir = baseDir ? (0, import_node_path10.join)(baseDir, config.outputPaths.kiro) : config.outputPaths.kiro;
|
|
2430
|
-
const filepath = (0, import_node_path10.join)(outputDir, `${rule.filename}.md`);
|
|
2431
|
-
outputs.push({
|
|
2432
|
-
tool: "kiro",
|
|
2433
|
-
filepath,
|
|
2434
|
-
content
|
|
2435
|
-
});
|
|
2436
|
-
}
|
|
2437
|
-
return outputs;
|
|
2438
|
-
}
|
|
2439
|
-
function generateKiroMarkdown(rule) {
|
|
2440
|
-
return rule.content.trim();
|
|
2621
|
+
return generateFromRegistry("kiro", rules, config, baseDir);
|
|
2441
2622
|
}
|
|
2442
2623
|
|
|
2443
2624
|
// src/generators/rules/roo.ts
|
|
2444
2625
|
async function generateRooConfig(rules, config, baseDir) {
|
|
2445
|
-
return
|
|
2446
|
-
rules,
|
|
2447
|
-
config,
|
|
2448
|
-
{
|
|
2449
|
-
tool: "roo",
|
|
2450
|
-
fileExtension: ".md",
|
|
2451
|
-
ignoreFileName: ".rooignore",
|
|
2452
|
-
generateContent: (rule) => rule.content.trim()
|
|
2453
|
-
},
|
|
2454
|
-
baseDir
|
|
2455
|
-
);
|
|
2626
|
+
return generateFromRegistry("roo", rules, config, baseDir);
|
|
2456
2627
|
}
|
|
2457
2628
|
|
|
2458
2629
|
// src/core/generator.ts
|
|
@@ -3035,7 +3206,7 @@ ${linesToAdd.join("\n")}
|
|
|
3035
3206
|
};
|
|
3036
3207
|
|
|
3037
3208
|
// src/core/importer.ts
|
|
3038
|
-
var
|
|
3209
|
+
var import_node_path19 = require("path");
|
|
3039
3210
|
var import_gray_matter5 = __toESM(require("gray-matter"), 1);
|
|
3040
3211
|
|
|
3041
3212
|
// src/parsers/augmentcode.ts
|
|
@@ -3061,36 +3232,63 @@ function addRules(result, rules) {
|
|
|
3061
3232
|
}
|
|
3062
3233
|
result.rules.push(...rules);
|
|
3063
3234
|
}
|
|
3064
|
-
function handleParseError(error, context) {
|
|
3065
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3066
|
-
return `${context}: ${errorMessage}`;
|
|
3067
|
-
}
|
|
3068
3235
|
async function safeReadFile(operation, errorContext) {
|
|
3069
3236
|
try {
|
|
3070
3237
|
const result = await operation();
|
|
3071
|
-
return
|
|
3238
|
+
return createSuccessResult(result);
|
|
3072
3239
|
} catch (error) {
|
|
3073
|
-
return
|
|
3074
|
-
success: false,
|
|
3075
|
-
error: handleParseError(error, errorContext)
|
|
3076
|
-
};
|
|
3240
|
+
return createErrorResult(error, errorContext);
|
|
3077
3241
|
}
|
|
3078
3242
|
}
|
|
3079
3243
|
|
|
3080
3244
|
// src/parsers/augmentcode.ts
|
|
3081
3245
|
async function parseAugmentcodeConfiguration(baseDir = process.cwd()) {
|
|
3246
|
+
return parseUnifiedAugmentcode(baseDir, {
|
|
3247
|
+
rulesDir: ".augment/rules",
|
|
3248
|
+
targetName: "augmentcode",
|
|
3249
|
+
filenamePrefix: "augmentcode"
|
|
3250
|
+
});
|
|
3251
|
+
}
|
|
3252
|
+
async function parseAugmentcodeLegacyConfiguration(baseDir = process.cwd()) {
|
|
3253
|
+
return parseUnifiedAugmentcode(baseDir, {
|
|
3254
|
+
legacyFilePath: ".augment-guidelines",
|
|
3255
|
+
targetName: "augmentcode-legacy",
|
|
3256
|
+
filenamePrefix: "augmentcode-legacy"
|
|
3257
|
+
});
|
|
3258
|
+
}
|
|
3259
|
+
async function parseUnifiedAugmentcode(baseDir, config) {
|
|
3082
3260
|
const result = createParseResult();
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3261
|
+
if (config.rulesDir) {
|
|
3262
|
+
const rulesDir = (0, import_node_path14.join)(baseDir, config.rulesDir);
|
|
3263
|
+
if (await fileExists(rulesDir)) {
|
|
3264
|
+
const rulesResult = await parseAugmentRules(rulesDir, config);
|
|
3265
|
+
addRules(result, rulesResult.rules);
|
|
3266
|
+
result.errors.push(...rulesResult.errors);
|
|
3267
|
+
} else {
|
|
3268
|
+
addError(
|
|
3269
|
+
result,
|
|
3270
|
+
`No AugmentCode configuration found. Expected ${config.rulesDir} directory.`
|
|
3271
|
+
);
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
if (config.legacyFilePath) {
|
|
3275
|
+
const legacyPath = (0, import_node_path14.join)(baseDir, config.legacyFilePath);
|
|
3276
|
+
if (await fileExists(legacyPath)) {
|
|
3277
|
+
const legacyResult = await parseAugmentGuidelines(legacyPath, config);
|
|
3278
|
+
if (legacyResult.rule) {
|
|
3279
|
+
addRule(result, legacyResult.rule);
|
|
3280
|
+
}
|
|
3281
|
+
result.errors.push(...legacyResult.errors);
|
|
3282
|
+
} else {
|
|
3283
|
+
addError(
|
|
3284
|
+
result,
|
|
3285
|
+
`No AugmentCode legacy configuration found. Expected ${config.legacyFilePath} file.`
|
|
3286
|
+
);
|
|
3287
|
+
}
|
|
3090
3288
|
}
|
|
3091
3289
|
return { rules: result.rules || [], errors: result.errors };
|
|
3092
3290
|
}
|
|
3093
|
-
async function parseAugmentRules(rulesDir) {
|
|
3291
|
+
async function parseAugmentRules(rulesDir, config) {
|
|
3094
3292
|
const rules = [];
|
|
3095
3293
|
const errors = [];
|
|
3096
3294
|
try {
|
|
@@ -3110,7 +3308,7 @@ async function parseAugmentRules(rulesDir) {
|
|
|
3110
3308
|
const filename = (0, import_node_path14.basename)(file, file.endsWith(".mdc") ? ".mdc" : ".md");
|
|
3111
3309
|
const frontmatter = {
|
|
3112
3310
|
root: isRoot,
|
|
3113
|
-
targets: [
|
|
3311
|
+
targets: [config.targetName],
|
|
3114
3312
|
description,
|
|
3115
3313
|
globs: ["**/*"],
|
|
3116
3314
|
// AugmentCode doesn't use specific globs in the same way
|
|
@@ -3119,7 +3317,7 @@ async function parseAugmentRules(rulesDir) {
|
|
|
3119
3317
|
rules.push({
|
|
3120
3318
|
frontmatter,
|
|
3121
3319
|
content: parsed.content.trim(),
|
|
3122
|
-
filename:
|
|
3320
|
+
filename: `${config.filenamePrefix}-${ruleType}-${filename}`,
|
|
3123
3321
|
filepath: filePath
|
|
3124
3322
|
});
|
|
3125
3323
|
} catch (error) {
|
|
@@ -3130,50 +3328,33 @@ async function parseAugmentRules(rulesDir) {
|
|
|
3130
3328
|
}
|
|
3131
3329
|
} catch (error) {
|
|
3132
3330
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3133
|
-
errors.push(`Failed to read .
|
|
3331
|
+
errors.push(`Failed to read ${config.rulesDir || rulesDir} directory: ${errorMessage}`);
|
|
3134
3332
|
}
|
|
3135
3333
|
return { rules, errors };
|
|
3136
3334
|
}
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
if (content.trim()) {
|
|
3161
|
-
const frontmatter = {
|
|
3162
|
-
root: true,
|
|
3163
|
-
// Legacy guidelines become root rules
|
|
3164
|
-
targets: ["augmentcode-legacy"],
|
|
3165
|
-
description: "Legacy AugmentCode guidelines",
|
|
3166
|
-
globs: ["**/*"]
|
|
3167
|
-
};
|
|
3168
|
-
return {
|
|
3169
|
-
frontmatter,
|
|
3170
|
-
content: content.trim(),
|
|
3171
|
-
filename: "augmentcode-legacy-guidelines",
|
|
3172
|
-
filepath: guidelinesPath
|
|
3173
|
-
};
|
|
3174
|
-
}
|
|
3175
|
-
return null;
|
|
3176
|
-
}, "Failed to parse .augment-guidelines");
|
|
3335
|
+
async function parseAugmentGuidelines(guidelinesPath, config) {
|
|
3336
|
+
const parseResult = await safeReadFile(
|
|
3337
|
+
async () => {
|
|
3338
|
+
const content = await readFileContent(guidelinesPath);
|
|
3339
|
+
if (content.trim()) {
|
|
3340
|
+
const frontmatter = {
|
|
3341
|
+
root: true,
|
|
3342
|
+
// Legacy guidelines become root rules
|
|
3343
|
+
targets: [config.targetName],
|
|
3344
|
+
description: "Legacy AugmentCode guidelines",
|
|
3345
|
+
globs: ["**/*"]
|
|
3346
|
+
};
|
|
3347
|
+
return {
|
|
3348
|
+
frontmatter,
|
|
3349
|
+
content: content.trim(),
|
|
3350
|
+
filename: `${config.filenamePrefix}-guidelines`,
|
|
3351
|
+
filepath: guidelinesPath
|
|
3352
|
+
};
|
|
3353
|
+
}
|
|
3354
|
+
return null;
|
|
3355
|
+
},
|
|
3356
|
+
`Failed to parse ${config.legacyFilePath || guidelinesPath}`
|
|
3357
|
+
);
|
|
3177
3358
|
if (parseResult.success) {
|
|
3178
3359
|
return { rule: parseResult.result || null, errors: [] };
|
|
3179
3360
|
} else {
|
|
@@ -3182,33 +3363,36 @@ async function parseAugmentGuidelines(guidelinesPath) {
|
|
|
3182
3363
|
}
|
|
3183
3364
|
|
|
3184
3365
|
// src/parsers/shared-helpers.ts
|
|
3185
|
-
var
|
|
3366
|
+
var import_node_path15 = require("path");
|
|
3186
3367
|
var import_gray_matter3 = __toESM(require("gray-matter"), 1);
|
|
3187
3368
|
async function parseConfigurationFiles(baseDir = process.cwd(), config) {
|
|
3188
3369
|
const errors = [];
|
|
3189
3370
|
const rules = [];
|
|
3190
3371
|
if (config.mainFile) {
|
|
3191
|
-
const
|
|
3372
|
+
const mainFile = config.mainFile;
|
|
3373
|
+
const mainFilePath = resolvePath(mainFile.path, baseDir);
|
|
3192
3374
|
if (await fileExists(mainFilePath)) {
|
|
3193
|
-
|
|
3375
|
+
const result = await safeAsyncOperation(async () => {
|
|
3194
3376
|
const rawContent = await readFileContent(mainFilePath);
|
|
3195
3377
|
let content;
|
|
3196
3378
|
let frontmatter;
|
|
3197
|
-
if (
|
|
3379
|
+
if (mainFile.useFrontmatter) {
|
|
3198
3380
|
const parsed = (0, import_gray_matter3.default)(rawContent);
|
|
3199
3381
|
content = parsed.content.trim();
|
|
3382
|
+
const parsedFrontmatter = parsed.data;
|
|
3200
3383
|
frontmatter = {
|
|
3201
|
-
root: false,
|
|
3384
|
+
root: mainFile.isRoot ?? false,
|
|
3202
3385
|
targets: [config.tool],
|
|
3203
|
-
description:
|
|
3204
|
-
globs: ["**/*"]
|
|
3386
|
+
description: parsedFrontmatter.description || mainFile.description,
|
|
3387
|
+
globs: Array.isArray(parsedFrontmatter.globs) ? parsedFrontmatter.globs : ["**/*"],
|
|
3388
|
+
...parsedFrontmatter.tags && { tags: parsedFrontmatter.tags }
|
|
3205
3389
|
};
|
|
3206
3390
|
} else {
|
|
3207
3391
|
content = rawContent.trim();
|
|
3208
3392
|
frontmatter = {
|
|
3209
|
-
root: false,
|
|
3393
|
+
root: mainFile.isRoot ?? false,
|
|
3210
3394
|
targets: [config.tool],
|
|
3211
|
-
description:
|
|
3395
|
+
description: mainFile.description,
|
|
3212
3396
|
globs: ["**/*"]
|
|
3213
3397
|
};
|
|
3214
3398
|
}
|
|
@@ -3216,43 +3400,52 @@ async function parseConfigurationFiles(baseDir = process.cwd(), config) {
|
|
|
3216
3400
|
rules.push({
|
|
3217
3401
|
frontmatter,
|
|
3218
3402
|
content,
|
|
3219
|
-
filename: "instructions",
|
|
3403
|
+
filename: mainFile.filenameOverride || "instructions",
|
|
3220
3404
|
filepath: mainFilePath
|
|
3221
3405
|
});
|
|
3222
3406
|
}
|
|
3223
|
-
}
|
|
3224
|
-
|
|
3225
|
-
errors.push(
|
|
3407
|
+
}, `Failed to parse ${mainFile.path}`);
|
|
3408
|
+
if (!result.success) {
|
|
3409
|
+
errors.push(result.error);
|
|
3226
3410
|
}
|
|
3227
3411
|
}
|
|
3228
3412
|
}
|
|
3229
3413
|
if (config.directories) {
|
|
3230
3414
|
for (const dirConfig of config.directories) {
|
|
3231
|
-
const dirPath = (
|
|
3415
|
+
const dirPath = resolvePath(dirConfig.directory, baseDir);
|
|
3232
3416
|
if (await fileExists(dirPath)) {
|
|
3233
|
-
|
|
3417
|
+
const result = await safeAsyncOperation(async () => {
|
|
3234
3418
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
3235
3419
|
const files = await readdir2(dirPath);
|
|
3236
3420
|
for (const file of files) {
|
|
3237
3421
|
if (file.endsWith(dirConfig.filePattern)) {
|
|
3238
|
-
const filePath = (0,
|
|
3239
|
-
|
|
3422
|
+
const filePath = (0, import_node_path15.join)(dirPath, file);
|
|
3423
|
+
const fileResult = await safeAsyncOperation(async () => {
|
|
3240
3424
|
const rawContent = await readFileContent(filePath);
|
|
3241
3425
|
let content;
|
|
3426
|
+
let frontmatter;
|
|
3427
|
+
const filename = file.replace(new RegExp(`\\${dirConfig.filePattern}$`), "");
|
|
3242
3428
|
if (dirConfig.filePattern === ".instructions.md") {
|
|
3243
3429
|
const parsed = (0, import_gray_matter3.default)(rawContent);
|
|
3244
3430
|
content = parsed.content.trim();
|
|
3431
|
+
const parsedFrontmatter = parsed.data;
|
|
3432
|
+
frontmatter = {
|
|
3433
|
+
root: false,
|
|
3434
|
+
targets: [config.tool],
|
|
3435
|
+
description: parsedFrontmatter.description || `${dirConfig.description}: ${filename}`,
|
|
3436
|
+
globs: Array.isArray(parsedFrontmatter.globs) ? parsedFrontmatter.globs : ["**/*"],
|
|
3437
|
+
...parsedFrontmatter.tags && { tags: parsedFrontmatter.tags }
|
|
3438
|
+
};
|
|
3245
3439
|
} else {
|
|
3246
3440
|
content = rawContent.trim();
|
|
3247
|
-
|
|
3248
|
-
if (content) {
|
|
3249
|
-
const filename = file.replace(new RegExp(`\\${dirConfig.filePattern}$`), "");
|
|
3250
|
-
const frontmatter = {
|
|
3441
|
+
frontmatter = {
|
|
3251
3442
|
root: false,
|
|
3252
3443
|
targets: [config.tool],
|
|
3253
3444
|
description: `${dirConfig.description}: ${filename}`,
|
|
3254
3445
|
globs: ["**/*"]
|
|
3255
3446
|
};
|
|
3447
|
+
}
|
|
3448
|
+
if (content) {
|
|
3256
3449
|
rules.push({
|
|
3257
3450
|
frontmatter,
|
|
3258
3451
|
content,
|
|
@@ -3260,15 +3453,15 @@ async function parseConfigurationFiles(baseDir = process.cwd(), config) {
|
|
|
3260
3453
|
filepath: filePath
|
|
3261
3454
|
});
|
|
3262
3455
|
}
|
|
3263
|
-
}
|
|
3264
|
-
|
|
3265
|
-
errors.push(
|
|
3456
|
+
}, `Failed to parse ${filePath}`);
|
|
3457
|
+
if (!fileResult.success) {
|
|
3458
|
+
errors.push(fileResult.error);
|
|
3266
3459
|
}
|
|
3267
3460
|
}
|
|
3268
3461
|
}
|
|
3269
|
-
}
|
|
3270
|
-
|
|
3271
|
-
errors.push(
|
|
3462
|
+
}, `Failed to parse ${dirConfig.directory} files`);
|
|
3463
|
+
if (!result.success) {
|
|
3464
|
+
errors.push(result.error);
|
|
3272
3465
|
}
|
|
3273
3466
|
}
|
|
3274
3467
|
}
|
|
@@ -3283,7 +3476,7 @@ async function parseMemoryBasedConfiguration(baseDir = process.cwd(), config) {
|
|
|
3283
3476
|
const rules = [];
|
|
3284
3477
|
let ignorePatterns;
|
|
3285
3478
|
let mcpServers;
|
|
3286
|
-
const mainFilePath = (
|
|
3479
|
+
const mainFilePath = resolvePath(config.mainFileName, baseDir);
|
|
3287
3480
|
if (!await fileExists(mainFilePath)) {
|
|
3288
3481
|
errors.push(`${config.mainFileName} file not found`);
|
|
3289
3482
|
return { rules, errors };
|
|
@@ -3294,12 +3487,12 @@ async function parseMemoryBasedConfiguration(baseDir = process.cwd(), config) {
|
|
|
3294
3487
|
if (mainRule) {
|
|
3295
3488
|
rules.push(mainRule);
|
|
3296
3489
|
}
|
|
3297
|
-
const memoryDir = (
|
|
3490
|
+
const memoryDir = resolvePath(config.memoryDirPath, baseDir);
|
|
3298
3491
|
if (await fileExists(memoryDir)) {
|
|
3299
3492
|
const memoryRules = await parseMemoryFiles(memoryDir, config);
|
|
3300
3493
|
rules.push(...memoryRules);
|
|
3301
3494
|
}
|
|
3302
|
-
const settingsPath = (
|
|
3495
|
+
const settingsPath = resolvePath(config.settingsPath, baseDir);
|
|
3303
3496
|
if (await fileExists(settingsPath)) {
|
|
3304
3497
|
const settingsResult = await parseSettingsFile(settingsPath, config.tool);
|
|
3305
3498
|
if (settingsResult.ignorePatterns) {
|
|
@@ -3311,7 +3504,7 @@ async function parseMemoryBasedConfiguration(baseDir = process.cwd(), config) {
|
|
|
3311
3504
|
errors.push(...settingsResult.errors);
|
|
3312
3505
|
}
|
|
3313
3506
|
if (config.additionalIgnoreFile) {
|
|
3314
|
-
const additionalIgnorePath = (
|
|
3507
|
+
const additionalIgnorePath = resolvePath(config.additionalIgnoreFile.path, baseDir);
|
|
3315
3508
|
if (await fileExists(additionalIgnorePath)) {
|
|
3316
3509
|
const additionalPatterns = await config.additionalIgnoreFile.parser(additionalIgnorePath);
|
|
3317
3510
|
if (additionalPatterns.length > 0) {
|
|
@@ -3320,8 +3513,7 @@ async function parseMemoryBasedConfiguration(baseDir = process.cwd(), config) {
|
|
|
3320
3513
|
}
|
|
3321
3514
|
}
|
|
3322
3515
|
} catch (error) {
|
|
3323
|
-
|
|
3324
|
-
errors.push(`Failed to parse ${config.tool} configuration: ${errorMessage}`);
|
|
3516
|
+
errors.push(`Failed to parse ${config.tool} configuration: ${getErrorMessage(error)}`);
|
|
3325
3517
|
}
|
|
3326
3518
|
return {
|
|
3327
3519
|
rules,
|
|
@@ -3365,10 +3557,10 @@ async function parseMemoryFiles(memoryDir, config) {
|
|
|
3365
3557
|
const files = await readdir2(memoryDir);
|
|
3366
3558
|
for (const file of files) {
|
|
3367
3559
|
if (file.endsWith(".md")) {
|
|
3368
|
-
const filePath = (0,
|
|
3560
|
+
const filePath = (0, import_node_path15.join)(memoryDir, file);
|
|
3369
3561
|
const content = await readFileContent(filePath);
|
|
3370
3562
|
if (content.trim()) {
|
|
3371
|
-
const filename = (0,
|
|
3563
|
+
const filename = (0, import_node_path15.basename)(file, ".md");
|
|
3372
3564
|
const frontmatter = {
|
|
3373
3565
|
root: false,
|
|
3374
3566
|
targets: [config.tool],
|
|
@@ -3417,8 +3609,7 @@ async function parseSettingsFile(settingsPath, tool) {
|
|
|
3417
3609
|
mcpServers = parseResult.data.mcpServers;
|
|
3418
3610
|
}
|
|
3419
3611
|
} catch (error) {
|
|
3420
|
-
|
|
3421
|
-
errors.push(`Failed to parse settings.json: ${errorMessage}`);
|
|
3612
|
+
errors.push(`Failed to parse settings.json: ${getErrorMessage(error)}`);
|
|
3422
3613
|
}
|
|
3423
3614
|
return {
|
|
3424
3615
|
errors,
|
|
@@ -3461,7 +3652,7 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
|
|
|
3461
3652
|
}
|
|
3462
3653
|
|
|
3463
3654
|
// src/parsers/codexcli.ts
|
|
3464
|
-
var
|
|
3655
|
+
var import_node_path16 = require("path");
|
|
3465
3656
|
|
|
3466
3657
|
// src/parsers/copilot.ts
|
|
3467
3658
|
async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
@@ -3484,7 +3675,7 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
|
3484
3675
|
}
|
|
3485
3676
|
|
|
3486
3677
|
// src/parsers/cursor.ts
|
|
3487
|
-
var
|
|
3678
|
+
var import_node_path17 = require("path");
|
|
3488
3679
|
var import_gray_matter4 = __toESM(require("gray-matter"), 1);
|
|
3489
3680
|
var import_js_yaml = require("js-yaml");
|
|
3490
3681
|
var import_mini7 = require("zod/mini");
|
|
@@ -3609,7 +3800,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
3609
3800
|
const rules = [];
|
|
3610
3801
|
let ignorePatterns;
|
|
3611
3802
|
let mcpServers;
|
|
3612
|
-
const cursorFilePath = (0,
|
|
3803
|
+
const cursorFilePath = (0, import_node_path17.join)(baseDir, ".cursorrules");
|
|
3613
3804
|
if (await fileExists(cursorFilePath)) {
|
|
3614
3805
|
try {
|
|
3615
3806
|
const rawContent = await readFileContent(cursorFilePath);
|
|
@@ -3630,20 +3821,20 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
3630
3821
|
errors.push(`Failed to parse .cursorrules file: ${errorMessage}`);
|
|
3631
3822
|
}
|
|
3632
3823
|
}
|
|
3633
|
-
const cursorRulesDir = (0,
|
|
3824
|
+
const cursorRulesDir = (0, import_node_path17.join)(baseDir, ".cursor", "rules");
|
|
3634
3825
|
if (await fileExists(cursorRulesDir)) {
|
|
3635
3826
|
try {
|
|
3636
3827
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
3637
3828
|
const files = await readdir2(cursorRulesDir);
|
|
3638
3829
|
for (const file of files) {
|
|
3639
3830
|
if (file.endsWith(".mdc")) {
|
|
3640
|
-
const filePath = (0,
|
|
3831
|
+
const filePath = (0, import_node_path17.join)(cursorRulesDir, file);
|
|
3641
3832
|
try {
|
|
3642
3833
|
const rawContent = await readFileContent(filePath);
|
|
3643
3834
|
const parsed = (0, import_gray_matter4.default)(rawContent, customMatterOptions);
|
|
3644
3835
|
const content = parsed.content.trim();
|
|
3645
3836
|
if (content) {
|
|
3646
|
-
const filename = (0,
|
|
3837
|
+
const filename = (0, import_node_path17.basename)(file, ".mdc");
|
|
3647
3838
|
const frontmatter = convertCursorMdcFrontmatter(parsed.data, filename);
|
|
3648
3839
|
rules.push({
|
|
3649
3840
|
frontmatter,
|
|
@@ -3666,7 +3857,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
3666
3857
|
if (rules.length === 0) {
|
|
3667
3858
|
errors.push("No Cursor configuration files found (.cursorrules or .cursor/rules/*.mdc)");
|
|
3668
3859
|
}
|
|
3669
|
-
const cursorIgnorePath = (0,
|
|
3860
|
+
const cursorIgnorePath = (0, import_node_path17.join)(baseDir, ".cursorignore");
|
|
3670
3861
|
if (await fileExists(cursorIgnorePath)) {
|
|
3671
3862
|
try {
|
|
3672
3863
|
const content = await readFileContent(cursorIgnorePath);
|
|
@@ -3679,7 +3870,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
3679
3870
|
errors.push(`Failed to parse .cursorignore: ${errorMessage}`);
|
|
3680
3871
|
}
|
|
3681
3872
|
}
|
|
3682
|
-
const cursorMcpPath = (0,
|
|
3873
|
+
const cursorMcpPath = (0, import_node_path17.join)(baseDir, ".cursor", "mcp.json");
|
|
3683
3874
|
if (await fileExists(cursorMcpPath)) {
|
|
3684
3875
|
try {
|
|
3685
3876
|
const content = await readFileContent(cursorMcpPath);
|
|
@@ -3728,11 +3919,11 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
|
|
|
3728
3919
|
}
|
|
3729
3920
|
|
|
3730
3921
|
// src/parsers/junie.ts
|
|
3731
|
-
var
|
|
3922
|
+
var import_node_path18 = require("path");
|
|
3732
3923
|
async function parseJunieConfiguration(baseDir = process.cwd()) {
|
|
3733
3924
|
const errors = [];
|
|
3734
3925
|
const rules = [];
|
|
3735
|
-
const guidelinesPath = (0,
|
|
3926
|
+
const guidelinesPath = (0, import_node_path18.join)(baseDir, ".junie", "guidelines.md");
|
|
3736
3927
|
if (!await fileExists(guidelinesPath)) {
|
|
3737
3928
|
errors.push(".junie/guidelines.md file not found");
|
|
3738
3929
|
return { rules, errors };
|
|
@@ -3867,7 +4058,7 @@ async function importConfiguration(options) {
|
|
|
3867
4058
|
if (rules.length === 0 && !ignorePatterns && !mcpServers) {
|
|
3868
4059
|
return { success: false, rulesCreated: 0, errors };
|
|
3869
4060
|
}
|
|
3870
|
-
const rulesDirPath = (0,
|
|
4061
|
+
const rulesDirPath = (0, import_node_path19.join)(baseDir, rulesDir);
|
|
3871
4062
|
try {
|
|
3872
4063
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
3873
4064
|
await mkdir3(rulesDirPath, { recursive: true });
|
|
@@ -3881,7 +4072,7 @@ async function importConfiguration(options) {
|
|
|
3881
4072
|
try {
|
|
3882
4073
|
const baseFilename = rule.filename;
|
|
3883
4074
|
const filename = await generateUniqueFilename(rulesDirPath, baseFilename);
|
|
3884
|
-
const filePath = (0,
|
|
4075
|
+
const filePath = (0, import_node_path19.join)(rulesDirPath, `${filename}.md`);
|
|
3885
4076
|
const content = generateRuleFileContent(rule);
|
|
3886
4077
|
await writeFileContent(filePath, content);
|
|
3887
4078
|
rulesCreated++;
|
|
@@ -3896,7 +4087,7 @@ async function importConfiguration(options) {
|
|
|
3896
4087
|
let ignoreFileCreated = false;
|
|
3897
4088
|
if (ignorePatterns && ignorePatterns.length > 0) {
|
|
3898
4089
|
try {
|
|
3899
|
-
const rulesyncignorePath = (0,
|
|
4090
|
+
const rulesyncignorePath = (0, import_node_path19.join)(baseDir, ".rulesyncignore");
|
|
3900
4091
|
const ignoreContent = `${ignorePatterns.join("\n")}
|
|
3901
4092
|
`;
|
|
3902
4093
|
await writeFileContent(rulesyncignorePath, ignoreContent);
|
|
@@ -3912,7 +4103,7 @@ async function importConfiguration(options) {
|
|
|
3912
4103
|
let mcpFileCreated = false;
|
|
3913
4104
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
3914
4105
|
try {
|
|
3915
|
-
const mcpPath = (0,
|
|
4106
|
+
const mcpPath = (0, import_node_path19.join)(baseDir, rulesDir, ".mcp.json");
|
|
3916
4107
|
const mcpContent = `${JSON.stringify({ mcpServers }, null, 2)}
|
|
3917
4108
|
`;
|
|
3918
4109
|
await writeFileContent(mcpPath, mcpContent);
|
|
@@ -3940,7 +4131,7 @@ function generateRuleFileContent(rule) {
|
|
|
3940
4131
|
async function generateUniqueFilename(rulesDir, baseFilename) {
|
|
3941
4132
|
let filename = baseFilename;
|
|
3942
4133
|
let counter = 1;
|
|
3943
|
-
while (await fileExists((0,
|
|
4134
|
+
while (await fileExists((0, import_node_path19.join)(rulesDir, `${filename}.md`))) {
|
|
3944
4135
|
filename = `${baseFilename}-${counter}`;
|
|
3945
4136
|
counter++;
|
|
3946
4137
|
}
|
|
@@ -4007,7 +4198,7 @@ async function importCommand(options = {}) {
|
|
|
4007
4198
|
}
|
|
4008
4199
|
|
|
4009
4200
|
// src/cli/commands/init.ts
|
|
4010
|
-
var
|
|
4201
|
+
var import_node_path20 = require("path");
|
|
4011
4202
|
async function initCommand() {
|
|
4012
4203
|
const aiRulesDir = ".rulesync";
|
|
4013
4204
|
console.log("Initializing rulesync...");
|
|
@@ -4054,7 +4245,7 @@ globs: ["**/*"]
|
|
|
4054
4245
|
- Follow single responsibility principle
|
|
4055
4246
|
`
|
|
4056
4247
|
};
|
|
4057
|
-
const filepath = (0,
|
|
4248
|
+
const filepath = (0, import_node_path20.join)(aiRulesDir, sampleFile.filename);
|
|
4058
4249
|
if (!await fileExists(filepath)) {
|
|
4059
4250
|
await writeFileContent(filepath, sampleFile.content);
|
|
4060
4251
|
console.log(`Created ${filepath}`);
|
|
@@ -4198,7 +4389,7 @@ async function watchCommand() {
|
|
|
4198
4389
|
|
|
4199
4390
|
// src/cli/index.ts
|
|
4200
4391
|
var program = new import_commander.Command();
|
|
4201
|
-
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.
|
|
4392
|
+
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.55.0");
|
|
4202
4393
|
program.command("init").description("Initialize rulesync in current directory").action(initCommand);
|
|
4203
4394
|
program.command("add <filename>").description("Add a new rule file").action(addCommand);
|
|
4204
4395
|
program.command("gitignore").description("Add generated files to .gitignore").action(gitignoreCommand);
|