rulesync 0.68.1 → 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 +916 -983
  3. package/dist/index.js +912 -979
  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
 
@@ -52,6 +52,7 @@ var ALL_TOOL_TARGETS = [
52
52
  "geminicli",
53
53
  "kiro",
54
54
  "junie",
55
+ "warp",
55
56
  "windsurf"
56
57
  ];
57
58
  var ALL_TOOL_TARGETS_WITH_WILDCARD = [...ALL_TOOL_TARGETS, "*"];
@@ -216,14 +217,6 @@ async function listDirectoryFiles(dir) {
216
217
  return [];
217
218
  }
218
219
  }
219
- async function findFiles(dir, extension = ".md") {
220
- try {
221
- const files = await (0, import_promises.readdir)(dir);
222
- return files.filter((file) => file.endsWith(extension)).map((file) => (0, import_node_path.join)(dir, file));
223
- } catch {
224
- return [];
225
- }
226
- }
227
220
  async function findFilesByGlobs(globs) {
228
221
  return (0, import_node_fs.globSync)(globs);
229
222
  }
@@ -273,7 +266,7 @@ async function initConfig() {
273
266
  var import_es_toolkit = require("es-toolkit");
274
267
 
275
268
  // src/commands/commands-processor.ts
276
- var import_node_path7 = require("path");
269
+ var import_node_path8 = require("path");
277
270
  var import_mini7 = require("zod/mini");
278
271
 
279
272
  // src/types/feature-processor.ts
@@ -306,15 +299,48 @@ var FeatureProcessor = class {
306
299
  };
307
300
 
308
301
  // src/commands/claudecode-command.ts
309
- var import_node_path4 = require("path");
302
+ var import_node_path5 = require("path");
310
303
  var import_mini4 = require("zod/mini");
311
304
 
312
305
  // src/utils/frontmatter.ts
313
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
+ }
314
342
  function stringifyFrontmatter(body, frontmatter) {
315
- const cleanFrontmatter = Object.fromEntries(
316
- Object.entries(frontmatter).filter(([, value]) => value !== null && value !== void 0)
317
- );
343
+ const cleanFrontmatter = deepRemoveNullishObject(frontmatter);
318
344
  return import_gray_matter.default.stringify(body, cleanFrontmatter);
319
345
  }
