rulesync 0.69.0 → 0.70.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 (4) hide show
  1. package/README.md +116 -9
  2. package/dist/index.cjs +851 -1009
  3. package/dist/index.js +846 -1004
  4. package/package.json +4 -4
package/dist/index.cjs CHANGED
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/cli/index.ts
27
- var import_node_path17 = require("path");
27
+ var import_node_path50 = require("path");
28
28
  var import_node_url = require("url");
29
29
  var import_commander = require("commander");
30
30
 
@@ -217,14 +217,6 @@ async function listDirectoryFiles(dir) {
217
217
  return [];
218
218
  }
219
219
  }
220
- async function findFiles(dir, extension = ".md") {
221
- try {
222
- const files = await (0, import_promises.readdir)(dir);
223
- return files.filter((file) => file.endsWith(extension)).map((file) => (0, import_node_path.join)(dir, file));
224
- } catch {
225
- return [];
226
- }
227
- }
228
220
  async function findFilesByGlobs(globs) {
229
221
  return (0, import_node_fs.globSync)(globs);
230
222
  }
@@ -274,7 +266,7 @@ async function initConfig() {
274
266
  var import_es_toolkit = require("es-toolkit");
275
267
 
276
268
  // src/commands/commands-processor.ts
277
- var import_node_path7 = require("path");
269
+ var import_node_path8 = require("path");
278
270
  var import_mini7 = require("zod/mini");
279
271
 
280
272
  // src/types/feature-processor.ts
@@ -307,15 +299,48 @@ var FeatureProcessor = class {
307
299
  };
308
300
 
309
301
  // src/commands/claudecode-command.ts
310
- var import_node_path4 = require("path");
302
+ var import_node_path5 = require("path");
311
303
  var import_mini4 = require("zod/mini");
312
304
 
313
305
  // src/utils/frontmatter.ts
314
306
  var import_gray_matter = __toESM(require("gray-matter"), 1);
307
+ function isPlainObject(value) {
308
+ if (value === null || typeof value !== "object") return false;
309
+ const prototype = Object.getPrototypeOf(value);
310
+ return prototype === Object.prototype || prototype === null;
311
+ }
312
+ function deepRemoveNullishValue(value) {
313
+ if (value === null || value === void 0) {
314
+ return void 0;
315
+ }
316
+ if (Array.isArray(value)) {
317
+ const cleanedArray = value.map((item) => deepRemoveNullishValue(item)).filter((item) => item !== void 0);
318
+ return cleanedArray;
319
+ }
320
+ if (isPlainObject(value)) {
321
+ const result = {};
322
+ for (const [key, val] of Object.entries(value)) {
323
+ const cleaned = deepRemoveNullishValue(val);
324
+ if (cleaned !== void 0) {
325
+ result[key] = cleaned;
326
+ }
327
+ }
328
+ return result;
329
+ }
330
+ return value;
331
+ }
332
+ function deepRemoveNullishObject(obj) {
333
+ const result = {};
334
+ for (const [key, val] of Object.entries(obj)) {
335
+ const cleaned = deepRemoveNullishValue(val);
336
+ if (cleaned !== void 0) {
337
+ result[key] = cleaned;
338
+ }
339
+ }
340
+ return result;
341
+ }
315
342
  function stringifyFrontmatter(body, frontmatter) {
316
- const cleanFrontmatter = Object.fromEntries(
317
- Object.entries(frontmatter).filter(([, value]) => value !== null && value !== void 0)
318
- );
343
+ const cleanFrontmatter = deepRemoveNullishObject(frontmatter);
319
344
  return import_gray_matter.default.stringify(body, cleanFrontmatter);
320
345
  }
321
346
  function parseFrontmatter(content) {
@@ -324,11 +349,20 @@ function parseFrontmatter(content) {
324
349
  }
325
350
 
326
351
  // src/commands/rulesync-command.ts
327
- var import_node_path3 = require("path");
352
+ var import_node_path4 = require("path");
328
353
  var import_mini3 = require("zod/mini");
329
354
 
355
+ // src/constants/paths.ts
356
+ var import_node_path2 = require("path");
357
+ var RULESYNC_DIR = ".rulesync";
358
+ var RULESYNC_RULES_DIR = (0, import_node_path2.join)(".rulesync", "rules");
359
+ var RULESYNC_RULES_DIR_LEGACY = ".rulesync";
360
+ var RULESYNC_MCP_FILE = (0, import_node_path2.join)(".rulesync", ".mcp.json");
361
+ var RULESYNC_COMMANDS_DIR = (0, import_node_path2.join)(".rulesync", "commands");
362
+ var RULESYNC_SUBAGENTS_DIR = (0, import_node_path2.join)(".rulesync", "subagents");
363
+
330
364
  // src/types/ai-file.ts
331
- var import_node_path2 = __toESM(require("path"), 1);
365
+ var import_node_path3 = __toESM(require("path"), 1);
332
366
  var AiFile = class {
333
367
  /**
334
368
  * @example "."
@@ -364,7 +398,7 @@ var AiFile = class {
364
398
  }
365
399
  }
366
400
  }
367
- static async fromFilePath(_params) {
401
+ static async fromFile(_params) {
368
402
  throw new Error("Please implement this method in the subclass.");
369
403
  }
370
404
  getBaseDir() {
@@ -377,13 +411,13 @@ var AiFile = class {
377
411
  return this.relativeFilePath;
378
412
  }
379
413
  getFilePath() {
380
- return import_node_path2.default.join(this.baseDir, this.relativeDirPath, this.relativeFilePath);
414
+ return import_node_path3.default.join(this.baseDir, this.relativeDirPath, this.relativeFilePath);
381
415
  }
382
416
  getFileContent() {
383
417
  return this.fileContent;
384
418
  }
385
419
  getRelativePathFromCwd() {
386
- return import_node_path2.default.join(this.relativeDirPath, this.relativeFilePath);
420
+ return import_node_path3.default.join(this.relativeDirPath, this.relativeFilePath);
387
421
  }
388
422
  setFileContent(newFileContent) {
389
423
  this.fileContent = newFileContent;
@@ -392,13 +426,10 @@ var AiFile = class {
392
426
 
393
427
  // src/types/rulesync-file.ts
394
428
  var RulesyncFile = class extends AiFile {
395
- static async fromFilePath(_params) {
396
- throw new Error("Please implement this method in the subclass.");
397
- }
398
429
  static async fromFile(_params) {
399
430
  throw new Error("Please implement this method in the subclass.");
400
431
  }
401
- static async fromLegacyFile(_params) {
432
+ static async fromFileLegacy(_params) {
402
433
  throw new Error("Please implement this method in the subclass.");
403
434
  }
404
435
  };
@@ -442,14 +473,16 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
442
473
  return { success: false, error: result.error };
443
474
  }
444
475
  }
445
- static async fromFilePath({ filePath }) {
446
- const fileContent = await readFileContent(filePath);
476
+ static async fromFile({
477
+ relativeFilePath
478
+ }) {
479
+ const fileContent = await readFileContent((0, import_node_path4.join)(RULESYNC_COMMANDS_DIR, relativeFilePath));
447
480
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
448
481
  const result = RulesyncCommandFrontmatterSchema.safeParse(frontmatter);
449
482
  if (!result.success) {
450
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
483
+ throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
451
484
  }
452
- const filename = (0, import_node_path3.basename)(filePath);
485
+ const filename = (0, import_node_path4.basename)(relativeFilePath);
453
486
  return new _RulesyncCommand({
454
487
  baseDir: ".",
455
488
  relativeDirPath: ".rulesync/commands",
@@ -475,7 +508,7 @@ var ToolCommand = class extends AiFile {
475
508
  * @param params - Parameters including the file path to load
476
509
  * @returns Promise resolving to a concrete ToolCommand instance
477
510
  */
478
- static async fromFilePath(_params) {
511
+ static async fromFile(_params) {
479
512
  throw new Error("Please implement this method in the subclass.");
480
513
  }
481
514
  /**
@@ -552,7 +585,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
552
585
  baseDir,
553
586
  frontmatter: claudecodeFrontmatter,
554
587
  body,
555
- relativeDirPath: (0, import_node_path4.join)(".claude", "commands"),
588
+ relativeDirPath: (0, import_node_path5.join)(".claude", "commands"),
556
589
  relativeFilePath: rulesyncCommand.getRelativeFilePath(),
557
590
  validate
558
591
  });
@@ -568,11 +601,12 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
568
601
  return { success: false, error: result.error };
569
602
  }
570
603
  }
571
- static async fromFilePath({
604
+ static async fromFile({
572
605
  baseDir = ".",
573
- filePath,
606
+ relativeFilePath,
574
607
  validate = true
575
608
  }) {
609
+ const filePath = (0, import_node_path5.join)(baseDir, ".claude", "commands", relativeFilePath);
576
610
  const fileContent = await readFileContent(filePath);
577
611
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
578
612
  const result = ClaudecodeCommandFrontmatterSchema.safeParse(frontmatter);
@@ -582,7 +616,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
582
616
  return new _ClaudecodeCommand({
583
617
  baseDir,
584
618
  relativeDirPath: ".claude/commands",
585
- relativeFilePath: (0, import_node_path4.basename)(filePath),
619
+ relativeFilePath: (0, import_node_path5.basename)(relativeFilePath),
586
620
  frontmatter: result.data,
587
621
  body: content.trim(),
588
622
  validate
@@ -591,7 +625,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
591
625
  };
592
626
 
593
627
  // src/commands/geminicli-command.ts
594
- var import_node_path5 = require("path");
628
+ var import_node_path6 = require("path");
595
629
  var import_smol_toml = require("smol-toml");
596
630
  var import_mini5 = require("zod/mini");
597
631
  var GeminiCliCommandFrontmatterSchema = import_mini5.z.object({
@@ -677,16 +711,17 @@ ${geminiFrontmatter.prompt}
677
711
  validate
678
712
  });
679
713
  }
680
- static async fromFilePath({
714
+ static async fromFile({
681
715
  baseDir = ".",
682
- filePath,
716
+ relativeFilePath,
683
717
  validate = true
684
718
  }) {
719
+ const filePath = (0, import_node_path6.join)(baseDir, ".gemini", "commands", relativeFilePath);
685
720
  const fileContent = await readFileContent(filePath);
686
721
  return new _GeminiCliCommand({
687
722
  baseDir,
688
723
  relativeDirPath: ".gemini/commands",
689
- relativeFilePath: (0, import_node_path5.basename)(filePath),
724
+ relativeFilePath: (0, import_node_path6.basename)(relativeFilePath),
690
725
  fileContent,
691
726
  validate
692
727
  });
@@ -699,26 +734,10 @@ ${geminiFrontmatter.prompt}
699
734
  return { success: false, error: error instanceof Error ? error : new Error(String(error)) };
700
735
  }
701
736
  }
702
- async processContent(content, args) {
703
- let processedContent = content;
704
- processedContent = this.processArgumentPlaceholder(processedContent, args);
705
- return processedContent;
706
- }
707
- processArgumentPlaceholder(content, args) {
708
- if (content.includes("{{args}}")) {
709
- return content.replace(/\{\{args\}\}/g, args || "");
710
- }
711
- if (args) {
712
- return `${content}
713
-
714
- ${args}`;
715
- }
716
- return content;
717
- }
718
737
  };
719
738
 
720
739
  // src/commands/roo-command.ts
721
- var import_node_path6 = require("path");
740
+ var import_node_path7 = require("path");
722
741
  var import_mini6 = require("zod/mini");
723
742
  var RooCommandFrontmatterSchema = import_mini6.z.object({
724
743
  description: import_mini6.z.string(),
@@ -795,11 +814,12 @@ var RooCommand = class _RooCommand extends ToolCommand {
795
814
  return { success: false, error: result.error };
796
815
  }
797
816
  }
798
- static async fromFilePath({
817
+ static async fromFile({
799
818
  baseDir = ".",
800
- filePath,
819
+ relativeFilePath,
801
820
  validate = true
802
821
  }) {
822
+ const filePath = (0, import_node_path7.join)(baseDir, ".roo", "commands", relativeFilePath);
803
823
  const fileContent = await readFileContent(filePath);
804
824
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
805
825
  const result = RooCommandFrontmatterSchema.safeParse(frontmatter);
@@ -809,7 +829,7 @@ var RooCommand = class _RooCommand extends ToolCommand {
809
829
  return new _RooCommand({
810
830
  baseDir,
811
831
  relativeDirPath: ".roo/commands",
812
- relativeFilePath: (0, import_node_path6.basename)(filePath),
832
+ relativeFilePath: (0, import_node_path7.basename)(relativeFilePath),
813
833
  frontmatter: result.data,
814
834
  body: content.trim(),
815
835
  fileContent,
@@ -871,37 +891,12 @@ var CommandsProcessor = class extends FeatureProcessor {
871
891
  * Load and parse rulesync command files from .rulesync/commands/ directory
872
892
  */
873
893
  async loadRulesyncFiles() {
874
- const commandsDir = (0, import_node_path7.join)(this.baseDir, ".rulesync", "commands");
875
- const dirExists = await directoryExists(commandsDir);
876
- if (!dirExists) {
877
- logger.debug(`Rulesync commands directory not found: ${commandsDir}`);
878
- return [];
879
- }
880
- const allMdFiles = await findFiles(commandsDir, ".md");
881
- const mdFiles = allMdFiles.map((f) => (0, import_node_path7.basename)(f));
882
- if (mdFiles.length === 0) {
883
- logger.debug(`No markdown files found in rulesync commands directory: ${commandsDir}`);
884
- return [];
885
- }
886
- logger.info(`Found ${mdFiles.length} command files in ${commandsDir}`);
887
- const rulesyncCommands = [];
888
- for (const mdFile of mdFiles) {
889
- const filepath = (0, import_node_path7.join)(commandsDir, mdFile);
890
- try {
891
- const rulesyncCommand = await RulesyncCommand.fromFilePath({
892
- filePath: filepath
893
- });
894
- rulesyncCommands.push(rulesyncCommand);
895
- logger.debug(`Successfully loaded command: ${mdFile}`);
896
- } catch (error) {
897
- logger.warn(`Failed to load command file ${filepath}:`, error);
898
- continue;
899
- }
900
- }
901
- if (rulesyncCommands.length === 0) {
902
- logger.debug(`No valid commands found in ${commandsDir}`);
903
- return [];
904
- }
894
+ const rulesyncCommandPaths = await findFilesByGlobs((0, import_node_path8.join)(".rulesync", "commands", "*.md"));
895
+ const rulesyncCommands = (await Promise.allSettled(
896
+ rulesyncCommandPaths.map(
897
+ (path2) => RulesyncCommand.fromFile({ relativeFilePath: (0, import_node_path8.basename)(path2) })
898
+ )
899
+ )).filter((result) => result.status === "fulfilled").map((result) => result.value);
905
900
  logger.info(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
906
901
  return rulesyncCommands;
907
902
  }
@@ -914,122 +909,67 @@ var CommandsProcessor = class extends FeatureProcessor {
914
909
  case "claudecode":
915
910
  return await this.loadClaudecodeCommands();
916
911
  case "geminicli":
917
- return await this.loadGeminiCliCommands();
912
+ return await this.loadGeminicliCommands();
918
913
  case "roo":
919
914
  return await this.loadRooCommands();
920
915
  default:
921
916
  throw new Error(`Unsupported tool target: ${this.toolTarget}`);
922
917
  }
923
918
  }
919
+ async loadToolCommandDefault({
920
+ toolTarget,
921
+ relativeDirPath,
922
+ extension
923
+ }) {
924
+ const commandFilePaths = await findFilesByGlobs(
925
+ (0, import_node_path8.join)(this.baseDir, relativeDirPath, `*.${extension}`)
926
+ );
927
+ const toolCommands = (await Promise.allSettled(
928
+ commandFilePaths.map((path2) => {
929
+ switch (toolTarget) {
930
+ case "claudecode":
931
+ return ClaudecodeCommand.fromFile({ relativeFilePath: (0, import_node_path8.basename)(path2) });
932
+ case "geminicli":
933
+ return GeminiCliCommand.fromFile({ relativeFilePath: (0, import_node_path8.basename)(path2) });
934
+ case "roo":
935
+ return RooCommand.fromFile({ relativeFilePath: (0, import_node_path8.basename)(path2) });
936
+ default:
937
+ throw new Error(`Unsupported tool target: ${toolTarget}`);
938
+ }
939
+ })
940
+ )).filter((result) => result.status === "fulfilled").map((result) => result.value);
941
+ logger.info(`Successfully loaded ${toolCommands.length} ${relativeDirPath} commands`);
942
+ return toolCommands;
943
+ }
924
944
  /**
925
945
  * Load Claude Code command configurations from .claude/commands/ directory
926
946
  */
927
947
  async loadClaudecodeCommands() {
928
- const commandsDir = (0, import_node_path7.join)(this.baseDir, ".claude", "commands");
929
- if (!await directoryExists(commandsDir)) {
930
- logger.warn(`Claude Code commands directory not found: ${commandsDir}`);
931
- return [];
932
- }
933
- const allMdFiles = await findFiles(commandsDir, ".md");
934
- const mdFiles = allMdFiles.map((f) => (0, import_node_path7.basename)(f));
935
- if (mdFiles.length === 0) {
936
- logger.info(`No markdown command files found in ${commandsDir}`);
937
- return [];
938
- }
939
- logger.info(`Found ${mdFiles.length} Claude Code command files in ${commandsDir}`);
940
- const toolCommands = [];
941
- for (const mdFile of mdFiles) {
942
- const filepath = (0, import_node_path7.join)(commandsDir, mdFile);
943
- try {
944
- const claudecodeCommand = await ClaudecodeCommand.fromFilePath({
945
- baseDir: this.baseDir,
946
- filePath: filepath
947
- });
948
- toolCommands.push(claudecodeCommand);
949
- logger.debug(`Successfully loaded Claude Code command: ${mdFile}`);
950
- } catch (error) {
951
- logger.warn(`Failed to load Claude Code command file ${filepath}:`, error);
952
- continue;
953
- }
954
- }
955
- logger.info(`Successfully loaded ${toolCommands.length} Claude Code commands`);
956
- return toolCommands;
948
+ return await this.loadToolCommandDefault({
949
+ toolTarget: "claudecode",
950
+ relativeDirPath: ".claude/commands",
951
+ extension: "md"
952
+ });
957
953
  }
958
954
  /**
959
955
  * Load Gemini CLI command configurations from .gemini/commands/ directory
960
956
  */
961
- async loadGeminiCliCommands() {
962
- const commandsDir = (0, import_node_path7.join)(this.baseDir, ".gemini", "commands");
963
- if (!await directoryExists(commandsDir)) {
964
- logger.warn(`Gemini CLI commands directory not found: ${commandsDir}`);
965
- return [];
966
- }
967
- const allFiles = await listDirectoryFiles(commandsDir);
968
- const tomlFiles = allFiles.filter((file) => file.endsWith(".toml"));
969
- if (tomlFiles.length === 0) {
970
- logger.info(`No TOML command files found in ${commandsDir}`);
971
- return [];
972
- }
973
- logger.info(`Found ${tomlFiles.length} Gemini CLI command files in ${commandsDir}`);
974
- const toolCommands = [];
975
- for (const tomlFile of tomlFiles) {
976
- const filepath = (0, import_node_path7.join)(commandsDir, tomlFile);
977
- try {
978
- const geminiCliCommand = await GeminiCliCommand.fromFilePath({
979
- baseDir: this.baseDir,
980
- filePath: filepath
981
- });
982
- toolCommands.push(geminiCliCommand);
983
- logger.debug(`Successfully loaded Gemini CLI command: ${tomlFile}`);
984
- } catch (error) {
985
- logger.warn(`Failed to load Gemini CLI command file ${filepath}:`, error);
986
- continue;
987
- }
988
- }
989
- logger.info(`Successfully loaded ${toolCommands.length} Gemini CLI commands`);
990
- return toolCommands;
957
+ async loadGeminicliCommands() {
958
+ return await this.loadToolCommandDefault({
959
+ toolTarget: "geminicli",
960
+ relativeDirPath: ".gemini/commands",
961
+ extension: "md"
962
+ });
991
963
  }
992
964
  /**
993
965
  * Load Roo Code command configurations from .roo/commands/ directory
994
966
  */
995
967
  async loadRooCommands() {
996
- const commandsDir = (0, import_node_path7.join)(this.baseDir, ".roo", "commands");
997
- if (!await directoryExists(commandsDir)) {
998
- logger.warn(`Roo Code commands directory not found: ${commandsDir}`);
999
- return [];
1000
- }
1001
- const allMdFiles = await findFiles(commandsDir, ".md");
1002
- const mdFiles = allMdFiles.map((f) => (0, import_node_path7.basename)(f));
1003
- if (mdFiles.length === 0) {
1004
- logger.info(`No markdown command files found in ${commandsDir}`);
1005
- return [];
1006
- }
1007
- logger.info(`Found ${mdFiles.length} Roo Code command files in ${commandsDir}`);
1008
- const toolCommands = [];
1009
- for (const mdFile of mdFiles) {
1010
- const filepath = (0, import_node_path7.join)(commandsDir, mdFile);
1011
- try {
1012
- const rooCommand = await RooCommand.fromFilePath({
1013
- baseDir: this.baseDir,
1014
- filePath: filepath
1015
- });
1016
- toolCommands.push(rooCommand);
1017
- logger.debug(`Successfully loaded Roo Code command: ${mdFile}`);
1018
- } catch (error) {
1019
- logger.warn(`Failed to load Roo Code command file ${filepath}:`, error);
1020
- continue;
1021
- }
1022
- }
1023
- logger.info(`Successfully loaded ${toolCommands.length} Roo Code commands`);
1024
- return toolCommands;
1025
- }
1026
- async writeToolCommandsFromRulesyncCommands(rulesyncCommands) {
1027
- const toolCommands = await this.convertRulesyncFilesToToolFiles(rulesyncCommands);
1028
- await this.writeAiFiles(toolCommands);
1029
- }
1030
- async writeRulesyncCommandsFromToolCommands(toolCommands) {
1031
- const rulesyncCommands = await this.convertToolFilesToRulesyncFiles(toolCommands);
1032
- await this.writeAiFiles(rulesyncCommands);
968
+ return await this.loadToolCommandDefault({
969
+ toolTarget: "roo",
970
+ relativeDirPath: ".roo/commands",
971
+ extension: "md"
972
+ });
1033
973
  }
1034
974
  /**
1035
975
  * Implementation of abstract method from FeatureProcessor
@@ -1141,6 +1081,9 @@ var ConfigResolver = class {
1141
1081
  // src/ignore/ignore-processor.ts
1142
1082
  var import_mini9 = require("zod/mini");
1143
1083
 
1084
+ // src/ignore/augmentcode-ignore.ts
1085
+ var import_node_path9 = require("path");
1086
+
1144
1087
  // src/types/tool-file.ts
1145
1088
  var ToolFile = class extends AiFile {
1146
1089
  };
@@ -1159,9 +1102,6 @@ var RulesyncIgnore = class _RulesyncIgnore extends RulesyncFile {
1159
1102
  fileContent
1160
1103
  });
1161
1104
  }
1162
- static async fromFilePath(_params) {
1163
- throw new Error("Please use the fromFile method instead.");
1164
- }
1165
1105
  };
1166
1106
 
1167
1107
  // src/ignore/tool-ignore.ts
@@ -1198,12 +1138,9 @@ var ToolIgnore = class extends ToolFile {
1198
1138
  fileContent: this.fileContent
1199
1139
  });
1200
1140
  }
1201
- static async fromFile() {
1141
+ static async fromFile(_params) {
1202
1142
  throw new Error("Please implement this method in the subclass.");
1203
1143
  }
1204
- static async fromFilePath(_params) {
1205
- throw new Error("Please use the fromFile method instead.");
1206
- }
1207
1144
  };
1208
1145
 
1209
1146
  // src/ignore/augmentcode-ignore.ts
@@ -1233,18 +1170,23 @@ var AugmentcodeIgnore = class _AugmentcodeIgnore extends ToolIgnore {
1233
1170
  * Create AugmentcodeIgnore from file path
1234
1171
  * Reads and parses .augmentignore file
1235
1172
  */
1236
- static async fromFile() {
1237
- const fileContent = await readFileContent(".augmentignore");
1173
+ static async fromFile({
1174
+ baseDir = ".",
1175
+ validate = true
1176
+ }) {
1177
+ const fileContent = await readFileContent((0, import_node_path9.join)(baseDir, ".augmentignore"));
1238
1178
  return new _AugmentcodeIgnore({
1239
- baseDir: ".",
1179
+ baseDir,
1240
1180
  relativeDirPath: ".",
1241
1181
  relativeFilePath: ".augmentignore",
1242
- fileContent
1182
+ fileContent,
1183
+ validate
1243
1184
  });
1244
1185
  }
1245
1186
  };
1246
1187
 
1247
1188
  // src/ignore/cline-ignore.ts
1189
+ var import_node_path10 = require("path");
1248
1190
  var ClineIgnore = class _ClineIgnore extends ToolIgnore {
1249
1191
  /**
1250
1192
  * Convert ClineIgnore to RulesyncIgnore format
@@ -1270,18 +1212,23 @@ var ClineIgnore = class _ClineIgnore extends ToolIgnore {
1270
1212
  /**
1271
1213
  * Load ClineIgnore from .clineignore file
1272
1214
  */
1273
- static async fromFile() {
1274
- const fileContent = await readFileContent(".clineignore");
1215
+ static async fromFile({
1216
+ baseDir = ".",
1217
+ validate = true
1218
+ }) {
1219
+ const fileContent = await readFileContent((0, import_node_path10.join)(baseDir, ".clineignore"));
1275
1220
  return new _ClineIgnore({
1276
- baseDir: ".",
1221
+ baseDir,
1277
1222
  relativeDirPath: ".",
1278
1223
  relativeFilePath: ".clineignore",
1279
- fileContent
1224
+ fileContent,
1225
+ validate
1280
1226
  });
1281
1227
  }
1282
1228
  };
1283
1229
 
1284
1230
  // src/ignore/codexcli-ignore.ts
1231
+ var import_node_path11 = require("path");
1285
1232
  var CodexcliIgnore = class _CodexcliIgnore extends ToolIgnore {
1286
1233
  toRulesyncIgnore() {
1287
1234
  return this.toRulesyncIgnoreDefault();
@@ -1300,20 +1247,23 @@ var CodexcliIgnore = class _CodexcliIgnore extends ToolIgnore {
1300
1247
  // Skip validation to allow empty patterns
1301
1248
  });
1302
1249
  }
1303
- static async fromFile() {
1304
- const fileContent = await readFileContent(".codexignore");
1250
+ static async fromFile({
1251
+ baseDir = ".",
1252
+ validate = true
1253
+ }) {
1254
+ const fileContent = await readFileContent((0, import_node_path11.join)(baseDir, ".codexignore"));
1305
1255
  return new _CodexcliIgnore({
1306
- baseDir: ".",
1256
+ baseDir,
1307
1257
  relativeDirPath: ".",
1308
1258
  relativeFilePath: ".codexignore",
1309
1259
  fileContent,
1310
- validate: true
1311
- // Skip validation to allow empty patterns
1260
+ validate
1312
1261
  });
1313
1262
  }
1314
1263
  };
1315
1264
 
1316
1265
  // src/ignore/cursor-ignore.ts
1266
+ var import_node_path12 = require("path");
1317
1267
  var CursorIgnore = class _CursorIgnore extends ToolIgnore {
1318
1268
  toRulesyncIgnore() {
1319
1269
  return new RulesyncIgnore({
@@ -1335,18 +1285,23 @@ var CursorIgnore = class _CursorIgnore extends ToolIgnore {
1335
1285
  fileContent: body
1336
1286
  });
1337
1287
  }
1338
- static async fromFile() {
1339
- const fileContent = await readFileContent(".cursorignore");
1288
+ static async fromFile({
1289
+ baseDir = ".",
1290
+ validate = true
1291
+ }) {
1292
+ const fileContent = await readFileContent((0, import_node_path12.join)(baseDir, ".cursorignore"));
1340
1293
  return new _CursorIgnore({
1341
- baseDir: ".",
1294
+ baseDir,
1342
1295
  relativeDirPath: ".",
1343
1296
  relativeFilePath: ".cursorignore",
1344
- fileContent
1297
+ fileContent,
1298
+ validate
1345
1299
  });
1346
1300
  }
1347
1301
  };
1348
1302
 
1349
1303
  // src/ignore/geminicli-ignore.ts
1304
+ var import_node_path13 = require("path");
1350
1305
  var GeminiCliIgnore = class _GeminiCliIgnore extends ToolIgnore {
1351
1306
  toRulesyncIgnore() {
1352
1307
  return this.toRulesyncIgnoreDefault();
@@ -1362,18 +1317,23 @@ var GeminiCliIgnore = class _GeminiCliIgnore extends ToolIgnore {
1362
1317
  fileContent: rulesyncIgnore.getFileContent()
1363
1318
  });
1364
1319
  }
1365
- static async fromFile() {
1366
- const fileContent = await readFileContent(".aiexclude");
1320
+ static async fromFile({
1321
+ baseDir = ".",
1322
+ validate = true
1323
+ }) {
1324
+ const fileContent = await readFileContent((0, import_node_path13.join)(baseDir, ".aiexclude"));
1367
1325
  return new _GeminiCliIgnore({
1368
- baseDir: ".",
1326
+ baseDir,
1369
1327
  relativeDirPath: ".",
1370
1328
  relativeFilePath: ".aiexclude",
1371
- fileContent
1329
+ fileContent,
1330
+ validate
1372
1331
  });
1373
1332
  }
1374
1333
  };
1375
1334
 
1376
1335
  // src/ignore/junie-ignore.ts
1336
+ var import_node_path14 = require("path");
1377
1337
  var JunieIgnore = class _JunieIgnore extends ToolIgnore {
1378
1338
  toRulesyncIgnore() {
1379
1339
  return this.toRulesyncIgnoreDefault();
@@ -1389,18 +1349,23 @@ var JunieIgnore = class _JunieIgnore extends ToolIgnore {
1389
1349
  fileContent: rulesyncIgnore.getFileContent()
1390
1350
  });
1391
1351
  }
1392
- static async fromFile() {
1393
- const fileContent = await readFileContent(".junieignore");
1352
+ static async fromFile({
1353
+ baseDir = ".",
1354
+ validate = true
1355
+ }) {
1356
+ const fileContent = await readFileContent((0, import_node_path14.join)(baseDir, ".junieignore"));
1394
1357
  return new _JunieIgnore({
1395
- baseDir: ".",
1358
+ baseDir,
1396
1359
  relativeDirPath: ".",
1397
1360
  relativeFilePath: ".junieignore",
1398
- fileContent
1361
+ fileContent,
1362
+ validate
1399
1363
  });
1400
1364
  }
1401
1365
  };
1402
1366
 
1403
1367
  // src/ignore/kiro-ignore.ts
1368
+ var import_node_path15 = require("path");
1404
1369
  var KiroIgnore = class _KiroIgnore extends ToolIgnore {
1405
1370
  toRulesyncIgnore() {
1406
1371
  return this.toRulesyncIgnoreDefault();
@@ -1416,18 +1381,23 @@ var KiroIgnore = class _KiroIgnore extends ToolIgnore {
1416
1381
  fileContent: rulesyncIgnore.getFileContent()
1417
1382
  });
1418
1383
  }
1419
- static async fromFile() {
1420
- const fileContent = await readFileContent(".aiignore");
1384
+ static async fromFile({
1385
+ baseDir = ".",
1386
+ validate = true
1387
+ }) {
1388
+ const fileContent = await readFileContent((0, import_node_path15.join)(baseDir, ".aiignore"));
1421
1389
  return new _KiroIgnore({
1422
- baseDir: ".",
1390
+ baseDir,
1423
1391
  relativeDirPath: ".",
1424
1392
  relativeFilePath: ".aiignore",
1425
- fileContent
1393
+ fileContent,
1394
+ validate
1426
1395
  });
1427
1396
  }
1428
1397
  };
1429
1398
 
1430
1399
  // src/ignore/qwencode-ignore.ts
1400
+ var import_node_path16 = require("path");
1431
1401
  var QwencodeIgnore = class _QwencodeIgnore extends ToolIgnore {
1432
1402
  toRulesyncIgnore() {
1433
1403
  return this.toRulesyncIgnoreDefault();
@@ -1443,18 +1413,23 @@ var QwencodeIgnore = class _QwencodeIgnore extends ToolIgnore {
1443
1413
  fileContent: rulesyncIgnore.getFileContent()
1444
1414
  });
1445
1415
  }
1446
- static async fromFile() {
1447
- const fileContent = await readFileContent(".geminiignore");
1416
+ static async fromFile({
1417
+ baseDir = ".",
1418
+ validate = true
1419
+ }) {
1420
+ const fileContent = await readFileContent((0, import_node_path16.join)(baseDir, ".geminiignore"));
1448
1421
  return new _QwencodeIgnore({
1449
- baseDir: ".",
1422
+ baseDir,
1450
1423
  relativeDirPath: ".",
1451
1424
  relativeFilePath: ".geminiignore",
1452
- fileContent
1425
+ fileContent,
1426
+ validate
1453
1427
  });
1454
1428
  }
1455
1429
  };
1456
1430
 
1457
1431
  // src/ignore/roo-ignore.ts
1432
+ var import_node_path17 = require("path");
1458
1433
  var RooIgnore = class _RooIgnore extends ToolIgnore {
1459
1434
  toRulesyncIgnore() {
1460
1435
  return this.toRulesyncIgnoreDefault();
@@ -1470,18 +1445,23 @@ var RooIgnore = class _RooIgnore extends ToolIgnore {
1470
1445
  fileContent: rulesyncIgnore.getFileContent()
1471
1446
  });
1472
1447
  }
1473
- static async fromFile() {
1474
- const fileContent = await readFileContent(".rooignore");
1448
+ static async fromFile({
1449
+ baseDir = ".",
1450
+ validate = true
1451
+ }) {
1452
+ const fileContent = await readFileContent((0, import_node_path17.join)(baseDir, ".rooignore"));
1475
1453
  return new _RooIgnore({
1476
- baseDir: ".",
1454
+ baseDir,
1477
1455
  relativeDirPath: ".",
1478
1456
  relativeFilePath: ".rooignore",
1479
- fileContent
1457
+ fileContent,
1458
+ validate
1480
1459
  });
1481
1460
  }
1482
1461
  };
1483
1462
 
1484
1463
  // src/ignore/windsurf-ignore.ts
1464
+ var import_node_path18 = require("path");
1485
1465
  var WindsurfIgnore = class _WindsurfIgnore extends ToolIgnore {
1486
1466
  toRulesyncIgnore() {
1487
1467
  return this.toRulesyncIgnoreDefault();
@@ -1497,6 +1477,19 @@ var WindsurfIgnore = class _WindsurfIgnore extends ToolIgnore {
1497
1477
  fileContent: rulesyncIgnore.getFileContent()
1498
1478
  });
1499
1479
  }
1480
+ static async fromFile({
1481
+ baseDir = ".",
1482
+ validate = true
1483
+ }) {
1484
+ const fileContent = await readFileContent((0, import_node_path18.join)(baseDir, ".codeiumignore"));
1485
+ return new _WindsurfIgnore({
1486
+ baseDir,
1487
+ relativeDirPath: ".",
1488
+ relativeFilePath: ".codeiumignore",
1489
+ fileContent,
1490
+ validate
1491
+ });
1492
+ }
1500
1493
  };
1501
1494
 
1502
1495
  // src/ignore/ignore-processor.ts
@@ -1554,25 +1547,25 @@ var IgnoreProcessor = class extends FeatureProcessor {
1554
1547
  async loadToolIgnores() {
1555
1548
  switch (this.toolTarget) {
1556
1549
  case "augmentcode":
1557
- return [await AugmentcodeIgnore.fromFile()];
1550
+ return [await AugmentcodeIgnore.fromFile({ baseDir: this.baseDir })];
1558
1551
  case "cline":
1559
- return [await ClineIgnore.fromFile()];
1552
+ return [await ClineIgnore.fromFile({ baseDir: this.baseDir })];
1560
1553
  case "codexcli":
1561
- return [await CodexcliIgnore.fromFile()];
1554
+ return [await CodexcliIgnore.fromFile({ baseDir: this.baseDir })];
1562
1555
  case "cursor":
1563
- return [await CursorIgnore.fromFile()];
1556
+ return [await CursorIgnore.fromFile({ baseDir: this.baseDir })];
1564
1557
  case "geminicli":
1565
- return [await GeminiCliIgnore.fromFile()];
1558
+ return [await GeminiCliIgnore.fromFile({ baseDir: this.baseDir })];
1566
1559
  case "junie":
1567
- return [await JunieIgnore.fromFile()];
1560
+ return [await JunieIgnore.fromFile({ baseDir: this.baseDir })];
1568
1561
  case "kiro":
1569
- return [await KiroIgnore.fromFile()];
1562
+ return [await KiroIgnore.fromFile({ baseDir: this.baseDir })];
1570
1563
  case "qwencode":
1571
- return [await QwencodeIgnore.fromFile()];
1564
+ return [await QwencodeIgnore.fromFile({ baseDir: this.baseDir })];
1572
1565
  case "roo":
1573
- return [await RooIgnore.fromFile()];
1566
+ return [await RooIgnore.fromFile({ baseDir: this.baseDir })];
1574
1567
  case "windsurf":
1575
- return [await WindsurfIgnore.fromFile()];
1568
+ return [await WindsurfIgnore.fromFile({ baseDir: this.baseDir })];
1576
1569
  default:
1577
1570
  throw new Error(`Unsupported tool target: ${this.toolTarget}`);
1578
1571
  }
@@ -1667,9 +1660,14 @@ var IgnoreProcessor = class extends FeatureProcessor {
1667
1660
  };
1668
1661
 
1669
1662
  // src/mcp/mcp-processor.ts
1670
- var import_node_path8 = require("path");
1671
1663
  var import_mini11 = require("zod/mini");
1672
1664
 
1665
+ // src/mcp/amazonqcli-mcp.ts
1666
+ var import_node_path20 = require("path");
1667
+
1668
+ // src/mcp/rulesync-mcp.ts
1669
+ var import_node_path19 = require("path");
1670
+
1673
1671
  // src/types/mcp.ts
1674
1672
  var import_mini10 = require("zod/mini");
1675
1673
  var McpTransportTypeSchema = import_mini10.z.enum(["stdio", "sse", "http"]);
@@ -1718,14 +1716,14 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
1718
1716
  validate() {
1719
1717
  return { success: true, error: null };
1720
1718
  }
1721
- static async fromFilePath({ filePath }) {
1722
- const fileContent = await readFileContent(filePath);
1719
+ static async fromFile({ validate = true }) {
1720
+ const fileContent = await readFileContent((0, import_node_path19.join)(RULESYNC_DIR, ".mcp.json"));
1723
1721
  return new _RulesyncMcp({
1724
1722
  baseDir: ".",
1725
- relativeDirPath: ".rulesync",
1723
+ relativeDirPath: RULESYNC_DIR,
1726
1724
  relativeFilePath: ".mcp.json",
1727
1725
  fileContent,
1728
- validate: true
1726
+ validate
1729
1727
  });
1730
1728
  }
1731
1729
  getJson() {
@@ -1761,7 +1759,7 @@ var ToolMcp = class extends ToolFile {
1761
1759
  fileContent: this.fileContent
1762
1760
  });
1763
1761
  }
1764
- static async fromFilePath(_params) {
1762
+ static async fromFile(_params) {
1765
1763
  throw new Error("Please implement this method in the subclass.");
1766
1764
  }
1767
1765
  static fromRulesyncMcp(_params) {
@@ -1771,14 +1769,17 @@ var ToolMcp = class extends ToolFile {
1771
1769
 
1772
1770
  // src/mcp/amazonqcli-mcp.ts
1773
1771
  var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
1774
- static async fromFilePath({ filePath }) {
1775
- const fileContent = await readFileContent(filePath);
1772
+ static async fromFile({
1773
+ baseDir = ".",
1774
+ validate = true
1775
+ }) {
1776
+ const fileContent = await readFileContent((0, import_node_path20.join)(baseDir, ".amazonq/mcp.json"));
1776
1777
  return new _AmazonqcliMcp({
1777
- baseDir: ".",
1778
+ baseDir,
1778
1779
  relativeDirPath: ".amazonq",
1779
- relativeFilePath: ".mcp.json",
1780
+ relativeFilePath: "mcp.json",
1780
1781
  fileContent,
1781
- validate: true
1782
+ validate
1782
1783
  });
1783
1784
  }
1784
1785
  static fromRulesyncMcp({
@@ -1803,15 +1804,19 @@ var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
1803
1804
  };
1804
1805
 
1805
1806
  // src/mcp/claudecode-mcp.ts
1807
+ var import_node_path21 = require("path");
1806
1808
  var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
1807
- static async fromFilePath({ filePath }) {
1808
- const fileContent = await readFileContent(filePath);
1809
+ static async fromFile({
1810
+ baseDir = ".",
1811
+ validate = true
1812
+ }) {
1813
+ const fileContent = await readFileContent((0, import_node_path21.join)(baseDir, ".mcp.json"));
1809
1814
  return new _ClaudecodeMcp({
1810
1815
  baseDir: ".",
1811
1816
  relativeDirPath: ".",
1812
1817
  relativeFilePath: ".mcp.json",
1813
1818
  fileContent,
1814
- validate: true
1819
+ validate
1815
1820
  });
1816
1821
  }
1817
1822
  static fromRulesyncMcp({
@@ -1836,15 +1841,19 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
1836
1841
  };
1837
1842
 
1838
1843
  // src/mcp/cline-mcp.ts
1844
+ var import_node_path22 = require("path");
1839
1845
  var ClineMcp = class _ClineMcp extends ToolMcp {
1840
- static async fromFilePath({ filePath }) {
1841
- const fileContent = await readFileContent(filePath);
1846
+ static async fromFile({
1847
+ baseDir = ".",
1848
+ validate = true
1849
+ }) {
1850
+ const fileContent = await readFileContent((0, import_node_path22.join)(baseDir, ".cline/mcp.json"));
1842
1851
  return new _ClineMcp({
1843
1852
  baseDir: ".",
1844
1853
  relativeDirPath: ".cline",
1845
1854
  relativeFilePath: "mcp.json",
1846
1855
  fileContent,
1847
- validate: true
1856
+ validate
1848
1857
  });
1849
1858
  }
1850
1859
  static fromRulesyncMcp({
@@ -1869,15 +1878,19 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
1869
1878
  };
1870
1879
 
1871
1880
  // src/mcp/copilot-mcp.ts
1881
+ var import_node_path23 = require("path");
1872
1882
  var CopilotMcp = class _CopilotMcp extends ToolMcp {
1873
- static async fromFilePath({ filePath }) {
1874
- const fileContent = await readFileContent(filePath);
1883
+ static async fromFilePath({
1884
+ baseDir = ".",
1885
+ validate = true
1886
+ }) {
1887
+ const fileContent = await readFileContent((0, import_node_path23.join)(baseDir, ".vscode/mcp.json"));
1875
1888
  return new _CopilotMcp({
1876
1889
  baseDir: ".",
1877
1890
  relativeDirPath: ".vscode",
1878
1891
  relativeFilePath: "mcp.json",
1879
1892
  fileContent,
1880
- validate: true
1893
+ validate
1881
1894
  });
1882
1895
  }
1883
1896
  static fromRulesyncMcp({
@@ -1902,15 +1915,19 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
1902
1915
  };
1903
1916
 
1904
1917
  // src/mcp/cursor-mcp.ts
1918
+ var import_node_path24 = require("path");
1905
1919
  var CursorMcp = class _CursorMcp extends ToolMcp {
1906
- static async fromFilePath({ filePath }) {
1907
- const fileContent = await readFileContent(filePath);
1920
+ static async fromFile({
1921
+ baseDir = ".",
1922
+ validate = true
1923
+ }) {
1924
+ const fileContent = await readFileContent((0, import_node_path24.join)(baseDir, ".cursor/mcp.json"));
1908
1925
  return new _CursorMcp({
1909
1926
  baseDir: ".",
1910
1927
  relativeDirPath: ".cursor",
1911
1928
  relativeFilePath: "mcp.json",
1912
1929
  fileContent,
1913
- validate: true
1930
+ validate
1914
1931
  });
1915
1932
  }
1916
1933
  static fromRulesyncMcp({
@@ -1946,15 +1963,19 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
1946
1963
  };
1947
1964
 
1948
1965
  // src/mcp/roo-mcp.ts
1966
+ var import_node_path25 = require("path");
1949
1967
  var RooMcp = class _RooMcp extends ToolMcp {
1950
- static async fromFilePath({ filePath }) {
1951
- const fileContent = await readFileContent(filePath);
1968
+ static async fromFile({
1969
+ baseDir = ".",
1970
+ validate = true
1971
+ }) {
1972
+ const fileContent = await readFileContent((0, import_node_path25.join)(baseDir, ".roo/mcp.json"));
1952
1973
  return new _RooMcp({
1953
1974
  baseDir: ".",
1954
1975
  relativeDirPath: ".roo",
1955
1976
  relativeFilePath: "mcp.json",
1956
1977
  fileContent,
1957
- validate: true
1978
+ validate
1958
1979
  });
1959
1980
  }
1960
1981
  static fromRulesyncMcp({
@@ -2004,9 +2025,7 @@ var McpProcessor = class extends FeatureProcessor {
2004
2025
  */
2005
2026
  async loadRulesyncFiles() {
2006
2027
  try {
2007
- return [
2008
- await RulesyncMcp.fromFilePath({ filePath: (0, import_node_path8.join)(this.baseDir, ".rulesync", ".mcp.json") })
2009
- ];
2028
+ return [await RulesyncMcp.fromFile({})];
2010
2029
  } catch (error) {
2011
2030
  logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
2012
2031
  return [];
@@ -2018,42 +2037,62 @@ var McpProcessor = class extends FeatureProcessor {
2018
2037
  */
2019
2038
  async loadToolFiles() {
2020
2039
  try {
2021
- switch (this.toolTarget) {
2022
- case "amazonqcli": {
2023
- return [
2024
- await AmazonqcliMcp.fromFilePath({
2025
- filePath: (0, import_node_path8.join)(this.baseDir, ".amazonq", "mcp.json")
2026
- })
2027
- ];
2028
- }
2029
- case "claudecode": {
2030
- return [
2031
- await ClaudecodeMcp.fromFilePath({
2032
- filePath: (0, import_node_path8.join)(this.baseDir, ".mcp.json")
2033
- })
2034
- ];
2035
- }
2036
- case "cline": {
2037
- return [
2038
- await ClineMcp.fromFilePath({ filePath: (0, import_node_path8.join)(this.baseDir, ".cline", "mcp.json") })
2039
- ];
2040
- }
2041
- case "copilot": {
2042
- return [
2043
- await CopilotMcp.fromFilePath({ filePath: (0, import_node_path8.join)(this.baseDir, ".vscode", "mcp.json") })
2044
- ];
2045
- }
2046
- case "cursor": {
2047
- return [
2048
- await CursorMcp.fromFilePath({ filePath: (0, import_node_path8.join)(this.baseDir, ".cursor", "mcp.json") })
2049
- ];
2050
- }
2051
- case "roo": {
2052
- return [await RooMcp.fromFilePath({ filePath: (0, import_node_path8.join)(this.baseDir, ".roo", "mcp.json") })];
2040
+ const toolMcps = await (async () => {
2041
+ switch (this.toolTarget) {
2042
+ case "amazonqcli": {
2043
+ return [
2044
+ await AmazonqcliMcp.fromFile({
2045
+ baseDir: this.baseDir,
2046
+ validate: true
2047
+ })
2048
+ ];
2049
+ }
2050
+ case "claudecode": {
2051
+ return [
2052
+ await ClaudecodeMcp.fromFile({
2053
+ baseDir: this.baseDir,
2054
+ validate: true
2055
+ })
2056
+ ];
2057
+ }
2058
+ case "cline": {
2059
+ return [
2060
+ await ClineMcp.fromFile({
2061
+ baseDir: this.baseDir,
2062
+ validate: true
2063
+ })
2064
+ ];
2065
+ }
2066
+ case "copilot": {
2067
+ return [
2068
+ await CopilotMcp.fromFile({
2069
+ baseDir: this.baseDir,
2070
+ validate: true
2071
+ })
2072
+ ];
2073
+ }
2074
+ case "cursor": {
2075
+ return [
2076
+ await CursorMcp.fromFile({
2077
+ baseDir: this.baseDir,
2078
+ validate: true
2079
+ })
2080
+ ];
2081
+ }
2082
+ case "roo": {
2083
+ return [
2084
+ await RooMcp.fromFile({
2085
+ baseDir: this.baseDir,
2086
+ validate: true
2087
+ })
2088
+ ];
2089
+ }
2090
+ default:
2091
+ throw new Error(`Unsupported tool target: ${this.toolTarget}`);
2053
2092
  }
2054
- default:
2055
- throw new Error(`Unsupported tool target: ${this.toolTarget}`);
2056
- }
2093
+ })();
2094
+ logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
2095
+ return toolMcps;
2057
2096
  } catch (error) {
2058
2097
  logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
2059
2098
  return [];
@@ -2129,21 +2168,15 @@ var McpProcessor = class extends FeatureProcessor {
2129
2168
  };
2130
2169
 
2131
2170
  // src/rules/rules-processor.ts
2132
- var import_node_path12 = require("path");
2171
+ var import_node_path44 = require("path");
2133
2172
  var import_fast_xml_parser = require("fast-xml-parser");
2134
2173
  var import_mini16 = require("zod/mini");
2135
2174
 
2136
- // src/constants/paths.ts
2137
- var import_node_path9 = require("path");
2138
- var RULESYNC_DIR = ".rulesync";
2139
- var RULESYNC_RULES_DIR = (0, import_node_path9.join)(".rulesync", "rules");
2140
- var RULESYNC_RULES_DIR_LEGACY = ".rulesync";
2141
- var RULESYNC_MCP_FILE = (0, import_node_path9.join)(".rulesync", ".mcp.json");
2142
- var RULESYNC_COMMANDS_DIR = (0, import_node_path9.join)(".rulesync", "commands");
2143
- var RULESYNC_SUBAGENTS_DIR = (0, import_node_path9.join)(".rulesync", "subagents");
2175
+ // src/rules/agentsmd-rule.ts
2176
+ var import_node_path27 = require("path");
2144
2177
 
2145
2178
  // src/rules/rulesync-rule.ts
2146
- var import_node_path10 = require("path");
2179
+ var import_node_path26 = require("path");
2147
2180
  var import_mini12 = require("zod/mini");
2148
2181
  var RulesyncRuleFrontmatterSchema = import_mini12.z.object({
2149
2182
  root: import_mini12.z.optional(import_mini12.z.optional(import_mini12.z.boolean())),
@@ -2189,10 +2222,11 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
2189
2222
  return { success: false, error: result.error };
2190
2223
  }
2191
2224
  }
2192
- static async fromLegacyFile({
2193
- relativeFilePath
2225
+ static async fromFileLegacy({
2226
+ relativeFilePath,
2227
+ validate = true
2194
2228
  }) {
2195
- const filePath = (0, import_node_path10.join)(RULESYNC_RULES_DIR_LEGACY, relativeFilePath);
2229
+ const filePath = (0, import_node_path26.join)(RULESYNC_RULES_DIR_LEGACY, relativeFilePath);
2196
2230
  const fileContent = await readFileContent(filePath);
2197
2231
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
2198
2232
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
@@ -2206,16 +2240,21 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
2206
2240
  globs: result.data.globs ?? [],
2207
2241
  cursor: result.data.cursor
2208
2242
  };
2209
- const filename = (0, import_node_path10.basename)(filePath);
2243
+ const filename = (0, import_node_path26.basename)(filePath);
2210
2244
  return new _RulesyncRule({
2211
2245
  baseDir: ".",
2212
2246
  relativeDirPath: RULESYNC_RULES_DIR,
2213
2247
  relativeFilePath: filename,
2214
2248
  frontmatter: validatedFrontmatter,
2215
- body: content.trim()
2249
+ body: content.trim(),
2250
+ validate
2216
2251
  });
2217
2252
  }
2218
- static async fromFilePath({ filePath }) {
2253
+ static async fromFile({
2254
+ relativeFilePath,
2255
+ validate = true
2256
+ }) {
2257
+ const filePath = (0, import_node_path26.join)(RULESYNC_RULES_DIR, relativeFilePath);
2219
2258
  const fileContent = await readFileContent(filePath);
2220
2259
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
2221
2260
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
@@ -2229,13 +2268,14 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
2229
2268
  globs: result.data.globs ?? [],
2230
2269
  cursor: result.data.cursor
2231
2270
  };
2232
- const filename = (0, import_node_path10.basename)(filePath);
2271
+ const filename = (0, import_node_path26.basename)(filePath);
2233
2272
  return new _RulesyncRule({
2234
2273
  baseDir: ".",
2235
2274
  relativeDirPath: RULESYNC_RULES_DIR,
2236
2275
  relativeFilePath: filename,
2237
2276
  frontmatter: validatedFrontmatter,
2238
- body: content.trim()
2277
+ body: content.trim(),
2278
+ validate
2239
2279
  });
2240
2280
  }
2241
2281
  getBody() {
@@ -2250,7 +2290,7 @@ var ToolRule = class extends ToolFile {
2250
2290
  super(rest);
2251
2291
  this.root = root;
2252
2292
  }
2253
- static async fromFilePath(_params) {
2293
+ static async fromFile(_params) {
2254
2294
  throw new Error("Please implement this method in the subclass.");
2255
2295
  }
2256
2296
  static fromRulesyncRule(_params) {
@@ -2301,19 +2341,18 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
2301
2341
  root: root ?? false
2302
2342
  });
2303
2343
  }
2304
- static async fromFilePath({
2344
+ static async fromFile({
2305
2345
  baseDir = ".",
2306
- relativeDirPath,
2307
2346
  relativeFilePath,
2308
- filePath,
2309
2347
  validate = true
2310
2348
  }) {
2311
- const fileContent = await readFileContent(filePath);
2312
2349
  const isRoot = relativeFilePath === "AGENTS.md";
2350
+ const relativePath = isRoot ? "AGENTS.md" : (0, import_node_path27.join)(".agents/memories", relativeFilePath);
2351
+ const fileContent = await readFileContent((0, import_node_path27.join)(baseDir, relativePath));
2313
2352
  return new _AgentsMdRule({
2314
2353
  baseDir,
2315
- relativeDirPath,
2316
- relativeFilePath,
2354
+ relativeDirPath: isRoot ? "." : ".agents/memories",
2355
+ relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
2317
2356
  fileContent,
2318
2357
  validate,
2319
2358
  root: isRoot
@@ -2341,15 +2380,20 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
2341
2380
  };
2342
2381
 
2343
2382
  // src/rules/amazonqcli-rule.ts
2383
+ var import_node_path28 = require("path");
2344
2384
  var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
2345
- static async fromFilePath(params) {
2346
- const fileContent = await readFileContent(params.filePath);
2385
+ static async fromFile({
2386
+ baseDir = ".",
2387
+ relativeFilePath,
2388
+ validate = true
2389
+ }) {
2390
+ const fileContent = await readFileContent((0, import_node_path28.join)(baseDir, ".amazonq/rules", relativeFilePath));
2347
2391
  return new _AmazonQCliRule({
2348
- baseDir: params.baseDir || ".",
2349
- relativeDirPath: params.relativeDirPath,
2350
- relativeFilePath: params.relativeFilePath,
2392
+ baseDir,
2393
+ relativeDirPath: ".amazonq/rules",
2394
+ relativeFilePath,
2351
2395
  fileContent,
2352
- validate: params.validate ?? false,
2396
+ validate,
2353
2397
  root: false
2354
2398
  });
2355
2399
  }
@@ -2376,6 +2420,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
2376
2420
  };
2377
2421
 
2378
2422
  // src/rules/augmentcode-legacy-rule.ts
2423
+ var import_node_path29 = require("path");
2379
2424
  var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
2380
2425
  toRulesyncRule() {
2381
2426
  const rulesyncFrontmatter = {
@@ -2411,19 +2456,18 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
2411
2456
  validate() {
2412
2457
  return { success: true, error: null };
2413
2458
  }
2414
- static async fromFilePath({
2459
+ static async fromFile({
2415
2460
  baseDir = ".",
2416
- relativeDirPath,
2417
2461
  relativeFilePath,
2418
- filePath,
2419
2462
  validate = true
2420
2463
  }) {
2421
- const fileContent = await readFileContent(filePath);
2422
2464
  const isRoot = relativeFilePath === ".augment-guidelines";
2465
+ const relativePath = isRoot ? ".augment-guidelines" : (0, import_node_path29.join)(".augment/rules", relativeFilePath);
2466
+ const fileContent = await readFileContent((0, import_node_path29.join)(baseDir, relativePath));
2423
2467
  return new _AugmentcodeLegacyRule({
2424
2468
  baseDir,
2425
- relativeDirPath,
2426
- relativeFilePath,
2469
+ relativeDirPath: isRoot ? "." : ".augment/rules",
2470
+ relativeFilePath: isRoot ? ".augment-guidelines" : relativeFilePath,
2427
2471
  fileContent,
2428
2472
  validate,
2429
2473
  root: isRoot
@@ -2432,6 +2476,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
2432
2476
  };
2433
2477
 
2434
2478
  // src/rules/augmentcode-rule.ts
2479
+ var import_node_path30 = require("path");
2435
2480
  var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
2436
2481
  toRulesyncRule() {
2437
2482
  return this.toRulesyncRuleDefault();
@@ -2450,18 +2495,16 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
2450
2495
  })
2451
2496
  );
2452
2497
  }
2453
- static async fromFilePath({
2498
+ static async fromFile({
2454
2499
  baseDir = ".",
2455
- relativeDirPath,
2456
2500
  relativeFilePath,
2457
- filePath,
2458
2501
  validate = true
2459
2502
  }) {
2460
- const fileContent = await readFileContent(filePath);
2503
+ const fileContent = await readFileContent((0, import_node_path30.join)(baseDir, ".augment/rules", relativeFilePath));
2461
2504
  const { body: content } = parseFrontmatter(fileContent);
2462
2505
  return new _AugmentcodeRule({
2463
2506
  baseDir,
2464
- relativeDirPath,
2507
+ relativeDirPath: ".augment/rules",
2465
2508
  relativeFilePath,
2466
2509
  fileContent: content.trim(),
2467
2510
  validate
@@ -2473,16 +2516,23 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
2473
2516
  };
2474
2517
 
2475
2518
  // src/rules/claudecode-rule.ts
2519
+ var import_node_path31 = require("path");
2476
2520
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
2477
- static async fromFilePath(params) {
2478
- const fileContent = await readFileContent(params.filePath);
2521
+ static async fromFile({
2522
+ baseDir = ".",
2523
+ relativeFilePath,
2524
+ validate = true
2525
+ }) {
2526
+ const isRoot = relativeFilePath === "CLAUDE.md";
2527
+ const relativePath = isRoot ? "CLAUDE.md" : (0, import_node_path31.join)(".claude/memories", relativeFilePath);
2528
+ const fileContent = await readFileContent((0, import_node_path31.join)(baseDir, relativePath));
2479
2529
  return new _ClaudecodeRule({
2480
- baseDir: params.baseDir || process.cwd(),
2481
- relativeDirPath: params.relativeDirPath,
2482
- relativeFilePath: params.relativeFilePath,
2530
+ baseDir,
2531
+ relativeDirPath: isRoot ? "." : ".claude/memories",
2532
+ relativeFilePath: isRoot ? "CLAUDE.md" : relativeFilePath,
2483
2533
  fileContent,
2484
- validate: params.validate ?? true,
2485
- root: params.relativeFilePath === "CLAUDE.md"
2534
+ validate,
2535
+ root: isRoot
2486
2536
  });
2487
2537
  }
2488
2538
  static fromRulesyncRule({
@@ -2509,6 +2559,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
2509
2559
  };
2510
2560
 
2511
2561
  // src/rules/cline-rule.ts
2562
+ var import_node_path32 = require("path");
2512
2563
  var import_mini13 = require("zod/mini");
2513
2564
  var ClineRuleFrontmatterSchema = import_mini13.z.object({
2514
2565
  description: import_mini13.z.string()
@@ -2534,17 +2585,15 @@ var ClineRule = class _ClineRule extends ToolRule {
2534
2585
  validate() {
2535
2586
  return { success: true, error: null };
2536
2587
  }
2537
- static async fromFilePath({
2588
+ static async fromFile({
2538
2589
  baseDir = ".",
2539
- relativeDirPath,
2540
2590
  relativeFilePath,
2541
- filePath,
2542
2591
  validate = true
2543
2592
  }) {
2544
- const fileContent = await readFileContent(filePath);
2593
+ const fileContent = await readFileContent((0, import_node_path32.join)(baseDir, ".clinerules", relativeFilePath));
2545
2594
  return new _ClineRule({
2546
2595
  baseDir,
2547
- relativeDirPath,
2596
+ relativeDirPath: ".clinerules",
2548
2597
  relativeFilePath,
2549
2598
  fileContent,
2550
2599
  validate
@@ -2553,16 +2602,23 @@ var ClineRule = class _ClineRule extends ToolRule {
2553
2602
  };
2554
2603
 
2555
2604
  // src/rules/codexcli-rule.ts
2605
+ var import_node_path33 = require("path");
2556
2606
  var CodexcliRule = class _CodexcliRule extends ToolRule {
2557
- static async fromFilePath(params) {
2558
- const fileContent = await readFileContent(params.filePath);
2607
+ static async fromFile({
2608
+ baseDir = ".",
2609
+ relativeFilePath,
2610
+ validate = true
2611
+ }) {
2612
+ const isRoot = relativeFilePath === "AGENTS.md";
2613
+ const relativePath = isRoot ? "AGENTS.md" : (0, import_node_path33.join)(".codex/memories", relativeFilePath);
2614
+ const fileContent = await readFileContent((0, import_node_path33.join)(baseDir, relativePath));
2559
2615
  return new _CodexcliRule({
2560
- baseDir: params.baseDir || process.cwd(),
2561
- relativeDirPath: params.relativeDirPath,
2562
- relativeFilePath: params.relativeFilePath,
2616
+ baseDir,
2617
+ relativeDirPath: isRoot ? "." : ".codex/memories",
2618
+ relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
2563
2619
  fileContent,
2564
- validate: params.validate ?? true,
2565
- root: params.relativeFilePath === "AGENTS.md"
2620
+ validate,
2621
+ root: isRoot
2566
2622
  });
2567
2623
  }
2568
2624
  static fromRulesyncRule({
@@ -2589,6 +2645,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
2589
2645
  };
2590
2646
 
2591
2647
  // src/rules/copilot-rule.ts
2648
+ var import_node_path34 = require("path");
2592
2649
  var import_mini14 = require("zod/mini");
2593
2650
  var CopilotRuleFrontmatterSchema = import_mini14.z.object({
2594
2651
  description: import_mini14.z.optional(import_mini14.z.string()),
@@ -2663,45 +2720,43 @@ var CopilotRule = class _CopilotRule extends ToolRule {
2663
2720
  root
2664
2721
  });
2665
2722
  }
2666
- static async fromFilePath({
2723
+ static async fromFile({
2667
2724
  baseDir = ".",
2668
- relativeDirPath,
2669
2725
  relativeFilePath,
2670
- filePath,
2671
2726
  validate = true
2672
2727
  }) {
2673
- const fileContent = await readFileContent(filePath);
2674
- const root = relativeFilePath === "copilot-instructions.md";
2675
- if (root) {
2728
+ const isRoot = relativeFilePath === "copilot-instructions.md";
2729
+ const relativePath = isRoot ? "copilot-instructions.md" : (0, import_node_path34.join)(".github/instructions", relativeFilePath);
2730
+ const fileContent = await readFileContent((0, import_node_path34.join)(baseDir, relativePath));
2731
+ if (isRoot) {
2676
2732
  return new _CopilotRule({
2677
2733
  baseDir,
2678
- relativeDirPath,
2679
- relativeFilePath,
2734
+ relativeDirPath: ".github",
2735
+ relativeFilePath: isRoot ? "copilot-instructions.md" : relativeFilePath,
2680
2736
  frontmatter: {
2681
2737
  description: "",
2682
2738
  applyTo: "**"
2683
2739
  },
2684
2740
  body: fileContent.trim(),
2685
2741
  validate,
2686
- root
2742
+ root: isRoot
2687
2743
  });
2688
2744
  }
2689
2745
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
2690
2746
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
2691
2747
  if (!result.success) {
2692
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
2748
+ throw new Error(
2749
+ `Invalid frontmatter in ${(0, import_node_path34.join)(baseDir, relativeFilePath)}: ${result.error.message}`
2750
+ );
2693
2751
  }
2694
2752
  return new _CopilotRule({
2695
2753
  baseDir,
2696
- relativeDirPath,
2697
- relativeFilePath,
2698
- frontmatter: {
2699
- ...result.data,
2700
- applyTo: result.data.applyTo || "**"
2701
- },
2754
+ relativeDirPath: ".github/instructions",
2755
+ relativeFilePath: relativeFilePath.replace(/\.md$/, ".instructions.md"),
2756
+ frontmatter: result.data,
2702
2757
  body: content.trim(),
2703
2758
  validate,
2704
- root
2759
+ root: isRoot
2705
2760
  });
2706
2761
  }
2707
2762
  validate() {
@@ -2724,7 +2779,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
2724
2779
  };
2725
2780
 
2726
2781
  // src/rules/cursor-rule.ts
2727
- var import_node_path11 = require("path");
2782
+ var import_node_path35 = require("path");
2728
2783
  var import_mini15 = require("zod/mini");
2729
2784
  var CursorRuleFrontmatterSchema = import_mini15.z.object({
2730
2785
  description: import_mini15.z.optional(import_mini15.z.string()),
@@ -2743,11 +2798,49 @@ var CursorRule = class _CursorRule extends ToolRule {
2743
2798
  }
2744
2799
  super({
2745
2800
  ...rest,
2746
- fileContent: stringifyFrontmatter(body, frontmatter)
2801
+ fileContent: _CursorRule.stringifyCursorFrontmatter(body, frontmatter)
2747
2802
  });
2748
2803
  this.frontmatter = frontmatter;
2749
2804
  this.body = body;
2750
2805
  }
2806
+ /**
2807
+ * Custom stringify function for Cursor MDC files
2808
+ * MDC files don't support quotes in YAML, so globs patterns must be output without quotes
2809
+ */
2810
+ static stringifyCursorFrontmatter(body, frontmatter) {
2811
+ if (!frontmatter.globs || typeof frontmatter.globs !== "string" || !frontmatter.globs.includes("*")) {
2812
+ return stringifyFrontmatter(body, frontmatter);
2813
+ }
2814
+ const lines = ["---"];
2815
+ if (frontmatter.alwaysApply !== void 0) {
2816
+ lines.push(`alwaysApply: ${frontmatter.alwaysApply}`);
2817
+ }
2818
+ if (frontmatter.description !== void 0) {
2819
+ lines.push(`description: ${frontmatter.description}`);
2820
+ }
2821
+ if (frontmatter.globs !== void 0) {
2822
+ lines.push(`globs: ${frontmatter.globs}`);
2823
+ }
2824
+ lines.push("---");
2825
+ lines.push("");
2826
+ if (body) {
2827
+ lines.push(body);
2828
+ }
2829
+ return lines.join("\n");
2830
+ }
2831
+ /**
2832
+ * Custom parse function for Cursor MDC files
2833
+ * MDC files don't support quotes in YAML, so we need to handle patterns like *.ts specially
2834
+ */
2835
+ static parseCursorFrontmatter(fileContent) {
2836
+ const preprocessedContent = fileContent.replace(
2837
+ /^globs:\s*(\*[^\n]*?)$/m,
2838
+ (_match, globPattern) => {
2839
+ return `globs: "${globPattern}"`;
2840
+ }
2841
+ );
2842
+ return parseFrontmatter(preprocessedContent);
2843
+ }
2751
2844
  toRulesyncRule() {
2752
2845
  const targets = ["*"];
2753
2846
  const isAlways = this.frontmatter.alwaysApply === true;
@@ -2764,13 +2857,18 @@ var CursorRule = class _CursorRule extends ToolRule {
2764
2857
  targets,
2765
2858
  root: false,
2766
2859
  description: this.frontmatter.description,
2767
- globs
2860
+ globs,
2861
+ cursor: {
2862
+ alwaysApply: this.frontmatter.alwaysApply,
2863
+ description: this.frontmatter.description,
2864
+ globs: globs.length > 0 ? globs : void 0
2865
+ }
2768
2866
  };
2769
2867
  return new RulesyncRule({
2770
2868
  frontmatter: rulesyncFrontmatter,
2771
2869
  body: this.body,
2772
2870
  relativeDirPath: ".rulesync/rules",
2773
- relativeFilePath: this.relativeFilePath,
2871
+ relativeFilePath: this.relativeFilePath.replace(/\.mdc$/, ".md"),
2774
2872
  validate: true
2775
2873
  });
2776
2874
  }
@@ -2798,20 +2896,23 @@ var CursorRule = class _CursorRule extends ToolRule {
2798
2896
  validate
2799
2897
  });
2800
2898
  }
2801
- static async fromFilePath({
2802
- filePath,
2899
+ static async fromFile({
2900
+ baseDir = ".",
2901
+ relativeFilePath,
2803
2902
  validate = true
2804
2903
  }) {
2805
- const fileContent = await readFileContent(filePath);
2806
- const { frontmatter, body: content } = parseFrontmatter(fileContent);
2904
+ const fileContent = await readFileContent((0, import_node_path35.join)(baseDir, ".cursor/rules", relativeFilePath));
2905
+ const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
2807
2906
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
2808
2907
  if (!result.success) {
2809
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
2908
+ throw new Error(
2909
+ `Invalid frontmatter in ${(0, import_node_path35.join)(baseDir, relativeFilePath)}: ${result.error.message}`
2910
+ );
2810
2911
  }
2811
2912
  return new _CursorRule({
2812
- baseDir: ".",
2913
+ baseDir,
2813
2914
  relativeDirPath: ".cursor/rules",
2814
- relativeFilePath: (0, import_node_path11.basename)(filePath),
2915
+ relativeFilePath: (0, import_node_path35.basename)(relativeFilePath),
2815
2916
  frontmatter: result.data,
2816
2917
  body: content.trim(),
2817
2918
  validate
@@ -2837,16 +2938,23 @@ var CursorRule = class _CursorRule extends ToolRule {
2837
2938
  };
2838
2939
 
2839
2940
  // src/rules/geminicli-rule.ts
2941
+ var import_node_path36 = require("path");
2840
2942
  var GeminiCliRule = class _GeminiCliRule extends ToolRule {
2841
- static async fromFilePath(params) {
2842
- const fileContent = await readFileContent(params.filePath);
2943
+ static async fromFile({
2944
+ baseDir = ".",
2945
+ relativeFilePath,
2946
+ validate = true
2947
+ }) {
2948
+ const isRoot = relativeFilePath === "GEMINI.md";
2949
+ const relativePath = isRoot ? "GEMINI.md" : (0, import_node_path36.join)(".gemini/memories", relativeFilePath);
2950
+ const fileContent = await readFileContent((0, import_node_path36.join)(baseDir, relativePath));
2843
2951
  return new _GeminiCliRule({
2844
- baseDir: params.baseDir || process.cwd(),
2845
- relativeDirPath: params.relativeDirPath,
2846
- relativeFilePath: params.relativeFilePath,
2952
+ baseDir,
2953
+ relativeDirPath: isRoot ? "." : ".gemini/memories",
2954
+ relativeFilePath: isRoot ? "GEMINI.md" : relativeFilePath,
2847
2955
  fileContent,
2848
- validate: params.validate ?? true,
2849
- root: params.relativeFilePath === "GEMINI.md"
2956
+ validate,
2957
+ root: isRoot
2850
2958
  });
2851
2959
  }
2852
2960
  static fromRulesyncRule({
@@ -2873,15 +2981,22 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
2873
2981
  };
2874
2982
 
2875
2983
  // src/rules/junie-rule.ts
2984
+ var import_node_path37 = require("path");
2876
2985
  var JunieRule = class _JunieRule extends ToolRule {
2877
- static async fromFilePath(params) {
2878
- const fileContent = await readFileContent(params.filePath);
2986
+ static async fromFile({
2987
+ baseDir = ".",
2988
+ relativeFilePath,
2989
+ validate = true
2990
+ }) {
2991
+ const isRoot = relativeFilePath === "guidelines.md";
2992
+ const relativePath = isRoot ? "guidelines.md" : (0, import_node_path37.join)(".junie/memories", relativeFilePath);
2993
+ const fileContent = await readFileContent((0, import_node_path37.join)(baseDir, relativePath));
2879
2994
  return new _JunieRule({
2880
- baseDir: params.baseDir || ".",
2881
- relativeDirPath: params.relativeDirPath,
2882
- relativeFilePath: params.relativeFilePath,
2995
+ baseDir,
2996
+ relativeDirPath: isRoot ? ".junie" : ".junie/memories",
2997
+ relativeFilePath: isRoot ? "guidelines.md" : relativeFilePath,
2883
2998
  fileContent,
2884
- validate: params.validate ?? true
2999
+ validate
2885
3000
  });
2886
3001
  }
2887
3002
  static fromRulesyncRule({
@@ -2894,8 +3009,8 @@ var JunieRule = class _JunieRule extends ToolRule {
2894
3009
  baseDir,
2895
3010
  rulesyncRule,
2896
3011
  validate,
2897
- rootPath: { relativeDirPath: ".", relativeFilePath: "guidelines.md" },
2898
- nonRootPath: { relativeDirPath: ".junie/guidelines" }
3012
+ rootPath: { relativeDirPath: ".junie", relativeFilePath: "guidelines.md" },
3013
+ nonRootPath: { relativeDirPath: ".junie/memories" }
2899
3014
  })
2900
3015
  );
2901
3016
  }
@@ -2908,15 +3023,20 @@ var JunieRule = class _JunieRule extends ToolRule {
2908
3023
  };
2909
3024
 
2910
3025
  // src/rules/kiro-rule.ts
3026
+ var import_node_path38 = require("path");
2911
3027
  var KiroRule = class _KiroRule extends ToolRule {
2912
- static async fromFilePath(params) {
2913
- const fileContent = await readFileContent(params.filePath);
3028
+ static async fromFile({
3029
+ baseDir = ".",
3030
+ relativeFilePath,
3031
+ validate = true
3032
+ }) {
3033
+ const fileContent = await readFileContent((0, import_node_path38.join)(baseDir, ".kiro/steering", relativeFilePath));
2914
3034
  return new _KiroRule({
2915
- baseDir: params.baseDir || ".",
2916
- relativeDirPath: params.relativeDirPath,
2917
- relativeFilePath: params.relativeFilePath,
3035
+ baseDir,
3036
+ relativeDirPath: ".kiro/steering",
3037
+ relativeFilePath,
2918
3038
  fileContent,
2919
- validate: params.validate ?? true,
3039
+ validate,
2920
3040
  root: false
2921
3041
  });
2922
3042
  }
@@ -2943,21 +3063,22 @@ var KiroRule = class _KiroRule extends ToolRule {
2943
3063
  };
2944
3064
 
2945
3065
  // src/rules/opencode-rule.ts
3066
+ var import_node_path39 = require("path");
2946
3067
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
2947
- static async fromFilePath({
3068
+ static async fromFile({
2948
3069
  baseDir = ".",
2949
- relativeDirPath,
2950
3070
  relativeFilePath,
2951
- filePath,
2952
3071
  validate = true
2953
3072
  }) {
2954
- const fileContent = await readFileContent(filePath);
3073
+ const isRoot = relativeFilePath === "AGENTS.md";
3074
+ const relativePath = isRoot ? "AGENTS.md" : (0, import_node_path39.join)(".opencode/memories", relativeFilePath);
3075
+ const fileContent = await readFileContent((0, import_node_path39.join)(baseDir, relativePath));
2955
3076
  return new _OpenCodeRule({
2956
3077
  baseDir,
2957
- relativeDirPath,
2958
- relativeFilePath,
3078
+ relativeDirPath: isRoot ? "." : ".opencode/memories",
3079
+ relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
2959
3080
  validate,
2960
- root: relativeFilePath === "AGENTS.md",
3081
+ root: isRoot,
2961
3082
  fileContent
2962
3083
  });
2963
3084
  }
@@ -2983,16 +3104,23 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
2983
3104
  };
2984
3105
 
2985
3106
  // src/rules/qwencode-rule.ts
3107
+ var import_node_path40 = require("path");
2986
3108
  var QwencodeRule = class _QwencodeRule extends ToolRule {
2987
- static async fromFilePath(params) {
2988
- const fileContent = await readFileContent(params.filePath);
3109
+ static async fromFile({
3110
+ baseDir = ".",
3111
+ relativeFilePath,
3112
+ validate = true
3113
+ }) {
3114
+ const isRoot = relativeFilePath === "QWEN.md";
3115
+ const relativePath = isRoot ? "QWEN.md" : (0, import_node_path40.join)(".qwencode/memories", relativeFilePath);
3116
+ const fileContent = await readFileContent((0, import_node_path40.join)(baseDir, relativePath));
2989
3117
  return new _QwencodeRule({
2990
- baseDir: params.baseDir || process.cwd(),
2991
- relativeDirPath: params.relativeDirPath,
2992
- relativeFilePath: params.relativeFilePath,
3118
+ baseDir,
3119
+ relativeDirPath: isRoot ? "." : ".qwencode/memories",
3120
+ relativeFilePath: isRoot ? "QWEN.md" : relativeFilePath,
2993
3121
  fileContent,
2994
- validate: params.validate ?? true,
2995
- root: params.relativeFilePath === "QWEN.md"
3122
+ validate,
3123
+ root: isRoot
2996
3124
  });
2997
3125
  }
2998
3126
  static fromRulesyncRule(params) {
@@ -3013,15 +3141,21 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
3013
3141
  };
3014
3142
 
3015
3143
  // src/rules/roo-rule.ts
3144
+ var import_node_path41 = require("path");
3016
3145
  var RooRule = class _RooRule extends ToolRule {
3017
- static async fromFilePath(params) {
3018
- const fileContent = await readFileContent(params.filePath);
3146
+ static async fromFile({
3147
+ baseDir = ".",
3148
+ relativeFilePath,
3149
+ validate = true
3150
+ }) {
3151
+ const fileContent = await readFileContent((0, import_node_path41.join)(baseDir, ".roo/rules", relativeFilePath));
3019
3152
  return new _RooRule({
3020
- baseDir: params.baseDir || ".",
3021
- relativeDirPath: params.relativeDirPath,
3022
- relativeFilePath: params.relativeFilePath,
3153
+ baseDir,
3154
+ relativeDirPath: ".roo/rules",
3155
+ relativeFilePath,
3023
3156
  fileContent,
3024
- validate: params.validate ?? true
3157
+ validate,
3158
+ root: false
3025
3159
  });
3026
3160
  }
3027
3161
  static fromRulesyncRule({
@@ -3062,6 +3196,7 @@ var RooRule = class _RooRule extends ToolRule {
3062
3196
  };
3063
3197
 
3064
3198
  // src/rules/warp-rule.ts
3199
+ var import_node_path42 = require("path");
3065
3200
  var WarpRule = class _WarpRule extends ToolRule {
3066
3201
  constructor({ fileContent, root, ...rest }) {
3067
3202
  super({
@@ -3070,14 +3205,14 @@ var WarpRule = class _WarpRule extends ToolRule {
3070
3205
  root: root ?? false
3071
3206
  });
3072
3207
  }
3073
- static async fromFilePath({
3208
+ static async fromFile({
3074
3209
  baseDir = ".",
3075
3210
  relativeFilePath,
3076
- filePath,
3077
3211
  validate = true
3078
3212
  }) {
3079
- const fileContent = await readFileContent(filePath);
3080
3213
  const isRoot = relativeFilePath === "WARP.md";
3214
+ const relativePath = isRoot ? "WARP.md" : (0, import_node_path42.join)(".warp/memories", relativeFilePath);
3215
+ const fileContent = await readFileContent((0, import_node_path42.join)(baseDir, relativePath));
3081
3216
  return new _WarpRule({
3082
3217
  baseDir,
3083
3218
  relativeDirPath: isRoot ? "." : ".warp",
@@ -3111,14 +3246,20 @@ var WarpRule = class _WarpRule extends ToolRule {
3111
3246
  };
3112
3247
 
3113
3248
  // src/rules/windsurf-rule.ts
3249
+ var import_node_path43 = require("path");
3114
3250
  var WindsurfRule = class _WindsurfRule extends ToolRule {
3115
- static async fromFilePath(params) {
3116
- const fileContent = await readFileContent(params.filePath);
3251
+ static async fromFile({
3252
+ baseDir = ".",
3253
+ relativeFilePath,
3254
+ validate = true
3255
+ }) {
3256
+ const fileContent = await readFileContent((0, import_node_path43.join)(baseDir, ".windsurf/rules", relativeFilePath));
3117
3257
  return new _WindsurfRule({
3118
- baseDir: params.baseDir || ".",
3119
- relativeDirPath: params.relativeDirPath,
3120
- relativeFilePath: params.relativeFilePath,
3121
- fileContent
3258
+ baseDir,
3259
+ relativeDirPath: ".windsurf/rules",
3260
+ relativeFilePath,
3261
+ fileContent,
3262
+ validate
3122
3263
  });
3123
3264
  }
3124
3265
  static fromRulesyncRule({
@@ -3376,57 +3517,18 @@ var RulesProcessor = class extends FeatureProcessor {
3376
3517
  * Load and parse rulesync rule files from .rulesync/rules/ directory
3377
3518
  */
3378
3519
  async loadRulesyncFiles() {
3379
- try {
3380
- const rulesDir = (0, import_node_path12.join)(this.baseDir, ".rulesync", "rules");
3381
- const dirExists = await directoryExists(rulesDir);
3382
- if (!dirExists) {
3383
- logger.debug(`Rulesync rules directory not found: ${rulesDir}`);
3384
- return [];
3385
- }
3386
- const entries = await listDirectoryFiles(rulesDir);
3387
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3388
- if (mdFiles.length === 0) {
3389
- logger.debug(`No markdown files found in rulesync rules directory: ${rulesDir}`);
3390
- return [];
3391
- }
3392
- logger.info(`Found ${mdFiles.length} rule files in ${rulesDir}`);
3393
- const rulesyncRules = [];
3394
- for (const mdFile of mdFiles) {
3395
- const filepath = (0, import_node_path12.join)(rulesDir, mdFile);
3396
- try {
3397
- const rulesyncRule = await RulesyncRule.fromFilePath({
3398
- filePath: filepath
3399
- });
3400
- rulesyncRules.push(rulesyncRule);
3401
- logger.debug(`Successfully loaded rule: ${mdFile}`);
3402
- } catch (error) {
3403
- logger.warn(`Failed to load rule file ${filepath}:`, error);
3404
- continue;
3405
- }
3406
- }
3407
- if (rulesyncRules.length === 0) {
3408
- logger.debug(`No valid rules found in ${rulesDir}`);
3409
- return [];
3410
- }
3411
- logger.info(`Successfully loaded ${rulesyncRules.length} rulesync rules`);
3412
- return rulesyncRules;
3413
- } catch (error) {
3414
- logger.debug(`No rulesync files found`, error);
3415
- return [];
3416
- }
3520
+ const files = await findFilesByGlobs((0, import_node_path44.join)(RULESYNC_RULES_DIR, "*.md"));
3521
+ logger.debug(`Found ${files.length} rulesync files`);
3522
+ return Promise.all(
3523
+ files.map((file) => RulesyncRule.fromFile({ relativeFilePath: (0, import_node_path44.basename)(file) }))
3524
+ );
3417
3525
  }
3418
- async loadLegacyRulesyncFiles() {
3419
- try {
3420
- const legacyFiles = await findFilesByGlobs((0, import_node_path12.join)(RULESYNC_RULES_DIR_LEGACY, "*.md"));
3421
- return Promise.all(
3422
- legacyFiles.map(
3423
- (file) => RulesyncRule.fromLegacyFile({ relativeFilePath: (0, import_node_path12.basename)(file) })
3424
- )
3425
- );
3426
- } catch (error) {
3427
- logger.debug(`No legacy rulesync files found`, error);
3428
- return [];
3429
- }
3526
+ async loadRulesyncFilesLegacy() {
3527
+ const legacyFiles = await findFilesByGlobs((0, import_node_path44.join)(RULESYNC_RULES_DIR_LEGACY, "*.md"));
3528
+ logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
3529
+ return Promise.all(
3530
+ legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: (0, import_node_path44.basename)(file) }))
3531
+ );
3430
3532
  }
3431
3533
  /**
3432
3534
  * Implementation of abstract method from FeatureProcessor
@@ -3477,527 +3579,296 @@ var RulesProcessor = class extends FeatureProcessor {
3477
3579
  return [];
3478
3580
  }
3479
3581
  }
3582
+ async loadToolRulesDefault({
3583
+ root,
3584
+ nonRoot
3585
+ }) {
3586
+ const rootToolRules = await (async () => {
3587
+ if (!root) {
3588
+ return [];
3589
+ }
3590
+ const rootFilePaths = await findFilesByGlobs(
3591
+ (0, import_node_path44.join)(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
3592
+ );
3593
+ return await Promise.all(
3594
+ rootFilePaths.map(
3595
+ (filePath) => root.fromFile({
3596
+ baseDir: this.baseDir,
3597
+ relativeFilePath: (0, import_node_path44.basename)(filePath)
3598
+ })
3599
+ )
3600
+ );
3601
+ })();
3602
+ logger.debug(`Found ${rootToolRules.length} root tool rule files`);
3603
+ const nonRootToolRules = await (async () => {
3604
+ if (!nonRoot) {
3605
+ return [];
3606
+ }
3607
+ const nonRootFilePaths = await findFilesByGlobs(
3608
+ (0, import_node_path44.join)(this.baseDir, nonRoot.relativeFilePath, `*.${nonRoot.extension}`)
3609
+ );
3610
+ return await Promise.all(
3611
+ nonRootFilePaths.map(
3612
+ (filePath) => nonRoot.fromFile({
3613
+ baseDir: this.baseDir,
3614
+ relativeFilePath: (0, import_node_path44.basename)(filePath)
3615
+ })
3616
+ )
3617
+ );
3618
+ })();
3619
+ logger.debug(`Found ${nonRootToolRules.length} non-root tool rule files`);
3620
+ return [...rootToolRules, ...nonRootToolRules];
3621
+ }
3480
3622
  /**
3481
3623
  * Load AGENTS.md rule configuration
3482
3624
  */
3483
3625
  async loadAgentsmdRules() {
3484
- const agentsFile = (0, import_node_path12.join)(this.baseDir, "AGENTS.md");
3485
- if (!await fileExists(agentsFile)) {
3486
- logger.warn(`AGENTS.md file not found: ${agentsFile}`);
3487
- return [];
3488
- }
3489
- try {
3490
- const agentsmdRule = await AgentsMdRule.fromFilePath({
3491
- baseDir: this.baseDir,
3626
+ return await this.loadToolRulesDefault({
3627
+ root: {
3492
3628
  relativeDirPath: ".",
3493
3629
  relativeFilePath: "AGENTS.md",
3494
- filePath: agentsFile,
3495
- validate: true
3496
- });
3497
- logger.info(`Successfully loaded AGENTS.md rule`);
3498
- return [agentsmdRule];
3499
- } catch (error) {
3500
- logger.warn(`Failed to load AGENTS.md file ${agentsFile}:`, error);
3501
- return [];
3502
- }
3630
+ fromFile: (params) => AgentsMdRule.fromFile(params)
3631
+ },
3632
+ nonRoot: {
3633
+ relativeFilePath: ".agents/memories",
3634
+ fromFile: (params) => AgentsMdRule.fromFile(params),
3635
+ extension: "md"
3636
+ }
3637
+ });
3503
3638
  }
3504
3639
  async loadWarpRules() {
3505
- const rootFilePaths = await findFilesByGlobs((0, import_node_path12.join)(this.baseDir, "WARP.md"));
3506
- const nonRootFilePaths = await findFilesByGlobs((0, import_node_path12.join)(this.baseDir, ".warp/memories/*.md"));
3507
- const rootFiles = await Promise.all(
3508
- rootFilePaths.map(
3509
- (filePath) => WarpRule.fromFilePath({
3510
- filePath,
3511
- validate: true,
3512
- relativeDirPath: ".",
3513
- relativeFilePath: "WARP.md"
3514
- })
3515
- )
3516
- );
3517
- const nonRootFiles = await Promise.all(
3518
- nonRootFilePaths.map(
3519
- (filePath) => WarpRule.fromFilePath({
3520
- filePath,
3521
- validate: true,
3522
- relativeDirPath: ".warp/memories",
3523
- relativeFilePath: (0, import_node_path12.basename)(filePath)
3524
- })
3525
- )
3526
- );
3527
- return [...rootFiles, ...nonRootFiles];
3640
+ return await this.loadToolRulesDefault({
3641
+ root: {
3642
+ relativeDirPath: ".",
3643
+ relativeFilePath: "WARP.md",
3644
+ fromFile: (params) => WarpRule.fromFile(params)
3645
+ },
3646
+ nonRoot: {
3647
+ relativeFilePath: ".warp/memories",
3648
+ fromFile: (params) => WarpRule.fromFile(params),
3649
+ extension: "md"
3650
+ }
3651
+ });
3528
3652
  }
3529
3653
  /**
3530
3654
  * Load Amazon Q Developer CLI rule configurations from .amazonq/rules/ directory
3531
3655
  */
3532
3656
  async loadAmazonqcliRules() {
3533
- return this.loadToolRulesFromDirectory(
3534
- (0, import_node_path12.join)(this.baseDir, ".amazonq", "rules"),
3535
- (filePath, relativeFilePath) => AmazonQCliRule.fromFilePath({
3536
- baseDir: this.baseDir,
3537
- relativeDirPath: ".amazonq/rules",
3538
- relativeFilePath,
3539
- filePath,
3540
- validate: true
3541
- }),
3542
- "Amazon Q Developer CLI"
3543
- );
3657
+ return await this.loadToolRulesDefault({
3658
+ nonRoot: {
3659
+ relativeFilePath: ".amazonq/rules",
3660
+ fromFile: (params) => AmazonQCliRule.fromFile(params),
3661
+ extension: "md"
3662
+ }
3663
+ });
3544
3664
  }
3545
3665
  /**
3546
3666
  * Load AugmentCode rule configurations from .augment/rules/ directory
3547
3667
  */
3548
3668
  async loadAugmentcodeRules() {
3549
- return this.loadToolRulesFromDirectory(
3550
- (0, import_node_path12.join)(this.baseDir, ".augment", "rules"),
3551
- (filePath, relativeFilePath) => AugmentcodeRule.fromFilePath({
3552
- baseDir: this.baseDir,
3553
- relativeDirPath: ".augment/rules",
3554
- relativeFilePath,
3555
- filePath,
3556
- validate: true
3557
- }),
3558
- "AugmentCode"
3559
- );
3669
+ return await this.loadToolRulesDefault({
3670
+ nonRoot: {
3671
+ relativeFilePath: ".augment/rules",
3672
+ fromFile: (params) => AugmentcodeRule.fromFile(params),
3673
+ extension: "md"
3674
+ }
3675
+ });
3560
3676
  }
3561
3677
  /**
3562
3678
  * Load AugmentCode legacy rule configuration from .augment-guidelines file and .augment/rules/ directory
3563
3679
  */
3564
3680
  async loadAugmentcodeLegacyRules() {
3565
- const toolRules = [];
3566
- const guidelinesFile = (0, import_node_path12.join)(this.baseDir, ".augment-guidelines");
3567
- if (await fileExists(guidelinesFile)) {
3568
- try {
3569
- const augmentcodeLegacyRule = await AugmentcodeLegacyRule.fromFilePath({
3570
- baseDir: this.baseDir,
3571
- relativeDirPath: ".",
3572
- relativeFilePath: ".augment-guidelines",
3573
- filePath: guidelinesFile,
3574
- validate: true
3575
- });
3576
- toolRules.push(augmentcodeLegacyRule);
3577
- logger.info(`Successfully loaded AugmentCode legacy guidelines`);
3578
- } catch (error) {
3579
- logger.warn(`Failed to load AugmentCode legacy guidelines file ${guidelinesFile}:`, error);
3681
+ return await this.loadToolRulesDefault({
3682
+ root: {
3683
+ relativeDirPath: ".",
3684
+ relativeFilePath: ".augment-guidelines",
3685
+ fromFile: (params) => AugmentcodeLegacyRule.fromFile(params)
3686
+ },
3687
+ nonRoot: {
3688
+ relativeFilePath: ".augment/rules",
3689
+ fromFile: (params) => AugmentcodeLegacyRule.fromFile(params),
3690
+ extension: "md"
3580
3691
  }
3581
- }
3582
- const rulesDir = (0, import_node_path12.join)(this.baseDir, ".augment", "rules");
3583
- if (await directoryExists(rulesDir)) {
3584
- const dirRules = await this.loadToolRulesFromDirectory(
3585
- rulesDir,
3586
- (filePath, relativeFilePath) => AugmentcodeLegacyRule.fromFilePath({
3587
- baseDir: this.baseDir,
3588
- relativeDirPath: (0, import_node_path12.join)(".augment", "rules"),
3589
- relativeFilePath,
3590
- filePath,
3591
- validate: true
3592
- }),
3593
- "AugmentCode Legacy"
3594
- );
3595
- toolRules.push(...dirRules);
3596
- }
3597
- return toolRules;
3692
+ });
3598
3693
  }
3599
3694
  /**
3600
3695
  * Load Claude Code rule configuration from CLAUDE.md file
3601
3696
  */
3602
3697
  async loadClaudecodeRules() {
3603
- const claudeMemoriesDir = (0, import_node_path12.join)(this.baseDir, ".claude", "memories");
3604
- if (!await directoryExists(claudeMemoriesDir)) {
3605
- logger.debug(`Claude Code memories directory not found: ${claudeMemoriesDir}`);
3606
- const claudeFile = (0, import_node_path12.join)(this.baseDir, "CLAUDE.md");
3607
- if (!await fileExists(claudeFile)) {
3608
- logger.debug(`Claude Code memory file not found: ${claudeFile}`);
3609
- return [];
3610
- }
3611
- try {
3612
- const claudecodeRule = await ClaudecodeRule.fromFilePath({
3613
- baseDir: this.baseDir,
3614
- relativeDirPath: ".",
3615
- relativeFilePath: "CLAUDE.md",
3616
- filePath: claudeFile,
3617
- validate: true
3618
- });
3619
- logger.info(`Successfully loaded Claude Code memory file`);
3620
- return [claudecodeRule];
3621
- } catch (error) {
3622
- logger.warn(`Failed to load Claude Code memory file ${claudeFile}:`, error);
3623
- return [];
3624
- }
3625
- }
3626
- const entries = await listDirectoryFiles(claudeMemoriesDir);
3627
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3628
- if (mdFiles.length === 0) {
3629
- logger.debug(
3630
- `No markdown files found in Claude Code memories directory: ${claudeMemoriesDir}`
3631
- );
3632
- return [];
3633
- }
3634
- logger.info(`Found ${mdFiles.length} Claude Code memory files in ${claudeMemoriesDir}`);
3635
- const toolRules = [];
3636
- for (const mdFile of mdFiles) {
3637
- const filePath = (0, import_node_path12.join)(claudeMemoriesDir, mdFile);
3638
- try {
3639
- const claudecodeRule = await ClaudecodeRule.fromFilePath({
3640
- baseDir: this.baseDir,
3641
- relativeDirPath: (0, import_node_path12.join)(".claude", "memories"),
3642
- relativeFilePath: mdFile,
3643
- filePath,
3644
- validate: true
3645
- });
3646
- toolRules.push(claudecodeRule);
3647
- logger.debug(`Successfully loaded Claude Code memory file: ${mdFile}`);
3648
- } catch (error) {
3649
- logger.warn(`Failed to load Claude Code memory file ${filePath}:`, error);
3650
- continue;
3698
+ return await this.loadToolRulesDefault({
3699
+ root: {
3700
+ relativeDirPath: ".",
3701
+ relativeFilePath: "CLAUDE.md",
3702
+ fromFile: (params) => ClaudecodeRule.fromFile(params)
3703
+ },
3704
+ nonRoot: {
3705
+ relativeFilePath: ".claude/memories",
3706
+ fromFile: (params) => ClaudecodeRule.fromFile(params),
3707
+ extension: "md"
3651
3708
  }
3652
- }
3653
- logger.info(`Successfully loaded ${toolRules.length} Claude Code memory files`);
3654
- return toolRules;
3709
+ });
3655
3710
  }
3656
3711
  /**
3657
3712
  * Load Cline rule configurations from .clinerules/ directory
3658
3713
  */
3659
3714
  async loadClineRules() {
3660
- return this.loadToolRulesFromDirectory(
3661
- (0, import_node_path12.join)(this.baseDir, ".clinerules"),
3662
- (filePath, relativeFilePath) => ClineRule.fromFilePath({
3663
- baseDir: this.baseDir,
3664
- relativeDirPath: ".clinerules",
3665
- relativeFilePath,
3666
- filePath,
3667
- validate: true
3668
- }),
3669
- "Cline"
3670
- );
3715
+ return await this.loadToolRulesDefault({
3716
+ nonRoot: {
3717
+ relativeFilePath: ".clinerules",
3718
+ fromFile: (params) => ClineRule.fromFile(params),
3719
+ extension: "md"
3720
+ }
3721
+ });
3671
3722
  }
3672
3723
  /**
3673
3724
  * Load OpenAI Codex CLI rule configuration from AGENTS.md and .codex/memories/*.md files
3674
3725
  */
3675
3726
  async loadCodexcliRules() {
3676
- const rules = [];
3677
- const agentsFile = (0, import_node_path12.join)(this.baseDir, "AGENTS.md");
3678
- if (await fileExists(agentsFile)) {
3679
- try {
3680
- const codexcliRule = await CodexcliRule.fromFilePath({
3681
- baseDir: this.baseDir,
3682
- relativeDirPath: ".",
3683
- relativeFilePath: "AGENTS.md",
3684
- filePath: agentsFile,
3685
- validate: true
3686
- });
3687
- rules.push(codexcliRule);
3688
- logger.info(`Successfully loaded OpenAI Codex CLI agents file`);
3689
- } catch (error) {
3690
- logger.warn(`Failed to load OpenAI Codex CLI agents file ${agentsFile}:`, error);
3691
- }
3692
- }
3693
- const memoriesDir = (0, import_node_path12.join)(this.baseDir, ".codex", "memories");
3694
- if (await directoryExists(memoriesDir)) {
3695
- try {
3696
- const entries = await listDirectoryFiles(memoriesDir);
3697
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3698
- for (const mdFile of mdFiles) {
3699
- const filePath = (0, import_node_path12.join)(memoriesDir, mdFile);
3700
- try {
3701
- const codexcliRule = await CodexcliRule.fromFilePath({
3702
- baseDir: this.baseDir,
3703
- relativeDirPath: (0, import_node_path12.join)(".codex", "memories"),
3704
- relativeFilePath: mdFile,
3705
- filePath,
3706
- validate: true
3707
- });
3708
- rules.push(codexcliRule);
3709
- } catch (error) {
3710
- logger.warn(`Failed to load Codex CLI memories file ${filePath}:`, error);
3711
- }
3712
- }
3713
- if (mdFiles.length > 0) {
3714
- logger.info(`Successfully loaded ${mdFiles.length} OpenAI Codex CLI memory files`);
3715
- }
3716
- } catch (error) {
3717
- logger.warn(`Failed to read OpenAI Codex CLI memories directory ${memoriesDir}:`, error);
3727
+ return await this.loadToolRulesDefault({
3728
+ root: {
3729
+ relativeDirPath: ".",
3730
+ relativeFilePath: "AGENTS.md",
3731
+ fromFile: (params) => CodexcliRule.fromFile(params)
3732
+ },
3733
+ nonRoot: {
3734
+ relativeFilePath: ".codex/memories",
3735
+ fromFile: (params) => CodexcliRule.fromFile(params),
3736
+ extension: "md"
3718
3737
  }
3719
- }
3720
- if (rules.length === 0) {
3721
- logger.warn(`No OpenAI Codex CLI rule files found`);
3722
- }
3723
- return rules;
3738
+ });
3724
3739
  }
3725
3740
  /**
3726
3741
  * Load GitHub Copilot rule configuration from .github/copilot-instructions.md file
3727
3742
  */
3728
3743
  async loadCopilotRules() {
3729
- const copilotFile = (0, import_node_path12.join)(this.baseDir, ".github", "copilot-instructions.md");
3730
- if (!await fileExists(copilotFile)) {
3731
- logger.warn(`GitHub Copilot instructions file not found: ${copilotFile}`);
3732
- return [];
3733
- }
3734
- try {
3735
- const copilotRule = await CopilotRule.fromFilePath({
3736
- baseDir: this.baseDir,
3737
- relativeDirPath: ".github",
3738
- relativeFilePath: "copilot-instructions.md",
3739
- filePath: copilotFile,
3740
- validate: true
3741
- });
3742
- logger.info(`Successfully loaded GitHub Copilot instructions file`);
3743
- return [copilotRule];
3744
- } catch (error) {
3745
- logger.warn(`Failed to load GitHub Copilot instructions file ${copilotFile}:`, error);
3746
- return [];
3747
- }
3744
+ return await this.loadToolRulesDefault({
3745
+ root: {
3746
+ relativeDirPath: ".",
3747
+ relativeFilePath: ".github/copilot-instructions.md",
3748
+ fromFile: (params) => CopilotRule.fromFile(params)
3749
+ },
3750
+ nonRoot: {
3751
+ relativeFilePath: ".github/instructions",
3752
+ fromFile: (params) => CopilotRule.fromFile(params),
3753
+ extension: "md"
3754
+ }
3755
+ });
3748
3756
  }
3749
3757
  /**
3750
3758
  * Load Cursor rule configurations from .cursor/rules/ directory
3751
3759
  */
3752
3760
  async loadCursorRules() {
3753
- return this.loadToolRulesFromDirectory(
3754
- (0, import_node_path12.join)(this.baseDir, ".cursor", "rules"),
3755
- (filePath) => CursorRule.fromFilePath({
3756
- filePath,
3757
- validate: true
3758
- }),
3759
- "Cursor"
3760
- );
3761
+ return await this.loadToolRulesDefault({
3762
+ nonRoot: {
3763
+ relativeFilePath: ".cursor/rules",
3764
+ fromFile: (params) => CursorRule.fromFile(params),
3765
+ extension: "md"
3766
+ }
3767
+ });
3761
3768
  }
3762
3769
  /**
3763
3770
  * Load Gemini CLI rule configuration from GEMINI.md file
3764
3771
  */
3765
3772
  async loadGeminicliRules() {
3766
- const geminiFile = (0, import_node_path12.join)(this.baseDir, "GEMINI.md");
3767
- if (!await fileExists(geminiFile)) {
3768
- logger.warn(`Gemini CLI memory file not found: ${geminiFile}`);
3769
- return [];
3770
- }
3771
- try {
3772
- const geminicliRule = await GeminiCliRule.fromFilePath({
3773
- baseDir: this.baseDir,
3773
+ return await this.loadToolRulesDefault({
3774
+ root: {
3774
3775
  relativeDirPath: ".",
3775
3776
  relativeFilePath: "GEMINI.md",
3776
- filePath: geminiFile,
3777
- validate: true
3778
- });
3779
- logger.info(`Successfully loaded Gemini CLI memory file`);
3780
- return [geminicliRule];
3781
- } catch (error) {
3782
- logger.warn(`Failed to load Gemini CLI memory file ${geminiFile}:`, error);
3783
- return [];
3784
- }
3777
+ fromFile: (params) => GeminiCliRule.fromFile(params)
3778
+ },
3779
+ nonRoot: {
3780
+ relativeFilePath: ".gemini/memories",
3781
+ fromFile: (params) => GeminiCliRule.fromFile(params),
3782
+ extension: "md"
3783
+ }
3784
+ });
3785
3785
  }
3786
3786
  /**
3787
3787
  * Load JetBrains Junie rule configuration from .junie/guidelines.md file
3788
3788
  */
3789
3789
  async loadJunieRules() {
3790
- const guidelinesFile = (0, import_node_path12.join)(this.baseDir, ".junie", "guidelines.md");
3791
- if (!await fileExists(guidelinesFile)) {
3792
- return [];
3793
- }
3794
- const junieRule = await JunieRule.fromFilePath({
3795
- baseDir: this.baseDir,
3796
- relativeDirPath: ".junie",
3797
- relativeFilePath: "guidelines.md",
3798
- filePath: guidelinesFile,
3799
- validate: true
3790
+ return await this.loadToolRulesDefault({
3791
+ root: {
3792
+ relativeDirPath: ".",
3793
+ relativeFilePath: ".junie/guidelines.md",
3794
+ fromFile: (params) => JunieRule.fromFile(params)
3795
+ },
3796
+ nonRoot: {
3797
+ relativeFilePath: ".junie/memories",
3798
+ fromFile: (params) => JunieRule.fromFile(params),
3799
+ extension: "md"
3800
+ }
3800
3801
  });
3801
- logger.info(`Successfully loaded JetBrains Junie guidelines file`);
3802
- return [junieRule];
3803
3802
  }
3804
3803
  /**
3805
3804
  * Load Kiro rule configurations from .kiro/steering/ directory
3806
3805
  */
3807
3806
  async loadKiroRules() {
3808
- return this.loadToolRulesFromDirectory(
3809
- (0, import_node_path12.join)(this.baseDir, ".kiro", "steering"),
3810
- (filePath, relativeFilePath) => KiroRule.fromFilePath({
3811
- baseDir: this.baseDir,
3812
- relativeDirPath: ".kiro/steering",
3813
- relativeFilePath,
3814
- filePath,
3815
- validate: true
3816
- }),
3817
- "Kiro"
3818
- );
3807
+ return await this.loadToolRulesDefault({
3808
+ nonRoot: {
3809
+ relativeFilePath: ".kiro/steering",
3810
+ fromFile: (params) => KiroRule.fromFile(params),
3811
+ extension: "md"
3812
+ }
3813
+ });
3819
3814
  }
3820
3815
  /**
3821
3816
  * Load OpenCode rule configuration from AGENTS.md file and .opencode/memories/*.md files
3822
3817
  */
3823
3818
  async loadOpencodeRules() {
3824
- const rules = [];
3825
- const agentsFile = (0, import_node_path12.join)(this.baseDir, "AGENTS.md");
3826
- if (await fileExists(agentsFile)) {
3827
- try {
3828
- const opencodeRule = await OpenCodeRule.fromFilePath({
3829
- baseDir: this.baseDir,
3830
- relativeDirPath: ".",
3831
- relativeFilePath: "AGENTS.md",
3832
- filePath: agentsFile,
3833
- validate: true
3834
- });
3835
- rules.push(opencodeRule);
3836
- logger.info(`Successfully loaded OpenCode agents file`);
3837
- } catch (error) {
3838
- logger.warn(`Failed to load OpenCode agents file ${agentsFile}:`, error);
3839
- }
3840
- }
3841
- const memoriesDir = (0, import_node_path12.join)(this.baseDir, ".opencode", "memories");
3842
- if (await directoryExists(memoriesDir)) {
3843
- try {
3844
- const entries = await listDirectoryFiles(memoriesDir);
3845
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3846
- for (const mdFile of mdFiles) {
3847
- const filePath = (0, import_node_path12.join)(memoriesDir, mdFile);
3848
- try {
3849
- const opencodeRule = await OpenCodeRule.fromFilePath({
3850
- baseDir: this.baseDir,
3851
- relativeDirPath: (0, import_node_path12.join)(".opencode", "memories"),
3852
- relativeFilePath: mdFile,
3853
- filePath,
3854
- validate: true
3855
- });
3856
- rules.push(opencodeRule);
3857
- } catch (error) {
3858
- logger.warn(`Failed to load OpenCode memories file ${filePath}:`, error);
3859
- }
3860
- }
3861
- if (mdFiles.length > 0) {
3862
- logger.info(`Successfully loaded ${mdFiles.length} OpenCode memory files`);
3863
- }
3864
- } catch (error) {
3865
- logger.warn(`Failed to read OpenCode memories directory ${memoriesDir}:`, error);
3819
+ return await this.loadToolRulesDefault({
3820
+ root: {
3821
+ relativeDirPath: ".",
3822
+ relativeFilePath: "AGENTS.md",
3823
+ fromFile: (params) => OpenCodeRule.fromFile(params)
3824
+ },
3825
+ nonRoot: {
3826
+ relativeFilePath: ".opencode/memories",
3827
+ fromFile: (params) => OpenCodeRule.fromFile(params),
3828
+ extension: "md"
3866
3829
  }
3867
- }
3868
- if (rules.length === 0) {
3869
- logger.warn(`No OpenCode rule files found`);
3870
- }
3871
- return rules;
3830
+ });
3872
3831
  }
3873
3832
  /**
3874
3833
  * Load Qwen Code rule configuration from QWEN.md file and .qwen/memories/*.md files
3875
3834
  */
3876
3835
  async loadQwencodeRules() {
3877
- const rules = [];
3878
- const qwenFile = (0, import_node_path12.join)(this.baseDir, "QWEN.md");
3879
- if (await fileExists(qwenFile)) {
3880
- try {
3881
- const qwencodeRule = await QwencodeRule.fromFilePath({
3882
- baseDir: this.baseDir,
3883
- relativeDirPath: ".",
3884
- relativeFilePath: "QWEN.md",
3885
- filePath: qwenFile,
3886
- validate: true
3887
- });
3888
- rules.push(qwencodeRule);
3889
- logger.info(`Successfully loaded Qwen Code memory file`);
3890
- } catch (error) {
3891
- logger.warn(`Failed to load Qwen Code memory file ${qwenFile}:`, error);
3892
- }
3893
- }
3894
- const memoriesDir = (0, import_node_path12.join)(this.baseDir, ".qwen", "memories");
3895
- if (await directoryExists(memoriesDir)) {
3896
- try {
3897
- const entries = await listDirectoryFiles(memoriesDir);
3898
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3899
- for (const mdFile of mdFiles) {
3900
- const filePath = (0, import_node_path12.join)(memoriesDir, mdFile);
3901
- try {
3902
- const qwencodeRule = await QwencodeRule.fromFilePath({
3903
- baseDir: this.baseDir,
3904
- relativeDirPath: (0, import_node_path12.join)(".qwen", "memories"),
3905
- relativeFilePath: mdFile,
3906
- filePath,
3907
- validate: true
3908
- });
3909
- rules.push(qwencodeRule);
3910
- } catch (error) {
3911
- logger.warn(`Failed to load Qwen Code memories file ${filePath}:`, error);
3912
- }
3913
- }
3914
- if (mdFiles.length > 0) {
3915
- logger.info(`Successfully loaded ${mdFiles.length} Qwen Code memory files`);
3916
- }
3917
- } catch (error) {
3918
- logger.warn(`Failed to read Qwen Code memories directory ${memoriesDir}:`, error);
3836
+ return await this.loadToolRulesDefault({
3837
+ root: {
3838
+ relativeDirPath: ".",
3839
+ relativeFilePath: "QWEN.md",
3840
+ fromFile: (params) => QwencodeRule.fromFile(params)
3841
+ },
3842
+ nonRoot: {
3843
+ relativeFilePath: ".qwen/memories",
3844
+ fromFile: (params) => QwencodeRule.fromFile(params),
3845
+ extension: "md"
3919
3846
  }
3920
- }
3921
- if (rules.length === 0) {
3922
- logger.warn(`No Qwen Code rule files found`);
3923
- }
3924
- return rules;
3847
+ });
3925
3848
  }
3926
3849
  /**
3927
3850
  * Load Roo Code rule configurations from .roo/rules/ directory
3928
3851
  */
3929
3852
  async loadRooRules() {
3930
- return this.loadToolRulesFromDirectory(
3931
- (0, import_node_path12.join)(this.baseDir, ".roo", "rules"),
3932
- (filePath, relativeFilePath) => RooRule.fromFilePath({
3933
- baseDir: this.baseDir,
3934
- relativeDirPath: ".roo/rules",
3935
- relativeFilePath,
3936
- filePath,
3937
- validate: true
3938
- }),
3939
- "Roo Code"
3940
- );
3853
+ return await this.loadToolRulesDefault({
3854
+ nonRoot: {
3855
+ relativeFilePath: ".roo/rules",
3856
+ fromFile: (params) => RooRule.fromFile(params),
3857
+ extension: "md"
3858
+ }
3859
+ });
3941
3860
  }
3942
3861
  /**
3943
3862
  * Load Windsurf rule configurations from .windsurf/rules/ directory
3944
3863
  */
3945
3864
  async loadWindsurfRules() {
3946
- return this.loadToolRulesFromDirectory(
3947
- (0, import_node_path12.join)(this.baseDir, ".windsurf", "rules"),
3948
- (filePath, relativeFilePath) => WindsurfRule.fromFilePath({
3949
- baseDir: this.baseDir,
3950
- relativeDirPath: ".windsurf/rules",
3951
- relativeFilePath,
3952
- filePath,
3953
- validate: true
3954
- }),
3955
- "Windsurf"
3956
- );
3957
- }
3958
- /**
3959
- * Common helper method to load tool rules from a directory with parallel processing
3960
- */
3961
- async loadToolRulesFromDirectory(dirPath, ruleFactory, toolName) {
3962
- if (!await directoryExists(dirPath)) {
3963
- logger.warn(`${toolName} rules directory not found: ${dirPath}`);
3964
- return [];
3965
- }
3966
- const entries = await listDirectoryFiles(dirPath);
3967
- const mdFiles = entries.filter((file) => file.endsWith(".md") || file.endsWith(".mdc"));
3968
- if (mdFiles.length === 0) {
3969
- logger.info(`No rule files found in ${dirPath}`);
3970
- return [];
3971
- }
3972
- logger.info(`Found ${mdFiles.length} ${toolName} rule files in ${dirPath}`);
3973
- const results = await Promise.allSettled(
3974
- mdFiles.map(async (mdFile) => {
3975
- const filepath = (0, import_node_path12.join)(dirPath, mdFile);
3976
- return {
3977
- rule: await ruleFactory(filepath, mdFile),
3978
- filename: mdFile
3979
- };
3980
- })
3981
- );
3982
- const toolRules = [];
3983
- for (const [index, result] of results.entries()) {
3984
- if (result.status === "fulfilled") {
3985
- toolRules.push(result.value.rule);
3986
- logger.debug(`Successfully loaded ${toolName} rule: ${result.value.filename}`);
3987
- } else {
3988
- logger.warn(`Failed to load ${toolName} rule file ${mdFiles[index]}:`, result.reason);
3865
+ return await this.loadToolRulesDefault({
3866
+ nonRoot: {
3867
+ relativeFilePath: ".windsurf/rules",
3868
+ fromFile: (params) => WindsurfRule.fromFile(params),
3869
+ extension: "md"
3989
3870
  }
3990
- }
3991
- logger.info(`Successfully loaded ${toolRules.length} ${toolName} rules`);
3992
- return toolRules;
3993
- }
3994
- async writeToolRulesFromRulesyncRules(rulesyncRules) {
3995
- const toolRules = await this.convertRulesyncFilesToToolFiles(rulesyncRules);
3996
- await this.writeAiFiles(toolRules);
3997
- }
3998
- async writeRulesyncRulesFromToolRules(toolRules) {
3999
- const rulesyncRules = await this.convertToolFilesToRulesyncFiles(toolRules);
4000
- await this.writeAiFiles(rulesyncRules);
3871
+ });
4001
3872
  }
4002
3873
  /**
4003
3874
  * Implementation of abstract method from FeatureProcessor
@@ -4006,30 +3877,6 @@ var RulesProcessor = class extends FeatureProcessor {
4006
3877
  static getToolTargets() {
4007
3878
  return rulesProcessorToolTargets;
4008
3879
  }
4009
- /**
4010
- * Get all supported tools
4011
- */
4012
- static getSupportedTools() {
4013
- const allTools = [
4014
- "agentsmd",
4015
- "amazonqcli",
4016
- "augmentcode",
4017
- "augmentcode-legacy",
4018
- "claudecode",
4019
- "cline",
4020
- "codexcli",
4021
- "copilot",
4022
- "cursor",
4023
- "geminicli",
4024
- "junie",
4025
- "kiro",
4026
- "opencode",
4027
- "qwencode",
4028
- "roo",
4029
- "windsurf"
4030
- ];
4031
- return allTools;
4032
- }
4033
3880
  generateXmlReferencesSection(toolRules) {
4034
3881
  const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
4035
3882
  if (toolRulesWithoutRoot.length === 0) {
@@ -4090,14 +3937,15 @@ var RulesProcessor = class extends FeatureProcessor {
4090
3937
  };
4091
3938
 
4092
3939
  // src/subagents/subagents-processor.ts
4093
- var import_node_path14 = require("path");
3940
+ var import_node_path47 = require("path");
4094
3941
  var import_mini19 = require("zod/mini");
4095
3942
 
4096
3943
  // src/subagents/claudecode-subagent.ts
3944
+ var import_node_path46 = require("path");
4097
3945
  var import_mini18 = require("zod/mini");
4098
3946
 
4099
3947
  // src/subagents/rulesync-subagent.ts
4100
- var import_node_path13 = require("path");
3948
+ var import_node_path45 = require("path");
4101
3949
  var import_mini17 = require("zod/mini");
4102
3950
  var RulesyncSubagentModelSchema = import_mini17.z.enum(["opus", "sonnet", "haiku", "inherit"]);
4103
3951
  var RulesyncSubagentFrontmatterSchema = import_mini17.z.object({
@@ -4143,14 +3991,16 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
4143
3991
  return { success: false, error: result.error };
4144
3992
  }
4145
3993
  }
4146
- static async fromFilePath({ filePath }) {
4147
- const fileContent = await readFileContent(filePath);
3994
+ static async fromFile({
3995
+ relativeFilePath
3996
+ }) {
3997
+ const fileContent = await readFileContent((0, import_node_path45.join)(RULESYNC_SUBAGENTS_DIR, relativeFilePath));
4148
3998
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4149
3999
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
4150
4000
  if (!result.success) {
4151
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
4001
+ throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
4152
4002
  }
4153
- const filename = (0, import_node_path13.basename)(filePath);
4003
+ const filename = (0, import_node_path45.basename)(relativeFilePath);
4154
4004
  return new _RulesyncSubagent({
4155
4005
  baseDir: ".",
4156
4006
  relativeDirPath: ".rulesync/subagents",
@@ -4164,7 +4014,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
4164
4014
 
4165
4015
  // src/subagents/tool-subagent.ts
4166
4016
  var ToolSubagent = class extends ToolFile {
4167
- static async fromFilePath(_params) {
4017
+ static async fromFile(_params) {
4168
4018
  throw new Error("Please implement this method in the subclass.");
4169
4019
  }
4170
4020
  static fromRulesyncSubagent(_params) {
@@ -4225,7 +4075,6 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4225
4075
  static fromRulesyncSubagent({
4226
4076
  baseDir = ".",
4227
4077
  rulesyncSubagent,
4228
- relativeDirPath,
4229
4078
  validate = true
4230
4079
  }) {
4231
4080
  const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
@@ -4240,7 +4089,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4240
4089
  baseDir,
4241
4090
  frontmatter: claudecodeFrontmatter,
4242
4091
  body,
4243
- relativeDirPath,
4092
+ relativeDirPath: ".claude/agents",
4244
4093
  relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
4245
4094
  fileContent,
4246
4095
  validate
@@ -4257,22 +4106,20 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4257
4106
  return { success: false, error: result.error };
4258
4107
  }
4259
4108
  }
4260
- static async fromFilePath({
4109
+ static async fromFile({
4261
4110
  baseDir = ".",
4262
- relativeDirPath,
4263
4111
  relativeFilePath,
4264
- filePath,
4265
4112
  validate = true
4266
4113
  }) {
4267
- const fileContent = await readFileContent(filePath);
4114
+ const fileContent = await readFileContent((0, import_node_path46.join)(baseDir, ".claude/agents", relativeFilePath));
4268
4115
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4269
4116
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
4270
4117
  if (!result.success) {
4271
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
4118
+ throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
4272
4119
  }
4273
4120
  return new _ClaudecodeSubagent({
4274
4121
  baseDir,
4275
- relativeDirPath,
4122
+ relativeDirPath: ".claude/agents",
4276
4123
  relativeFilePath,
4277
4124
  frontmatter: result.data,
4278
4125
  body: content.trim(),
@@ -4326,7 +4173,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
4326
4173
  * Load and parse rulesync subagent files from .rulesync/subagents/ directory
4327
4174
  */
4328
4175
  async loadRulesyncFiles() {
4329
- const subagentsDir = (0, import_node_path14.join)(this.baseDir, ".rulesync", "subagents");
4176
+ const subagentsDir = (0, import_node_path47.join)(this.baseDir, ".rulesync", "subagents");
4330
4177
  const dirExists = await directoryExists(subagentsDir);
4331
4178
  if (!dirExists) {
4332
4179
  logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
@@ -4341,10 +4188,11 @@ var SubagentsProcessor = class extends FeatureProcessor {
4341
4188
  logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
4342
4189
  const rulesyncSubagents = [];
4343
4190
  for (const mdFile of mdFiles) {
4344
- const filepath = (0, import_node_path14.join)(subagentsDir, mdFile);
4191
+ const filepath = (0, import_node_path47.join)(subagentsDir, mdFile);
4345
4192
  try {
4346
- const rulesyncSubagent = await RulesyncSubagent.fromFilePath({
4347
- filePath: filepath
4193
+ const rulesyncSubagent = await RulesyncSubagent.fromFile({
4194
+ relativeFilePath: mdFile,
4195
+ validate: true
4348
4196
  });
4349
4197
  rulesyncSubagents.push(rulesyncSubagent);
4350
4198
  logger.debug(`Successfully loaded subagent: ${mdFile}`);
@@ -4376,43 +4224,19 @@ var SubagentsProcessor = class extends FeatureProcessor {
4376
4224
  * Load Claude Code subagent configurations from .claude/agents/ directory
4377
4225
  */
4378
4226
  async loadClaudecodeSubagents() {
4379
- const agentsDir = (0, import_node_path14.join)(this.baseDir, ".claude", "agents");
4380
- if (!await directoryExists(agentsDir)) {
4381
- logger.warn(`Claude Code agents directory not found: ${agentsDir}`);
4382
- return [];
4383
- }
4384
- let entries;
4385
- try {
4386
- entries = await listDirectoryFiles(agentsDir);
4387
- } catch (error) {
4388
- logger.warn(`Failed to read Claude Code agents directory ${agentsDir}:`, error);
4389
- return [];
4390
- }
4391
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
4392
- if (mdFiles.length === 0) {
4393
- logger.info(`No JSON agent files found in ${agentsDir}`);
4394
- return [];
4395
- }
4396
- logger.info(`Found ${mdFiles.length} Claude Code agent files in ${agentsDir}`);
4397
- const toolSubagents = [];
4398
- for (const mdFile of mdFiles) {
4399
- const filepath = (0, import_node_path14.join)(agentsDir, mdFile);
4400
- try {
4401
- const claudecodeSubagent = await ClaudecodeSubagent.fromFilePath({
4402
- baseDir: this.baseDir,
4403
- relativeDirPath: ".claude/agents",
4404
- relativeFilePath: mdFile,
4405
- filePath: filepath
4406
- });
4407
- toolSubagents.push(claudecodeSubagent);
4408
- logger.debug(`Successfully loaded Claude Code agent: ${mdFile}`);
4409
- } catch (error) {
4410
- logger.warn(`Failed to load Claude Code agent file ${filepath}:`, error);
4411
- continue;
4412
- }
4413
- }
4414
- logger.info(`Successfully loaded ${toolSubagents.length} Claude Code subagents`);
4415
- return toolSubagents;
4227
+ return await this.loadToolSubagentsDefault({
4228
+ relativeDirPath: ".claude/agents",
4229
+ fromFile: (relativeFilePath) => ClaudecodeSubagent.fromFile({ relativeFilePath })
4230
+ });
4231
+ }
4232
+ async loadToolSubagentsDefault({
4233
+ relativeDirPath,
4234
+ fromFile
4235
+ }) {
4236
+ const paths = await findFilesByGlobs((0, import_node_path47.join)(this.baseDir, relativeDirPath, "*.md"));
4237
+ const subagents = (await Promise.allSettled(paths.map((path2) => fromFile((0, import_node_path47.basename)(path2))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
4238
+ logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
4239
+ return subagents;
4416
4240
  }
4417
4241
  /**
4418
4242
  * Implementation of abstract method from FeatureProcessor
@@ -4448,7 +4272,7 @@ async function generateCommand(options) {
4448
4272
  }
4449
4273
  let rulesyncFiles = await processor.loadRulesyncFiles();
4450
4274
  if (rulesyncFiles.length === 0) {
4451
- rulesyncFiles = await processor.loadLegacyRulesyncFiles();
4275
+ rulesyncFiles = await processor.loadRulesyncFilesLegacy();
4452
4276
  }
4453
4277
  const toolFiles = await processor.convertRulesyncFilesToToolFiles(rulesyncFiles);
4454
4278
  const writtenCount = await processor.writeAiFiles(toolFiles);
@@ -4602,9 +4426,9 @@ async function generateCommand(options) {
4602
4426
  }
4603
4427
 
4604
4428
  // src/cli/commands/gitignore.ts
4605
- var import_node_path15 = require("path");
4429
+ var import_node_path48 = require("path");
4606
4430
  var gitignoreCommand = async () => {
4607
- const gitignorePath = (0, import_node_path15.join)(process.cwd(), ".gitignore");
4431
+ const gitignorePath = (0, import_node_path48.join)(process.cwd(), ".gitignore");
4608
4432
  const rulesFilesToIgnore = [
4609
4433
  "# Generated by rulesync - AI tool configuration files",
4610
4434
  "**/.amazonq/rules/",
@@ -4733,6 +4557,24 @@ async function importCommand(options) {
4733
4557
  logger.success(`Created ${ignoreFileCreated} ignore files`);
4734
4558
  }
4735
4559
  }
4560
+ let mcpCreated = 0;
4561
+ if (config.getFeatures().includes("mcp")) {
4562
+ if (McpProcessor.getToolTargets().includes(tool)) {
4563
+ const mcpProcessor = new McpProcessor({
4564
+ baseDir: ".",
4565
+ toolTarget: tool
4566
+ });
4567
+ const toolFiles = await mcpProcessor.loadToolFiles();
4568
+ if (toolFiles.length > 0) {
4569
+ const rulesyncFiles = await mcpProcessor.convertToolFilesToRulesyncFiles(toolFiles);
4570
+ const writtenCount = await mcpProcessor.writeAiFiles(rulesyncFiles);
4571
+ mcpCreated = writtenCount;
4572
+ }
4573
+ }
4574
+ }
4575
+ if (config.getVerbose() && mcpCreated > 0) {
4576
+ logger.success(`Created ${mcpCreated} MCP files`);
4577
+ }
4736
4578
  let subagentsCreated = 0;
4737
4579
  if (config.getFeatures().includes("subagents")) {
4738
4580
  if (SubagentsProcessor.getToolTargets().includes(tool)) {
@@ -4773,7 +4615,7 @@ async function importCommand(options) {
4773
4615
  }
4774
4616
 
4775
4617
  // src/cli/commands/init.ts
4776
- var import_node_path16 = require("path");
4618
+ var import_node_path49 = require("path");
4777
4619
  async function initCommand() {
4778
4620
  logger.info("Initializing rulesync...");
4779
4621
  await ensureDir(RULESYNC_DIR);
@@ -4819,7 +4661,7 @@ globs: ["**/*"]
4819
4661
  - Follow single responsibility principle
4820
4662
  `
4821
4663
  };
4822
- const filepath = (0, import_node_path16.join)(RULESYNC_RULES_DIR, sampleFile.filename);
4664
+ const filepath = (0, import_node_path49.join)(RULESYNC_RULES_DIR, sampleFile.filename);
4823
4665
  await ensureDir(RULESYNC_RULES_DIR);
4824
4666
  await ensureDir(RULESYNC_COMMANDS_DIR);
4825
4667
  await ensureDir(RULESYNC_SUBAGENTS_DIR);
@@ -4838,15 +4680,15 @@ var getVersion = async () => {
4838
4680
  let packageJsonPath;
4839
4681
  if (typeof import_meta !== "undefined" && import_meta.url) {
4840
4682
  const __filename = (0, import_node_url.fileURLToPath)(import_meta.url);
4841
- const __dirname = (0, import_node_path17.join)(__filename, "..");
4842
- packageJsonPath = (0, import_node_path17.join)(__dirname, "../../package.json");
4683
+ const __dirname = (0, import_node_path50.join)(__filename, "..");
4684
+ packageJsonPath = (0, import_node_path50.join)(__dirname, "../../package.json");
4843
4685
  } else {
4844
- packageJsonPath = (0, import_node_path17.join)(process.cwd(), "package.json");
4686
+ packageJsonPath = (0, import_node_path50.join)(process.cwd(), "package.json");
4845
4687
  }
4846
4688
  const packageJson = await readJsonFile(packageJsonPath);
4847
4689
  return packageJson.version;
4848
4690
  } catch {
4849
- return "0.69.0";
4691
+ return "0.70.0";
4850
4692
  }
4851
4693
  };
4852
4694
  var main = async () => {