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.
Files changed (3) hide show
  1. package/dist/index.cjs +401 -210
  2. package/dist/index.js +399 -208
  3. 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 baseDir ? (0, import_node_path5.join)(baseDir, config.outputPaths[tool]) : config.outputPaths[tool];
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 = baseDir ? (0, import_node_path5.join)(baseDir, generatorConfig.ignoreFileName) : generatorConfig.ignoreFileName;
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 = baseDir ? (0, import_node_path5.join)(baseDir, generatorConfig.detailSubDir, `${rule.filename}.md`) : (0, import_node_path5.join)(generatorConfig.detailSubDir, `${rule.filename}.md`);
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 = baseDir ? (0, import_node_path5.join)(baseDir, generatorConfig.rootFilePath) : generatorConfig.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 = baseDir ? (0, import_node_path5.join)(baseDir, generatorConfig.ignoreFileName) : generatorConfig.ignoreFileName;
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 outputs = [];
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
- filepath: (0, import_node_path7.join)(claudeOutputDir, "CLAUDE.md"),
2129
- content: claudeMdContent
2130
- });
2131
- for (const rule of detailRules) {
2132
- const memoryContent = generateMemoryFile(rule);
2133
- outputs.push({
2134
- tool: "claudecode",
2135
- filepath: (0, import_node_path7.join)(claudeOutputDir, ".claude", "memories", `${rule.filename}.md`),
2136
- content: memoryContent
2137
- });
2138
- }
2139
- const ignorePatterns = await loadIgnorePatterns(baseDir);
2140
- if (ignorePatterns.patterns.length > 0) {
2141
- const settingsPath = baseDir ? (0, import_node_path7.join)(baseDir, ".claude", "settings.json") : (0, import_node_path7.join)(".claude", "settings.json");
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/cline.ts
2205
- async function generateClineConfig(rules, config, baseDir) {
2206
- return generateRulesConfig(
2207
- rules,
2208
- config,
2209
- {
2210
- tool: "cline",
2211
- fileExtension: ".md",
2212
- ignoreFileName: ".clineignore",
2213
- generateContent: (rule) => rule.content.trim()
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
- baseDir
2216
- );
2217
- }
2218
-
2219
- // src/generators/rules/codexcli.ts
2220
- async function generateCodexConfig(rules, config, baseDir) {
2221
- const generatorConfig = {
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: generateCodexInstructionsMarkdown,
2226
- pathResolver: (rule, outputDir) => {
2227
- if (rule.frontmatter.root === true) {
2228
- return `${outputDir}/codex.md`;
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
- return `${outputDir}/${rule.filename}.md`;
2321
+ lines.push(rule.content.trim());
2322
+ return lines.join("\n");
2231
2323
  }
2232
- };
2233
- return generateRulesConfig(rules, config, generatorConfig, baseDir);
2234
- }
2235
- function generateCodexInstructionsMarkdown(rule) {
2236
- const lines = [];
2237
- if (rule.frontmatter.root === false && rule.frontmatter.description && rule.frontmatter.description !== "Main instructions" && !rule.frontmatter.description.includes("Project-level Codex CLI instructions")) {
2238
- lines.push(`<!-- ${rule.frontmatter.description} -->`);
2239
- if (rule.content.trim()) {
2240
- lines.push("");
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
- const content = rule.content.trim();
2244
- if (content) {
2245
- lines.push(content);
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
- return lines.join("\n");
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 import_node_path8 = require("path");
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, import_node_path8.join)(outputDir, `${baseFilename}.instructions.md`);
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 import_node_path9 = require("path");
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, import_node_path9.join)(outputDir, `${rule.filename}.mdc`);
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
- const outputs = [];
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 generateRulesConfig(
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 import_node_path20 = require("path");
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 { success: true, result };
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
- const rulesDir = (0, import_node_path14.join)(baseDir, ".augment", "rules");
3084
- if (await fileExists(rulesDir)) {
3085
- const rulesResult = await parseAugmentRules(rulesDir);
3086
- addRules(result, rulesResult.rules);
3087
- result.errors.push(...rulesResult.errors);
3088
- } else {
3089
- addError(result, "No AugmentCode configuration found. Expected .augment/rules/ directory.");
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: ["augmentcode"],
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: `augmentcode-${ruleType}-${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 .augment/rules/ directory: ${errorMessage}`);
3331
+ errors.push(`Failed to read ${config.rulesDir || rulesDir} directory: ${errorMessage}`);
3134
3332
  }
3135
3333
  return { rules, errors };
3136
3334
  }
3137
-
3138
- // src/parsers/augmentcode-legacy.ts
3139
- var import_node_path15 = require("path");
3140
- async function parseAugmentcodeLegacyConfiguration(baseDir = process.cwd()) {
3141
- const result = createParseResult();
3142
- const guidelinesPath = (0, import_node_path15.join)(baseDir, ".augment-guidelines");
3143
- if (await fileExists(guidelinesPath)) {
3144
- const guidelinesResult = await parseAugmentGuidelines(guidelinesPath);
3145
- if (guidelinesResult.rule) {
3146
- addRule(result, guidelinesResult.rule);
3147
- }
3148
- result.errors.push(...guidelinesResult.errors);
3149
- } else {
3150
- addError(
3151
- result,
3152
- "No AugmentCode legacy configuration found. Expected .augment-guidelines file."
3153
- );
3154
- }
3155
- return { rules: result.rules || [], errors: result.errors };
3156
- }
3157
- async function parseAugmentGuidelines(guidelinesPath) {
3158
- const parseResult = await safeReadFile(async () => {
3159
- const content = await readFileContent(guidelinesPath);
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 import_node_path16 = require("path");
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 mainFilePath = (0, import_node_path16.join)(baseDir, config.mainFile.path);
3372
+ const mainFile = config.mainFile;
3373
+ const mainFilePath = resolvePath(mainFile.path, baseDir);
3192
3374
  if (await fileExists(mainFilePath)) {
3193
- try {
3375
+ const result = await safeAsyncOperation(async () => {
3194
3376
  const rawContent = await readFileContent(mainFilePath);
3195
3377
  let content;
3196
3378
  let frontmatter;
3197
- if (config.mainFile.useFrontmatter) {
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: config.mainFile.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: config.mainFile.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
- } catch (error) {
3224
- const errorMessage = error instanceof Error ? error.message : String(error);
3225
- errors.push(`Failed to parse ${config.mainFile.path}: ${errorMessage}`);
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 = (0, import_node_path16.join)(baseDir, dirConfig.directory);
3415
+ const dirPath = resolvePath(dirConfig.directory, baseDir);
3232
3416
  if (await fileExists(dirPath)) {
3233
- try {
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, import_node_path16.join)(dirPath, file);
3239
- try {
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
- } catch (error) {
3264
- const errorMessage = error instanceof Error ? error.message : String(error);
3265
- errors.push(`Failed to parse ${filePath}: ${errorMessage}`);
3456
+ }, `Failed to parse ${filePath}`);
3457
+ if (!fileResult.success) {
3458
+ errors.push(fileResult.error);
3266
3459
  }
3267
3460
  }
3268
3461
  }
3269
- } catch (error) {
3270
- const errorMessage = error instanceof Error ? error.message : String(error);
3271
- errors.push(`Failed to parse ${dirConfig.directory} files: ${errorMessage}`);
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 = (0, import_node_path16.join)(baseDir, config.mainFileName);
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 = (0, import_node_path16.join)(baseDir, config.memoryDirPath);
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 = (0, import_node_path16.join)(baseDir, config.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 = (0, import_node_path16.join)(baseDir, config.additionalIgnoreFile.path);
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
- const errorMessage = error instanceof Error ? error.message : String(error);
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, import_node_path16.join)(memoryDir, file);
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, import_node_path16.basename)(file, ".md");
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
- const errorMessage = error instanceof Error ? error.message : String(error);
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 import_node_path17 = require("path");
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 import_node_path18 = require("path");
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, import_node_path18.join)(baseDir, ".cursorrules");
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, import_node_path18.join)(baseDir, ".cursor", "rules");
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, import_node_path18.join)(cursorRulesDir, file);
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, import_node_path18.basename)(file, ".mdc");
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, import_node_path18.join)(baseDir, ".cursorignore");
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, import_node_path18.join)(baseDir, ".cursor", "mcp.json");
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 import_node_path19 = require("path");
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, import_node_path19.join)(baseDir, ".junie", "guidelines.md");
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, import_node_path20.join)(baseDir, rulesDir);
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, import_node_path20.join)(rulesDirPath, `${filename}.md`);
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, import_node_path20.join)(baseDir, ".rulesyncignore");
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, import_node_path20.join)(baseDir, rulesDir, ".mcp.json");
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, import_node_path20.join)(rulesDir, `${filename}.md`))) {
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 import_node_path21 = require("path");
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, import_node_path21.join)(aiRulesDir, sampleFile.filename);
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.54.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);