320
346
  function parseFrontmatter(content) {
@@ -323,11 +349,20 @@ function parseFrontmatter(content) {
323
349
  }
324
350
 
325
351
  // src/commands/rulesync-command.ts
326
- var import_node_path3 = require("path");
352
+ var import_node_path4 = require("path");
327
353
  var import_mini3 = require("zod/mini");
328
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
+
329
364
  // src/types/ai-file.ts
330
- var import_node_path2 = __toESM(require("path"), 1);
365
+ var import_node_path3 = __toESM(require("path"), 1);
331
366
  var AiFile = class {
332
367
  /**
333
368
  * @example "."
@@ -363,7 +398,7 @@ var AiFile = class {
363
398
  }
364
399
  }
365
400
  }
366
- static async fromFilePath(_params) {
401
+ static async fromFile(_params) {
367
402
  throw new Error("Please implement this method in the subclass.");
368
403
  }
369
404
  getBaseDir() {
@@ -376,13 +411,13 @@ var AiFile = class {
376
411
  return this.relativeFilePath;
377
412
  }
378
413
  getFilePath() {
379
- 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);
380
415
  }
381
416
  getFileContent() {
382
417
  return this.fileContent;
383
418
  }
384
419
  getRelativePathFromCwd() {
385
- return import_node_path2.default.join(this.relativeDirPath, this.relativeFilePath);
420
+ return import_node_path3.default.join(this.relativeDirPath, this.relativeFilePath);
386
421
  }
387
422
  setFileContent(newFileContent) {
388
423
  this.fileContent = newFileContent;
@@ -391,13 +426,10 @@ var AiFile = class {
391
426
 
392
427
  // src/types/rulesync-file.ts
393
428
  var RulesyncFile = class extends AiFile {
394
- static async fromFilePath(_params) {
395
- throw new Error("Please implement this method in the subclass.");
396
- }
397
429
  static async fromFile(_params) {
398
430
  throw new Error("Please implement this method in the subclass.");
399
431
  }
400
- static async fromLegacyFile(_params) {
432
+ static async fromFileLegacy(_params) {
401
433
  throw new Error("Please implement this method in the subclass.");
402
434
  }
403
435
  };
@@ -441,14 +473,16 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
441
473
  return { success: false, error: result.error };
442
474
  }
443
475
  }
444
- static async fromFilePath({ filePath }) {
445
- 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));
446
480
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
447
481
  const result = RulesyncCommandFrontmatterSchema.safeParse(frontmatter);
448
482
  if (!result.success) {
449
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
483
+ throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
450
484
  }
451
- const filename = (0, import_node_path3.basename)(filePath);
485
+ const filename = (0, import_node_path4.basename)(relativeFilePath);
452
486
  return new _RulesyncCommand({
453
487
  baseDir: ".",
454
488
  relativeDirPath: ".rulesync/commands",
@@ -474,7 +508,7 @@ var ToolCommand = class extends AiFile {
474
508
  * @param params - Parameters including the file path to load
475
509
  * @returns Promise resolving to a concrete ToolCommand instance
476
510
  */
477
- static async fromFilePath(_params) {
511
+ static async fromFile(_params) {
478
512
  throw new Error("Please implement this method in the subclass.");
479
513
  }
480
514
  /**
@@ -551,7 +585,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
551
585
  baseDir,
552
586
  frontmatter: claudecodeFrontmatter,
553
587
  body,
554
- relativeDirPath: (0, import_node_path4.join)(".claude", "commands"),
588
+ relativeDirPath: (0, import_node_path5.join)(".claude", "commands"),
555
589
  relativeFilePath: rulesyncCommand.getRelativeFilePath(),
556
590
  validate
557
591
  });
@@ -567,11 +601,12 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
567
601
  return { success: false, error: result.error };
568
602
  }
569
603
  }
570
- static async fromFilePath({
604
+ static async fromFile({
571
605
  baseDir = ".",
572
- filePath,
606
+ relativeFilePath,
573
607
  validate = true
574
608
  }) {
609
+ const filePath = (0, import_node_path5.join)(baseDir, ".claude", "commands", relativeFilePath);
575
610
  const fileContent = await readFileContent(filePath);
576
611
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
577
612
  const result = ClaudecodeCommandFrontmatterSchema.safeParse(frontmatter);
@@ -581,7 +616,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
581
616
  return new _ClaudecodeCommand({
582
617
  baseDir,
583
618
  relativeDirPath: ".claude/commands",
584
- relativeFilePath: (0, import_node_path4.basename)(filePath),
619
+ relativeFilePath: (0, import_node_path5.basename)(relativeFilePath),
585
620
  frontmatter: result.data,
586
621
  body: content.trim(),
587
622
  validate
@@ -590,7 +625,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
590
625
  };
591
626
 
592
627
  // src/commands/geminicli-command.ts
593
- var import_node_path5 = require("path");
628
+ var import_node_path6 = require("path");
594
629
  var import_smol_toml = require("smol-toml");
595
630
  var import_mini5 = require("zod/mini");
596
631
  var GeminiCliCommandFrontmatterSchema = import_mini5.z.object({
@@ -676,16 +711,17 @@ ${geminiFrontmatter.prompt}
676
711
  validate
677
712
  });
678
713
  }
679
- static async fromFilePath({
714
+ static async fromFile({
680
715
  baseDir = ".",
681
- filePath,
716
+ relativeFilePath,
682
717
  validate = true
683
718
  }) {
719
+ const filePath = (0, import_node_path6.join)(baseDir, ".gemini", "commands", relativeFilePath);
684
720
  const fileContent = await readFileContent(filePath);
685
721
  return new _GeminiCliCommand({
686
722
  baseDir,
687
723
  relativeDirPath: ".gemini/commands",
688
- relativeFilePath: (0, import_node_path5.basename)(filePath),
724
+ relativeFilePath: (0, import_node_path6.basename)(relativeFilePath),
689
725
  fileContent,
690
726
  validate
691
727
  });
@@ -698,26 +734,10 @@ ${geminiFrontmatter.prompt}
698
734
  return { success: false, error: error instanceof Error ? error : new Error(String(error)) };
699
735
  }
700
736
  }
701
- async processContent(content, args) {
702
- let processedContent = content;
703
- processedContent = this.processArgumentPlaceholder(processedContent, args);
704
- return processedContent;
705
- }
706
- processArgumentPlaceholder(content, args) {
707
- if (content.includes("{{args}}")) {
708
- return content.replace(/\{\{args\}\}/g, args || "");
709
- }
710
- if (args) {
711
- return `${content}
712
-
713
- ${args}`;
714
- }
715
- return content;
716
- }
717
737
  };
718
738
 
719
739
  // src/commands/roo-command.ts
720
- var import_node_path6 = require("path");
740
+ var import_node_path7 = require("path");
721
741
  var import_mini6 = require("zod/mini");
722
742
  var RooCommandFrontmatterSchema = import_mini6.z.object({
723
743
  description: import_mini6.z.string(),
@@ -794,11 +814,12 @@ var RooCommand = class _RooCommand extends ToolCommand {
794
814
  return { success: false, error: result.error };
795
815
  }
796
816
  }
797
- static async fromFilePath({
817
+ static async fromFile({
798
818
  baseDir = ".",
799
- filePath,
819
+ relativeFilePath,
800
820
  validate = true
801
821
  }) {
822
+ const filePath = (0, import_node_path7.join)(baseDir, ".roo", "commands", relativeFilePath);
802
823
  const fileContent = await readFileContent(filePath);
803
824
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
804
825
  const result = RooCommandFrontmatterSchema.safeParse(frontmatter);
@@ -808,7 +829,7 @@ var RooCommand = class _RooCommand extends ToolCommand {
808
829
  return new _RooCommand({
809
830
  baseDir,
810
831
  relativeDirPath: ".roo/commands",
811
- relativeFilePath: (0, import_node_path6.basename)(filePath),
832
+ relativeFilePath: (0, import_node_path7.basename)(relativeFilePath),
812
833
  frontmatter: result.data,
813
834
  body: content.trim(),
814
835
  fileContent,
@@ -870,37 +891,12 @@ var CommandsProcessor = class extends FeatureProcessor {
870
891
  * Load and parse rulesync command files from .rulesync/commands/ directory
871
892
  */
872
893
  async loadRulesyncFiles() {
873
- const commandsDir = (0, import_node_path7.join)(this.baseDir, ".rulesync", "commands");
874
- const dirExists = await directoryExists(commandsDir);
875
- if (!dirExists) {
876
- logger.debug(`Rulesync commands directory not found: ${commandsDir}`);
877
- return [];
878
- }
879
- const allMdFiles = await findFiles(commandsDir, ".md");
880
- const mdFiles = allMdFiles.map((f) => (0, import_node_path7.basename)(f));
881
- if (mdFiles.length === 0) {
882
- logger.debug(`No markdown files found in rulesync commands directory: ${commandsDir}`);
883
- return [];
884
- }
885
- logger.info(`Found ${mdFiles.length} command files in ${commandsDir}`);
886
- const rulesyncCommands = [];
887
- for (const mdFile of mdFiles) {
888
- const filepath = (0, import_node_path7.join)(commandsDir, mdFile);
889
- try {
890
- const rulesyncCommand = await RulesyncCommand.fromFilePath({
891
- filePath: filepath
892
- });
893
- rulesyncCommands.push(rulesyncCommand);
894
- logger.debug(`Successfully loaded command: ${mdFile}`);
895
- } catch (error) {
896
- logger.warn(`Failed to load command file ${filepath}:`, error);
897
- continue;
898
- }
899
- }
900
- if (rulesyncCommands.length === 0) {
901
- logger.debug(`No valid commands found in ${commandsDir}`);
902
- return [];
903
- }
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);
904
900
  logger.info(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
905
901
  return rulesyncCommands;
906
902
  }
@@ -913,122 +909,67 @@ var CommandsProcessor = class extends FeatureProcessor {
913
909
  case "claudecode":
914
910
  return await this.loadClaudecodeCommands();
915
911
  case "geminicli":
916
- return await this.loadGeminiCliCommands();
912
+ return await this.loadGeminicliCommands();
917
913
  case "roo":
918
914
  return await this.loadRooCommands();
919
915
  default:
920
916
  throw new Error(`Unsupported tool target: ${this.toolTarget}`);
921
917
  }
922
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
+ }
923
944
  /**
924
945
  * Load Claude Code command configurations from .claude/commands/ directory
925
946
  */
926
947
  async loadClaudecodeCommands() {
927
- const commandsDir = (0, import_node_path7.join)(this.baseDir, ".claude", "commands");
928
- if (!await directoryExists(commandsDir)) {
929
- logger.warn(`Claude Code commands directory not found: ${commandsDir}`);
930
- return [];
931
- }
932
- const allMdFiles = await findFiles(commandsDir, ".md");
933
- const mdFiles = allMdFiles.map((f) => (0, import_node_path7.basename)(f));
934
- if (mdFiles.length === 0) {
935
- logger.info(`No markdown command files found in ${commandsDir}`);
936
- return [];
937
- }
938
- logger.info(`Found ${mdFiles.length} Claude Code command files in ${commandsDir}`);
939
- const toolCommands = [];
940
- for (const mdFile of mdFiles) {
941
- const filepath = (0, import_node_path7.join)(commandsDir, mdFile);
942
- try {
943
- const claudecodeCommand = await ClaudecodeCommand.fromFilePath({
944
- baseDir: this.baseDir,
945
- filePath: filepath
946
- });
947
- toolCommands.push(claudecodeCommand);
948
- logger.debug(`Successfully loaded Claude Code command: ${mdFile}`);
949
- } catch (error) {
950
- logger.warn(`Failed to load Claude Code command file ${filepath}:`, error);
951
- continue;
952
- }
953
- }
954
- logger.info(`Successfully loaded ${toolCommands.length} Claude Code commands`);
955
- return toolCommands;
948
+ return await this.loadToolCommandDefault({
949
+ toolTarget: "claudecode",
950
+ relativeDirPath: ".claude/commands",
951
+ extension: "md"
952
+ });
956
953
  }
957
954
  /**
958
955
  * Load Gemini CLI command configurations from .gemini/commands/ directory
959
956
  */
960
- async loadGeminiCliCommands() {
961
- const commandsDir = (0, import_node_path7.join)(this.baseDir, ".gemini", "commands");
962
- if (!await directoryExists(commandsDir)) {
963
- logger.warn(`Gemini CLI commands directory not found: ${commandsDir}`);
964
- return [];
965
- }
966
- const allFiles = await listDirectoryFiles(commandsDir);
967
- const tomlFiles = allFiles.filter((file) => file.endsWith(".toml"));
968
- if (tomlFiles.length === 0) {
969
- logger.info(`No TOML command files found in ${commandsDir}`);
970
- return [];
971
- }
972
- logger.info(`Found ${tomlFiles.length} Gemini CLI command files in ${commandsDir}`);
973
- const toolCommands = [];
974
- for (const tomlFile of tomlFiles) {
975
- const filepath = (0, import_node_path7.join)(commandsDir, tomlFile);
976
- try {
977
- const geminiCliCommand = await GeminiCliCommand.fromFilePath({
978
- baseDir: this.baseDir,
979
- filePath: filepath
980
- });
981
- toolCommands.push(geminiCliCommand);
982
- logger.debug(`Successfully loaded Gemini CLI command: ${tomlFile}`);
983
- } catch (error) {
984
- logger.warn(`Failed to load Gemini CLI command file ${filepath}:`, error);
985
- continue;
986
- }
987
- }
988
- logger.info(`Successfully loaded ${toolCommands.length} Gemini CLI commands`);
989
- return toolCommands;
957
+ async loadGeminicliCommands() {
958
+ return await this.loadToolCommandDefault({
959
+ toolTarget: "geminicli",
960
+ relativeDirPath: ".gemini/commands",
961
+ extension: "md"
962
+ });
990
963
  }
991
964
  /**
992
965
  * Load Roo Code command configurations from .roo/commands/ directory
993
966
  */
994
967
  async loadRooCommands() {
995
- const commandsDir = (0, import_node_path7.join)(this.baseDir, ".roo", "commands");
996
- if (!await directoryExists(commandsDir)) {
997
- logger.warn(`Roo Code commands directory not found: ${commandsDir}`);
998
- return [];
999
- }
1000
- const allMdFiles = await findFiles(commandsDir, ".md");
1001
- const mdFiles = allMdFiles.map((f) => (0, import_node_path7.basename)(f));
1002
- if (mdFiles.length === 0) {
1003
- logger.info(`No markdown command files found in ${commandsDir}`);
1004
- return [];
1005
- }
1006
- logger.info(`Found ${mdFiles.length} Roo Code command files in ${commandsDir}`);
1007
- const toolCommands = [];
1008
- for (const mdFile of mdFiles) {
1009
- const filepath = (0, import_node_path7.join)(commandsDir, mdFile);
1010
- try {
1011
- const rooCommand = await RooCommand.fromFilePath({
1012
- baseDir: this.baseDir,
1013
- filePath: filepath
1014
- });
1015
- toolCommands.push(rooCommand);
1016
- logger.debug(`Successfully loaded Roo Code command: ${mdFile}`);
1017
- } catch (error) {
1018
- logger.warn(`Failed to load Roo Code command file ${filepath}:`, error);
1019
- continue;
1020
- }
1021
- }
1022
- logger.info(`Successfully loaded ${toolCommands.length} Roo Code commands`);
1023
- return toolCommands;
1024
- }
1025
- async writeToolCommandsFromRulesyncCommands(rulesyncCommands) {
1026
- const toolCommands = await this.convertRulesyncFilesToToolFiles(rulesyncCommands);
1027
- await this.writeAiFiles(toolCommands);
1028
- }
1029
- async writeRulesyncCommandsFromToolCommands(toolCommands) {
1030
- const rulesyncCommands = await this.convertToolFilesToRulesyncFiles(toolCommands);
1031
- await this.writeAiFiles(rulesyncCommands);
968
+ return await this.loadToolCommandDefault({
969
+ toolTarget: "roo",
970
+ relativeDirPath: ".roo/commands",
971
+ extension: "md"
972
+ });
1032
973
  }
1033
974
  /**
1034
975
  * Implementation of abstract method from FeatureProcessor
@@ -1140,6 +1081,9 @@ var ConfigResolver = class {
1140
1081
  // src/ignore/ignore-processor.ts
1141
1082
  var import_mini9 = require("zod/mini");
1142
1083
 
1084
+ // src/ignore/augmentcode-ignore.ts
1085
+ var import_node_path9 = require("path");
1086
+
1143
1087
  // src/types/tool-file.ts
1144
1088
  var ToolFile = class extends AiFile {
1145
1089
  };
@@ -1158,9 +1102,6 @@ var RulesyncIgnore = class _RulesyncIgnore extends RulesyncFile {
1158
1102
  fileContent
1159
1103
  });
1160
1104
  }
1161
- static async fromFilePath(_params) {
1162
- throw new Error("Please use the fromFile method instead.");
1163
- }
1164
1105
  };
1165
1106
 
1166
1107
  // src/ignore/tool-ignore.ts
@@ -1197,12 +1138,9 @@ var ToolIgnore = class extends ToolFile {
1197
1138
  fileContent: this.fileContent
1198
1139
  });
1199
1140
  }
1200
- static async fromFile() {
1141
+ static async fromFile(_params) {
1201
1142
  throw new Error("Please implement this method in the subclass.");
1202
1143
  }
1203
- static async fromFilePath(_params) {
1204
- throw new Error("Please use the fromFile method instead.");
1205
- }
1206
1144
  };
1207
1145
 
1208
1146
  // src/ignore/augmentcode-ignore.ts
@@ -1232,18 +1170,23 @@ var AugmentcodeIgnore = class _AugmentcodeIgnore extends ToolIgnore {
1232
1170
  * Create AugmentcodeIgnore from file path
1233
1171
  * Reads and parses .augmentignore file
1234
1172
  */
1235
- static async fromFile() {
1236
- 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"));
1237
1178
  return new _AugmentcodeIgnore({
1238
- baseDir: ".",
1179
+ baseDir,
1239
1180
  relativeDirPath: ".",
1240
1181
  relativeFilePath: ".augmentignore",
1241
- fileContent
1182
+ fileContent,
1183
+ validate
1242
1184
  });
1243
1185
  }
1244
1186
  };
1245
1187
 
1246
1188
  // src/ignore/cline-ignore.ts
1189
+ var import_node_path10 = require("path");
1247
1190
  var ClineIgnore = class _ClineIgnore extends ToolIgnore {
1248
1191
  /**
1249
1192
  * Convert ClineIgnore to RulesyncIgnore format
@@ -1269,18 +1212,23 @@ var ClineIgnore = class _ClineIgnore extends ToolIgnore {
1269
1212
  /**
1270
1213
  * Load ClineIgnore from .clineignore file
1271
1214
  */
1272
- static async fromFile() {
1273
- 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"));
1274
1220
  return new _ClineIgnore({
1275
- baseDir: ".",
1221
+ baseDir,
1276
1222
  relativeDirPath: ".",
1277
1223
  relativeFilePath: ".clineignore",
1278
- fileContent
1224
+ fileContent,
1225
+ validate
1279
1226
  });
1280
1227
  }
1281
1228
  };
1282
1229
 
1283
1230
  // src/ignore/codexcli-ignore.ts
1231
+ var import_node_path11 = require("path");
1284
1232
  var CodexcliIgnore = class _CodexcliIgnore extends ToolIgnore {
1285
1233
  toRulesyncIgnore() {
1286
1234
  return this.toRulesyncIgnoreDefault();
@@ -1299,20 +1247,23 @@ var CodexcliIgnore = class _CodexcliIgnore extends ToolIgnore {
1299
1247
  // Skip validation to allow empty patterns
1300
1248
  });
1301
1249
  }
1302
- static async fromFile() {
1303
- 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"));
1304
1255
  return new _CodexcliIgnore({
1305
- baseDir: ".",
1256
+ baseDir,
1306
1257
  relativeDirPath: ".",
1307
1258
  relativeFilePath: ".codexignore",
1308
1259
  fileContent,
1309
- validate: true
1310
- // Skip validation to allow empty patterns
1260
+ validate
1311
1261
  });
1312
1262
  }
1313
1263
  };
1314
1264
 
1315
1265
  // src/ignore/cursor-ignore.ts
1266
+ var import_node_path12 = require("path");
1316
1267
  var CursorIgnore = class _CursorIgnore extends ToolIgnore {
1317
1268
  toRulesyncIgnore() {
1318
1269
  return new RulesyncIgnore({
@@ -1334,18 +1285,23 @@ var CursorIgnore = class _CursorIgnore extends ToolIgnore {
1334
1285
  fileContent: body
1335
1286
  });
1336
1287
  }
1337
- static async fromFile() {
1338
- 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"));
1339
1293
  return new _CursorIgnore({
1340
- baseDir: ".",
1294
+ baseDir,
1341
1295
  relativeDirPath: ".",
1342
1296
  relativeFilePath: ".cursorignore",
1343
- fileContent
1297
+ fileContent,
1298
+ validate
1344
1299
  });
1345
1300
  }
1346
1301
  };
1347
1302
 
1348
1303
  // src/ignore/geminicli-ignore.ts
1304
+ var import_node_path13 = require("path");
1349
1305
  var GeminiCliIgnore = class _GeminiCliIgnore extends ToolIgnore {
1350
1306
  toRulesyncIgnore() {
1351
1307
  return this.toRulesyncIgnoreDefault();
@@ -1361,18 +1317,23 @@ var GeminiCliIgnore = class _GeminiCliIgnore extends ToolIgnore {
1361
1317
  fileContent: rulesyncIgnore.getFileContent()
1362
1318
  });
1363
1319
  }
1364
- static async fromFile() {
1365
- 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"));
1366
1325
  return new _GeminiCliIgnore({
1367
- baseDir: ".",
1326
+ baseDir,
1368
1327
  relativeDirPath: ".",
1369
1328
  relativeFilePath: ".aiexclude",
1370
- fileContent
1329
+ fileContent,
1330
+ validate
1371
1331
  });
1372
1332
  }
1373
1333
  };
1374
1334
 
1375
1335
  // src/ignore/junie-ignore.ts
1336
+ var import_node_path14 = require("path");
1376
1337
  var JunieIgnore = class _JunieIgnore extends ToolIgnore {
1377
1338
  toRulesyncIgnore() {
1378
1339
  return this.toRulesyncIgnoreDefault();
@@ -1388,18 +1349,23 @@ var JunieIgnore = class _JunieIgnore extends ToolIgnore {
1388
1349
  fileContent: rulesyncIgnore.getFileContent()
1389
1350
  });
1390
1351
  }
1391
- static async fromFile() {
1392
- 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"));
1393
1357
  return new _JunieIgnore({
1394
- baseDir: ".",
1358
+ baseDir,
1395
1359
  relativeDirPath: ".",
1396
1360
  relativeFilePath: ".junieignore",
1397
- fileContent
1361
+ fileContent,
1362
+ validate
1398
1363
  });
1399
1364
  }
1400
1365
  };
1401
1366
 
1402
1367
  // src/ignore/kiro-ignore.ts
1368
+ var import_node_path15 = require("path");
1403
1369
  var KiroIgnore = class _KiroIgnore extends ToolIgnore {
1404
1370
  toRulesyncIgnore() {
1405
1371
  return this.toRulesyncIgnoreDefault();
@@ -1415,18 +1381,23 @@ var KiroIgnore = class _KiroIgnore extends ToolIgnore {
1415
1381
  fileContent: rulesyncIgnore.getFileContent()
1416
1382
  });
1417
1383
  }
1418
- static async fromFile() {
1419
- 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"));
1420
1389
  return new _KiroIgnore({
1421
- baseDir: ".",
1390
+ baseDir,
1422
1391
  relativeDirPath: ".",
1423
1392
  relativeFilePath: ".aiignore",
1424
- fileContent
1393
+ fileContent,
1394
+ validate
1425
1395
  });
1426
1396
  }
1427
1397
  };
1428
1398
 
1429
1399
  // src/ignore/qwencode-ignore.ts
1400
+ var import_node_path16 = require("path");
1430
1401
  var QwencodeIgnore = class _QwencodeIgnore extends ToolIgnore {
1431
1402
  toRulesyncIgnore() {
1432
1403
  return this.toRulesyncIgnoreDefault();
@@ -1442,18 +1413,23 @@ var QwencodeIgnore = class _QwencodeIgnore extends ToolIgnore {
1442
1413
  fileContent: rulesyncIgnore.getFileContent()
1443
1414
  });
1444
1415
  }
1445
- static async fromFile() {
1446
- 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"));
1447
1421
  return new _QwencodeIgnore({
1448
- baseDir: ".",
1422
+ baseDir,
1449
1423
  relativeDirPath: ".",
1450
1424
  relativeFilePath: ".geminiignore",
1451
- fileContent
1425
+ fileContent,
1426
+ validate
1452
1427
  });
1453
1428
  }
1454
1429
  };
1455
1430
 
1456
1431
  // src/ignore/roo-ignore.ts
1432
+ var import_node_path17 = require("path");
1457
1433
  var RooIgnore = class _RooIgnore extends ToolIgnore {
1458
1434
  toRulesyncIgnore() {
1459
1435
  return this.toRulesyncIgnoreDefault();
@@ -1469,18 +1445,23 @@ var RooIgnore = class _RooIgnore extends ToolIgnore {
1469
1445
  fileContent: rulesyncIgnore.getFileContent()
1470
1446
  });
1471
1447
  }
1472
- static async fromFile() {
1473
- 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"));
1474
1453
  return new _RooIgnore({
1475
- baseDir: ".",
1454
+ baseDir,
1476
1455
  relativeDirPath: ".",
1477
1456
  relativeFilePath: ".rooignore",
1478
- fileContent
1457
+ fileContent,
1458
+ validate
1479
1459
  });
1480
1460
  }
1481
1461
  };
1482
1462
 
1483
1463
  // src/ignore/windsurf-ignore.ts
1464
+ var import_node_path18 = require("path");
1484
1465
  var WindsurfIgnore = class _WindsurfIgnore extends ToolIgnore {
1485
1466
  toRulesyncIgnore() {
1486
1467
  return this.toRulesyncIgnoreDefault();
@@ -1496,6 +1477,19 @@ var WindsurfIgnore = class _WindsurfIgnore extends ToolIgnore {
1496
1477
  fileContent: rulesyncIgnore.getFileContent()
1497
1478
  });
1498
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
+ }
1499
1493
  };
1500
1494
 
1501
1495
  // src/ignore/ignore-processor.ts
@@ -1553,25 +1547,25 @@ var IgnoreProcessor = class extends FeatureProcessor {
1553
1547
  async loadToolIgnores() {
1554
1548
  switch (this.toolTarget) {
1555
1549
  case "augmentcode":
1556
- return [await AugmentcodeIgnore.fromFile()];
1550
+ return [await AugmentcodeIgnore.fromFile({ baseDir: this.baseDir })];
1557
1551
  case "cline":
1558
- return [await ClineIgnore.fromFile()];
1552
+ return [await ClineIgnore.fromFile({ baseDir: this.baseDir })];
1559
1553
  case "codexcli":
1560
- return [await CodexcliIgnore.fromFile()];
1554
+ return [await CodexcliIgnore.fromFile({ baseDir: this.baseDir })];
1561
1555
  case "cursor":
1562
- return [await CursorIgnore.fromFile()];
1556
+ return [await CursorIgnore.fromFile({ baseDir: this.baseDir })];
1563
1557
  case "geminicli":
1564
- return [await GeminiCliIgnore.fromFile()];
1558
+ return [await GeminiCliIgnore.fromFile({ baseDir: this.baseDir })];
1565
1559
  case "junie":
1566
- return [await JunieIgnore.fromFile()];
1560
+ return [await JunieIgnore.fromFile({ baseDir: this.baseDir })];
1567
1561
  case "kiro":
1568
- return [await KiroIgnore.fromFile()];
1562
+ return [await KiroIgnore.fromFile({ baseDir: this.baseDir })];
1569
1563
  case "qwencode":
1570
- return [await QwencodeIgnore.fromFile()];
1564
+ return [await QwencodeIgnore.fromFile({ baseDir: this.baseDir })];
1571
1565
  case "roo":
1572
- return [await RooIgnore.fromFile()];
1566
+ return [await RooIgnore.fromFile({ baseDir: this.baseDir })];
1573
1567
  case "windsurf":
1574
- return [await WindsurfIgnore.fromFile()];
1568
+ return [await WindsurfIgnore.fromFile({ baseDir: this.baseDir })];
1575
1569
  default:
1576
1570
  throw new Error(`Unsupported tool target: ${this.toolTarget}`);
1577
1571
  }
@@ -1666,9 +1660,14 @@ var IgnoreProcessor = class extends FeatureProcessor {
1666
1660
  };
1667
1661
 
1668
1662
  // src/mcp/mcp-processor.ts
1669
- var import_node_path8 = require("path");
1670
1663
  var import_mini11 = require("zod/mini");
1671
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
+
1672
1671
  // src/types/mcp.ts
1673
1672
  var import_mini10 = require("zod/mini");
1674
1673
  var McpTransportTypeSchema = import_mini10.z.enum(["stdio", "sse", "http"]);
@@ -1717,14 +1716,14 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
1717
1716
  validate() {
1718
1717
  return { success: true, error: null };
1719
1718
  }
1720
- static async fromFilePath({ filePath }) {
1721
- 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"));
1722
1721
  return new _RulesyncMcp({
1723
1722
  baseDir: ".",
1724
- relativeDirPath: ".rulesync",
1723
+ relativeDirPath: RULESYNC_DIR,
1725
1724
  relativeFilePath: ".mcp.json",
1726
1725
  fileContent,
1727
- validate: true
1726
+ validate
1728
1727
  });
1729
1728
  }
1730
1729
  getJson() {
@@ -1760,7 +1759,7 @@ var ToolMcp = class extends ToolFile {
1760
1759
  fileContent: this.fileContent
1761
1760
  });
1762
1761
  }
1763
- static async fromFilePath(_params) {
1762
+ static async fromFile(_params) {
1764
1763
  throw new Error("Please implement this method in the subclass.");
1765
1764
  }
1766
1765
  static fromRulesyncMcp(_params) {
@@ -1770,14 +1769,17 @@ var ToolMcp = class extends ToolFile {
1770
1769
 
1771
1770
  // src/mcp/amazonqcli-mcp.ts
1772
1771
  var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
1773
- static async fromFilePath({ filePath }) {
1774
- 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"));
1775
1777
  return new _AmazonqcliMcp({
1776
- baseDir: ".",
1778
+ baseDir,
1777
1779
  relativeDirPath: ".amazonq",
1778
- relativeFilePath: ".mcp.json",
1780
+ relativeFilePath: "mcp.json",
1779
1781
  fileContent,
1780
- validate: true
1782
+ validate
1781
1783
  });
1782
1784
  }
1783
1785
  static fromRulesyncMcp({
@@ -1802,15 +1804,19 @@ var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
1802
1804
  };
1803
1805
 
1804
1806
  // src/mcp/claudecode-mcp.ts
1807
+ var import_node_path21 = require("path");
1805
1808
  var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
1806
- static async fromFilePath({ filePath }) {
1807
- 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"));
1808
1814
  return new _ClaudecodeMcp({
1809
1815
  baseDir: ".",
1810
1816
  relativeDirPath: ".",
1811
1817
  relativeFilePath: ".mcp.json",
1812
1818
  fileContent,
1813
- validate: true
1819
+ validate
1814
1820
  });
1815
1821
  }
1816
1822
  static fromRulesyncMcp({
@@ -1835,15 +1841,19 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
1835
1841
  };
1836
1842
 
1837
1843
  // src/mcp/cline-mcp.ts
1844
+ var import_node_path22 = require("path");
1838
1845
  var ClineMcp = class _ClineMcp extends ToolMcp {
1839
- static async fromFilePath({ filePath }) {
1840
- 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"));
1841
1851
  return new _ClineMcp({
1842
1852
  baseDir: ".",
1843
1853
  relativeDirPath: ".cline",
1844
1854
  relativeFilePath: "mcp.json",
1845
1855
  fileContent,
1846
- validate: true
1856
+ validate
1847
1857
  });
1848
1858
  }
1849
1859
  static fromRulesyncMcp({
@@ -1868,15 +1878,19 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
1868
1878
  };
1869
1879
 
1870
1880
  // src/mcp/copilot-mcp.ts
1881
+ var import_node_path23 = require("path");
1871
1882
  var CopilotMcp = class _CopilotMcp extends ToolMcp {
1872
- static async fromFilePath({ filePath }) {
1873
- 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"));
1874
1888
  return new _CopilotMcp({
1875
1889
  baseDir: ".",
1876
1890
  relativeDirPath: ".vscode",
1877
1891
  relativeFilePath: "mcp.json",
1878
1892
  fileContent,
1879
- validate: true
1893
+ validate
1880
1894
  });
1881
1895
  }
1882
1896
  static fromRulesyncMcp({
@@ -1901,15 +1915,19 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
1901
1915
  };
1902
1916
 
1903
1917
  // src/mcp/cursor-mcp.ts
1918
+ var import_node_path24 = require("path");
1904
1919
  var CursorMcp = class _CursorMcp extends ToolMcp {
1905
- static async fromFilePath({ filePath }) {
1906
- 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"));
1907
1925
  return new _CursorMcp({
1908
1926
  baseDir: ".",
1909
1927
  relativeDirPath: ".cursor",
1910
1928
  relativeFilePath: "mcp.json",
1911
1929
  fileContent,
1912
- validate: true
1930
+ validate
1913
1931
  });
1914
1932
  }
1915
1933
  static fromRulesyncMcp({
@@ -1945,15 +1963,19 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
1945
1963
  };
1946
1964
 
1947
1965
  // src/mcp/roo-mcp.ts
1966
+ var import_node_path25 = require("path");
1948
1967
  var RooMcp = class _RooMcp extends ToolMcp {
1949
- static async fromFilePath({ filePath }) {
1950
- 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"));
1951
1973
  return new _RooMcp({
1952
1974
  baseDir: ".",
1953
1975
  relativeDirPath: ".roo",
1954
1976
  relativeFilePath: "mcp.json",
1955
1977
  fileContent,
1956
- validate: true
1978
+ validate
1957
1979
  });
1958
1980
  }
1959
1981
  static fromRulesyncMcp({
@@ -2003,9 +2025,7 @@ var McpProcessor = class extends FeatureProcessor {
2003
2025
  */
2004
2026
  async loadRulesyncFiles() {
2005
2027
  try {
2006
- return [
2007
- await RulesyncMcp.fromFilePath({ filePath: (0, import_node_path8.join)(this.baseDir, ".rulesync", ".mcp.json") })
2008
- ];
2028
+ return [await RulesyncMcp.fromFile({})];
2009
2029
  } catch (error) {
2010
2030
  logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
2011
2031
  return [];
@@ -2017,42 +2037,62 @@ var McpProcessor = class extends FeatureProcessor {
2017
2037
  */
2018
2038
  async loadToolFiles() {
2019
2039
  try {
2020
- switch (this.toolTarget) {
2021
- case "amazonqcli": {
2022
- return [
2023
- await AmazonqcliMcp.fromFilePath({
2024
- filePath: (0, import_node_path8.join)(this.baseDir, ".amazonq", "mcp.json")
2025
- })
2026
- ];
2027
- }
2028
- case "claudecode": {
2029
- return [
2030
- await ClaudecodeMcp.fromFilePath({
2031
- filePath: (0, import_node_path8.join)(this.baseDir, ".mcp.json")
2032
- })
2033
- ];
2034
- }
2035
- case "cline": {
2036
- return [
2037
- await ClineMcp.fromFilePath({ filePath: (0, import_node_path8.join)(this.baseDir, ".cline", "mcp.json") })
2038
- ];
2039
- }
2040
- case "copilot": {
2041
- return [
2042
- await CopilotMcp.fromFilePath({ filePath: (0, import_node_path8.join)(this.baseDir, ".vscode", "mcp.json") })
2043
- ];
2044
- }
2045
- case "cursor": {
2046
- return [
2047
- await CursorMcp.fromFilePath({ filePath: (0, import_node_path8.join)(this.baseDir, ".cursor", "mcp.json") })
2048
- ];
2049
- }
2050
- case "roo": {
2051
- 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}`);
2052
2092
  }
2053
- default:
2054
- throw new Error(`Unsupported tool target: ${this.toolTarget}`);
2055
- }
2093
+ })();
2094
+ logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
2095
+ return toolMcps;
2056
2096
  } catch (error) {
2057
2097
  logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
2058
2098
  return [];
@@ -2128,21 +2168,15 @@ var McpProcessor = class extends FeatureProcessor {
2128
2168
  };
2129
2169
 
2130
2170
  // src/rules/rules-processor.ts
2131
- var import_node_path12 = require("path");
2171
+ var import_node_path44 = require("path");
2132
2172
  var import_fast_xml_parser = require("fast-xml-parser");
2133
2173
  var import_mini16 = require("zod/mini");
2134
2174
 
2135
- // src/constants/paths.ts
2136
- var import_node_path9 = require("path");
2137
- var RULESYNC_DIR = ".rulesync";
2138
- var RULESYNC_RULES_DIR = (0, import_node_path9.join)(".rulesync", "rules");
2139
- var RULESYNC_RULES_DIR_LEGACY = ".rulesync";
2140
- var RULESYNC_MCP_FILE = (0, import_node_path9.join)(".rulesync", ".mcp.json");
2141
- var RULESYNC_COMMANDS_DIR = (0, import_node_path9.join)(".rulesync", "commands");
2142
- var RULESYNC_SUBAGENTS_DIR = (0, import_node_path9.join)(".rulesync", "subagents");
2175
+ // src/rules/agentsmd-rule.ts
2176
+ var import_node_path27 = require("path");
2143
2177
 
2144
2178
  // src/rules/rulesync-rule.ts
2145
- var import_node_path10 = require("path");
2179
+ var import_node_path26 = require("path");
2146
2180
  var import_mini12 = require("zod/mini");
2147
2181
  var RulesyncRuleFrontmatterSchema = import_mini12.z.object({
2148
2182
  root: import_mini12.z.optional(import_mini12.z.optional(import_mini12.z.boolean())),
@@ -2188,10 +2222,11 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
2188
2222
  return { success: false, error: result.error };
2189
2223
  }
2190
2224
  }
2191
- static async fromLegacyFile({
2192
- relativeFilePath
2225
+ static async fromFileLegacy({
2226
+ relativeFilePath,
2227
+ validate = true
2193
2228
  }) {
2194
- 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);
2195
2230
  const fileContent = await readFileContent(filePath);
2196
2231
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
2197
2232
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
@@ -2205,16 +2240,21 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
2205
2240
  globs: result.data.globs ?? [],
2206
2241
  cursor: result.data.cursor
2207
2242
  };
2208
- const filename = (0, import_node_path10.basename)(filePath);
2243
+ const filename = (0, import_node_path26.basename)(filePath);
2209
2244
  return new _RulesyncRule({
2210
2245
  baseDir: ".",
2211
2246
  relativeDirPath: RULESYNC_RULES_DIR,
2212
2247
  relativeFilePath: filename,
2213
2248
  frontmatter: validatedFrontmatter,
2214
- body: content.trim()
2249
+ body: content.trim(),
2250
+ validate
2215
2251
  });
2216
2252
  }
2217
- 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);
2218
2258
  const fileContent = await readFileContent(filePath);
2219
2259
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
2220
2260
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
@@ -2228,13 +2268,14 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
2228
2268
  globs: result.data.globs ?? [],
2229
2269
  cursor: result.data.cursor
2230
2270
  };
2231
- const filename = (0, import_node_path10.basename)(filePath);
2271
+ const filename = (0, import_node_path26.basename)(filePath);
2232
2272
  return new _RulesyncRule({
2233
2273
  baseDir: ".",
2234
2274
  relativeDirPath: RULESYNC_RULES_DIR,
2235
2275
  relativeFilePath: filename,
2236
2276
  frontmatter: validatedFrontmatter,
2237
- body: content.trim()
2277
+ body: content.trim(),
2278
+ validate
2238
2279
  });
2239
2280
  }
2240
2281
  getBody() {
@@ -2249,7 +2290,7 @@ var ToolRule = class extends ToolFile {
2249
2290
  super(rest);
2250
2291
  this.root = root;
2251
2292
  }
2252
- static async fromFilePath(_params) {
2293
+ static async fromFile(_params) {
2253
2294
  throw new Error("Please implement this method in the subclass.");
2254
2295
  }
2255
2296
  static fromRulesyncRule(_params) {
@@ -2300,19 +2341,18 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
2300
2341
  root: root ?? false
2301
2342
  });
2302
2343
  }
2303
- static async fromFilePath({
2344
+ static async fromFile({
2304
2345
  baseDir = ".",
2305
- relativeDirPath,
2306
2346
  relativeFilePath,
2307
- filePath,
2308
2347
  validate = true
2309
2348
  }) {
2310
- const fileContent = await readFileContent(filePath);
2311
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));
2312
2352
  return new _AgentsMdRule({
2313
2353
  baseDir,
2314
- relativeDirPath,
2315
- relativeFilePath,
2354
+ relativeDirPath: isRoot ? "." : ".agents/memories",
2355
+ relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
2316
2356
  fileContent,
2317
2357
  validate,
2318
2358
  root: isRoot
@@ -2340,15 +2380,20 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
2340
2380
  };
2341
2381
 
2342
2382
  // src/rules/amazonqcli-rule.ts
2383
+ var import_node_path28 = require("path");
2343
2384
  var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
2344
- static async fromFilePath(params) {
2345
- 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));
2346
2391
  return new _AmazonQCliRule({
2347
- baseDir: params.baseDir || ".",
2348
- relativeDirPath: params.relativeDirPath,
2349
- relativeFilePath: params.relativeFilePath,
2392
+ baseDir,
2393
+ relativeDirPath: ".amazonq/rules",
2394
+ relativeFilePath,
2350
2395
  fileContent,
2351
- validate: params.validate ?? false,
2396
+ validate,
2352
2397
  root: false
2353
2398
  });
2354
2399
  }
@@ -2375,6 +2420,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
2375
2420
  };
2376
2421
 
2377
2422
  // src/rules/augmentcode-legacy-rule.ts
2423
+ var import_node_path29 = require("path");
2378
2424
  var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
2379
2425
  toRulesyncRule() {
2380
2426
  const rulesyncFrontmatter = {
@@ -2410,19 +2456,18 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
2410
2456
  validate() {
2411
2457
  return { success: true, error: null };
2412
2458
  }
2413
- static async fromFilePath({
2459
+ static async fromFile({
2414
2460
  baseDir = ".",
2415
- relativeDirPath,
2416
2461
  relativeFilePath,
2417
- filePath,
2418
2462
  validate = true
2419
2463
  }) {
2420
- const fileContent = await readFileContent(filePath);
2421
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));
2422
2467
  return new _AugmentcodeLegacyRule({
2423
2468
  baseDir,
2424
- relativeDirPath,
2425
- relativeFilePath,
2469
+ relativeDirPath: isRoot ? "." : ".augment/rules",
2470
+ relativeFilePath: isRoot ? ".augment-guidelines" : relativeFilePath,
2426
2471
  fileContent,
2427
2472
  validate,
2428
2473
  root: isRoot
@@ -2431,6 +2476,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
2431
2476
  };
2432
2477
 
2433
2478
  // src/rules/augmentcode-rule.ts
2479
+ var import_node_path30 = require("path");
2434
2480
  var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
2435
2481
  toRulesyncRule() {
2436
2482
  return this.toRulesyncRuleDefault();
@@ -2449,18 +2495,16 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
2449
2495
  })
2450
2496
  );
2451
2497
  }
2452
- static async fromFilePath({
2498
+ static async fromFile({
2453
2499
  baseDir = ".",
2454
- relativeDirPath,
2455
2500
  relativeFilePath,
2456
- filePath,
2457
2501
  validate = true
2458
2502
  }) {
2459
- const fileContent = await readFileContent(filePath);
2503
+ const fileContent = await readFileContent((0, import_node_path30.join)(baseDir, ".augment/rules", relativeFilePath));
2460
2504
  const { body: content } = parseFrontmatter(fileContent);
2461
2505
  return new _AugmentcodeRule({
2462
2506
  baseDir,
2463
- relativeDirPath,
2507
+ relativeDirPath: ".augment/rules",
2464
2508
  relativeFilePath,
2465
2509
  fileContent: content.trim(),
2466
2510
  validate
@@ -2472,16 +2516,23 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
2472
2516
  };
2473
2517
 
2474
2518
  // src/rules/claudecode-rule.ts
2519
+ var import_node_path31 = require("path");
2475
2520
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
2476
- static async fromFilePath(params) {
2477
- 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));
2478
2529
  return new _ClaudecodeRule({
2479
- baseDir: params.baseDir || process.cwd(),
2480
- relativeDirPath: params.relativeDirPath,
2481
- relativeFilePath: params.relativeFilePath,
2530
+ baseDir,
2531
+ relativeDirPath: isRoot ? "." : ".claude/memories",
2532
+ relativeFilePath: isRoot ? "CLAUDE.md" : relativeFilePath,
2482
2533
  fileContent,
2483
- validate: params.validate ?? true,
2484
- root: params.relativeFilePath === "CLAUDE.md"
2534
+ validate,
2535
+ root: isRoot
2485
2536
  });
2486
2537
  }
2487
2538
  static fromRulesyncRule({
@@ -2508,6 +2559,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
2508
2559
  };
2509
2560
 
2510
2561
  // src/rules/cline-rule.ts
2562
+ var import_node_path32 = require("path");
2511
2563
  var import_mini13 = require("zod/mini");
2512
2564
  var ClineRuleFrontmatterSchema = import_mini13.z.object({
2513
2565
  description: import_mini13.z.string()
@@ -2533,17 +2585,15 @@ var ClineRule = class _ClineRule extends ToolRule {
2533
2585
  validate() {
2534
2586
  return { success: true, error: null };
2535
2587
  }
2536
- static async fromFilePath({
2588
+ static async fromFile({
2537
2589
  baseDir = ".",
2538
- relativeDirPath,
2539
2590
  relativeFilePath,
2540
- filePath,
2541
2591
  validate = true
2542
2592
  }) {
2543
- const fileContent = await readFileContent(filePath);
2593
+ const fileContent = await readFileContent((0, import_node_path32.join)(baseDir, ".clinerules", relativeFilePath));
2544
2594
  return new _ClineRule({
2545
2595
  baseDir,
2546
- relativeDirPath,
2596
+ relativeDirPath: ".clinerules",
2547
2597
  relativeFilePath,
2548
2598
  fileContent,
2549
2599
  validate
@@ -2552,16 +2602,23 @@ var ClineRule = class _ClineRule extends ToolRule {
2552
2602
  };
2553
2603
 
2554
2604
  // src/rules/codexcli-rule.ts
2605
+ var import_node_path33 = require("path");
2555
2606
  var CodexcliRule = class _CodexcliRule extends ToolRule {
2556
- static async fromFilePath(params) {
2557
- 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));
2558
2615
  return new _CodexcliRule({
2559
- baseDir: params.baseDir || process.cwd(),
2560
- relativeDirPath: params.relativeDirPath,
2561
- relativeFilePath: params.relativeFilePath,
2616
+ baseDir,
2617
+ relativeDirPath: isRoot ? "." : ".codex/memories",
2618
+ relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
2562
2619
  fileContent,
2563
- validate: params.validate ?? true,
2564
- root: params.relativeFilePath === "AGENTS.md"
2620
+ validate,
2621
+ root: isRoot
2565
2622
  });
2566
2623
  }
2567
2624
  static fromRulesyncRule({
@@ -2588,6 +2645,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
2588
2645
  };
2589
2646
 
2590
2647
  // src/rules/copilot-rule.ts
2648
+ var import_node_path34 = require("path");
2591
2649
  var import_mini14 = require("zod/mini");
2592
2650
  var CopilotRuleFrontmatterSchema = import_mini14.z.object({
2593
2651
  description: import_mini14.z.optional(import_mini14.z.string()),
@@ -2662,45 +2720,43 @@ var CopilotRule = class _CopilotRule extends ToolRule {
2662
2720
  root
2663
2721
  });
2664
2722
  }
2665
- static async fromFilePath({
2723
+ static async fromFile({
2666
2724
  baseDir = ".",
2667
- relativeDirPath,
2668
2725
  relativeFilePath,
2669
- filePath,
2670
2726
  validate = true
2671
2727
  }) {
2672
- const fileContent = await readFileContent(filePath);
2673
- const root = relativeFilePath === "copilot-instructions.md";
2674
- 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) {
2675
2732
  return new _CopilotRule({
2676
2733
  baseDir,
2677
- relativeDirPath,
2678
- relativeFilePath,
2734
+ relativeDirPath: ".github",
2735
+ relativeFilePath: isRoot ? "copilot-instructions.md" : relativeFilePath,
2679
2736
  frontmatter: {
2680
2737
  description: "",
2681
2738
  applyTo: "**"
2682
2739
  },
2683
2740
  body: fileContent.trim(),
2684
2741
  validate,
2685
- root
2742
+ root: isRoot
2686
2743
  });
2687
2744
  }
2688
2745
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
2689
2746
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
2690
2747
  if (!result.success) {
2691
- 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
+ );
2692
2751
  }
2693
2752
  return new _CopilotRule({
2694
2753
  baseDir,
2695
- relativeDirPath,
2696
- relativeFilePath,
2697
- frontmatter: {
2698
- ...result.data,
2699
- applyTo: result.data.applyTo || "**"
2700
- },
2754
+ relativeDirPath: ".github/instructions",
2755
+ relativeFilePath: relativeFilePath.replace(/\.md$/, ".instructions.md"),
2756
+ frontmatter: result.data,
2701
2757
  body: content.trim(),
2702
2758
  validate,
2703
- root
2759
+ root: isRoot
2704
2760
  });
2705
2761
  }
2706
2762
  validate() {
@@ -2723,7 +2779,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
2723
2779
  };
2724
2780
 
2725
2781
  // src/rules/cursor-rule.ts
2726
- var import_node_path11 = require("path");
2782
+ var import_node_path35 = require("path");
2727
2783
  var import_mini15 = require("zod/mini");
2728
2784
  var CursorRuleFrontmatterSchema = import_mini15.z.object({
2729
2785
  description: import_mini15.z.optional(import_mini15.z.string()),
@@ -2742,11 +2798,49 @@ var CursorRule = class _CursorRule extends ToolRule {
2742
2798
  }
2743
2799
  super({
2744
2800
  ...rest,
2745
- fileContent: stringifyFrontmatter(body, frontmatter)
2801
+ fileContent: _CursorRule.stringifyCursorFrontmatter(body, frontmatter)
2746
2802
  });
2747
2803
  this.frontmatter = frontmatter;
2748
2804
  this.body = body;
2749
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
+ }
2750
2844
  toRulesyncRule() {
2751
2845
  const targets = ["*"];
2752
2846
  const isAlways = this.frontmatter.alwaysApply === true;
@@ -2763,13 +2857,18 @@ var CursorRule = class _CursorRule extends ToolRule {
2763
2857
  targets,
2764
2858
  root: false,
2765
2859
  description: this.frontmatter.description,
2766
- globs
2860
+ globs,
2861
+ cursor: {
2862
+ alwaysApply: this.frontmatter.alwaysApply,
2863
+ description: this.frontmatter.description,
2864
+ globs: globs.length > 0 ? globs : void 0
2865
+ }
2767
2866
  };
2768
2867
  return new RulesyncRule({
2769
2868
  frontmatter: rulesyncFrontmatter,
2770
2869
  body: this.body,
2771
2870
  relativeDirPath: ".rulesync/rules",
2772
- relativeFilePath: this.relativeFilePath,
2871
+ relativeFilePath: this.relativeFilePath.replace(/\.mdc$/, ".md"),
2773
2872
  validate: true
2774
2873
  });
2775
2874
  }
@@ -2797,20 +2896,23 @@ var CursorRule = class _CursorRule extends ToolRule {
2797
2896
  validate
2798
2897
  });
2799
2898
  }
2800
- static async fromFilePath({
2801
- filePath,
2899
+ static async fromFile({
2900
+ baseDir = ".",
2901
+ relativeFilePath,
2802
2902
  validate = true
2803
2903
  }) {
2804
- const fileContent = await readFileContent(filePath);
2805
- 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);
2806
2906
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
2807
2907
  if (!result.success) {
2808
- 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
+ );
2809
2911
  }
2810
2912
  return new _CursorRule({
2811
- baseDir: ".",
2913
+ baseDir,
2812
2914
  relativeDirPath: ".cursor/rules",
2813
- relativeFilePath: (0, import_node_path11.basename)(filePath),
2915
+ relativeFilePath: (0, import_node_path35.basename)(relativeFilePath),
2814
2916
  frontmatter: result.data,
2815
2917
  body: content.trim(),
2816
2918
  validate
@@ -2836,16 +2938,23 @@ var CursorRule = class _CursorRule extends ToolRule {
2836
2938
  };
2837
2939
 
2838
2940
  // src/rules/geminicli-rule.ts
2941
+ var import_node_path36 = require("path");
2839
2942
  var GeminiCliRule = class _GeminiCliRule extends ToolRule {
2840
- static async fromFilePath(params) {
2841
- 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));
2842
2951
  return new _GeminiCliRule({
2843
- baseDir: params.baseDir || process.cwd(),
2844
- relativeDirPath: params.relativeDirPath,
2845
- relativeFilePath: params.relativeFilePath,
2952
+ baseDir,
2953
+ relativeDirPath: isRoot ? "." : ".gemini/memories",
2954
+ relativeFilePath: isRoot ? "GEMINI.md" : relativeFilePath,
2846
2955
  fileContent,
2847
- validate: params.validate ?? true,
2848
- root: params.relativeFilePath === "GEMINI.md"
2956
+ validate,
2957
+ root: isRoot
2849
2958
  });
2850
2959
  }
2851
2960
  static fromRulesyncRule({
@@ -2872,15 +2981,22 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
2872
2981
  };
2873
2982
 
2874
2983
  // src/rules/junie-rule.ts
2984
+ var import_node_path37 = require("path");
2875
2985
  var JunieRule = class _JunieRule extends ToolRule {
2876
- static async fromFilePath(params) {
2877
- 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));
2878
2994
  return new _JunieRule({
2879
- baseDir: params.baseDir || ".",
2880
- relativeDirPath: params.relativeDirPath,
2881
- relativeFilePath: params.relativeFilePath,
2995
+ baseDir,
2996
+ relativeDirPath: isRoot ? ".junie" : ".junie/memories",
2997
+ relativeFilePath: isRoot ? "guidelines.md" : relativeFilePath,
2882
2998
  fileContent,
2883
- validate: params.validate ?? true
2999
+ validate
2884
3000
  });
2885
3001
  }
2886
3002
  static fromRulesyncRule({
@@ -2893,8 +3009,8 @@ var JunieRule = class _JunieRule extends ToolRule {
2893
3009
  baseDir,
2894
3010
  rulesyncRule,
2895
3011
  validate,
2896
- rootPath: { relativeDirPath: ".", relativeFilePath: "guidelines.md" },
2897
- nonRootPath: { relativeDirPath: ".junie/guidelines" }
3012
+ rootPath: { relativeDirPath: ".junie", relativeFilePath: "guidelines.md" },
3013
+ nonRootPath: { relativeDirPath: ".junie/memories" }
2898
3014
  })
2899
3015
  );
2900
3016
  }
@@ -2907,15 +3023,20 @@ var JunieRule = class _JunieRule extends ToolRule {
2907
3023
  };
2908
3024
 
2909
3025
  // src/rules/kiro-rule.ts
3026
+ var import_node_path38 = require("path");
2910
3027
  var KiroRule = class _KiroRule extends ToolRule {
2911
- static async fromFilePath(params) {
2912
- 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));
2913
3034
  return new _KiroRule({
2914
- baseDir: params.baseDir || ".",
2915
- relativeDirPath: params.relativeDirPath,
2916
- relativeFilePath: params.relativeFilePath,
3035
+ baseDir,
3036
+ relativeDirPath: ".kiro/steering",
3037
+ relativeFilePath,
2917
3038
  fileContent,
2918
- validate: params.validate ?? true,
3039
+ validate,
2919
3040
  root: false
2920
3041
  });
2921
3042
  }
@@ -2942,21 +3063,22 @@ var KiroRule = class _KiroRule extends ToolRule {
2942
3063
  };
2943
3064
 
2944
3065
  // src/rules/opencode-rule.ts
3066
+ var import_node_path39 = require("path");
2945
3067
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
2946
- static async fromFilePath({
3068
+ static async fromFile({
2947
3069
  baseDir = ".",
2948
- relativeDirPath,
2949
3070
  relativeFilePath,
2950
- filePath,
2951
3071
  validate = true
2952
3072
  }) {
2953
- 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));
2954
3076
  return new _OpenCodeRule({
2955
3077
  baseDir,
2956
- relativeDirPath,
2957
- relativeFilePath,
3078
+ relativeDirPath: isRoot ? "." : ".opencode/memories",
3079
+ relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
2958
3080
  validate,
2959
- root: relativeFilePath === "AGENTS.md",
3081
+ root: isRoot,
2960
3082
  fileContent
2961
3083
  });
2962
3084
  }
@@ -2982,16 +3104,23 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
2982
3104
  };
2983
3105
 
2984
3106
  // src/rules/qwencode-rule.ts
3107
+ var import_node_path40 = require("path");
2985
3108
  var QwencodeRule = class _QwencodeRule extends ToolRule {
2986
- static async fromFilePath(params) {
2987
- 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));
2988
3117
  return new _QwencodeRule({
2989
- baseDir: params.baseDir || process.cwd(),
2990
- relativeDirPath: params.relativeDirPath,
2991
- relativeFilePath: params.relativeFilePath,
3118
+ baseDir,
3119
+ relativeDirPath: isRoot ? "." : ".qwencode/memories",
3120
+ relativeFilePath: isRoot ? "QWEN.md" : relativeFilePath,
2992
3121
  fileContent,
2993
- validate: params.validate ?? true,
2994
- root: params.relativeFilePath === "QWEN.md"
3122
+ validate,
3123
+ root: isRoot
2995
3124
  });
2996
3125
  }
2997
3126
  static fromRulesyncRule(params) {
@@ -3012,15 +3141,21 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
3012
3141
  };
3013
3142
 
3014
3143
  // src/rules/roo-rule.ts
3144
+ var import_node_path41 = require("path");
3015
3145
  var RooRule = class _RooRule extends ToolRule {
3016
- static async fromFilePath(params) {
3017
- 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));
3018
3152
  return new _RooRule({
3019
- baseDir: params.baseDir || ".",
3020
- relativeDirPath: params.relativeDirPath,
3021
- relativeFilePath: params.relativeFilePath,
3153
+ baseDir,
3154
+ relativeDirPath: ".roo/rules",
3155
+ relativeFilePath,
3022
3156
  fileContent,
3023
- validate: params.validate ?? true
3157
+ validate,
3158
+ root: false
3024
3159
  });
3025
3160
  }
3026
3161
  static fromRulesyncRule({
@@ -3060,15 +3195,71 @@ var RooRule = class _RooRule extends ToolRule {
3060
3195
  }
3061
3196
  };
3062
3197
 
3198
+ // src/rules/warp-rule.ts
3199
+ var import_node_path42 = require("path");
3200
+ var WarpRule = class _WarpRule extends ToolRule {
3201
+ constructor({ fileContent, root, ...rest }) {
3202
+ super({
3203
+ ...rest,
3204
+ fileContent,
3205
+ root: root ?? false
3206
+ });
3207
+ }
3208
+ static async fromFile({
3209
+ baseDir = ".",
3210
+ relativeFilePath,
3211
+ validate = true
3212
+ }) {
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));
3216
+ return new _WarpRule({
3217
+ baseDir,
3218
+ relativeDirPath: isRoot ? "." : ".warp",
3219
+ relativeFilePath: isRoot ? "WARP.md" : relativeFilePath,
3220
+ fileContent,
3221
+ validate,
3222
+ root: isRoot
3223
+ });
3224
+ }
3225
+ static fromRulesyncRule({
3226
+ baseDir = ".",
3227
+ rulesyncRule,
3228
+ validate = true
3229
+ }) {
3230
+ return new _WarpRule(
3231
+ this.buildToolRuleParamsDefault({
3232
+ baseDir,
3233
+ rulesyncRule,
3234
+ validate,
3235
+ rootPath: { relativeDirPath: ".", relativeFilePath: "WARP.md" },
3236
+ nonRootPath: { relativeDirPath: ".warp/memories" }
3237
+ })
3238
+ );
3239
+ }
3240
+ toRulesyncRule() {
3241
+ return this.toRulesyncRuleDefault();
3242
+ }
3243
+ validate() {
3244
+ return { success: true, error: null };
3245
+ }
3246
+ };
3247
+
3063
3248
  // src/rules/windsurf-rule.ts
3249
+ var import_node_path43 = require("path");
3064
3250
  var WindsurfRule = class _WindsurfRule extends ToolRule {
3065
- static async fromFilePath(params) {
3066
- 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));
3067
3257
  return new _WindsurfRule({
3068
- baseDir: params.baseDir || ".",
3069
- relativeDirPath: params.relativeDirPath,
3070
- relativeFilePath: params.relativeFilePath,
3071
- fileContent
3258
+ baseDir,
3259
+ relativeDirPath: ".windsurf/rules",
3260
+ relativeFilePath,
3261
+ fileContent,
3262
+ validate
3072
3263
  });
3073
3264
  }
3074
3265
  static fromRulesyncRule({
@@ -3110,6 +3301,7 @@ var rulesProcessorToolTargets = [
3110
3301
  "opencode",
3111
3302
  "qwencode",
3112
3303
  "roo",
3304
+ "warp",
3113
3305
  "windsurf"
3114
3306
  ];
3115
3307
  var RulesProcessorToolTargetSchema = import_mini16.z.enum(rulesProcessorToolTargets);
@@ -3218,6 +3410,12 @@ var RulesProcessor = class extends FeatureProcessor {
3218
3410
  rulesyncRule,
3219
3411
  validate: true
3220
3412
  });
3413
+ case "warp":
3414
+ return WarpRule.fromRulesyncRule({
3415
+ baseDir: this.baseDir,
3416
+ rulesyncRule,
3417
+ validate: true
3418
+ });
3221
3419
  case "windsurf":
3222
3420
  return WindsurfRule.fromRulesyncRule({
3223
3421
  baseDir: this.baseDir,
@@ -3296,6 +3494,13 @@ var RulesProcessor = class extends FeatureProcessor {
3296
3494
  );
3297
3495
  return toolRules;
3298
3496
  }
3497
+ case "warp": {
3498
+ const rootRule = toolRules[rootRuleIndex];
3499
+ rootRule?.setFileContent(
3500
+ this.generateXmlReferencesSection(toolRules) + rootRule.getFileContent()
3501
+ );
3502
+ return toolRules;
3503
+ }
3299
3504
  default:
3300
3505
  return toolRules;
3301
3506
  }
@@ -3312,57 +3517,18 @@ var RulesProcessor = class extends FeatureProcessor {
3312
3517
  * Load and parse rulesync rule files from .rulesync/rules/ directory
3313
3518
  */
3314
3519
  async loadRulesyncFiles() {
3315
- try {
3316
- const rulesDir = (0, import_node_path12.join)(this.baseDir, ".rulesync", "rules");
3317
- const dirExists = await directoryExists(rulesDir);
3318
- if (!dirExists) {
3319
- logger.debug(`Rulesync rules directory not found: ${rulesDir}`);
3320
- return [];
3321
- }
3322
- const entries = await listDirectoryFiles(rulesDir);
3323
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3324
- if (mdFiles.length === 0) {
3325
- logger.debug(`No markdown files found in rulesync rules directory: ${rulesDir}`);
3326
- return [];
3327
- }
3328
- logger.info(`Found ${mdFiles.length} rule files in ${rulesDir}`);
3329
- const rulesyncRules = [];
3330
- for (const mdFile of mdFiles) {
3331
- const filepath = (0, import_node_path12.join)(rulesDir, mdFile);
3332
- try {
3333
- const rulesyncRule = await RulesyncRule.fromFilePath({
3334
- filePath: filepath
3335
- });
3336
- rulesyncRules.push(rulesyncRule);
3337
- logger.debug(`Successfully loaded rule: ${mdFile}`);
3338
- } catch (error) {
3339
- logger.warn(`Failed to load rule file ${filepath}:`, error);
3340
- continue;
3341
- }
3342
- }
3343
- if (rulesyncRules.length === 0) {
3344
- logger.debug(`No valid rules found in ${rulesDir}`);
3345
- return [];
3346
- }
3347
- logger.info(`Successfully loaded ${rulesyncRules.length} rulesync rules`);
3348
- return rulesyncRules;
3349
- } catch (error) {
3350
- logger.debug(`No rulesync files found`, error);
3351
- return [];
3352
- }
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
+ );
3353
3525
  }
3354
- async loadLegacyRulesyncFiles() {
3355
- try {
3356
- const legacyFiles = await findFilesByGlobs((0, import_node_path12.join)(RULESYNC_RULES_DIR_LEGACY, "*.md"));
3357
- return Promise.all(
3358
- legacyFiles.map(
3359
- (file) => RulesyncRule.fromLegacyFile({ relativeFilePath: (0, import_node_path12.basename)(file) })
3360
- )
3361
- );
3362
- } catch (error) {
3363
- logger.debug(`No legacy rulesync files found`, error);
3364
- return [];
3365
- }
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
+ );
3366
3532
  }
3367
3533
  /**
3368
3534
  * Implementation of abstract method from FeatureProcessor
@@ -3401,6 +3567,8 @@ var RulesProcessor = class extends FeatureProcessor {
3401
3567
  return await this.loadQwencodeRules();
3402
3568
  case "roo":
3403
3569
  return await this.loadRooRules();
3570
+ case "warp":
3571
+ return await this.loadWarpRules();
3404
3572
  case "windsurf":
3405
3573
  return await this.loadWindsurfRules();
3406
3574
  default:
@@ -3411,502 +3579,296 @@ var RulesProcessor = class extends FeatureProcessor {
3411
3579
  return [];
3412
3580
  }
3413
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
+ }
3414
3622
  /**
3415
3623
  * Load AGENTS.md rule configuration
3416
3624
  */
3417
3625
  async loadAgentsmdRules() {
3418
- const agentsFile = (0, import_node_path12.join)(this.baseDir, "AGENTS.md");
3419
- if (!await fileExists(agentsFile)) {
3420
- logger.warn(`AGENTS.md file not found: ${agentsFile}`);
3421
- return [];
3422
- }
3423
- try {
3424
- const agentsmdRule = await AgentsMdRule.fromFilePath({
3425
- baseDir: this.baseDir,
3626
+ return await this.loadToolRulesDefault({
3627
+ root: {
3426
3628
  relativeDirPath: ".",
3427
3629
  relativeFilePath: "AGENTS.md",
3428
- filePath: agentsFile,
3429
- validate: true
3430
- });
3431
- logger.info(`Successfully loaded AGENTS.md rule`);
3432
- return [agentsmdRule];
3433
- } catch (error) {
3434
- logger.warn(`Failed to load AGENTS.md file ${agentsFile}:`, error);
3435
- return [];
3436
- }
3630
+ fromFile: (params) => AgentsMdRule.fromFile(params)
3631
+ },
3632
+ nonRoot: {
3633
+ relativeFilePath: ".agents/memories",
3634
+ fromFile: (params) => AgentsMdRule.fromFile(params),
3635
+ extension: "md"
3636
+ }
3637
+ });
3638
+ }
3639
+ async loadWarpRules() {
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
+ });
3437
3652
  }
3438
3653
  /**
3439
3654
  * Load Amazon Q Developer CLI rule configurations from .amazonq/rules/ directory
3440
3655
  */
3441
3656
  async loadAmazonqcliRules() {
3442
- return this.loadToolRulesFromDirectory(
3443
- (0, import_node_path12.join)(this.baseDir, ".amazonq", "rules"),
3444
- (filePath, relativeFilePath) => AmazonQCliRule.fromFilePath({
3445
- baseDir: this.baseDir,
3446
- relativeDirPath: ".amazonq/rules",
3447
- relativeFilePath,
3448
- filePath,
3449
- validate: true
3450
- }),
3451
- "Amazon Q Developer CLI"
3452
- );
3657
+ return await this.loadToolRulesDefault({
3658
+ nonRoot: {
3659
+ relativeFilePath: ".amazonq/rules",
3660
+ fromFile: (params) => AmazonQCliRule.fromFile(params),
3661
+ extension: "md"
3662
+ }
3663
+ });
3453
3664
  }
3454
3665
  /**
3455
3666
  * Load AugmentCode rule configurations from .augment/rules/ directory
3456
3667
  */
3457
3668
  async loadAugmentcodeRules() {
3458
- return this.loadToolRulesFromDirectory(
3459
- (0, import_node_path12.join)(this.baseDir, ".augment", "rules"),
3460
- (filePath, relativeFilePath) => AugmentcodeRule.fromFilePath({
3461
- baseDir: this.baseDir,
3462
- relativeDirPath: ".augment/rules",
3463
- relativeFilePath,
3464
- filePath,
3465
- validate: true
3466
- }),
3467
- "AugmentCode"
3468
- );
3669
+ return await this.loadToolRulesDefault({
3670
+ nonRoot: {
3671
+ relativeFilePath: ".augment/rules",
3672
+ fromFile: (params) => AugmentcodeRule.fromFile(params),
3673
+ extension: "md"
3674
+ }
3675
+ });
3469
3676
  }
3470
3677
  /**
3471
3678
  * Load AugmentCode legacy rule configuration from .augment-guidelines file and .augment/rules/ directory
3472
3679
  */
3473
3680
  async loadAugmentcodeLegacyRules() {
3474
- const toolRules = [];
3475
- const guidelinesFile = (0, import_node_path12.join)(this.baseDir, ".augment-guidelines");
3476
- if (await fileExists(guidelinesFile)) {
3477
- try {
3478
- const augmentcodeLegacyRule = await AugmentcodeLegacyRule.fromFilePath({
3479
- baseDir: this.baseDir,
3480
- relativeDirPath: ".",
3481
- relativeFilePath: ".augment-guidelines",
3482
- filePath: guidelinesFile,
3483
- validate: true
3484
- });
3485
- toolRules.push(augmentcodeLegacyRule);
3486
- logger.info(`Successfully loaded AugmentCode legacy guidelines`);
3487
- } catch (error) {
3488
- 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"
3489
3691
  }
3490
- }
3491
- const rulesDir = (0, import_node_path12.join)(this.baseDir, ".augment", "rules");
3492
- if (await directoryExists(rulesDir)) {
3493
- const dirRules = await this.loadToolRulesFromDirectory(
3494
- rulesDir,
3495
- (filePath, relativeFilePath) => AugmentcodeLegacyRule.fromFilePath({
3496
- baseDir: this.baseDir,
3497
- relativeDirPath: (0, import_node_path12.join)(".augment", "rules"),
3498
- relativeFilePath,
3499
- filePath,
3500
- validate: true
3501
- }),
3502
- "AugmentCode Legacy"
3503
- );
3504
- toolRules.push(...dirRules);
3505
- }
3506
- return toolRules;
3692
+ });
3507
3693
  }
3508
3694
  /**
3509
3695
  * Load Claude Code rule configuration from CLAUDE.md file
3510
3696
  */
3511
3697
  async loadClaudecodeRules() {
3512
- const claudeMemoriesDir = (0, import_node_path12.join)(this.baseDir, ".claude", "memories");
3513
- if (!await directoryExists(claudeMemoriesDir)) {
3514
- logger.debug(`Claude Code memories directory not found: ${claudeMemoriesDir}`);
3515
- const claudeFile = (0, import_node_path12.join)(this.baseDir, "CLAUDE.md");
3516
- if (!await fileExists(claudeFile)) {
3517
- logger.debug(`Claude Code memory file not found: ${claudeFile}`);
3518
- return [];
3519
- }
3520
- try {
3521
- const claudecodeRule = await ClaudecodeRule.fromFilePath({
3522
- baseDir: this.baseDir,
3523
- relativeDirPath: ".",
3524
- relativeFilePath: "CLAUDE.md",
3525
- filePath: claudeFile,
3526
- validate: true
3527
- });
3528
- logger.info(`Successfully loaded Claude Code memory file`);
3529
- return [claudecodeRule];
3530
- } catch (error) {
3531
- logger.warn(`Failed to load Claude Code memory file ${claudeFile}:`, error);
3532
- return [];
3533
- }
3534
- }
3535
- const entries = await listDirectoryFiles(claudeMemoriesDir);
3536
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3537
- if (mdFiles.length === 0) {
3538
- logger.debug(
3539
- `No markdown files found in Claude Code memories directory: ${claudeMemoriesDir}`
3540
- );
3541
- return [];
3542
- }
3543
- logger.info(`Found ${mdFiles.length} Claude Code memory files in ${claudeMemoriesDir}`);
3544
- const toolRules = [];
3545
- for (const mdFile of mdFiles) {
3546
- const filePath = (0, import_node_path12.join)(claudeMemoriesDir, mdFile);
3547
- try {
3548
- const claudecodeRule = await ClaudecodeRule.fromFilePath({
3549
- baseDir: this.baseDir,
3550
- relativeDirPath: (0, import_node_path12.join)(".claude", "memories"),
3551
- relativeFilePath: mdFile,
3552
- filePath,
3553
- validate: true
3554
- });
3555
- toolRules.push(claudecodeRule);
3556
- logger.debug(`Successfully loaded Claude Code memory file: ${mdFile}`);
3557
- } catch (error) {
3558
- logger.warn(`Failed to load Claude Code memory file ${filePath}:`, error);
3559
- 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"
3560
3708
  }
3561
- }
3562
- logger.info(`Successfully loaded ${toolRules.length} Claude Code memory files`);
3563
- return toolRules;
3709
+ });
3564
3710
  }
3565
3711
  /**
3566
3712
  * Load Cline rule configurations from .clinerules/ directory
3567
3713
  */
3568
3714
  async loadClineRules() {
3569
- return this.loadToolRulesFromDirectory(
3570
- (0, import_node_path12.join)(this.baseDir, ".clinerules"),
3571
- (filePath, relativeFilePath) => ClineRule.fromFilePath({
3572
- baseDir: this.baseDir,
3573
- relativeDirPath: ".clinerules",
3574
- relativeFilePath,
3575
- filePath,
3576
- validate: true
3577
- }),
3578
- "Cline"
3579
- );
3715
+ return await this.loadToolRulesDefault({
3716
+ nonRoot: {
3717
+ relativeFilePath: ".clinerules",
3718
+ fromFile: (params) => ClineRule.fromFile(params),
3719
+ extension: "md"
3720
+ }
3721
+ });
3580
3722
  }
3581
3723
  /**
3582
3724
  * Load OpenAI Codex CLI rule configuration from AGENTS.md and .codex/memories/*.md files
3583
3725
  */
3584
3726
  async loadCodexcliRules() {
3585
- const rules = [];
3586
- const agentsFile = (0, import_node_path12.join)(this.baseDir, "AGENTS.md");
3587
- if (await fileExists(agentsFile)) {
3588
- try {
3589
- const codexcliRule = await CodexcliRule.fromFilePath({
3590
- baseDir: this.baseDir,
3591
- relativeDirPath: ".",
3592
- relativeFilePath: "AGENTS.md",
3593
- filePath: agentsFile,
3594
- validate: true
3595
- });
3596
- rules.push(codexcliRule);
3597
- logger.info(`Successfully loaded OpenAI Codex CLI agents file`);
3598
- } catch (error) {
3599
- logger.warn(`Failed to load OpenAI Codex CLI agents file ${agentsFile}:`, error);
3600
- }
3601
- }
3602
- const memoriesDir = (0, import_node_path12.join)(this.baseDir, ".codex", "memories");
3603
- if (await directoryExists(memoriesDir)) {
3604
- try {
3605
- const entries = await listDirectoryFiles(memoriesDir);
3606
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3607
- for (const mdFile of mdFiles) {
3608
- const filePath = (0, import_node_path12.join)(memoriesDir, mdFile);
3609
- try {
3610
- const codexcliRule = await CodexcliRule.fromFilePath({
3611
- baseDir: this.baseDir,
3612
- relativeDirPath: (0, import_node_path12.join)(".codex", "memories"),
3613
- relativeFilePath: mdFile,
3614
- filePath,
3615
- validate: true
3616
- });
3617
- rules.push(codexcliRule);
3618
- } catch (error) {
3619
- logger.warn(`Failed to load Codex CLI memories file ${filePath}:`, error);
3620
- }
3621
- }
3622
- if (mdFiles.length > 0) {
3623
- logger.info(`Successfully loaded ${mdFiles.length} OpenAI Codex CLI memory files`);
3624
- }
3625
- } catch (error) {
3626
- 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"
3627
3737
  }
3628
- }
3629
- if (rules.length === 0) {
3630
- logger.warn(`No OpenAI Codex CLI rule files found`);
3631
- }
3632
- return rules;
3738
+ });
3633
3739
  }
3634
3740
  /**
3635
3741
  * Load GitHub Copilot rule configuration from .github/copilot-instructions.md file
3636
3742
  */
3637
3743
  async loadCopilotRules() {
3638
- const copilotFile = (0, import_node_path12.join)(this.baseDir, ".github", "copilot-instructions.md");
3639
- if (!await fileExists(copilotFile)) {
3640
- logger.warn(`GitHub Copilot instructions file not found: ${copilotFile}`);
3641
- return [];
3642
- }
3643
- try {
3644
- const copilotRule = await CopilotRule.fromFilePath({
3645
- baseDir: this.baseDir,
3646
- relativeDirPath: ".github",
3647
- relativeFilePath: "copilot-instructions.md",
3648
- filePath: copilotFile,
3649
- validate: true
3650
- });
3651
- logger.info(`Successfully loaded GitHub Copilot instructions file`);
3652
- return [copilotRule];
3653
- } catch (error) {
3654
- logger.warn(`Failed to load GitHub Copilot instructions file ${copilotFile}:`, error);
3655
- return [];
3656
- }
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
+ });
3657
3756
  }
3658
3757
  /**
3659
3758
  * Load Cursor rule configurations from .cursor/rules/ directory
3660
3759
  */
3661
3760
  async loadCursorRules() {
3662
- return this.loadToolRulesFromDirectory(
3663
- (0, import_node_path12.join)(this.baseDir, ".cursor", "rules"),
3664
- (filePath) => CursorRule.fromFilePath({
3665
- filePath,
3666
- validate: true
3667
- }),
3668
- "Cursor"
3669
- );
3761
+ return await this.loadToolRulesDefault({
3762
+ nonRoot: {
3763
+ relativeFilePath: ".cursor/rules",
3764
+ fromFile: (params) => CursorRule.fromFile(params),
3765
+ extension: "md"
3766
+ }
3767
+ });
3670
3768
  }
3671
3769
  /**
3672
3770
  * Load Gemini CLI rule configuration from GEMINI.md file
3673
3771
  */
3674
3772
  async loadGeminicliRules() {
3675
- const geminiFile = (0, import_node_path12.join)(this.baseDir, "GEMINI.md");
3676
- if (!await fileExists(geminiFile)) {
3677
- logger.warn(`Gemini CLI memory file not found: ${geminiFile}`);
3678
- return [];
3679
- }
3680
- try {
3681
- const geminicliRule = await GeminiCliRule.fromFilePath({
3682
- baseDir: this.baseDir,
3773
+ return await this.loadToolRulesDefault({
3774
+ root: {
3683
3775
  relativeDirPath: ".",
3684
3776
  relativeFilePath: "GEMINI.md",
3685
- filePath: geminiFile,
3686
- validate: true
3687
- });
3688
- logger.info(`Successfully loaded Gemini CLI memory file`);
3689
- return [geminicliRule];
3690
- } catch (error) {
3691
- logger.warn(`Failed to load Gemini CLI memory file ${geminiFile}:`, error);
3692
- return [];
3693
- }
3777
+ fromFile: (params) => GeminiCliRule.fromFile(params)
3778
+ },
3779
+ nonRoot: {
3780
+ relativeFilePath: ".gemini/memories",
3781
+ fromFile: (params) => GeminiCliRule.fromFile(params),
3782
+ extension: "md"
3783
+ }
3784
+ });
3694
3785
  }
3695
3786
  /**
3696
3787
  * Load JetBrains Junie rule configuration from .junie/guidelines.md file
3697
3788
  */
3698
3789
  async loadJunieRules() {
3699
- const guidelinesFile = (0, import_node_path12.join)(this.baseDir, ".junie", "guidelines.md");
3700
- if (!await fileExists(guidelinesFile)) {
3701
- return [];
3702
- }
3703
- const junieRule = await JunieRule.fromFilePath({
3704
- baseDir: this.baseDir,
3705
- relativeDirPath: ".junie",
3706
- relativeFilePath: "guidelines.md",
3707
- filePath: guidelinesFile,
3708
- 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
+ }
3709
3801
  });
3710
- logger.info(`Successfully loaded JetBrains Junie guidelines file`);
3711
- return [junieRule];
3712
3802
  }
3713
3803
  /**
3714
3804
  * Load Kiro rule configurations from .kiro/steering/ directory
3715
3805
  */
3716
3806
  async loadKiroRules() {
3717
- return this.loadToolRulesFromDirectory(
3718
- (0, import_node_path12.join)(this.baseDir, ".kiro", "steering"),
3719
- (filePath, relativeFilePath) => KiroRule.fromFilePath({
3720
- baseDir: this.baseDir,
3721
- relativeDirPath: ".kiro/steering",
3722
- relativeFilePath,
3723
- filePath,
3724
- validate: true
3725
- }),
3726
- "Kiro"
3727
- );
3807
+ return await this.loadToolRulesDefault({
3808
+ nonRoot: {
3809
+ relativeFilePath: ".kiro/steering",
3810
+ fromFile: (params) => KiroRule.fromFile(params),
3811
+ extension: "md"
3812
+ }
3813
+ });
3728
3814
  }
3729
3815
  /**
3730
3816
  * Load OpenCode rule configuration from AGENTS.md file and .opencode/memories/*.md files
3731
3817
  */
3732
3818
  async loadOpencodeRules() {
3733
- const rules = [];
3734
- const agentsFile = (0, import_node_path12.join)(this.baseDir, "AGENTS.md");
3735
- if (await fileExists(agentsFile)) {
3736
- try {
3737
- const opencodeRule = await OpenCodeRule.fromFilePath({
3738
- baseDir: this.baseDir,
3739
- relativeDirPath: ".",
3740
- relativeFilePath: "AGENTS.md",
3741
- filePath: agentsFile,
3742
- validate: true
3743
- });
3744
- rules.push(opencodeRule);
3745
- logger.info(`Successfully loaded OpenCode agents file`);
3746
- } catch (error) {
3747
- logger.warn(`Failed to load OpenCode agents file ${agentsFile}:`, error);
3748
- }
3749
- }
3750
- const memoriesDir = (0, import_node_path12.join)(this.baseDir, ".opencode", "memories");
3751
- if (await directoryExists(memoriesDir)) {
3752
- try {
3753
- const entries = await listDirectoryFiles(memoriesDir);
3754
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3755
- for (const mdFile of mdFiles) {
3756
- const filePath = (0, import_node_path12.join)(memoriesDir, mdFile);
3757
- try {
3758
- const opencodeRule = await OpenCodeRule.fromFilePath({
3759
- baseDir: this.baseDir,
3760
- relativeDirPath: (0, import_node_path12.join)(".opencode", "memories"),
3761
- relativeFilePath: mdFile,
3762
- filePath,
3763
- validate: true
3764
- });
3765
- rules.push(opencodeRule);
3766
- } catch (error) {
3767
- logger.warn(`Failed to load OpenCode memories file ${filePath}:`, error);
3768
- }
3769
- }
3770
- if (mdFiles.length > 0) {
3771
- logger.info(`Successfully loaded ${mdFiles.length} OpenCode memory files`);
3772
- }
3773
- } catch (error) {
3774
- 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"
3775
3829
  }
3776
- }
3777
- if (rules.length === 0) {
3778
- logger.warn(`No OpenCode rule files found`);
3779
- }
3780
- return rules;
3830
+ });
3781
3831
  }
3782
3832
  /**
3783
3833
  * Load Qwen Code rule configuration from QWEN.md file and .qwen/memories/*.md files
3784
3834
  */
3785
3835
  async loadQwencodeRules() {
3786
- const rules = [];
3787
- const qwenFile = (0, import_node_path12.join)(this.baseDir, "QWEN.md");
3788
- if (await fileExists(qwenFile)) {
3789
- try {
3790
- const qwencodeRule = await QwencodeRule.fromFilePath({
3791
- baseDir: this.baseDir,
3792
- relativeDirPath: ".",
3793
- relativeFilePath: "QWEN.md",
3794
- filePath: qwenFile,
3795
- validate: true
3796
- });
3797
- rules.push(qwencodeRule);
3798
- logger.info(`Successfully loaded Qwen Code memory file`);
3799
- } catch (error) {
3800
- logger.warn(`Failed to load Qwen Code memory file ${qwenFile}:`, error);
3801
- }
3802
- }
3803
- const memoriesDir = (0, import_node_path12.join)(this.baseDir, ".qwen", "memories");
3804
- if (await directoryExists(memoriesDir)) {
3805
- try {
3806
- const entries = await listDirectoryFiles(memoriesDir);
3807
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
3808
- for (const mdFile of mdFiles) {
3809
- const filePath = (0, import_node_path12.join)(memoriesDir, mdFile);
3810
- try {
3811
- const qwencodeRule = await QwencodeRule.fromFilePath({
3812
- baseDir: this.baseDir,
3813
- relativeDirPath: (0, import_node_path12.join)(".qwen", "memories"),
3814
- relativeFilePath: mdFile,
3815
- filePath,
3816
- validate: true
3817
- });
3818
- rules.push(qwencodeRule);
3819
- } catch (error) {
3820
- logger.warn(`Failed to load Qwen Code memories file ${filePath}:`, error);
3821
- }
3822
- }
3823
- if (mdFiles.length > 0) {
3824
- logger.info(`Successfully loaded ${mdFiles.length} Qwen Code memory files`);
3825
- }
3826
- } catch (error) {
3827
- 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"
3828
3846
  }
3829
- }
3830
- if (rules.length === 0) {
3831
- logger.warn(`No Qwen Code rule files found`);
3832
- }
3833
- return rules;
3847
+ });
3834
3848
  }
3835
3849
  /**
3836
3850
  * Load Roo Code rule configurations from .roo/rules/ directory
3837
3851
  */
3838
3852
  async loadRooRules() {
3839
- return this.loadToolRulesFromDirectory(
3840
- (0, import_node_path12.join)(this.baseDir, ".roo", "rules"),
3841
- (filePath, relativeFilePath) => RooRule.fromFilePath({
3842
- baseDir: this.baseDir,
3843
- relativeDirPath: ".roo/rules",
3844
- relativeFilePath,
3845
- filePath,
3846
- validate: true
3847
- }),
3848
- "Roo Code"
3849
- );
3853
+ return await this.loadToolRulesDefault({
3854
+ nonRoot: {
3855
+ relativeFilePath: ".roo/rules",
3856
+ fromFile: (params) => RooRule.fromFile(params),
3857
+ extension: "md"
3858
+ }
3859
+ });
3850
3860
  }
3851
3861
  /**
3852
3862
  * Load Windsurf rule configurations from .windsurf/rules/ directory
3853
3863
  */
3854
3864
  async loadWindsurfRules() {
3855
- return this.loadToolRulesFromDirectory(
3856
- (0, import_node_path12.join)(this.baseDir, ".windsurf", "rules"),
3857
- (filePath, relativeFilePath) => WindsurfRule.fromFilePath({
3858
- baseDir: this.baseDir,
3859
- relativeDirPath: ".windsurf/rules",
3860
- relativeFilePath,
3861
- filePath,
3862
- validate: true
3863
- }),
3864
- "Windsurf"
3865
- );
3866
- }
3867
- /**
3868
- * Common helper method to load tool rules from a directory with parallel processing
3869
- */
3870
- async loadToolRulesFromDirectory(dirPath, ruleFactory, toolName) {
3871
- if (!await directoryExists(dirPath)) {
3872
- logger.warn(`${toolName} rules directory not found: ${dirPath}`);
3873
- return [];
3874
- }
3875
- const entries = await listDirectoryFiles(dirPath);
3876
- const mdFiles = entries.filter((file) => file.endsWith(".md") || file.endsWith(".mdc"));
3877
- if (mdFiles.length === 0) {
3878
- logger.info(`No rule files found in ${dirPath}`);
3879
- return [];
3880
- }
3881
- logger.info(`Found ${mdFiles.length} ${toolName} rule files in ${dirPath}`);
3882
- const results = await Promise.allSettled(
3883
- mdFiles.map(async (mdFile) => {
3884
- const filepath = (0, import_node_path12.join)(dirPath, mdFile);
3885
- return {
3886
- rule: await ruleFactory(filepath, mdFile),
3887
- filename: mdFile
3888
- };
3889
- })
3890
- );
3891
- const toolRules = [];
3892
- for (const [index, result] of results.entries()) {
3893
- if (result.status === "fulfilled") {
3894
- toolRules.push(result.value.rule);
3895
- logger.debug(`Successfully loaded ${toolName} rule: ${result.value.filename}`);
3896
- } else {
3897
- 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"
3898
3870
  }
3899
- }
3900
- logger.info(`Successfully loaded ${toolRules.length} ${toolName} rules`);
3901
- return toolRules;
3902
- }
3903
- async writeToolRulesFromRulesyncRules(rulesyncRules) {
3904
- const toolRules = await this.convertRulesyncFilesToToolFiles(rulesyncRules);
3905
- await this.writeAiFiles(toolRules);
3906
- }
3907
- async writeRulesyncRulesFromToolRules(toolRules) {
3908
- const rulesyncRules = await this.convertToolFilesToRulesyncFiles(toolRules);
3909
- await this.writeAiFiles(rulesyncRules);
3871
+ });
3910
3872
  }
3911
3873
  /**
3912
3874
  * Implementation of abstract method from FeatureProcessor
@@ -3915,30 +3877,6 @@ var RulesProcessor = class extends FeatureProcessor {
3915
3877
  static getToolTargets() {
3916
3878
  return rulesProcessorToolTargets;
3917
3879
  }
3918
- /**
3919
- * Get all supported tools
3920
- */
3921
- static getSupportedTools() {
3922
- const allTools = [
3923
- "agentsmd",
3924
- "amazonqcli",
3925
- "augmentcode",
3926
- "augmentcode-legacy",
3927
- "claudecode",
3928
- "cline",
3929
- "codexcli",
3930
- "copilot",
3931
- "cursor",
3932
- "geminicli",
3933
- "junie",
3934
- "kiro",
3935
- "opencode",
3936
- "qwencode",
3937
- "roo",
3938
- "windsurf"
3939
- ];
3940
- return allTools;
3941
- }
3942
3880
  generateXmlReferencesSection(toolRules) {
3943
3881
  const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
3944
3882
  if (toolRulesWithoutRoot.length === 0) {
@@ -3999,14 +3937,15 @@ var RulesProcessor = class extends FeatureProcessor {
3999
3937
  };
4000
3938
 
4001
3939
  // src/subagents/subagents-processor.ts
4002
- var import_node_path14 = require("path");
3940
+ var import_node_path47 = require("path");
4003
3941
  var import_mini19 = require("zod/mini");
4004
3942
 
4005
3943
  // src/subagents/claudecode-subagent.ts
3944
+ var import_node_path46 = require("path");
4006
3945
  var import_mini18 = require("zod/mini");
4007
3946
 
4008
3947
  // src/subagents/rulesync-subagent.ts
4009
- var import_node_path13 = require("path");
3948
+ var import_node_path45 = require("path");
4010
3949
  var import_mini17 = require("zod/mini");
4011
3950
  var RulesyncSubagentModelSchema = import_mini17.z.enum(["opus", "sonnet", "haiku", "inherit"]);
4012
3951
  var RulesyncSubagentFrontmatterSchema = import_mini17.z.object({
@@ -4052,14 +3991,16 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
4052
3991
  return { success: false, error: result.error };
4053
3992
  }
4054
3993
  }
4055
- static async fromFilePath({ filePath }) {
4056
- 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));
4057
3998
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4058
3999
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
4059
4000
  if (!result.success) {
4060
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
4001
+ throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
4061
4002
  }
4062
- const filename = (0, import_node_path13.basename)(filePath);
4003
+ const filename = (0, import_node_path45.basename)(relativeFilePath);
4063
4004
  return new _RulesyncSubagent({
4064
4005
  baseDir: ".",
4065
4006
  relativeDirPath: ".rulesync/subagents",
@@ -4073,7 +4014,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
4073
4014
 
4074
4015
  // src/subagents/tool-subagent.ts
4075
4016
  var ToolSubagent = class extends ToolFile {
4076
- static async fromFilePath(_params) {
4017
+ static async fromFile(_params) {
4077
4018
  throw new Error("Please implement this method in the subclass.");
4078
4019
  }
4079
4020
  static fromRulesyncSubagent(_params) {
@@ -4134,7 +4075,6 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4134
4075
  static fromRulesyncSubagent({
4135
4076
  baseDir = ".",
4136
4077
  rulesyncSubagent,
4137
- relativeDirPath,
4138
4078
  validate = true
4139
4079
  }) {
4140
4080
  const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
@@ -4149,7 +4089,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4149
4089
  baseDir,
4150
4090
  frontmatter: claudecodeFrontmatter,
4151
4091
  body,
4152
- relativeDirPath,
4092
+ relativeDirPath: ".claude/agents",
4153
4093
  relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
4154
4094
  fileContent,
4155
4095
  validate
@@ -4166,22 +4106,20 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4166
4106
  return { success: false, error: result.error };
4167
4107
  }
4168
4108
  }
4169
- static async fromFilePath({
4109
+ static async fromFile({
4170
4110
  baseDir = ".",
4171
- relativeDirPath,
4172
4111
  relativeFilePath,
4173
- filePath,
4174
4112
  validate = true
4175
4113
  }) {
4176
- const fileContent = await readFileContent(filePath);
4114
+ const fileContent = await readFileContent((0, import_node_path46.join)(baseDir, ".claude/agents", relativeFilePath));
4177
4115
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4178
4116
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
4179
4117
  if (!result.success) {
4180
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
4118
+ throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
4181
4119
  }
4182
4120
  return new _ClaudecodeSubagent({
4183
4121
  baseDir,
4184
- relativeDirPath,
4122
+ relativeDirPath: ".claude/agents",
4185
4123
  relativeFilePath,
4186
4124
  frontmatter: result.data,
4187
4125
  body: content.trim(),
@@ -4235,7 +4173,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
4235
4173
  * Load and parse rulesync subagent files from .rulesync/subagents/ directory
4236
4174
  */
4237
4175
  async loadRulesyncFiles() {
4238
- const subagentsDir = (0, import_node_path14.join)(this.baseDir, ".rulesync", "subagents");
4176
+ const subagentsDir = (0, import_node_path47.join)(this.baseDir, ".rulesync", "subagents");
4239
4177
  const dirExists = await directoryExists(subagentsDir);
4240
4178
  if (!dirExists) {
4241
4179
  logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
@@ -4250,10 +4188,11 @@ var SubagentsProcessor = class extends FeatureProcessor {
4250
4188
  logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
4251
4189
  const rulesyncSubagents = [];
4252
4190
  for (const mdFile of mdFiles) {
4253
- const filepath = (0, import_node_path14.join)(subagentsDir, mdFile);
4191
+ const filepath = (0, import_node_path47.join)(subagentsDir, mdFile);
4254
4192
  try {
4255
- const rulesyncSubagent = await RulesyncSubagent.fromFilePath({
4256
- filePath: filepath
4193
+ const rulesyncSubagent = await RulesyncSubagent.fromFile({
4194
+ relativeFilePath: mdFile,
4195
+ validate: true
4257
4196
  });
4258
4197
  rulesyncSubagents.push(rulesyncSubagent);
4259
4198
  logger.debug(`Successfully loaded subagent: ${mdFile}`);
@@ -4285,43 +4224,19 @@ var SubagentsProcessor = class extends FeatureProcessor {
4285
4224
  * Load Claude Code subagent configurations from .claude/agents/ directory
4286
4225
  */
4287
4226
  async loadClaudecodeSubagents() {
4288
- const agentsDir = (0, import_node_path14.join)(this.baseDir, ".claude", "agents");
4289
- if (!await directoryExists(agentsDir)) {
4290
- logger.warn(`Claude Code agents directory not found: ${agentsDir}`);
4291
- return [];
4292
- }
4293
- let entries;
4294
- try {
4295
- entries = await listDirectoryFiles(agentsDir);
4296
- } catch (error) {
4297
- logger.warn(`Failed to read Claude Code agents directory ${agentsDir}:`, error);
4298
- return [];
4299
- }
4300
- const mdFiles = entries.filter((file) => file.endsWith(".md"));
4301
- if (mdFiles.length === 0) {
4302
- logger.info(`No JSON agent files found in ${agentsDir}`);
4303
- return [];
4304
- }
4305
- logger.info(`Found ${mdFiles.length} Claude Code agent files in ${agentsDir}`);
4306
- const toolSubagents = [];
4307
- for (const mdFile of mdFiles) {
4308
- const filepath = (0, import_node_path14.join)(agentsDir, mdFile);
4309
- try {
4310
- const claudecodeSubagent = await ClaudecodeSubagent.fromFilePath({
4311
- baseDir: this.baseDir,
4312
- relativeDirPath: ".claude/agents",
4313
- relativeFilePath: mdFile,
4314
- filePath: filepath
4315
- });
4316
- toolSubagents.push(claudecodeSubagent);
4317
- logger.debug(`Successfully loaded Claude Code agent: ${mdFile}`);
4318
- } catch (error) {
4319
- logger.warn(`Failed to load Claude Code agent file ${filepath}:`, error);
4320
- continue;
4321
- }
4322
- }
4323
- logger.info(`Successfully loaded ${toolSubagents.length} Claude Code subagents`);
4324
- 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;
4325
4240
  }
4326
4241
  /**
4327
4242
  * Implementation of abstract method from FeatureProcessor
@@ -4357,7 +4272,7 @@ async function generateCommand(options) {
4357
4272
  }
4358
4273
  let rulesyncFiles = await processor.loadRulesyncFiles();
4359
4274
  if (rulesyncFiles.length === 0) {
4360
- rulesyncFiles = await processor.loadLegacyRulesyncFiles();
4275
+ rulesyncFiles = await processor.loadRulesyncFilesLegacy();
4361
4276
  }
4362
4277
  const toolFiles = await processor.convertRulesyncFilesToToolFiles(rulesyncFiles);
4363
4278
  const writtenCount = await processor.writeAiFiles(toolFiles);
@@ -4511,9 +4426,9 @@ async function generateCommand(options) {
4511
4426
  }
4512
4427
 
4513
4428
  // src/cli/commands/gitignore.ts
4514
- var import_node_path15 = require("path");
4429
+ var import_node_path48 = require("path");
4515
4430
  var gitignoreCommand = async () => {
4516
- const gitignorePath = (0, import_node_path15.join)(process.cwd(), ".gitignore");
4431
+ const gitignorePath = (0, import_node_path48.join)(process.cwd(), ".gitignore");
4517
4432
  const rulesFilesToIgnore = [
4518
4433
  "# Generated by rulesync - AI tool configuration files",
4519
4434
  "**/.amazonq/rules/",
@@ -4642,6 +4557,24 @@ async function importCommand(options) {
4642
4557
  logger.success(`Created ${ignoreFileCreated} ignore files`);
4643
4558
  }
4644
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
+ }
4645
4578
  let subagentsCreated = 0;
4646
4579
  if (config.getFeatures().includes("subagents")) {
4647
4580
  if (SubagentsProcessor.getToolTargets().includes(tool)) {
@@ -4682,7 +4615,7 @@ async function importCommand(options) {
4682
4615
  }
4683
4616
 
4684
4617
  // src/cli/commands/init.ts
4685
- var import_node_path16 = require("path");
4618
+ var import_node_path49 = require("path");
4686
4619
  async function initCommand() {
4687
4620
  logger.info("Initializing rulesync...");
4688
4621
  await ensureDir(RULESYNC_DIR);
@@ -4728,7 +4661,7 @@ globs: ["**/*"]
4728
4661
  - Follow single responsibility principle
4729
4662
  `
4730
4663
  };
4731
- 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);
4732
4665
  await ensureDir(RULESYNC_RULES_DIR);
4733
4666
  await ensureDir(RULESYNC_COMMANDS_DIR);
4734
4667
  await ensureDir(RULESYNC_SUBAGENTS_DIR);
@@ -4747,15 +4680,15 @@ var getVersion = async () => {
4747
4680
  let packageJsonPath;
4748
4681
  if (typeof import_meta !== "undefined" && import_meta.url) {
4749
4682
  const __filename = (0, import_node_url.fileURLToPath)(import_meta.url);
4750
- const __dirname = (0, import_node_path17.join)(__filename, "..");
4751
- 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");
4752
4685
  } else {
4753
- packageJsonPath = (0, import_node_path17.join)(process.cwd(), "package.json");
4686
+ packageJsonPath = (0, import_node_path50.join)(process.cwd(), "package.json");
4754
4687
  }
4755
4688
  const packageJson = await readJsonFile(packageJsonPath);
4756
4689
  return packageJson.version;
4757
4690
  } catch {
4758
- return "0.68.1";
4691
+ return "0.70.0";
4759
4692
  }
4760
4693
  };
4761
4694
  var main = async () => {