rulesync 0.69.0 → 0.70.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -9
- package/dist/index.cjs +851 -1009
- package/dist/index.js +846 -1004
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
|
-
import { join as
|
|
4
|
+
import { join as join49 } from "path";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
|
|
@@ -194,14 +194,6 @@ async function listDirectoryFiles(dir) {
|
|
|
194
194
|
return [];
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
|
-
async function findFiles(dir, extension = ".md") {
|
|
198
|
-
try {
|
|
199
|
-
const files = await readdir(dir);
|
|
200
|
-
return files.filter((file) => file.endsWith(extension)).map((file) => join(dir, file));
|
|
201
|
-
} catch {
|
|
202
|
-
return [];
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
197
|
async function findFilesByGlobs(globs) {
|
|
206
198
|
return globSync(globs);
|
|
207
199
|
}
|
|
@@ -251,7 +243,7 @@ async function initConfig() {
|
|
|
251
243
|
import { intersection } from "es-toolkit";
|
|
252
244
|
|
|
253
245
|
// src/commands/commands-processor.ts
|
|
254
|
-
import { basename as basename6, join as
|
|
246
|
+
import { basename as basename6, join as join7 } from "path";
|
|
255
247
|
import { z as z7 } from "zod/mini";
|
|
256
248
|
|
|
257
249
|
// src/types/feature-processor.ts
|
|
@@ -284,15 +276,48 @@ var FeatureProcessor = class {
|
|
|
284
276
|
};
|
|
285
277
|
|
|
286
278
|
// src/commands/claudecode-command.ts
|
|
287
|
-
import { basename as basename3, join as
|
|
279
|
+
import { basename as basename3, join as join4 } from "path";
|
|
288
280
|
import { z as z4 } from "zod/mini";
|
|
289
281
|
|
|
290
282
|
// src/utils/frontmatter.ts
|
|
291
283
|
import matter from "gray-matter";
|
|
284
|
+
function isPlainObject(value) {
|
|
285
|
+
if (value === null || typeof value !== "object") return false;
|
|
286
|
+
const prototype = Object.getPrototypeOf(value);
|
|
287
|
+
return prototype === Object.prototype || prototype === null;
|
|
288
|
+
}
|
|
289
|
+
function deepRemoveNullishValue(value) {
|
|
290
|
+
if (value === null || value === void 0) {
|
|
291
|
+
return void 0;
|
|
292
|
+
}
|
|
293
|
+
if (Array.isArray(value)) {
|
|
294
|
+
const cleanedArray = value.map((item) => deepRemoveNullishValue(item)).filter((item) => item !== void 0);
|
|
295
|
+
return cleanedArray;
|
|
296
|
+
}
|
|
297
|
+
if (isPlainObject(value)) {
|
|
298
|
+
const result = {};
|
|
299
|
+
for (const [key, val] of Object.entries(value)) {
|
|
300
|
+
const cleaned = deepRemoveNullishValue(val);
|
|
301
|
+
if (cleaned !== void 0) {
|
|
302
|
+
result[key] = cleaned;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return result;
|
|
306
|
+
}
|
|
307
|
+
return value;
|
|
308
|
+
}
|
|
309
|
+
function deepRemoveNullishObject(obj) {
|
|
310
|
+
const result = {};
|
|
311
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
312
|
+
const cleaned = deepRemoveNullishValue(val);
|
|
313
|
+
if (cleaned !== void 0) {
|
|
314
|
+
result[key] = cleaned;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
292
319
|
function stringifyFrontmatter(body, frontmatter) {
|
|
293
|
-
const cleanFrontmatter =
|
|
294
|
-
Object.entries(frontmatter).filter(([, value]) => value !== null && value !== void 0)
|
|
295
|
-
);
|
|
320
|
+
const cleanFrontmatter = deepRemoveNullishObject(frontmatter);
|
|
296
321
|
return matter.stringify(body, cleanFrontmatter);
|
|
297
322
|
}
|
|
298
323
|
function parseFrontmatter(content) {
|
|
@@ -301,9 +326,18 @@ function parseFrontmatter(content) {
|
|
|
301
326
|
}
|
|
302
327
|
|
|
303
328
|
// src/commands/rulesync-command.ts
|
|
304
|
-
import { basename as basename2 } from "path";
|
|
329
|
+
import { basename as basename2, join as join3 } from "path";
|
|
305
330
|
import { z as z3 } from "zod/mini";
|
|
306
331
|
|
|
332
|
+
// src/constants/paths.ts
|
|
333
|
+
import { join as join2 } from "path";
|
|
334
|
+
var RULESYNC_DIR = ".rulesync";
|
|
335
|
+
var RULESYNC_RULES_DIR = join2(".rulesync", "rules");
|
|
336
|
+
var RULESYNC_RULES_DIR_LEGACY = ".rulesync";
|
|
337
|
+
var RULESYNC_MCP_FILE = join2(".rulesync", ".mcp.json");
|
|
338
|
+
var RULESYNC_COMMANDS_DIR = join2(".rulesync", "commands");
|
|
339
|
+
var RULESYNC_SUBAGENTS_DIR = join2(".rulesync", "subagents");
|
|
340
|
+
|
|
307
341
|
// src/types/ai-file.ts
|
|
308
342
|
import path from "path";
|
|
309
343
|
var AiFile = class {
|
|
@@ -341,7 +375,7 @@ var AiFile = class {
|
|
|
341
375
|
}
|
|
342
376
|
}
|
|
343
377
|
}
|
|
344
|
-
static async
|
|
378
|
+
static async fromFile(_params) {
|
|
345
379
|
throw new Error("Please implement this method in the subclass.");
|
|
346
380
|
}
|
|
347
381
|
getBaseDir() {
|
|
@@ -369,13 +403,10 @@ var AiFile = class {
|
|
|
369
403
|
|
|
370
404
|
// src/types/rulesync-file.ts
|
|
371
405
|
var RulesyncFile = class extends AiFile {
|
|
372
|
-
static async fromFilePath(_params) {
|
|
373
|
-
throw new Error("Please implement this method in the subclass.");
|
|
374
|
-
}
|
|
375
406
|
static async fromFile(_params) {
|
|
376
407
|
throw new Error("Please implement this method in the subclass.");
|
|
377
408
|
}
|
|
378
|
-
static async
|
|
409
|
+
static async fromFileLegacy(_params) {
|
|
379
410
|
throw new Error("Please implement this method in the subclass.");
|
|
380
411
|
}
|
|
381
412
|
};
|
|
@@ -419,14 +450,16 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
|
|
|
419
450
|
return { success: false, error: result.error };
|
|
420
451
|
}
|
|
421
452
|
}
|
|
422
|
-
static async
|
|
423
|
-
|
|
453
|
+
static async fromFile({
|
|
454
|
+
relativeFilePath
|
|
455
|
+
}) {
|
|
456
|
+
const fileContent = await readFileContent(join3(RULESYNC_COMMANDS_DIR, relativeFilePath));
|
|
424
457
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
425
458
|
const result = RulesyncCommandFrontmatterSchema.safeParse(frontmatter);
|
|
426
459
|
if (!result.success) {
|
|
427
|
-
throw new Error(`Invalid frontmatter in ${
|
|
460
|
+
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
|
|
428
461
|
}
|
|
429
|
-
const filename = basename2(
|
|
462
|
+
const filename = basename2(relativeFilePath);
|
|
430
463
|
return new _RulesyncCommand({
|
|
431
464
|
baseDir: ".",
|
|
432
465
|
relativeDirPath: ".rulesync/commands",
|
|
@@ -452,7 +485,7 @@ var ToolCommand = class extends AiFile {
|
|
|
452
485
|
* @param params - Parameters including the file path to load
|
|
453
486
|
* @returns Promise resolving to a concrete ToolCommand instance
|
|
454
487
|
*/
|
|
455
|
-
static async
|
|
488
|
+
static async fromFile(_params) {
|
|
456
489
|
throw new Error("Please implement this method in the subclass.");
|
|
457
490
|
}
|
|
458
491
|
/**
|
|
@@ -529,7 +562,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
529
562
|
baseDir,
|
|
530
563
|
frontmatter: claudecodeFrontmatter,
|
|
531
564
|
body,
|
|
532
|
-
relativeDirPath:
|
|
565
|
+
relativeDirPath: join4(".claude", "commands"),
|
|
533
566
|
relativeFilePath: rulesyncCommand.getRelativeFilePath(),
|
|
534
567
|
validate
|
|
535
568
|
});
|
|
@@ -545,11 +578,12 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
545
578
|
return { success: false, error: result.error };
|
|
546
579
|
}
|
|
547
580
|
}
|
|
548
|
-
static async
|
|
581
|
+
static async fromFile({
|
|
549
582
|
baseDir = ".",
|
|
550
|
-
|
|
583
|
+
relativeFilePath,
|
|
551
584
|
validate = true
|
|
552
585
|
}) {
|
|
586
|
+
const filePath = join4(baseDir, ".claude", "commands", relativeFilePath);
|
|
553
587
|
const fileContent = await readFileContent(filePath);
|
|
554
588
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
555
589
|
const result = ClaudecodeCommandFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -559,7 +593,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
559
593
|
return new _ClaudecodeCommand({
|
|
560
594
|
baseDir,
|
|
561
595
|
relativeDirPath: ".claude/commands",
|
|
562
|
-
relativeFilePath: basename3(
|
|
596
|
+
relativeFilePath: basename3(relativeFilePath),
|
|
563
597
|
frontmatter: result.data,
|
|
564
598
|
body: content.trim(),
|
|
565
599
|
validate
|
|
@@ -568,7 +602,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
568
602
|
};
|
|
569
603
|
|
|
570
604
|
// src/commands/geminicli-command.ts
|
|
571
|
-
import { basename as basename4 } from "path";
|
|
605
|
+
import { basename as basename4, join as join5 } from "path";
|
|
572
606
|
import { parse as parseToml } from "smol-toml";
|
|
573
607
|
import { z as z5 } from "zod/mini";
|
|
574
608
|
var GeminiCliCommandFrontmatterSchema = z5.object({
|
|
@@ -654,16 +688,17 @@ ${geminiFrontmatter.prompt}
|
|
|
654
688
|
validate
|
|
655
689
|
});
|
|
656
690
|
}
|
|
657
|
-
static async
|
|
691
|
+
static async fromFile({
|
|
658
692
|
baseDir = ".",
|
|
659
|
-
|
|
693
|
+
relativeFilePath,
|
|
660
694
|
validate = true
|
|
661
695
|
}) {
|
|
696
|
+
const filePath = join5(baseDir, ".gemini", "commands", relativeFilePath);
|
|
662
697
|
const fileContent = await readFileContent(filePath);
|
|
663
698
|
return new _GeminiCliCommand({
|
|
664
699
|
baseDir,
|
|
665
700
|
relativeDirPath: ".gemini/commands",
|
|
666
|
-
relativeFilePath: basename4(
|
|
701
|
+
relativeFilePath: basename4(relativeFilePath),
|
|
667
702
|
fileContent,
|
|
668
703
|
validate
|
|
669
704
|
});
|
|
@@ -676,26 +711,10 @@ ${geminiFrontmatter.prompt}
|
|
|
676
711
|
return { success: false, error: error instanceof Error ? error : new Error(String(error)) };
|
|
677
712
|
}
|
|
678
713
|
}
|
|
679
|
-
async processContent(content, args) {
|
|
680
|
-
let processedContent = content;
|
|
681
|
-
processedContent = this.processArgumentPlaceholder(processedContent, args);
|
|
682
|
-
return processedContent;
|
|
683
|
-
}
|
|
684
|
-
processArgumentPlaceholder(content, args) {
|
|
685
|
-
if (content.includes("{{args}}")) {
|
|
686
|
-
return content.replace(/\{\{args\}\}/g, args || "");
|
|
687
|
-
}
|
|
688
|
-
if (args) {
|
|
689
|
-
return `${content}
|
|
690
|
-
|
|
691
|
-
${args}`;
|
|
692
|
-
}
|
|
693
|
-
return content;
|
|
694
|
-
}
|
|
695
714
|
};
|
|
696
715
|
|
|
697
716
|
// src/commands/roo-command.ts
|
|
698
|
-
import { basename as basename5 } from "path";
|
|
717
|
+
import { basename as basename5, join as join6 } from "path";
|
|
699
718
|
import { optional, z as z6 } from "zod/mini";
|
|
700
719
|
var RooCommandFrontmatterSchema = z6.object({
|
|
701
720
|
description: z6.string(),
|
|
@@ -772,11 +791,12 @@ var RooCommand = class _RooCommand extends ToolCommand {
|
|
|
772
791
|
return { success: false, error: result.error };
|
|
773
792
|
}
|
|
774
793
|
}
|
|
775
|
-
static async
|
|
794
|
+
static async fromFile({
|
|
776
795
|
baseDir = ".",
|
|
777
|
-
|
|
796
|
+
relativeFilePath,
|
|
778
797
|
validate = true
|
|
779
798
|
}) {
|
|
799
|
+
const filePath = join6(baseDir, ".roo", "commands", relativeFilePath);
|
|
780
800
|
const fileContent = await readFileContent(filePath);
|
|
781
801
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
782
802
|
const result = RooCommandFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -786,7 +806,7 @@ var RooCommand = class _RooCommand extends ToolCommand {
|
|
|
786
806
|
return new _RooCommand({
|
|
787
807
|
baseDir,
|
|
788
808
|
relativeDirPath: ".roo/commands",
|
|
789
|
-
relativeFilePath: basename5(
|
|
809
|
+
relativeFilePath: basename5(relativeFilePath),
|
|
790
810
|
frontmatter: result.data,
|
|
791
811
|
body: content.trim(),
|
|
792
812
|
fileContent,
|
|
@@ -848,37 +868,12 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
848
868
|
* Load and parse rulesync command files from .rulesync/commands/ directory
|
|
849
869
|
*/
|
|
850
870
|
async loadRulesyncFiles() {
|
|
851
|
-
const
|
|
852
|
-
const
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
const allMdFiles = await findFiles(commandsDir, ".md");
|
|
858
|
-
const mdFiles = allMdFiles.map((f) => basename6(f));
|
|
859
|
-
if (mdFiles.length === 0) {
|
|
860
|
-
logger.debug(`No markdown files found in rulesync commands directory: ${commandsDir}`);
|
|
861
|
-
return [];
|
|
862
|
-
}
|
|
863
|
-
logger.info(`Found ${mdFiles.length} command files in ${commandsDir}`);
|
|
864
|
-
const rulesyncCommands = [];
|
|
865
|
-
for (const mdFile of mdFiles) {
|
|
866
|
-
const filepath = join3(commandsDir, mdFile);
|
|
867
|
-
try {
|
|
868
|
-
const rulesyncCommand = await RulesyncCommand.fromFilePath({
|
|
869
|
-
filePath: filepath
|
|
870
|
-
});
|
|
871
|
-
rulesyncCommands.push(rulesyncCommand);
|
|
872
|
-
logger.debug(`Successfully loaded command: ${mdFile}`);
|
|
873
|
-
} catch (error) {
|
|
874
|
-
logger.warn(`Failed to load command file ${filepath}:`, error);
|
|
875
|
-
continue;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
if (rulesyncCommands.length === 0) {
|
|
879
|
-
logger.debug(`No valid commands found in ${commandsDir}`);
|
|
880
|
-
return [];
|
|
881
|
-
}
|
|
871
|
+
const rulesyncCommandPaths = await findFilesByGlobs(join7(".rulesync", "commands", "*.md"));
|
|
872
|
+
const rulesyncCommands = (await Promise.allSettled(
|
|
873
|
+
rulesyncCommandPaths.map(
|
|
874
|
+
(path2) => RulesyncCommand.fromFile({ relativeFilePath: basename6(path2) })
|
|
875
|
+
)
|
|
876
|
+
)).filter((result) => result.status === "fulfilled").map((result) => result.value);
|
|
882
877
|
logger.info(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
|
|
883
878
|
return rulesyncCommands;
|
|
884
879
|
}
|
|
@@ -891,122 +886,67 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
891
886
|
case "claudecode":
|
|
892
887
|
return await this.loadClaudecodeCommands();
|
|
893
888
|
case "geminicli":
|
|
894
|
-
return await this.
|
|
889
|
+
return await this.loadGeminicliCommands();
|
|
895
890
|
case "roo":
|
|
896
891
|
return await this.loadRooCommands();
|
|
897
892
|
default:
|
|
898
893
|
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
899
894
|
}
|
|
900
895
|
}
|
|
896
|
+
async loadToolCommandDefault({
|
|
897
|
+
toolTarget,
|
|
898
|
+
relativeDirPath,
|
|
899
|
+
extension
|
|
900
|
+
}) {
|
|
901
|
+
const commandFilePaths = await findFilesByGlobs(
|
|
902
|
+
join7(this.baseDir, relativeDirPath, `*.${extension}`)
|
|
903
|
+
);
|
|
904
|
+
const toolCommands = (await Promise.allSettled(
|
|
905
|
+
commandFilePaths.map((path2) => {
|
|
906
|
+
switch (toolTarget) {
|
|
907
|
+
case "claudecode":
|
|
908
|
+
return ClaudecodeCommand.fromFile({ relativeFilePath: basename6(path2) });
|
|
909
|
+
case "geminicli":
|
|
910
|
+
return GeminiCliCommand.fromFile({ relativeFilePath: basename6(path2) });
|
|
911
|
+
case "roo":
|
|
912
|
+
return RooCommand.fromFile({ relativeFilePath: basename6(path2) });
|
|
913
|
+
default:
|
|
914
|
+
throw new Error(`Unsupported tool target: ${toolTarget}`);
|
|
915
|
+
}
|
|
916
|
+
})
|
|
917
|
+
)).filter((result) => result.status === "fulfilled").map((result) => result.value);
|
|
918
|
+
logger.info(`Successfully loaded ${toolCommands.length} ${relativeDirPath} commands`);
|
|
919
|
+
return toolCommands;
|
|
920
|
+
}
|
|
901
921
|
/**
|
|
902
922
|
* Load Claude Code command configurations from .claude/commands/ directory
|
|
903
923
|
*/
|
|
904
924
|
async loadClaudecodeCommands() {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
}
|
|
910
|
-
const allMdFiles = await findFiles(commandsDir, ".md");
|
|
911
|
-
const mdFiles = allMdFiles.map((f) => basename6(f));
|
|
912
|
-
if (mdFiles.length === 0) {
|
|
913
|
-
logger.info(`No markdown command files found in ${commandsDir}`);
|
|
914
|
-
return [];
|
|
915
|
-
}
|
|
916
|
-
logger.info(`Found ${mdFiles.length} Claude Code command files in ${commandsDir}`);
|
|
917
|
-
const toolCommands = [];
|
|
918
|
-
for (const mdFile of mdFiles) {
|
|
919
|
-
const filepath = join3(commandsDir, mdFile);
|
|
920
|
-
try {
|
|
921
|
-
const claudecodeCommand = await ClaudecodeCommand.fromFilePath({
|
|
922
|
-
baseDir: this.baseDir,
|
|
923
|
-
filePath: filepath
|
|
924
|
-
});
|
|
925
|
-
toolCommands.push(claudecodeCommand);
|
|
926
|
-
logger.debug(`Successfully loaded Claude Code command: ${mdFile}`);
|
|
927
|
-
} catch (error) {
|
|
928
|
-
logger.warn(`Failed to load Claude Code command file ${filepath}:`, error);
|
|
929
|
-
continue;
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
logger.info(`Successfully loaded ${toolCommands.length} Claude Code commands`);
|
|
933
|
-
return toolCommands;
|
|
925
|
+
return await this.loadToolCommandDefault({
|
|
926
|
+
toolTarget: "claudecode",
|
|
927
|
+
relativeDirPath: ".claude/commands",
|
|
928
|
+
extension: "md"
|
|
929
|
+
});
|
|
934
930
|
}
|
|
935
931
|
/**
|
|
936
932
|
* Load Gemini CLI command configurations from .gemini/commands/ directory
|
|
937
933
|
*/
|
|
938
|
-
async
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
}
|
|
944
|
-
const allFiles = await listDirectoryFiles(commandsDir);
|
|
945
|
-
const tomlFiles = allFiles.filter((file) => file.endsWith(".toml"));
|
|
946
|
-
if (tomlFiles.length === 0) {
|
|
947
|
-
logger.info(`No TOML command files found in ${commandsDir}`);
|
|
948
|
-
return [];
|
|
949
|
-
}
|
|
950
|
-
logger.info(`Found ${tomlFiles.length} Gemini CLI command files in ${commandsDir}`);
|
|
951
|
-
const toolCommands = [];
|
|
952
|
-
for (const tomlFile of tomlFiles) {
|
|
953
|
-
const filepath = join3(commandsDir, tomlFile);
|
|
954
|
-
try {
|
|
955
|
-
const geminiCliCommand = await GeminiCliCommand.fromFilePath({
|
|
956
|
-
baseDir: this.baseDir,
|
|
957
|
-
filePath: filepath
|
|
958
|
-
});
|
|
959
|
-
toolCommands.push(geminiCliCommand);
|
|
960
|
-
logger.debug(`Successfully loaded Gemini CLI command: ${tomlFile}`);
|
|
961
|
-
} catch (error) {
|
|
962
|
-
logger.warn(`Failed to load Gemini CLI command file ${filepath}:`, error);
|
|
963
|
-
continue;
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
logger.info(`Successfully loaded ${toolCommands.length} Gemini CLI commands`);
|
|
967
|
-
return toolCommands;
|
|
934
|
+
async loadGeminicliCommands() {
|
|
935
|
+
return await this.loadToolCommandDefault({
|
|
936
|
+
toolTarget: "geminicli",
|
|
937
|
+
relativeDirPath: ".gemini/commands",
|
|
938
|
+
extension: "md"
|
|
939
|
+
});
|
|
968
940
|
}
|
|
969
941
|
/**
|
|
970
942
|
* Load Roo Code command configurations from .roo/commands/ directory
|
|
971
943
|
*/
|
|
972
944
|
async loadRooCommands() {
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
}
|
|
978
|
-
const allMdFiles = await findFiles(commandsDir, ".md");
|
|
979
|
-
const mdFiles = allMdFiles.map((f) => basename6(f));
|
|
980
|
-
if (mdFiles.length === 0) {
|
|
981
|
-
logger.info(`No markdown command files found in ${commandsDir}`);
|
|
982
|
-
return [];
|
|
983
|
-
}
|
|
984
|
-
logger.info(`Found ${mdFiles.length} Roo Code command files in ${commandsDir}`);
|
|
985
|
-
const toolCommands = [];
|
|
986
|
-
for (const mdFile of mdFiles) {
|
|
987
|
-
const filepath = join3(commandsDir, mdFile);
|
|
988
|
-
try {
|
|
989
|
-
const rooCommand = await RooCommand.fromFilePath({
|
|
990
|
-
baseDir: this.baseDir,
|
|
991
|
-
filePath: filepath
|
|
992
|
-
});
|
|
993
|
-
toolCommands.push(rooCommand);
|
|
994
|
-
logger.debug(`Successfully loaded Roo Code command: ${mdFile}`);
|
|
995
|
-
} catch (error) {
|
|
996
|
-
logger.warn(`Failed to load Roo Code command file ${filepath}:`, error);
|
|
997
|
-
continue;
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
logger.info(`Successfully loaded ${toolCommands.length} Roo Code commands`);
|
|
1001
|
-
return toolCommands;
|
|
1002
|
-
}
|
|
1003
|
-
async writeToolCommandsFromRulesyncCommands(rulesyncCommands) {
|
|
1004
|
-
const toolCommands = await this.convertRulesyncFilesToToolFiles(rulesyncCommands);
|
|
1005
|
-
await this.writeAiFiles(toolCommands);
|
|
1006
|
-
}
|
|
1007
|
-
async writeRulesyncCommandsFromToolCommands(toolCommands) {
|
|
1008
|
-
const rulesyncCommands = await this.convertToolFilesToRulesyncFiles(toolCommands);
|
|
1009
|
-
await this.writeAiFiles(rulesyncCommands);
|
|
945
|
+
return await this.loadToolCommandDefault({
|
|
946
|
+
toolTarget: "roo",
|
|
947
|
+
relativeDirPath: ".roo/commands",
|
|
948
|
+
extension: "md"
|
|
949
|
+
});
|
|
1010
950
|
}
|
|
1011
951
|
/**
|
|
1012
952
|
* Implementation of abstract method from FeatureProcessor
|
|
@@ -1118,6 +1058,9 @@ var ConfigResolver = class {
|
|
|
1118
1058
|
// src/ignore/ignore-processor.ts
|
|
1119
1059
|
import { z as z9 } from "zod/mini";
|
|
1120
1060
|
|
|
1061
|
+
// src/ignore/augmentcode-ignore.ts
|
|
1062
|
+
import { join as join8 } from "path";
|
|
1063
|
+
|
|
1121
1064
|
// src/types/tool-file.ts
|
|
1122
1065
|
var ToolFile = class extends AiFile {
|
|
1123
1066
|
};
|
|
@@ -1136,9 +1079,6 @@ var RulesyncIgnore = class _RulesyncIgnore extends RulesyncFile {
|
|
|
1136
1079
|
fileContent
|
|
1137
1080
|
});
|
|
1138
1081
|
}
|
|
1139
|
-
static async fromFilePath(_params) {
|
|
1140
|
-
throw new Error("Please use the fromFile method instead.");
|
|
1141
|
-
}
|
|
1142
1082
|
};
|
|
1143
1083
|
|
|
1144
1084
|
// src/ignore/tool-ignore.ts
|
|
@@ -1175,12 +1115,9 @@ var ToolIgnore = class extends ToolFile {
|
|
|
1175
1115
|
fileContent: this.fileContent
|
|
1176
1116
|
});
|
|
1177
1117
|
}
|
|
1178
|
-
static async fromFile() {
|
|
1118
|
+
static async fromFile(_params) {
|
|
1179
1119
|
throw new Error("Please implement this method in the subclass.");
|
|
1180
1120
|
}
|
|
1181
|
-
static async fromFilePath(_params) {
|
|
1182
|
-
throw new Error("Please use the fromFile method instead.");
|
|
1183
|
-
}
|
|
1184
1121
|
};
|
|
1185
1122
|
|
|
1186
1123
|
// src/ignore/augmentcode-ignore.ts
|
|
@@ -1210,18 +1147,23 @@ var AugmentcodeIgnore = class _AugmentcodeIgnore extends ToolIgnore {
|
|
|
1210
1147
|
* Create AugmentcodeIgnore from file path
|
|
1211
1148
|
* Reads and parses .augmentignore file
|
|
1212
1149
|
*/
|
|
1213
|
-
static async fromFile(
|
|
1214
|
-
|
|
1150
|
+
static async fromFile({
|
|
1151
|
+
baseDir = ".",
|
|
1152
|
+
validate = true
|
|
1153
|
+
}) {
|
|
1154
|
+
const fileContent = await readFileContent(join8(baseDir, ".augmentignore"));
|
|
1215
1155
|
return new _AugmentcodeIgnore({
|
|
1216
|
-
baseDir
|
|
1156
|
+
baseDir,
|
|
1217
1157
|
relativeDirPath: ".",
|
|
1218
1158
|
relativeFilePath: ".augmentignore",
|
|
1219
|
-
fileContent
|
|
1159
|
+
fileContent,
|
|
1160
|
+
validate
|
|
1220
1161
|
});
|
|
1221
1162
|
}
|
|
1222
1163
|
};
|
|
1223
1164
|
|
|
1224
1165
|
// src/ignore/cline-ignore.ts
|
|
1166
|
+
import { join as join9 } from "path";
|
|
1225
1167
|
var ClineIgnore = class _ClineIgnore extends ToolIgnore {
|
|
1226
1168
|
/**
|
|
1227
1169
|
* Convert ClineIgnore to RulesyncIgnore format
|
|
@@ -1247,18 +1189,23 @@ var ClineIgnore = class _ClineIgnore extends ToolIgnore {
|
|
|
1247
1189
|
/**
|
|
1248
1190
|
* Load ClineIgnore from .clineignore file
|
|
1249
1191
|
*/
|
|
1250
|
-
static async fromFile(
|
|
1251
|
-
|
|
1192
|
+
static async fromFile({
|
|
1193
|
+
baseDir = ".",
|
|
1194
|
+
validate = true
|
|
1195
|
+
}) {
|
|
1196
|
+
const fileContent = await readFileContent(join9(baseDir, ".clineignore"));
|
|
1252
1197
|
return new _ClineIgnore({
|
|
1253
|
-
baseDir
|
|
1198
|
+
baseDir,
|
|
1254
1199
|
relativeDirPath: ".",
|
|
1255
1200
|
relativeFilePath: ".clineignore",
|
|
1256
|
-
fileContent
|
|
1201
|
+
fileContent,
|
|
1202
|
+
validate
|
|
1257
1203
|
});
|
|
1258
1204
|
}
|
|
1259
1205
|
};
|
|
1260
1206
|
|
|
1261
1207
|
// src/ignore/codexcli-ignore.ts
|
|
1208
|
+
import { join as join10 } from "path";
|
|
1262
1209
|
var CodexcliIgnore = class _CodexcliIgnore extends ToolIgnore {
|
|
1263
1210
|
toRulesyncIgnore() {
|
|
1264
1211
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1277,20 +1224,23 @@ var CodexcliIgnore = class _CodexcliIgnore extends ToolIgnore {
|
|
|
1277
1224
|
// Skip validation to allow empty patterns
|
|
1278
1225
|
});
|
|
1279
1226
|
}
|
|
1280
|
-
static async fromFile(
|
|
1281
|
-
|
|
1227
|
+
static async fromFile({
|
|
1228
|
+
baseDir = ".",
|
|
1229
|
+
validate = true
|
|
1230
|
+
}) {
|
|
1231
|
+
const fileContent = await readFileContent(join10(baseDir, ".codexignore"));
|
|
1282
1232
|
return new _CodexcliIgnore({
|
|
1283
|
-
baseDir
|
|
1233
|
+
baseDir,
|
|
1284
1234
|
relativeDirPath: ".",
|
|
1285
1235
|
relativeFilePath: ".codexignore",
|
|
1286
1236
|
fileContent,
|
|
1287
|
-
validate
|
|
1288
|
-
// Skip validation to allow empty patterns
|
|
1237
|
+
validate
|
|
1289
1238
|
});
|
|
1290
1239
|
}
|
|
1291
1240
|
};
|
|
1292
1241
|
|
|
1293
1242
|
// src/ignore/cursor-ignore.ts
|
|
1243
|
+
import { join as join11 } from "path";
|
|
1294
1244
|
var CursorIgnore = class _CursorIgnore extends ToolIgnore {
|
|
1295
1245
|
toRulesyncIgnore() {
|
|
1296
1246
|
return new RulesyncIgnore({
|
|
@@ -1312,18 +1262,23 @@ var CursorIgnore = class _CursorIgnore extends ToolIgnore {
|
|
|
1312
1262
|
fileContent: body
|
|
1313
1263
|
});
|
|
1314
1264
|
}
|
|
1315
|
-
static async fromFile(
|
|
1316
|
-
|
|
1265
|
+
static async fromFile({
|
|
1266
|
+
baseDir = ".",
|
|
1267
|
+
validate = true
|
|
1268
|
+
}) {
|
|
1269
|
+
const fileContent = await readFileContent(join11(baseDir, ".cursorignore"));
|
|
1317
1270
|
return new _CursorIgnore({
|
|
1318
|
-
baseDir
|
|
1271
|
+
baseDir,
|
|
1319
1272
|
relativeDirPath: ".",
|
|
1320
1273
|
relativeFilePath: ".cursorignore",
|
|
1321
|
-
fileContent
|
|
1274
|
+
fileContent,
|
|
1275
|
+
validate
|
|
1322
1276
|
});
|
|
1323
1277
|
}
|
|
1324
1278
|
};
|
|
1325
1279
|
|
|
1326
1280
|
// src/ignore/geminicli-ignore.ts
|
|
1281
|
+
import { join as join12 } from "path";
|
|
1327
1282
|
var GeminiCliIgnore = class _GeminiCliIgnore extends ToolIgnore {
|
|
1328
1283
|
toRulesyncIgnore() {
|
|
1329
1284
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1339,18 +1294,23 @@ var GeminiCliIgnore = class _GeminiCliIgnore extends ToolIgnore {
|
|
|
1339
1294
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1340
1295
|
});
|
|
1341
1296
|
}
|
|
1342
|
-
static async fromFile(
|
|
1343
|
-
|
|
1297
|
+
static async fromFile({
|
|
1298
|
+
baseDir = ".",
|
|
1299
|
+
validate = true
|
|
1300
|
+
}) {
|
|
1301
|
+
const fileContent = await readFileContent(join12(baseDir, ".aiexclude"));
|
|
1344
1302
|
return new _GeminiCliIgnore({
|
|
1345
|
-
baseDir
|
|
1303
|
+
baseDir,
|
|
1346
1304
|
relativeDirPath: ".",
|
|
1347
1305
|
relativeFilePath: ".aiexclude",
|
|
1348
|
-
fileContent
|
|
1306
|
+
fileContent,
|
|
1307
|
+
validate
|
|
1349
1308
|
});
|
|
1350
1309
|
}
|
|
1351
1310
|
};
|
|
1352
1311
|
|
|
1353
1312
|
// src/ignore/junie-ignore.ts
|
|
1313
|
+
import { join as join13 } from "path";
|
|
1354
1314
|
var JunieIgnore = class _JunieIgnore extends ToolIgnore {
|
|
1355
1315
|
toRulesyncIgnore() {
|
|
1356
1316
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1366,18 +1326,23 @@ var JunieIgnore = class _JunieIgnore extends ToolIgnore {
|
|
|
1366
1326
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1367
1327
|
});
|
|
1368
1328
|
}
|
|
1369
|
-
static async fromFile(
|
|
1370
|
-
|
|
1329
|
+
static async fromFile({
|
|
1330
|
+
baseDir = ".",
|
|
1331
|
+
validate = true
|
|
1332
|
+
}) {
|
|
1333
|
+
const fileContent = await readFileContent(join13(baseDir, ".junieignore"));
|
|
1371
1334
|
return new _JunieIgnore({
|
|
1372
|
-
baseDir
|
|
1335
|
+
baseDir,
|
|
1373
1336
|
relativeDirPath: ".",
|
|
1374
1337
|
relativeFilePath: ".junieignore",
|
|
1375
|
-
fileContent
|
|
1338
|
+
fileContent,
|
|
1339
|
+
validate
|
|
1376
1340
|
});
|
|
1377
1341
|
}
|
|
1378
1342
|
};
|
|
1379
1343
|
|
|
1380
1344
|
// src/ignore/kiro-ignore.ts
|
|
1345
|
+
import { join as join14 } from "path";
|
|
1381
1346
|
var KiroIgnore = class _KiroIgnore extends ToolIgnore {
|
|
1382
1347
|
toRulesyncIgnore() {
|
|
1383
1348
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1393,18 +1358,23 @@ var KiroIgnore = class _KiroIgnore extends ToolIgnore {
|
|
|
1393
1358
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1394
1359
|
});
|
|
1395
1360
|
}
|
|
1396
|
-
static async fromFile(
|
|
1397
|
-
|
|
1361
|
+
static async fromFile({
|
|
1362
|
+
baseDir = ".",
|
|
1363
|
+
validate = true
|
|
1364
|
+
}) {
|
|
1365
|
+
const fileContent = await readFileContent(join14(baseDir, ".aiignore"));
|
|
1398
1366
|
return new _KiroIgnore({
|
|
1399
|
-
baseDir
|
|
1367
|
+
baseDir,
|
|
1400
1368
|
relativeDirPath: ".",
|
|
1401
1369
|
relativeFilePath: ".aiignore",
|
|
1402
|
-
fileContent
|
|
1370
|
+
fileContent,
|
|
1371
|
+
validate
|
|
1403
1372
|
});
|
|
1404
1373
|
}
|
|
1405
1374
|
};
|
|
1406
1375
|
|
|
1407
1376
|
// src/ignore/qwencode-ignore.ts
|
|
1377
|
+
import { join as join15 } from "path";
|
|
1408
1378
|
var QwencodeIgnore = class _QwencodeIgnore extends ToolIgnore {
|
|
1409
1379
|
toRulesyncIgnore() {
|
|
1410
1380
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1420,18 +1390,23 @@ var QwencodeIgnore = class _QwencodeIgnore extends ToolIgnore {
|
|
|
1420
1390
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1421
1391
|
});
|
|
1422
1392
|
}
|
|
1423
|
-
static async fromFile(
|
|
1424
|
-
|
|
1393
|
+
static async fromFile({
|
|
1394
|
+
baseDir = ".",
|
|
1395
|
+
validate = true
|
|
1396
|
+
}) {
|
|
1397
|
+
const fileContent = await readFileContent(join15(baseDir, ".geminiignore"));
|
|
1425
1398
|
return new _QwencodeIgnore({
|
|
1426
|
-
baseDir
|
|
1399
|
+
baseDir,
|
|
1427
1400
|
relativeDirPath: ".",
|
|
1428
1401
|
relativeFilePath: ".geminiignore",
|
|
1429
|
-
fileContent
|
|
1402
|
+
fileContent,
|
|
1403
|
+
validate
|
|
1430
1404
|
});
|
|
1431
1405
|
}
|
|
1432
1406
|
};
|
|
1433
1407
|
|
|
1434
1408
|
// src/ignore/roo-ignore.ts
|
|
1409
|
+
import { join as join16 } from "path";
|
|
1435
1410
|
var RooIgnore = class _RooIgnore extends ToolIgnore {
|
|
1436
1411
|
toRulesyncIgnore() {
|
|
1437
1412
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1447,18 +1422,23 @@ var RooIgnore = class _RooIgnore extends ToolIgnore {
|
|
|
1447
1422
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1448
1423
|
});
|
|
1449
1424
|
}
|
|
1450
|
-
static async fromFile(
|
|
1451
|
-
|
|
1425
|
+
static async fromFile({
|
|
1426
|
+
baseDir = ".",
|
|
1427
|
+
validate = true
|
|
1428
|
+
}) {
|
|
1429
|
+
const fileContent = await readFileContent(join16(baseDir, ".rooignore"));
|
|
1452
1430
|
return new _RooIgnore({
|
|
1453
|
-
baseDir
|
|
1431
|
+
baseDir,
|
|
1454
1432
|
relativeDirPath: ".",
|
|
1455
1433
|
relativeFilePath: ".rooignore",
|
|
1456
|
-
fileContent
|
|
1434
|
+
fileContent,
|
|
1435
|
+
validate
|
|
1457
1436
|
});
|
|
1458
1437
|
}
|
|
1459
1438
|
};
|
|
1460
1439
|
|
|
1461
1440
|
// src/ignore/windsurf-ignore.ts
|
|
1441
|
+
import { join as join17 } from "path";
|
|
1462
1442
|
var WindsurfIgnore = class _WindsurfIgnore extends ToolIgnore {
|
|
1463
1443
|
toRulesyncIgnore() {
|
|
1464
1444
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1474,6 +1454,19 @@ var WindsurfIgnore = class _WindsurfIgnore extends ToolIgnore {
|
|
|
1474
1454
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1475
1455
|
});
|
|
1476
1456
|
}
|
|
1457
|
+
static async fromFile({
|
|
1458
|
+
baseDir = ".",
|
|
1459
|
+
validate = true
|
|
1460
|
+
}) {
|
|
1461
|
+
const fileContent = await readFileContent(join17(baseDir, ".codeiumignore"));
|
|
1462
|
+
return new _WindsurfIgnore({
|
|
1463
|
+
baseDir,
|
|
1464
|
+
relativeDirPath: ".",
|
|
1465
|
+
relativeFilePath: ".codeiumignore",
|
|
1466
|
+
fileContent,
|
|
1467
|
+
validate
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1477
1470
|
};
|
|
1478
1471
|
|
|
1479
1472
|
// src/ignore/ignore-processor.ts
|
|
@@ -1531,25 +1524,25 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
1531
1524
|
async loadToolIgnores() {
|
|
1532
1525
|
switch (this.toolTarget) {
|
|
1533
1526
|
case "augmentcode":
|
|
1534
|
-
return [await AugmentcodeIgnore.fromFile()];
|
|
1527
|
+
return [await AugmentcodeIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1535
1528
|
case "cline":
|
|
1536
|
-
return [await ClineIgnore.fromFile()];
|
|
1529
|
+
return [await ClineIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1537
1530
|
case "codexcli":
|
|
1538
|
-
return [await CodexcliIgnore.fromFile()];
|
|
1531
|
+
return [await CodexcliIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1539
1532
|
case "cursor":
|
|
1540
|
-
return [await CursorIgnore.fromFile()];
|
|
1533
|
+
return [await CursorIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1541
1534
|
case "geminicli":
|
|
1542
|
-
return [await GeminiCliIgnore.fromFile()];
|
|
1535
|
+
return [await GeminiCliIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1543
1536
|
case "junie":
|
|
1544
|
-
return [await JunieIgnore.fromFile()];
|
|
1537
|
+
return [await JunieIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1545
1538
|
case "kiro":
|
|
1546
|
-
return [await KiroIgnore.fromFile()];
|
|
1539
|
+
return [await KiroIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1547
1540
|
case "qwencode":
|
|
1548
|
-
return [await QwencodeIgnore.fromFile()];
|
|
1541
|
+
return [await QwencodeIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1549
1542
|
case "roo":
|
|
1550
|
-
return [await RooIgnore.fromFile()];
|
|
1543
|
+
return [await RooIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1551
1544
|
case "windsurf":
|
|
1552
|
-
return [await WindsurfIgnore.fromFile()];
|
|
1545
|
+
return [await WindsurfIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1553
1546
|
default:
|
|
1554
1547
|
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
1555
1548
|
}
|
|
@@ -1644,9 +1637,14 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
1644
1637
|
};
|
|
1645
1638
|
|
|
1646
1639
|
// src/mcp/mcp-processor.ts
|
|
1647
|
-
import { join as join4 } from "path";
|
|
1648
1640
|
import { z as z11 } from "zod/mini";
|
|
1649
1641
|
|
|
1642
|
+
// src/mcp/amazonqcli-mcp.ts
|
|
1643
|
+
import { join as join19 } from "path";
|
|
1644
|
+
|
|
1645
|
+
// src/mcp/rulesync-mcp.ts
|
|
1646
|
+
import { join as join18 } from "path";
|
|
1647
|
+
|
|
1650
1648
|
// src/types/mcp.ts
|
|
1651
1649
|
import { z as z10 } from "zod/mini";
|
|
1652
1650
|
var McpTransportTypeSchema = z10.enum(["stdio", "sse", "http"]);
|
|
@@ -1695,14 +1693,14 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
|
|
|
1695
1693
|
validate() {
|
|
1696
1694
|
return { success: true, error: null };
|
|
1697
1695
|
}
|
|
1698
|
-
static async
|
|
1699
|
-
const fileContent = await readFileContent(
|
|
1696
|
+
static async fromFile({ validate = true }) {
|
|
1697
|
+
const fileContent = await readFileContent(join18(RULESYNC_DIR, ".mcp.json"));
|
|
1700
1698
|
return new _RulesyncMcp({
|
|
1701
1699
|
baseDir: ".",
|
|
1702
|
-
relativeDirPath:
|
|
1700
|
+
relativeDirPath: RULESYNC_DIR,
|
|
1703
1701
|
relativeFilePath: ".mcp.json",
|
|
1704
1702
|
fileContent,
|
|
1705
|
-
validate
|
|
1703
|
+
validate
|
|
1706
1704
|
});
|
|
1707
1705
|
}
|
|
1708
1706
|
getJson() {
|
|
@@ -1738,7 +1736,7 @@ var ToolMcp = class extends ToolFile {
|
|
|
1738
1736
|
fileContent: this.fileContent
|
|
1739
1737
|
});
|
|
1740
1738
|
}
|
|
1741
|
-
static async
|
|
1739
|
+
static async fromFile(_params) {
|
|
1742
1740
|
throw new Error("Please implement this method in the subclass.");
|
|
1743
1741
|
}
|
|
1744
1742
|
static fromRulesyncMcp(_params) {
|
|
@@ -1748,14 +1746,17 @@ var ToolMcp = class extends ToolFile {
|
|
|
1748
1746
|
|
|
1749
1747
|
// src/mcp/amazonqcli-mcp.ts
|
|
1750
1748
|
var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
|
|
1751
|
-
static async
|
|
1752
|
-
|
|
1749
|
+
static async fromFile({
|
|
1750
|
+
baseDir = ".",
|
|
1751
|
+
validate = true
|
|
1752
|
+
}) {
|
|
1753
|
+
const fileContent = await readFileContent(join19(baseDir, ".amazonq/mcp.json"));
|
|
1753
1754
|
return new _AmazonqcliMcp({
|
|
1754
|
-
baseDir
|
|
1755
|
+
baseDir,
|
|
1755
1756
|
relativeDirPath: ".amazonq",
|
|
1756
|
-
relativeFilePath: "
|
|
1757
|
+
relativeFilePath: "mcp.json",
|
|
1757
1758
|
fileContent,
|
|
1758
|
-
validate
|
|
1759
|
+
validate
|
|
1759
1760
|
});
|
|
1760
1761
|
}
|
|
1761
1762
|
static fromRulesyncMcp({
|
|
@@ -1780,15 +1781,19 @@ var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
|
|
|
1780
1781
|
};
|
|
1781
1782
|
|
|
1782
1783
|
// src/mcp/claudecode-mcp.ts
|
|
1784
|
+
import { join as join20 } from "path";
|
|
1783
1785
|
var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
|
|
1784
|
-
static async
|
|
1785
|
-
|
|
1786
|
+
static async fromFile({
|
|
1787
|
+
baseDir = ".",
|
|
1788
|
+
validate = true
|
|
1789
|
+
}) {
|
|
1790
|
+
const fileContent = await readFileContent(join20(baseDir, ".mcp.json"));
|
|
1786
1791
|
return new _ClaudecodeMcp({
|
|
1787
1792
|
baseDir: ".",
|
|
1788
1793
|
relativeDirPath: ".",
|
|
1789
1794
|
relativeFilePath: ".mcp.json",
|
|
1790
1795
|
fileContent,
|
|
1791
|
-
validate
|
|
1796
|
+
validate
|
|
1792
1797
|
});
|
|
1793
1798
|
}
|
|
1794
1799
|
static fromRulesyncMcp({
|
|
@@ -1813,15 +1818,19 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
|
|
|
1813
1818
|
};
|
|
1814
1819
|
|
|
1815
1820
|
// src/mcp/cline-mcp.ts
|
|
1821
|
+
import { join as join21 } from "path";
|
|
1816
1822
|
var ClineMcp = class _ClineMcp extends ToolMcp {
|
|
1817
|
-
static async
|
|
1818
|
-
|
|
1823
|
+
static async fromFile({
|
|
1824
|
+
baseDir = ".",
|
|
1825
|
+
validate = true
|
|
1826
|
+
}) {
|
|
1827
|
+
const fileContent = await readFileContent(join21(baseDir, ".cline/mcp.json"));
|
|
1819
1828
|
return new _ClineMcp({
|
|
1820
1829
|
baseDir: ".",
|
|
1821
1830
|
relativeDirPath: ".cline",
|
|
1822
1831
|
relativeFilePath: "mcp.json",
|
|
1823
1832
|
fileContent,
|
|
1824
|
-
validate
|
|
1833
|
+
validate
|
|
1825
1834
|
});
|
|
1826
1835
|
}
|
|
1827
1836
|
static fromRulesyncMcp({
|
|
@@ -1846,15 +1855,19 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
|
|
|
1846
1855
|
};
|
|
1847
1856
|
|
|
1848
1857
|
// src/mcp/copilot-mcp.ts
|
|
1858
|
+
import { join as join22 } from "path";
|
|
1849
1859
|
var CopilotMcp = class _CopilotMcp extends ToolMcp {
|
|
1850
|
-
static async fromFilePath({
|
|
1851
|
-
|
|
1860
|
+
static async fromFilePath({
|
|
1861
|
+
baseDir = ".",
|
|
1862
|
+
validate = true
|
|
1863
|
+
}) {
|
|
1864
|
+
const fileContent = await readFileContent(join22(baseDir, ".vscode/mcp.json"));
|
|
1852
1865
|
return new _CopilotMcp({
|
|
1853
1866
|
baseDir: ".",
|
|
1854
1867
|
relativeDirPath: ".vscode",
|
|
1855
1868
|
relativeFilePath: "mcp.json",
|
|
1856
1869
|
fileContent,
|
|
1857
|
-
validate
|
|
1870
|
+
validate
|
|
1858
1871
|
});
|
|
1859
1872
|
}
|
|
1860
1873
|
static fromRulesyncMcp({
|
|
@@ -1879,15 +1892,19 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
|
|
|
1879
1892
|
};
|
|
1880
1893
|
|
|
1881
1894
|
// src/mcp/cursor-mcp.ts
|
|
1895
|
+
import { join as join23 } from "path";
|
|
1882
1896
|
var CursorMcp = class _CursorMcp extends ToolMcp {
|
|
1883
|
-
static async
|
|
1884
|
-
|
|
1897
|
+
static async fromFile({
|
|
1898
|
+
baseDir = ".",
|
|
1899
|
+
validate = true
|
|
1900
|
+
}) {
|
|
1901
|
+
const fileContent = await readFileContent(join23(baseDir, ".cursor/mcp.json"));
|
|
1885
1902
|
return new _CursorMcp({
|
|
1886
1903
|
baseDir: ".",
|
|
1887
1904
|
relativeDirPath: ".cursor",
|
|
1888
1905
|
relativeFilePath: "mcp.json",
|
|
1889
1906
|
fileContent,
|
|
1890
|
-
validate
|
|
1907
|
+
validate
|
|
1891
1908
|
});
|
|
1892
1909
|
}
|
|
1893
1910
|
static fromRulesyncMcp({
|
|
@@ -1923,15 +1940,19 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
|
|
|
1923
1940
|
};
|
|
1924
1941
|
|
|
1925
1942
|
// src/mcp/roo-mcp.ts
|
|
1943
|
+
import { join as join24 } from "path";
|
|
1926
1944
|
var RooMcp = class _RooMcp extends ToolMcp {
|
|
1927
|
-
static async
|
|
1928
|
-
|
|
1945
|
+
static async fromFile({
|
|
1946
|
+
baseDir = ".",
|
|
1947
|
+
validate = true
|
|
1948
|
+
}) {
|
|
1949
|
+
const fileContent = await readFileContent(join24(baseDir, ".roo/mcp.json"));
|
|
1929
1950
|
return new _RooMcp({
|
|
1930
1951
|
baseDir: ".",
|
|
1931
1952
|
relativeDirPath: ".roo",
|
|
1932
1953
|
relativeFilePath: "mcp.json",
|
|
1933
1954
|
fileContent,
|
|
1934
|
-
validate
|
|
1955
|
+
validate
|
|
1935
1956
|
});
|
|
1936
1957
|
}
|
|
1937
1958
|
static fromRulesyncMcp({
|
|
@@ -1981,9 +2002,7 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
1981
2002
|
*/
|
|
1982
2003
|
async loadRulesyncFiles() {
|
|
1983
2004
|
try {
|
|
1984
|
-
return [
|
|
1985
|
-
await RulesyncMcp.fromFilePath({ filePath: join4(this.baseDir, ".rulesync", ".mcp.json") })
|
|
1986
|
-
];
|
|
2005
|
+
return [await RulesyncMcp.fromFile({})];
|
|
1987
2006
|
} catch (error) {
|
|
1988
2007
|
logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
|
|
1989
2008
|
return [];
|
|
@@ -1995,42 +2014,62 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
1995
2014
|
*/
|
|
1996
2015
|
async loadToolFiles() {
|
|
1997
2016
|
try {
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2017
|
+
const toolMcps = await (async () => {
|
|
2018
|
+
switch (this.toolTarget) {
|
|
2019
|
+
case "amazonqcli": {
|
|
2020
|
+
return [
|
|
2021
|
+
await AmazonqcliMcp.fromFile({
|
|
2022
|
+
baseDir: this.baseDir,
|
|
2023
|
+
validate: true
|
|
2024
|
+
})
|
|
2025
|
+
];
|
|
2026
|
+
}
|
|
2027
|
+
case "claudecode": {
|
|
2028
|
+
return [
|
|
2029
|
+
await ClaudecodeMcp.fromFile({
|
|
2030
|
+
baseDir: this.baseDir,
|
|
2031
|
+
validate: true
|
|
2032
|
+
})
|
|
2033
|
+
];
|
|
2034
|
+
}
|
|
2035
|
+
case "cline": {
|
|
2036
|
+
return [
|
|
2037
|
+
await ClineMcp.fromFile({
|
|
2038
|
+
baseDir: this.baseDir,
|
|
2039
|
+
validate: true
|
|
2040
|
+
})
|
|
2041
|
+
];
|
|
2042
|
+
}
|
|
2043
|
+
case "copilot": {
|
|
2044
|
+
return [
|
|
2045
|
+
await CopilotMcp.fromFile({
|
|
2046
|
+
baseDir: this.baseDir,
|
|
2047
|
+
validate: true
|
|
2048
|
+
})
|
|
2049
|
+
];
|
|
2050
|
+
}
|
|
2051
|
+
case "cursor": {
|
|
2052
|
+
return [
|
|
2053
|
+
await CursorMcp.fromFile({
|
|
2054
|
+
baseDir: this.baseDir,
|
|
2055
|
+
validate: true
|
|
2056
|
+
})
|
|
2057
|
+
];
|
|
2058
|
+
}
|
|
2059
|
+
case "roo": {
|
|
2060
|
+
return [
|
|
2061
|
+
await RooMcp.fromFile({
|
|
2062
|
+
baseDir: this.baseDir,
|
|
2063
|
+
validate: true
|
|
2064
|
+
})
|
|
2065
|
+
];
|
|
2066
|
+
}
|
|
2067
|
+
default:
|
|
2068
|
+
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
2030
2069
|
}
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2070
|
+
})();
|
|
2071
|
+
logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
|
|
2072
|
+
return toolMcps;
|
|
2034
2073
|
} catch (error) {
|
|
2035
2074
|
logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
|
|
2036
2075
|
return [];
|
|
@@ -2106,21 +2145,15 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
2106
2145
|
};
|
|
2107
2146
|
|
|
2108
2147
|
// src/rules/rules-processor.ts
|
|
2109
|
-
import { basename as basename9, join as
|
|
2148
|
+
import { basename as basename9, join as join43 } from "path";
|
|
2110
2149
|
import { XMLBuilder } from "fast-xml-parser";
|
|
2111
2150
|
import { z as z16 } from "zod/mini";
|
|
2112
2151
|
|
|
2113
|
-
// src/
|
|
2114
|
-
import { join as
|
|
2115
|
-
var RULESYNC_DIR = ".rulesync";
|
|
2116
|
-
var RULESYNC_RULES_DIR = join5(".rulesync", "rules");
|
|
2117
|
-
var RULESYNC_RULES_DIR_LEGACY = ".rulesync";
|
|
2118
|
-
var RULESYNC_MCP_FILE = join5(".rulesync", ".mcp.json");
|
|
2119
|
-
var RULESYNC_COMMANDS_DIR = join5(".rulesync", "commands");
|
|
2120
|
-
var RULESYNC_SUBAGENTS_DIR = join5(".rulesync", "subagents");
|
|
2152
|
+
// src/rules/agentsmd-rule.ts
|
|
2153
|
+
import { join as join26 } from "path";
|
|
2121
2154
|
|
|
2122
2155
|
// src/rules/rulesync-rule.ts
|
|
2123
|
-
import { basename as basename7, join as
|
|
2156
|
+
import { basename as basename7, join as join25 } from "path";
|
|
2124
2157
|
import { z as z12 } from "zod/mini";
|
|
2125
2158
|
var RulesyncRuleFrontmatterSchema = z12.object({
|
|
2126
2159
|
root: z12.optional(z12.optional(z12.boolean())),
|
|
@@ -2166,10 +2199,11 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
2166
2199
|
return { success: false, error: result.error };
|
|
2167
2200
|
}
|
|
2168
2201
|
}
|
|
2169
|
-
static async
|
|
2170
|
-
relativeFilePath
|
|
2202
|
+
static async fromFileLegacy({
|
|
2203
|
+
relativeFilePath,
|
|
2204
|
+
validate = true
|
|
2171
2205
|
}) {
|
|
2172
|
-
const filePath =
|
|
2206
|
+
const filePath = join25(RULESYNC_RULES_DIR_LEGACY, relativeFilePath);
|
|
2173
2207
|
const fileContent = await readFileContent(filePath);
|
|
2174
2208
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
2175
2209
|
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -2189,10 +2223,15 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
2189
2223
|
relativeDirPath: RULESYNC_RULES_DIR,
|
|
2190
2224
|
relativeFilePath: filename,
|
|
2191
2225
|
frontmatter: validatedFrontmatter,
|
|
2192
|
-
body: content.trim()
|
|
2226
|
+
body: content.trim(),
|
|
2227
|
+
validate
|
|
2193
2228
|
});
|
|
2194
2229
|
}
|
|
2195
|
-
static async
|
|
2230
|
+
static async fromFile({
|
|
2231
|
+
relativeFilePath,
|
|
2232
|
+
validate = true
|
|
2233
|
+
}) {
|
|
2234
|
+
const filePath = join25(RULESYNC_RULES_DIR, relativeFilePath);
|
|
2196
2235
|
const fileContent = await readFileContent(filePath);
|
|
2197
2236
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
2198
2237
|
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -2212,7 +2251,8 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
2212
2251
|
relativeDirPath: RULESYNC_RULES_DIR,
|
|
2213
2252
|
relativeFilePath: filename,
|
|
2214
2253
|
frontmatter: validatedFrontmatter,
|
|
2215
|
-
body: content.trim()
|
|
2254
|
+
body: content.trim(),
|
|
2255
|
+
validate
|
|
2216
2256
|
});
|
|
2217
2257
|
}
|
|
2218
2258
|
getBody() {
|
|
@@ -2227,7 +2267,7 @@ var ToolRule = class extends ToolFile {
|
|
|
2227
2267
|
super(rest);
|
|
2228
2268
|
this.root = root;
|
|
2229
2269
|
}
|
|
2230
|
-
static async
|
|
2270
|
+
static async fromFile(_params) {
|
|
2231
2271
|
throw new Error("Please implement this method in the subclass.");
|
|
2232
2272
|
}
|
|
2233
2273
|
static fromRulesyncRule(_params) {
|
|
@@ -2278,19 +2318,18 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
2278
2318
|
root: root ?? false
|
|
2279
2319
|
});
|
|
2280
2320
|
}
|
|
2281
|
-
static async
|
|
2321
|
+
static async fromFile({
|
|
2282
2322
|
baseDir = ".",
|
|
2283
|
-
relativeDirPath,
|
|
2284
2323
|
relativeFilePath,
|
|
2285
|
-
filePath,
|
|
2286
2324
|
validate = true
|
|
2287
2325
|
}) {
|
|
2288
|
-
const fileContent = await readFileContent(filePath);
|
|
2289
2326
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
2327
|
+
const relativePath = isRoot ? "AGENTS.md" : join26(".agents/memories", relativeFilePath);
|
|
2328
|
+
const fileContent = await readFileContent(join26(baseDir, relativePath));
|
|
2290
2329
|
return new _AgentsMdRule({
|
|
2291
2330
|
baseDir,
|
|
2292
|
-
relativeDirPath,
|
|
2293
|
-
relativeFilePath,
|
|
2331
|
+
relativeDirPath: isRoot ? "." : ".agents/memories",
|
|
2332
|
+
relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
|
|
2294
2333
|
fileContent,
|
|
2295
2334
|
validate,
|
|
2296
2335
|
root: isRoot
|
|
@@ -2318,15 +2357,20 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
2318
2357
|
};
|
|
2319
2358
|
|
|
2320
2359
|
// src/rules/amazonqcli-rule.ts
|
|
2360
|
+
import { join as join27 } from "path";
|
|
2321
2361
|
var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
2322
|
-
static async
|
|
2323
|
-
|
|
2362
|
+
static async fromFile({
|
|
2363
|
+
baseDir = ".",
|
|
2364
|
+
relativeFilePath,
|
|
2365
|
+
validate = true
|
|
2366
|
+
}) {
|
|
2367
|
+
const fileContent = await readFileContent(join27(baseDir, ".amazonq/rules", relativeFilePath));
|
|
2324
2368
|
return new _AmazonQCliRule({
|
|
2325
|
-
baseDir
|
|
2326
|
-
relativeDirPath:
|
|
2327
|
-
relativeFilePath
|
|
2369
|
+
baseDir,
|
|
2370
|
+
relativeDirPath: ".amazonq/rules",
|
|
2371
|
+
relativeFilePath,
|
|
2328
2372
|
fileContent,
|
|
2329
|
-
validate
|
|
2373
|
+
validate,
|
|
2330
2374
|
root: false
|
|
2331
2375
|
});
|
|
2332
2376
|
}
|
|
@@ -2353,6 +2397,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
|
2353
2397
|
};
|
|
2354
2398
|
|
|
2355
2399
|
// src/rules/augmentcode-legacy-rule.ts
|
|
2400
|
+
import { join as join28 } from "path";
|
|
2356
2401
|
var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
2357
2402
|
toRulesyncRule() {
|
|
2358
2403
|
const rulesyncFrontmatter = {
|
|
@@ -2388,19 +2433,18 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
2388
2433
|
validate() {
|
|
2389
2434
|
return { success: true, error: null };
|
|
2390
2435
|
}
|
|
2391
|
-
static async
|
|
2436
|
+
static async fromFile({
|
|
2392
2437
|
baseDir = ".",
|
|
2393
|
-
relativeDirPath,
|
|
2394
2438
|
relativeFilePath,
|
|
2395
|
-
filePath,
|
|
2396
2439
|
validate = true
|
|
2397
2440
|
}) {
|
|
2398
|
-
const fileContent = await readFileContent(filePath);
|
|
2399
2441
|
const isRoot = relativeFilePath === ".augment-guidelines";
|
|
2442
|
+
const relativePath = isRoot ? ".augment-guidelines" : join28(".augment/rules", relativeFilePath);
|
|
2443
|
+
const fileContent = await readFileContent(join28(baseDir, relativePath));
|
|
2400
2444
|
return new _AugmentcodeLegacyRule({
|
|
2401
2445
|
baseDir,
|
|
2402
|
-
relativeDirPath,
|
|
2403
|
-
relativeFilePath,
|
|
2446
|
+
relativeDirPath: isRoot ? "." : ".augment/rules",
|
|
2447
|
+
relativeFilePath: isRoot ? ".augment-guidelines" : relativeFilePath,
|
|
2404
2448
|
fileContent,
|
|
2405
2449
|
validate,
|
|
2406
2450
|
root: isRoot
|
|
@@ -2409,6 +2453,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
2409
2453
|
};
|
|
2410
2454
|
|
|
2411
2455
|
// src/rules/augmentcode-rule.ts
|
|
2456
|
+
import { join as join29 } from "path";
|
|
2412
2457
|
var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
2413
2458
|
toRulesyncRule() {
|
|
2414
2459
|
return this.toRulesyncRuleDefault();
|
|
@@ -2427,18 +2472,16 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
2427
2472
|
})
|
|
2428
2473
|
);
|
|
2429
2474
|
}
|
|
2430
|
-
static async
|
|
2475
|
+
static async fromFile({
|
|
2431
2476
|
baseDir = ".",
|
|
2432
|
-
relativeDirPath,
|
|
2433
2477
|
relativeFilePath,
|
|
2434
|
-
filePath,
|
|
2435
2478
|
validate = true
|
|
2436
2479
|
}) {
|
|
2437
|
-
const fileContent = await readFileContent(
|
|
2480
|
+
const fileContent = await readFileContent(join29(baseDir, ".augment/rules", relativeFilePath));
|
|
2438
2481
|
const { body: content } = parseFrontmatter(fileContent);
|
|
2439
2482
|
return new _AugmentcodeRule({
|
|
2440
2483
|
baseDir,
|
|
2441
|
-
relativeDirPath,
|
|
2484
|
+
relativeDirPath: ".augment/rules",
|
|
2442
2485
|
relativeFilePath,
|
|
2443
2486
|
fileContent: content.trim(),
|
|
2444
2487
|
validate
|
|
@@ -2450,16 +2493,23 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
2450
2493
|
};
|
|
2451
2494
|
|
|
2452
2495
|
// src/rules/claudecode-rule.ts
|
|
2496
|
+
import { join as join30 } from "path";
|
|
2453
2497
|
var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
2454
|
-
static async
|
|
2455
|
-
|
|
2498
|
+
static async fromFile({
|
|
2499
|
+
baseDir = ".",
|
|
2500
|
+
relativeFilePath,
|
|
2501
|
+
validate = true
|
|
2502
|
+
}) {
|
|
2503
|
+
const isRoot = relativeFilePath === "CLAUDE.md";
|
|
2504
|
+
const relativePath = isRoot ? "CLAUDE.md" : join30(".claude/memories", relativeFilePath);
|
|
2505
|
+
const fileContent = await readFileContent(join30(baseDir, relativePath));
|
|
2456
2506
|
return new _ClaudecodeRule({
|
|
2457
|
-
baseDir
|
|
2458
|
-
relativeDirPath:
|
|
2459
|
-
relativeFilePath:
|
|
2507
|
+
baseDir,
|
|
2508
|
+
relativeDirPath: isRoot ? "." : ".claude/memories",
|
|
2509
|
+
relativeFilePath: isRoot ? "CLAUDE.md" : relativeFilePath,
|
|
2460
2510
|
fileContent,
|
|
2461
|
-
validate
|
|
2462
|
-
root:
|
|
2511
|
+
validate,
|
|
2512
|
+
root: isRoot
|
|
2463
2513
|
});
|
|
2464
2514
|
}
|
|
2465
2515
|
static fromRulesyncRule({
|
|
@@ -2486,6 +2536,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
2486
2536
|
};
|
|
2487
2537
|
|
|
2488
2538
|
// src/rules/cline-rule.ts
|
|
2539
|
+
import { join as join31 } from "path";
|
|
2489
2540
|
import { z as z13 } from "zod/mini";
|
|
2490
2541
|
var ClineRuleFrontmatterSchema = z13.object({
|
|
2491
2542
|
description: z13.string()
|
|
@@ -2511,17 +2562,15 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
2511
2562
|
validate() {
|
|
2512
2563
|
return { success: true, error: null };
|
|
2513
2564
|
}
|
|
2514
|
-
static async
|
|
2565
|
+
static async fromFile({
|
|
2515
2566
|
baseDir = ".",
|
|
2516
|
-
relativeDirPath,
|
|
2517
2567
|
relativeFilePath,
|
|
2518
|
-
filePath,
|
|
2519
2568
|
validate = true
|
|
2520
2569
|
}) {
|
|
2521
|
-
const fileContent = await readFileContent(
|
|
2570
|
+
const fileContent = await readFileContent(join31(baseDir, ".clinerules", relativeFilePath));
|
|
2522
2571
|
return new _ClineRule({
|
|
2523
2572
|
baseDir,
|
|
2524
|
-
relativeDirPath,
|
|
2573
|
+
relativeDirPath: ".clinerules",
|
|
2525
2574
|
relativeFilePath,
|
|
2526
2575
|
fileContent,
|
|
2527
2576
|
validate
|
|
@@ -2530,16 +2579,23 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
2530
2579
|
};
|
|
2531
2580
|
|
|
2532
2581
|
// src/rules/codexcli-rule.ts
|
|
2582
|
+
import { join as join32 } from "path";
|
|
2533
2583
|
var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
2534
|
-
static async
|
|
2535
|
-
|
|
2584
|
+
static async fromFile({
|
|
2585
|
+
baseDir = ".",
|
|
2586
|
+
relativeFilePath,
|
|
2587
|
+
validate = true
|
|
2588
|
+
}) {
|
|
2589
|
+
const isRoot = relativeFilePath === "AGENTS.md";
|
|
2590
|
+
const relativePath = isRoot ? "AGENTS.md" : join32(".codex/memories", relativeFilePath);
|
|
2591
|
+
const fileContent = await readFileContent(join32(baseDir, relativePath));
|
|
2536
2592
|
return new _CodexcliRule({
|
|
2537
|
-
baseDir
|
|
2538
|
-
relativeDirPath:
|
|
2539
|
-
relativeFilePath:
|
|
2593
|
+
baseDir,
|
|
2594
|
+
relativeDirPath: isRoot ? "." : ".codex/memories",
|
|
2595
|
+
relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
|
|
2540
2596
|
fileContent,
|
|
2541
|
-
validate
|
|
2542
|
-
root:
|
|
2597
|
+
validate,
|
|
2598
|
+
root: isRoot
|
|
2543
2599
|
});
|
|
2544
2600
|
}
|
|
2545
2601
|
static fromRulesyncRule({
|
|
@@ -2566,6 +2622,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
2566
2622
|
};
|
|
2567
2623
|
|
|
2568
2624
|
// src/rules/copilot-rule.ts
|
|
2625
|
+
import { join as join33 } from "path";
|
|
2569
2626
|
import { z as z14 } from "zod/mini";
|
|
2570
2627
|
var CopilotRuleFrontmatterSchema = z14.object({
|
|
2571
2628
|
description: z14.optional(z14.string()),
|
|
@@ -2640,45 +2697,43 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
2640
2697
|
root
|
|
2641
2698
|
});
|
|
2642
2699
|
}
|
|
2643
|
-
static async
|
|
2700
|
+
static async fromFile({
|
|
2644
2701
|
baseDir = ".",
|
|
2645
|
-
relativeDirPath,
|
|
2646
2702
|
relativeFilePath,
|
|
2647
|
-
filePath,
|
|
2648
2703
|
validate = true
|
|
2649
2704
|
}) {
|
|
2650
|
-
const
|
|
2651
|
-
const
|
|
2652
|
-
|
|
2705
|
+
const isRoot = relativeFilePath === "copilot-instructions.md";
|
|
2706
|
+
const relativePath = isRoot ? "copilot-instructions.md" : join33(".github/instructions", relativeFilePath);
|
|
2707
|
+
const fileContent = await readFileContent(join33(baseDir, relativePath));
|
|
2708
|
+
if (isRoot) {
|
|
2653
2709
|
return new _CopilotRule({
|
|
2654
2710
|
baseDir,
|
|
2655
|
-
relativeDirPath,
|
|
2656
|
-
relativeFilePath,
|
|
2711
|
+
relativeDirPath: ".github",
|
|
2712
|
+
relativeFilePath: isRoot ? "copilot-instructions.md" : relativeFilePath,
|
|
2657
2713
|
frontmatter: {
|
|
2658
2714
|
description: "",
|
|
2659
2715
|
applyTo: "**"
|
|
2660
2716
|
},
|
|
2661
2717
|
body: fileContent.trim(),
|
|
2662
2718
|
validate,
|
|
2663
|
-
root
|
|
2719
|
+
root: isRoot
|
|
2664
2720
|
});
|
|
2665
2721
|
}
|
|
2666
2722
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
2667
2723
|
const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
|
|
2668
2724
|
if (!result.success) {
|
|
2669
|
-
throw new Error(
|
|
2725
|
+
throw new Error(
|
|
2726
|
+
`Invalid frontmatter in ${join33(baseDir, relativeFilePath)}: ${result.error.message}`
|
|
2727
|
+
);
|
|
2670
2728
|
}
|
|
2671
2729
|
return new _CopilotRule({
|
|
2672
2730
|
baseDir,
|
|
2673
|
-
relativeDirPath,
|
|
2674
|
-
relativeFilePath,
|
|
2675
|
-
frontmatter:
|
|
2676
|
-
...result.data,
|
|
2677
|
-
applyTo: result.data.applyTo || "**"
|
|
2678
|
-
},
|
|
2731
|
+
relativeDirPath: ".github/instructions",
|
|
2732
|
+
relativeFilePath: relativeFilePath.replace(/\.md$/, ".instructions.md"),
|
|
2733
|
+
frontmatter: result.data,
|
|
2679
2734
|
body: content.trim(),
|
|
2680
2735
|
validate,
|
|
2681
|
-
root
|
|
2736
|
+
root: isRoot
|
|
2682
2737
|
});
|
|
2683
2738
|
}
|
|
2684
2739
|
validate() {
|
|
@@ -2701,7 +2756,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
2701
2756
|
};
|
|
2702
2757
|
|
|
2703
2758
|
// src/rules/cursor-rule.ts
|
|
2704
|
-
import { basename as basename8 } from "path";
|
|
2759
|
+
import { basename as basename8, join as join34 } from "path";
|
|
2705
2760
|
import { z as z15 } from "zod/mini";
|
|
2706
2761
|
var CursorRuleFrontmatterSchema = z15.object({
|
|
2707
2762
|
description: z15.optional(z15.string()),
|
|
@@ -2720,11 +2775,49 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
2720
2775
|
}
|
|
2721
2776
|
super({
|
|
2722
2777
|
...rest,
|
|
2723
|
-
fileContent:
|
|
2778
|
+
fileContent: _CursorRule.stringifyCursorFrontmatter(body, frontmatter)
|
|
2724
2779
|
});
|
|
2725
2780
|
this.frontmatter = frontmatter;
|
|
2726
2781
|
this.body = body;
|
|
2727
2782
|
}
|
|
2783
|
+
/**
|
|
2784
|
+
* Custom stringify function for Cursor MDC files
|
|
2785
|
+
* MDC files don't support quotes in YAML, so globs patterns must be output without quotes
|
|
2786
|
+
*/
|
|
2787
|
+
static stringifyCursorFrontmatter(body, frontmatter) {
|
|
2788
|
+
if (!frontmatter.globs || typeof frontmatter.globs !== "string" || !frontmatter.globs.includes("*")) {
|
|
2789
|
+
return stringifyFrontmatter(body, frontmatter);
|
|
2790
|
+
}
|
|
2791
|
+
const lines = ["---"];
|
|
2792
|
+
if (frontmatter.alwaysApply !== void 0) {
|
|
2793
|
+
lines.push(`alwaysApply: ${frontmatter.alwaysApply}`);
|
|
2794
|
+
}
|
|
2795
|
+
if (frontmatter.description !== void 0) {
|
|
2796
|
+
lines.push(`description: ${frontmatter.description}`);
|
|
2797
|
+
}
|
|
2798
|
+
if (frontmatter.globs !== void 0) {
|
|
2799
|
+
lines.push(`globs: ${frontmatter.globs}`);
|
|
2800
|
+
}
|
|
2801
|
+
lines.push("---");
|
|
2802
|
+
lines.push("");
|
|
2803
|
+
if (body) {
|
|
2804
|
+
lines.push(body);
|
|
2805
|
+
}
|
|
2806
|
+
return lines.join("\n");
|
|
2807
|
+
}
|
|
2808
|
+
/**
|
|
2809
|
+
* Custom parse function for Cursor MDC files
|
|
2810
|
+
* MDC files don't support quotes in YAML, so we need to handle patterns like *.ts specially
|
|
2811
|
+
*/
|
|
2812
|
+
static parseCursorFrontmatter(fileContent) {
|
|
2813
|
+
const preprocessedContent = fileContent.replace(
|
|
2814
|
+
/^globs:\s*(\*[^\n]*?)$/m,
|
|
2815
|
+
(_match, globPattern) => {
|
|
2816
|
+
return `globs: "${globPattern}"`;
|
|
2817
|
+
}
|
|
2818
|
+
);
|
|
2819
|
+
return parseFrontmatter(preprocessedContent);
|
|
2820
|
+
}
|
|
2728
2821
|
toRulesyncRule() {
|
|
2729
2822
|
const targets = ["*"];
|
|
2730
2823
|
const isAlways = this.frontmatter.alwaysApply === true;
|
|
@@ -2741,13 +2834,18 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
2741
2834
|
targets,
|
|
2742
2835
|
root: false,
|
|
2743
2836
|
description: this.frontmatter.description,
|
|
2744
|
-
globs
|
|
2837
|
+
globs,
|
|
2838
|
+
cursor: {
|
|
2839
|
+
alwaysApply: this.frontmatter.alwaysApply,
|
|
2840
|
+
description: this.frontmatter.description,
|
|
2841
|
+
globs: globs.length > 0 ? globs : void 0
|
|
2842
|
+
}
|
|
2745
2843
|
};
|
|
2746
2844
|
return new RulesyncRule({
|
|
2747
2845
|
frontmatter: rulesyncFrontmatter,
|
|
2748
2846
|
body: this.body,
|
|
2749
2847
|
relativeDirPath: ".rulesync/rules",
|
|
2750
|
-
relativeFilePath: this.relativeFilePath,
|
|
2848
|
+
relativeFilePath: this.relativeFilePath.replace(/\.mdc$/, ".md"),
|
|
2751
2849
|
validate: true
|
|
2752
2850
|
});
|
|
2753
2851
|
}
|
|
@@ -2775,20 +2873,23 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
2775
2873
|
validate
|
|
2776
2874
|
});
|
|
2777
2875
|
}
|
|
2778
|
-
static async
|
|
2779
|
-
|
|
2876
|
+
static async fromFile({
|
|
2877
|
+
baseDir = ".",
|
|
2878
|
+
relativeFilePath,
|
|
2780
2879
|
validate = true
|
|
2781
2880
|
}) {
|
|
2782
|
-
const fileContent = await readFileContent(
|
|
2783
|
-
const { frontmatter, body: content } =
|
|
2881
|
+
const fileContent = await readFileContent(join34(baseDir, ".cursor/rules", relativeFilePath));
|
|
2882
|
+
const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
|
|
2784
2883
|
const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
|
|
2785
2884
|
if (!result.success) {
|
|
2786
|
-
throw new Error(
|
|
2885
|
+
throw new Error(
|
|
2886
|
+
`Invalid frontmatter in ${join34(baseDir, relativeFilePath)}: ${result.error.message}`
|
|
2887
|
+
);
|
|
2787
2888
|
}
|
|
2788
2889
|
return new _CursorRule({
|
|
2789
|
-
baseDir
|
|
2890
|
+
baseDir,
|
|
2790
2891
|
relativeDirPath: ".cursor/rules",
|
|
2791
|
-
relativeFilePath: basename8(
|
|
2892
|
+
relativeFilePath: basename8(relativeFilePath),
|
|
2792
2893
|
frontmatter: result.data,
|
|
2793
2894
|
body: content.trim(),
|
|
2794
2895
|
validate
|
|
@@ -2814,16 +2915,23 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
2814
2915
|
};
|
|
2815
2916
|
|
|
2816
2917
|
// src/rules/geminicli-rule.ts
|
|
2918
|
+
import { join as join35 } from "path";
|
|
2817
2919
|
var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
2818
|
-
static async
|
|
2819
|
-
|
|
2920
|
+
static async fromFile({
|
|
2921
|
+
baseDir = ".",
|
|
2922
|
+
relativeFilePath,
|
|
2923
|
+
validate = true
|
|
2924
|
+
}) {
|
|
2925
|
+
const isRoot = relativeFilePath === "GEMINI.md";
|
|
2926
|
+
const relativePath = isRoot ? "GEMINI.md" : join35(".gemini/memories", relativeFilePath);
|
|
2927
|
+
const fileContent = await readFileContent(join35(baseDir, relativePath));
|
|
2820
2928
|
return new _GeminiCliRule({
|
|
2821
|
-
baseDir
|
|
2822
|
-
relativeDirPath:
|
|
2823
|
-
relativeFilePath:
|
|
2929
|
+
baseDir,
|
|
2930
|
+
relativeDirPath: isRoot ? "." : ".gemini/memories",
|
|
2931
|
+
relativeFilePath: isRoot ? "GEMINI.md" : relativeFilePath,
|
|
2824
2932
|
fileContent,
|
|
2825
|
-
validate
|
|
2826
|
-
root:
|
|
2933
|
+
validate,
|
|
2934
|
+
root: isRoot
|
|
2827
2935
|
});
|
|
2828
2936
|
}
|
|
2829
2937
|
static fromRulesyncRule({
|
|
@@ -2850,15 +2958,22 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
2850
2958
|
};
|
|
2851
2959
|
|
|
2852
2960
|
// src/rules/junie-rule.ts
|
|
2961
|
+
import { join as join36 } from "path";
|
|
2853
2962
|
var JunieRule = class _JunieRule extends ToolRule {
|
|
2854
|
-
static async
|
|
2855
|
-
|
|
2963
|
+
static async fromFile({
|
|
2964
|
+
baseDir = ".",
|
|
2965
|
+
relativeFilePath,
|
|
2966
|
+
validate = true
|
|
2967
|
+
}) {
|
|
2968
|
+
const isRoot = relativeFilePath === "guidelines.md";
|
|
2969
|
+
const relativePath = isRoot ? "guidelines.md" : join36(".junie/memories", relativeFilePath);
|
|
2970
|
+
const fileContent = await readFileContent(join36(baseDir, relativePath));
|
|
2856
2971
|
return new _JunieRule({
|
|
2857
|
-
baseDir
|
|
2858
|
-
relativeDirPath:
|
|
2859
|
-
relativeFilePath:
|
|
2972
|
+
baseDir,
|
|
2973
|
+
relativeDirPath: isRoot ? ".junie" : ".junie/memories",
|
|
2974
|
+
relativeFilePath: isRoot ? "guidelines.md" : relativeFilePath,
|
|
2860
2975
|
fileContent,
|
|
2861
|
-
validate
|
|
2976
|
+
validate
|
|
2862
2977
|
});
|
|
2863
2978
|
}
|
|
2864
2979
|
static fromRulesyncRule({
|
|
@@ -2871,8 +2986,8 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
2871
2986
|
baseDir,
|
|
2872
2987
|
rulesyncRule,
|
|
2873
2988
|
validate,
|
|
2874
|
-
rootPath: { relativeDirPath: ".", relativeFilePath: "guidelines.md" },
|
|
2875
|
-
nonRootPath: { relativeDirPath: ".junie/
|
|
2989
|
+
rootPath: { relativeDirPath: ".junie", relativeFilePath: "guidelines.md" },
|
|
2990
|
+
nonRootPath: { relativeDirPath: ".junie/memories" }
|
|
2876
2991
|
})
|
|
2877
2992
|
);
|
|
2878
2993
|
}
|
|
@@ -2885,15 +3000,20 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
2885
3000
|
};
|
|
2886
3001
|
|
|
2887
3002
|
// src/rules/kiro-rule.ts
|
|
3003
|
+
import { join as join37 } from "path";
|
|
2888
3004
|
var KiroRule = class _KiroRule extends ToolRule {
|
|
2889
|
-
static async
|
|
2890
|
-
|
|
3005
|
+
static async fromFile({
|
|
3006
|
+
baseDir = ".",
|
|
3007
|
+
relativeFilePath,
|
|
3008
|
+
validate = true
|
|
3009
|
+
}) {
|
|
3010
|
+
const fileContent = await readFileContent(join37(baseDir, ".kiro/steering", relativeFilePath));
|
|
2891
3011
|
return new _KiroRule({
|
|
2892
|
-
baseDir
|
|
2893
|
-
relativeDirPath:
|
|
2894
|
-
relativeFilePath
|
|
3012
|
+
baseDir,
|
|
3013
|
+
relativeDirPath: ".kiro/steering",
|
|
3014
|
+
relativeFilePath,
|
|
2895
3015
|
fileContent,
|
|
2896
|
-
validate
|
|
3016
|
+
validate,
|
|
2897
3017
|
root: false
|
|
2898
3018
|
});
|
|
2899
3019
|
}
|
|
@@ -2920,21 +3040,22 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
2920
3040
|
};
|
|
2921
3041
|
|
|
2922
3042
|
// src/rules/opencode-rule.ts
|
|
3043
|
+
import { join as join38 } from "path";
|
|
2923
3044
|
var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
2924
|
-
static async
|
|
3045
|
+
static async fromFile({
|
|
2925
3046
|
baseDir = ".",
|
|
2926
|
-
relativeDirPath,
|
|
2927
3047
|
relativeFilePath,
|
|
2928
|
-
filePath,
|
|
2929
3048
|
validate = true
|
|
2930
3049
|
}) {
|
|
2931
|
-
const
|
|
3050
|
+
const isRoot = relativeFilePath === "AGENTS.md";
|
|
3051
|
+
const relativePath = isRoot ? "AGENTS.md" : join38(".opencode/memories", relativeFilePath);
|
|
3052
|
+
const fileContent = await readFileContent(join38(baseDir, relativePath));
|
|
2932
3053
|
return new _OpenCodeRule({
|
|
2933
3054
|
baseDir,
|
|
2934
|
-
relativeDirPath,
|
|
2935
|
-
relativeFilePath,
|
|
3055
|
+
relativeDirPath: isRoot ? "." : ".opencode/memories",
|
|
3056
|
+
relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
|
|
2936
3057
|
validate,
|
|
2937
|
-
root:
|
|
3058
|
+
root: isRoot,
|
|
2938
3059
|
fileContent
|
|
2939
3060
|
});
|
|
2940
3061
|
}
|
|
@@ -2960,16 +3081,23 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
2960
3081
|
};
|
|
2961
3082
|
|
|
2962
3083
|
// src/rules/qwencode-rule.ts
|
|
3084
|
+
import { join as join39 } from "path";
|
|
2963
3085
|
var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
2964
|
-
static async
|
|
2965
|
-
|
|
3086
|
+
static async fromFile({
|
|
3087
|
+
baseDir = ".",
|
|
3088
|
+
relativeFilePath,
|
|
3089
|
+
validate = true
|
|
3090
|
+
}) {
|
|
3091
|
+
const isRoot = relativeFilePath === "QWEN.md";
|
|
3092
|
+
const relativePath = isRoot ? "QWEN.md" : join39(".qwencode/memories", relativeFilePath);
|
|
3093
|
+
const fileContent = await readFileContent(join39(baseDir, relativePath));
|
|
2966
3094
|
return new _QwencodeRule({
|
|
2967
|
-
baseDir
|
|
2968
|
-
relativeDirPath:
|
|
2969
|
-
relativeFilePath:
|
|
3095
|
+
baseDir,
|
|
3096
|
+
relativeDirPath: isRoot ? "." : ".qwencode/memories",
|
|
3097
|
+
relativeFilePath: isRoot ? "QWEN.md" : relativeFilePath,
|
|
2970
3098
|
fileContent,
|
|
2971
|
-
validate
|
|
2972
|
-
root:
|
|
3099
|
+
validate,
|
|
3100
|
+
root: isRoot
|
|
2973
3101
|
});
|
|
2974
3102
|
}
|
|
2975
3103
|
static fromRulesyncRule(params) {
|
|
@@ -2990,15 +3118,21 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
2990
3118
|
};
|
|
2991
3119
|
|
|
2992
3120
|
// src/rules/roo-rule.ts
|
|
3121
|
+
import { join as join40 } from "path";
|
|
2993
3122
|
var RooRule = class _RooRule extends ToolRule {
|
|
2994
|
-
static async
|
|
2995
|
-
|
|
3123
|
+
static async fromFile({
|
|
3124
|
+
baseDir = ".",
|
|
3125
|
+
relativeFilePath,
|
|
3126
|
+
validate = true
|
|
3127
|
+
}) {
|
|
3128
|
+
const fileContent = await readFileContent(join40(baseDir, ".roo/rules", relativeFilePath));
|
|
2996
3129
|
return new _RooRule({
|
|
2997
|
-
baseDir
|
|
2998
|
-
relativeDirPath:
|
|
2999
|
-
relativeFilePath
|
|
3130
|
+
baseDir,
|
|
3131
|
+
relativeDirPath: ".roo/rules",
|
|
3132
|
+
relativeFilePath,
|
|
3000
3133
|
fileContent,
|
|
3001
|
-
validate
|
|
3134
|
+
validate,
|
|
3135
|
+
root: false
|
|
3002
3136
|
});
|
|
3003
3137
|
}
|
|
3004
3138
|
static fromRulesyncRule({
|
|
@@ -3039,6 +3173,7 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
3039
3173
|
};
|
|
3040
3174
|
|
|
3041
3175
|
// src/rules/warp-rule.ts
|
|
3176
|
+
import { join as join41 } from "path";
|
|
3042
3177
|
var WarpRule = class _WarpRule extends ToolRule {
|
|
3043
3178
|
constructor({ fileContent, root, ...rest }) {
|
|
3044
3179
|
super({
|
|
@@ -3047,14 +3182,14 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
3047
3182
|
root: root ?? false
|
|
3048
3183
|
});
|
|
3049
3184
|
}
|
|
3050
|
-
static async
|
|
3185
|
+
static async fromFile({
|
|
3051
3186
|
baseDir = ".",
|
|
3052
3187
|
relativeFilePath,
|
|
3053
|
-
filePath,
|
|
3054
3188
|
validate = true
|
|
3055
3189
|
}) {
|
|
3056
|
-
const fileContent = await readFileContent(filePath);
|
|
3057
3190
|
const isRoot = relativeFilePath === "WARP.md";
|
|
3191
|
+
const relativePath = isRoot ? "WARP.md" : join41(".warp/memories", relativeFilePath);
|
|
3192
|
+
const fileContent = await readFileContent(join41(baseDir, relativePath));
|
|
3058
3193
|
return new _WarpRule({
|
|
3059
3194
|
baseDir,
|
|
3060
3195
|
relativeDirPath: isRoot ? "." : ".warp",
|
|
@@ -3088,14 +3223,20 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
3088
3223
|
};
|
|
3089
3224
|
|
|
3090
3225
|
// src/rules/windsurf-rule.ts
|
|
3226
|
+
import { join as join42 } from "path";
|
|
3091
3227
|
var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
3092
|
-
static async
|
|
3093
|
-
|
|
3228
|
+
static async fromFile({
|
|
3229
|
+
baseDir = ".",
|
|
3230
|
+
relativeFilePath,
|
|
3231
|
+
validate = true
|
|
3232
|
+
}) {
|
|
3233
|
+
const fileContent = await readFileContent(join42(baseDir, ".windsurf/rules", relativeFilePath));
|
|
3094
3234
|
return new _WindsurfRule({
|
|
3095
|
-
baseDir
|
|
3096
|
-
relativeDirPath:
|
|
3097
|
-
relativeFilePath
|
|
3098
|
-
fileContent
|
|
3235
|
+
baseDir,
|
|
3236
|
+
relativeDirPath: ".windsurf/rules",
|
|
3237
|
+
relativeFilePath,
|
|
3238
|
+
fileContent,
|
|
3239
|
+
validate
|
|
3099
3240
|
});
|
|
3100
3241
|
}
|
|
3101
3242
|
static fromRulesyncRule({
|
|
@@ -3353,57 +3494,18 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3353
3494
|
* Load and parse rulesync rule files from .rulesync/rules/ directory
|
|
3354
3495
|
*/
|
|
3355
3496
|
async loadRulesyncFiles() {
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
return [];
|
|
3362
|
-
}
|
|
3363
|
-
const entries = await listDirectoryFiles(rulesDir);
|
|
3364
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3365
|
-
if (mdFiles.length === 0) {
|
|
3366
|
-
logger.debug(`No markdown files found in rulesync rules directory: ${rulesDir}`);
|
|
3367
|
-
return [];
|
|
3368
|
-
}
|
|
3369
|
-
logger.info(`Found ${mdFiles.length} rule files in ${rulesDir}`);
|
|
3370
|
-
const rulesyncRules = [];
|
|
3371
|
-
for (const mdFile of mdFiles) {
|
|
3372
|
-
const filepath = join7(rulesDir, mdFile);
|
|
3373
|
-
try {
|
|
3374
|
-
const rulesyncRule = await RulesyncRule.fromFilePath({
|
|
3375
|
-
filePath: filepath
|
|
3376
|
-
});
|
|
3377
|
-
rulesyncRules.push(rulesyncRule);
|
|
3378
|
-
logger.debug(`Successfully loaded rule: ${mdFile}`);
|
|
3379
|
-
} catch (error) {
|
|
3380
|
-
logger.warn(`Failed to load rule file ${filepath}:`, error);
|
|
3381
|
-
continue;
|
|
3382
|
-
}
|
|
3383
|
-
}
|
|
3384
|
-
if (rulesyncRules.length === 0) {
|
|
3385
|
-
logger.debug(`No valid rules found in ${rulesDir}`);
|
|
3386
|
-
return [];
|
|
3387
|
-
}
|
|
3388
|
-
logger.info(`Successfully loaded ${rulesyncRules.length} rulesync rules`);
|
|
3389
|
-
return rulesyncRules;
|
|
3390
|
-
} catch (error) {
|
|
3391
|
-
logger.debug(`No rulesync files found`, error);
|
|
3392
|
-
return [];
|
|
3393
|
-
}
|
|
3497
|
+
const files = await findFilesByGlobs(join43(RULESYNC_RULES_DIR, "*.md"));
|
|
3498
|
+
logger.debug(`Found ${files.length} rulesync files`);
|
|
3499
|
+
return Promise.all(
|
|
3500
|
+
files.map((file) => RulesyncRule.fromFile({ relativeFilePath: basename9(file) }))
|
|
3501
|
+
);
|
|
3394
3502
|
}
|
|
3395
|
-
async
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
)
|
|
3402
|
-
);
|
|
3403
|
-
} catch (error) {
|
|
3404
|
-
logger.debug(`No legacy rulesync files found`, error);
|
|
3405
|
-
return [];
|
|
3406
|
-
}
|
|
3503
|
+
async loadRulesyncFilesLegacy() {
|
|
3504
|
+
const legacyFiles = await findFilesByGlobs(join43(RULESYNC_RULES_DIR_LEGACY, "*.md"));
|
|
3505
|
+
logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
|
|
3506
|
+
return Promise.all(
|
|
3507
|
+
legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: basename9(file) }))
|
|
3508
|
+
);
|
|
3407
3509
|
}
|
|
3408
3510
|
/**
|
|
3409
3511
|
* Implementation of abstract method from FeatureProcessor
|
|
@@ -3454,527 +3556,296 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3454
3556
|
return [];
|
|
3455
3557
|
}
|
|
3456
3558
|
}
|
|
3559
|
+
async loadToolRulesDefault({
|
|
3560
|
+
root,
|
|
3561
|
+
nonRoot
|
|
3562
|
+
}) {
|
|
3563
|
+
const rootToolRules = await (async () => {
|
|
3564
|
+
if (!root) {
|
|
3565
|
+
return [];
|
|
3566
|
+
}
|
|
3567
|
+
const rootFilePaths = await findFilesByGlobs(
|
|
3568
|
+
join43(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
|
|
3569
|
+
);
|
|
3570
|
+
return await Promise.all(
|
|
3571
|
+
rootFilePaths.map(
|
|
3572
|
+
(filePath) => root.fromFile({
|
|
3573
|
+
baseDir: this.baseDir,
|
|
3574
|
+
relativeFilePath: basename9(filePath)
|
|
3575
|
+
})
|
|
3576
|
+
)
|
|
3577
|
+
);
|
|
3578
|
+
})();
|
|
3579
|
+
logger.debug(`Found ${rootToolRules.length} root tool rule files`);
|
|
3580
|
+
const nonRootToolRules = await (async () => {
|
|
3581
|
+
if (!nonRoot) {
|
|
3582
|
+
return [];
|
|
3583
|
+
}
|
|
3584
|
+
const nonRootFilePaths = await findFilesByGlobs(
|
|
3585
|
+
join43(this.baseDir, nonRoot.relativeFilePath, `*.${nonRoot.extension}`)
|
|
3586
|
+
);
|
|
3587
|
+
return await Promise.all(
|
|
3588
|
+
nonRootFilePaths.map(
|
|
3589
|
+
(filePath) => nonRoot.fromFile({
|
|
3590
|
+
baseDir: this.baseDir,
|
|
3591
|
+
relativeFilePath: basename9(filePath)
|
|
3592
|
+
})
|
|
3593
|
+
)
|
|
3594
|
+
);
|
|
3595
|
+
})();
|
|
3596
|
+
logger.debug(`Found ${nonRootToolRules.length} non-root tool rule files`);
|
|
3597
|
+
return [...rootToolRules, ...nonRootToolRules];
|
|
3598
|
+
}
|
|
3457
3599
|
/**
|
|
3458
3600
|
* Load AGENTS.md rule configuration
|
|
3459
3601
|
*/
|
|
3460
3602
|
async loadAgentsmdRules() {
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
logger.warn(`AGENTS.md file not found: ${agentsFile}`);
|
|
3464
|
-
return [];
|
|
3465
|
-
}
|
|
3466
|
-
try {
|
|
3467
|
-
const agentsmdRule = await AgentsMdRule.fromFilePath({
|
|
3468
|
-
baseDir: this.baseDir,
|
|
3603
|
+
return await this.loadToolRulesDefault({
|
|
3604
|
+
root: {
|
|
3469
3605
|
relativeDirPath: ".",
|
|
3470
3606
|
relativeFilePath: "AGENTS.md",
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
}
|
|
3607
|
+
fromFile: (params) => AgentsMdRule.fromFile(params)
|
|
3608
|
+
},
|
|
3609
|
+
nonRoot: {
|
|
3610
|
+
relativeFilePath: ".agents/memories",
|
|
3611
|
+
fromFile: (params) => AgentsMdRule.fromFile(params),
|
|
3612
|
+
extension: "md"
|
|
3613
|
+
}
|
|
3614
|
+
});
|
|
3480
3615
|
}
|
|
3481
3616
|
async loadWarpRules() {
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
(
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
);
|
|
3494
|
-
const nonRootFiles = await Promise.all(
|
|
3495
|
-
nonRootFilePaths.map(
|
|
3496
|
-
(filePath) => WarpRule.fromFilePath({
|
|
3497
|
-
filePath,
|
|
3498
|
-
validate: true,
|
|
3499
|
-
relativeDirPath: ".warp/memories",
|
|
3500
|
-
relativeFilePath: basename9(filePath)
|
|
3501
|
-
})
|
|
3502
|
-
)
|
|
3503
|
-
);
|
|
3504
|
-
return [...rootFiles, ...nonRootFiles];
|
|
3617
|
+
return await this.loadToolRulesDefault({
|
|
3618
|
+
root: {
|
|
3619
|
+
relativeDirPath: ".",
|
|
3620
|
+
relativeFilePath: "WARP.md",
|
|
3621
|
+
fromFile: (params) => WarpRule.fromFile(params)
|
|
3622
|
+
},
|
|
3623
|
+
nonRoot: {
|
|
3624
|
+
relativeFilePath: ".warp/memories",
|
|
3625
|
+
fromFile: (params) => WarpRule.fromFile(params),
|
|
3626
|
+
extension: "md"
|
|
3627
|
+
}
|
|
3628
|
+
});
|
|
3505
3629
|
}
|
|
3506
3630
|
/**
|
|
3507
3631
|
* Load Amazon Q Developer CLI rule configurations from .amazonq/rules/ directory
|
|
3508
3632
|
*/
|
|
3509
3633
|
async loadAmazonqcliRules() {
|
|
3510
|
-
return this.
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
validate: true
|
|
3518
|
-
}),
|
|
3519
|
-
"Amazon Q Developer CLI"
|
|
3520
|
-
);
|
|
3634
|
+
return await this.loadToolRulesDefault({
|
|
3635
|
+
nonRoot: {
|
|
3636
|
+
relativeFilePath: ".amazonq/rules",
|
|
3637
|
+
fromFile: (params) => AmazonQCliRule.fromFile(params),
|
|
3638
|
+
extension: "md"
|
|
3639
|
+
}
|
|
3640
|
+
});
|
|
3521
3641
|
}
|
|
3522
3642
|
/**
|
|
3523
3643
|
* Load AugmentCode rule configurations from .augment/rules/ directory
|
|
3524
3644
|
*/
|
|
3525
3645
|
async loadAugmentcodeRules() {
|
|
3526
|
-
return this.
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
validate: true
|
|
3534
|
-
}),
|
|
3535
|
-
"AugmentCode"
|
|
3536
|
-
);
|
|
3646
|
+
return await this.loadToolRulesDefault({
|
|
3647
|
+
nonRoot: {
|
|
3648
|
+
relativeFilePath: ".augment/rules",
|
|
3649
|
+
fromFile: (params) => AugmentcodeRule.fromFile(params),
|
|
3650
|
+
extension: "md"
|
|
3651
|
+
}
|
|
3652
|
+
});
|
|
3537
3653
|
}
|
|
3538
3654
|
/**
|
|
3539
3655
|
* Load AugmentCode legacy rule configuration from .augment-guidelines file and .augment/rules/ directory
|
|
3540
3656
|
*/
|
|
3541
3657
|
async loadAugmentcodeLegacyRules() {
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
});
|
|
3553
|
-
toolRules.push(augmentcodeLegacyRule);
|
|
3554
|
-
logger.info(`Successfully loaded AugmentCode legacy guidelines`);
|
|
3555
|
-
} catch (error) {
|
|
3556
|
-
logger.warn(`Failed to load AugmentCode legacy guidelines file ${guidelinesFile}:`, error);
|
|
3658
|
+
return await this.loadToolRulesDefault({
|
|
3659
|
+
root: {
|
|
3660
|
+
relativeDirPath: ".",
|
|
3661
|
+
relativeFilePath: ".augment-guidelines",
|
|
3662
|
+
fromFile: (params) => AugmentcodeLegacyRule.fromFile(params)
|
|
3663
|
+
},
|
|
3664
|
+
nonRoot: {
|
|
3665
|
+
relativeFilePath: ".augment/rules",
|
|
3666
|
+
fromFile: (params) => AugmentcodeLegacyRule.fromFile(params),
|
|
3667
|
+
extension: "md"
|
|
3557
3668
|
}
|
|
3558
|
-
}
|
|
3559
|
-
const rulesDir = join7(this.baseDir, ".augment", "rules");
|
|
3560
|
-
if (await directoryExists(rulesDir)) {
|
|
3561
|
-
const dirRules = await this.loadToolRulesFromDirectory(
|
|
3562
|
-
rulesDir,
|
|
3563
|
-
(filePath, relativeFilePath) => AugmentcodeLegacyRule.fromFilePath({
|
|
3564
|
-
baseDir: this.baseDir,
|
|
3565
|
-
relativeDirPath: join7(".augment", "rules"),
|
|
3566
|
-
relativeFilePath,
|
|
3567
|
-
filePath,
|
|
3568
|
-
validate: true
|
|
3569
|
-
}),
|
|
3570
|
-
"AugmentCode Legacy"
|
|
3571
|
-
);
|
|
3572
|
-
toolRules.push(...dirRules);
|
|
3573
|
-
}
|
|
3574
|
-
return toolRules;
|
|
3669
|
+
});
|
|
3575
3670
|
}
|
|
3576
3671
|
/**
|
|
3577
3672
|
* Load Claude Code rule configuration from CLAUDE.md file
|
|
3578
3673
|
*/
|
|
3579
3674
|
async loadClaudecodeRules() {
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
baseDir: this.baseDir,
|
|
3591
|
-
relativeDirPath: ".",
|
|
3592
|
-
relativeFilePath: "CLAUDE.md",
|
|
3593
|
-
filePath: claudeFile,
|
|
3594
|
-
validate: true
|
|
3595
|
-
});
|
|
3596
|
-
logger.info(`Successfully loaded Claude Code memory file`);
|
|
3597
|
-
return [claudecodeRule];
|
|
3598
|
-
} catch (error) {
|
|
3599
|
-
logger.warn(`Failed to load Claude Code memory file ${claudeFile}:`, error);
|
|
3600
|
-
return [];
|
|
3601
|
-
}
|
|
3602
|
-
}
|
|
3603
|
-
const entries = await listDirectoryFiles(claudeMemoriesDir);
|
|
3604
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3605
|
-
if (mdFiles.length === 0) {
|
|
3606
|
-
logger.debug(
|
|
3607
|
-
`No markdown files found in Claude Code memories directory: ${claudeMemoriesDir}`
|
|
3608
|
-
);
|
|
3609
|
-
return [];
|
|
3610
|
-
}
|
|
3611
|
-
logger.info(`Found ${mdFiles.length} Claude Code memory files in ${claudeMemoriesDir}`);
|
|
3612
|
-
const toolRules = [];
|
|
3613
|
-
for (const mdFile of mdFiles) {
|
|
3614
|
-
const filePath = join7(claudeMemoriesDir, mdFile);
|
|
3615
|
-
try {
|
|
3616
|
-
const claudecodeRule = await ClaudecodeRule.fromFilePath({
|
|
3617
|
-
baseDir: this.baseDir,
|
|
3618
|
-
relativeDirPath: join7(".claude", "memories"),
|
|
3619
|
-
relativeFilePath: mdFile,
|
|
3620
|
-
filePath,
|
|
3621
|
-
validate: true
|
|
3622
|
-
});
|
|
3623
|
-
toolRules.push(claudecodeRule);
|
|
3624
|
-
logger.debug(`Successfully loaded Claude Code memory file: ${mdFile}`);
|
|
3625
|
-
} catch (error) {
|
|
3626
|
-
logger.warn(`Failed to load Claude Code memory file ${filePath}:`, error);
|
|
3627
|
-
continue;
|
|
3675
|
+
return await this.loadToolRulesDefault({
|
|
3676
|
+
root: {
|
|
3677
|
+
relativeDirPath: ".",
|
|
3678
|
+
relativeFilePath: "CLAUDE.md",
|
|
3679
|
+
fromFile: (params) => ClaudecodeRule.fromFile(params)
|
|
3680
|
+
},
|
|
3681
|
+
nonRoot: {
|
|
3682
|
+
relativeFilePath: ".claude/memories",
|
|
3683
|
+
fromFile: (params) => ClaudecodeRule.fromFile(params),
|
|
3684
|
+
extension: "md"
|
|
3628
3685
|
}
|
|
3629
|
-
}
|
|
3630
|
-
logger.info(`Successfully loaded ${toolRules.length} Claude Code memory files`);
|
|
3631
|
-
return toolRules;
|
|
3686
|
+
});
|
|
3632
3687
|
}
|
|
3633
3688
|
/**
|
|
3634
3689
|
* Load Cline rule configurations from .clinerules/ directory
|
|
3635
3690
|
*/
|
|
3636
3691
|
async loadClineRules() {
|
|
3637
|
-
return this.
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
validate: true
|
|
3645
|
-
}),
|
|
3646
|
-
"Cline"
|
|
3647
|
-
);
|
|
3692
|
+
return await this.loadToolRulesDefault({
|
|
3693
|
+
nonRoot: {
|
|
3694
|
+
relativeFilePath: ".clinerules",
|
|
3695
|
+
fromFile: (params) => ClineRule.fromFile(params),
|
|
3696
|
+
extension: "md"
|
|
3697
|
+
}
|
|
3698
|
+
});
|
|
3648
3699
|
}
|
|
3649
3700
|
/**
|
|
3650
3701
|
* Load OpenAI Codex CLI rule configuration from AGENTS.md and .codex/memories/*.md files
|
|
3651
3702
|
*/
|
|
3652
3703
|
async loadCodexcliRules() {
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
});
|
|
3664
|
-
rules.push(codexcliRule);
|
|
3665
|
-
logger.info(`Successfully loaded OpenAI Codex CLI agents file`);
|
|
3666
|
-
} catch (error) {
|
|
3667
|
-
logger.warn(`Failed to load OpenAI Codex CLI agents file ${agentsFile}:`, error);
|
|
3668
|
-
}
|
|
3669
|
-
}
|
|
3670
|
-
const memoriesDir = join7(this.baseDir, ".codex", "memories");
|
|
3671
|
-
if (await directoryExists(memoriesDir)) {
|
|
3672
|
-
try {
|
|
3673
|
-
const entries = await listDirectoryFiles(memoriesDir);
|
|
3674
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3675
|
-
for (const mdFile of mdFiles) {
|
|
3676
|
-
const filePath = join7(memoriesDir, mdFile);
|
|
3677
|
-
try {
|
|
3678
|
-
const codexcliRule = await CodexcliRule.fromFilePath({
|
|
3679
|
-
baseDir: this.baseDir,
|
|
3680
|
-
relativeDirPath: join7(".codex", "memories"),
|
|
3681
|
-
relativeFilePath: mdFile,
|
|
3682
|
-
filePath,
|
|
3683
|
-
validate: true
|
|
3684
|
-
});
|
|
3685
|
-
rules.push(codexcliRule);
|
|
3686
|
-
} catch (error) {
|
|
3687
|
-
logger.warn(`Failed to load Codex CLI memories file ${filePath}:`, error);
|
|
3688
|
-
}
|
|
3689
|
-
}
|
|
3690
|
-
if (mdFiles.length > 0) {
|
|
3691
|
-
logger.info(`Successfully loaded ${mdFiles.length} OpenAI Codex CLI memory files`);
|
|
3692
|
-
}
|
|
3693
|
-
} catch (error) {
|
|
3694
|
-
logger.warn(`Failed to read OpenAI Codex CLI memories directory ${memoriesDir}:`, error);
|
|
3704
|
+
return await this.loadToolRulesDefault({
|
|
3705
|
+
root: {
|
|
3706
|
+
relativeDirPath: ".",
|
|
3707
|
+
relativeFilePath: "AGENTS.md",
|
|
3708
|
+
fromFile: (params) => CodexcliRule.fromFile(params)
|
|
3709
|
+
},
|
|
3710
|
+
nonRoot: {
|
|
3711
|
+
relativeFilePath: ".codex/memories",
|
|
3712
|
+
fromFile: (params) => CodexcliRule.fromFile(params),
|
|
3713
|
+
extension: "md"
|
|
3695
3714
|
}
|
|
3696
|
-
}
|
|
3697
|
-
if (rules.length === 0) {
|
|
3698
|
-
logger.warn(`No OpenAI Codex CLI rule files found`);
|
|
3699
|
-
}
|
|
3700
|
-
return rules;
|
|
3715
|
+
});
|
|
3701
3716
|
}
|
|
3702
3717
|
/**
|
|
3703
3718
|
* Load GitHub Copilot rule configuration from .github/copilot-instructions.md file
|
|
3704
3719
|
*/
|
|
3705
3720
|
async loadCopilotRules() {
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
});
|
|
3719
|
-
logger.info(`Successfully loaded GitHub Copilot instructions file`);
|
|
3720
|
-
return [copilotRule];
|
|
3721
|
-
} catch (error) {
|
|
3722
|
-
logger.warn(`Failed to load GitHub Copilot instructions file ${copilotFile}:`, error);
|
|
3723
|
-
return [];
|
|
3724
|
-
}
|
|
3721
|
+
return await this.loadToolRulesDefault({
|
|
3722
|
+
root: {
|
|
3723
|
+
relativeDirPath: ".",
|
|
3724
|
+
relativeFilePath: ".github/copilot-instructions.md",
|
|
3725
|
+
fromFile: (params) => CopilotRule.fromFile(params)
|
|
3726
|
+
},
|
|
3727
|
+
nonRoot: {
|
|
3728
|
+
relativeFilePath: ".github/instructions",
|
|
3729
|
+
fromFile: (params) => CopilotRule.fromFile(params),
|
|
3730
|
+
extension: "md"
|
|
3731
|
+
}
|
|
3732
|
+
});
|
|
3725
3733
|
}
|
|
3726
3734
|
/**
|
|
3727
3735
|
* Load Cursor rule configurations from .cursor/rules/ directory
|
|
3728
3736
|
*/
|
|
3729
3737
|
async loadCursorRules() {
|
|
3730
|
-
return this.
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
}
|
|
3736
|
-
|
|
3737
|
-
);
|
|
3738
|
+
return await this.loadToolRulesDefault({
|
|
3739
|
+
nonRoot: {
|
|
3740
|
+
relativeFilePath: ".cursor/rules",
|
|
3741
|
+
fromFile: (params) => CursorRule.fromFile(params),
|
|
3742
|
+
extension: "md"
|
|
3743
|
+
}
|
|
3744
|
+
});
|
|
3738
3745
|
}
|
|
3739
3746
|
/**
|
|
3740
3747
|
* Load Gemini CLI rule configuration from GEMINI.md file
|
|
3741
3748
|
*/
|
|
3742
3749
|
async loadGeminicliRules() {
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
logger.warn(`Gemini CLI memory file not found: ${geminiFile}`);
|
|
3746
|
-
return [];
|
|
3747
|
-
}
|
|
3748
|
-
try {
|
|
3749
|
-
const geminicliRule = await GeminiCliRule.fromFilePath({
|
|
3750
|
-
baseDir: this.baseDir,
|
|
3750
|
+
return await this.loadToolRulesDefault({
|
|
3751
|
+
root: {
|
|
3751
3752
|
relativeDirPath: ".",
|
|
3752
3753
|
relativeFilePath: "GEMINI.md",
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
}
|
|
3754
|
+
fromFile: (params) => GeminiCliRule.fromFile(params)
|
|
3755
|
+
},
|
|
3756
|
+
nonRoot: {
|
|
3757
|
+
relativeFilePath: ".gemini/memories",
|
|
3758
|
+
fromFile: (params) => GeminiCliRule.fromFile(params),
|
|
3759
|
+
extension: "md"
|
|
3760
|
+
}
|
|
3761
|
+
});
|
|
3762
3762
|
}
|
|
3763
3763
|
/**
|
|
3764
3764
|
* Load JetBrains Junie rule configuration from .junie/guidelines.md file
|
|
3765
3765
|
*/
|
|
3766
3766
|
async loadJunieRules() {
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3767
|
+
return await this.loadToolRulesDefault({
|
|
3768
|
+
root: {
|
|
3769
|
+
relativeDirPath: ".",
|
|
3770
|
+
relativeFilePath: ".junie/guidelines.md",
|
|
3771
|
+
fromFile: (params) => JunieRule.fromFile(params)
|
|
3772
|
+
},
|
|
3773
|
+
nonRoot: {
|
|
3774
|
+
relativeFilePath: ".junie/memories",
|
|
3775
|
+
fromFile: (params) => JunieRule.fromFile(params),
|
|
3776
|
+
extension: "md"
|
|
3777
|
+
}
|
|
3777
3778
|
});
|
|
3778
|
-
logger.info(`Successfully loaded JetBrains Junie guidelines file`);
|
|
3779
|
-
return [junieRule];
|
|
3780
3779
|
}
|
|
3781
3780
|
/**
|
|
3782
3781
|
* Load Kiro rule configurations from .kiro/steering/ directory
|
|
3783
3782
|
*/
|
|
3784
3783
|
async loadKiroRules() {
|
|
3785
|
-
return this.
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
validate: true
|
|
3793
|
-
}),
|
|
3794
|
-
"Kiro"
|
|
3795
|
-
);
|
|
3784
|
+
return await this.loadToolRulesDefault({
|
|
3785
|
+
nonRoot: {
|
|
3786
|
+
relativeFilePath: ".kiro/steering",
|
|
3787
|
+
fromFile: (params) => KiroRule.fromFile(params),
|
|
3788
|
+
extension: "md"
|
|
3789
|
+
}
|
|
3790
|
+
});
|
|
3796
3791
|
}
|
|
3797
3792
|
/**
|
|
3798
3793
|
* Load OpenCode rule configuration from AGENTS.md file and .opencode/memories/*.md files
|
|
3799
3794
|
*/
|
|
3800
3795
|
async loadOpencodeRules() {
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
});
|
|
3812
|
-
rules.push(opencodeRule);
|
|
3813
|
-
logger.info(`Successfully loaded OpenCode agents file`);
|
|
3814
|
-
} catch (error) {
|
|
3815
|
-
logger.warn(`Failed to load OpenCode agents file ${agentsFile}:`, error);
|
|
3816
|
-
}
|
|
3817
|
-
}
|
|
3818
|
-
const memoriesDir = join7(this.baseDir, ".opencode", "memories");
|
|
3819
|
-
if (await directoryExists(memoriesDir)) {
|
|
3820
|
-
try {
|
|
3821
|
-
const entries = await listDirectoryFiles(memoriesDir);
|
|
3822
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3823
|
-
for (const mdFile of mdFiles) {
|
|
3824
|
-
const filePath = join7(memoriesDir, mdFile);
|
|
3825
|
-
try {
|
|
3826
|
-
const opencodeRule = await OpenCodeRule.fromFilePath({
|
|
3827
|
-
baseDir: this.baseDir,
|
|
3828
|
-
relativeDirPath: join7(".opencode", "memories"),
|
|
3829
|
-
relativeFilePath: mdFile,
|
|
3830
|
-
filePath,
|
|
3831
|
-
validate: true
|
|
3832
|
-
});
|
|
3833
|
-
rules.push(opencodeRule);
|
|
3834
|
-
} catch (error) {
|
|
3835
|
-
logger.warn(`Failed to load OpenCode memories file ${filePath}:`, error);
|
|
3836
|
-
}
|
|
3837
|
-
}
|
|
3838
|
-
if (mdFiles.length > 0) {
|
|
3839
|
-
logger.info(`Successfully loaded ${mdFiles.length} OpenCode memory files`);
|
|
3840
|
-
}
|
|
3841
|
-
} catch (error) {
|
|
3842
|
-
logger.warn(`Failed to read OpenCode memories directory ${memoriesDir}:`, error);
|
|
3796
|
+
return await this.loadToolRulesDefault({
|
|
3797
|
+
root: {
|
|
3798
|
+
relativeDirPath: ".",
|
|
3799
|
+
relativeFilePath: "AGENTS.md",
|
|
3800
|
+
fromFile: (params) => OpenCodeRule.fromFile(params)
|
|
3801
|
+
},
|
|
3802
|
+
nonRoot: {
|
|
3803
|
+
relativeFilePath: ".opencode/memories",
|
|
3804
|
+
fromFile: (params) => OpenCodeRule.fromFile(params),
|
|
3805
|
+
extension: "md"
|
|
3843
3806
|
}
|
|
3844
|
-
}
|
|
3845
|
-
if (rules.length === 0) {
|
|
3846
|
-
logger.warn(`No OpenCode rule files found`);
|
|
3847
|
-
}
|
|
3848
|
-
return rules;
|
|
3807
|
+
});
|
|
3849
3808
|
}
|
|
3850
3809
|
/**
|
|
3851
3810
|
* Load Qwen Code rule configuration from QWEN.md file and .qwen/memories/*.md files
|
|
3852
3811
|
*/
|
|
3853
3812
|
async loadQwencodeRules() {
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
});
|
|
3865
|
-
rules.push(qwencodeRule);
|
|
3866
|
-
logger.info(`Successfully loaded Qwen Code memory file`);
|
|
3867
|
-
} catch (error) {
|
|
3868
|
-
logger.warn(`Failed to load Qwen Code memory file ${qwenFile}:`, error);
|
|
3869
|
-
}
|
|
3870
|
-
}
|
|
3871
|
-
const memoriesDir = join7(this.baseDir, ".qwen", "memories");
|
|
3872
|
-
if (await directoryExists(memoriesDir)) {
|
|
3873
|
-
try {
|
|
3874
|
-
const entries = await listDirectoryFiles(memoriesDir);
|
|
3875
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3876
|
-
for (const mdFile of mdFiles) {
|
|
3877
|
-
const filePath = join7(memoriesDir, mdFile);
|
|
3878
|
-
try {
|
|
3879
|
-
const qwencodeRule = await QwencodeRule.fromFilePath({
|
|
3880
|
-
baseDir: this.baseDir,
|
|
3881
|
-
relativeDirPath: join7(".qwen", "memories"),
|
|
3882
|
-
relativeFilePath: mdFile,
|
|
3883
|
-
filePath,
|
|
3884
|
-
validate: true
|
|
3885
|
-
});
|
|
3886
|
-
rules.push(qwencodeRule);
|
|
3887
|
-
} catch (error) {
|
|
3888
|
-
logger.warn(`Failed to load Qwen Code memories file ${filePath}:`, error);
|
|
3889
|
-
}
|
|
3890
|
-
}
|
|
3891
|
-
if (mdFiles.length > 0) {
|
|
3892
|
-
logger.info(`Successfully loaded ${mdFiles.length} Qwen Code memory files`);
|
|
3893
|
-
}
|
|
3894
|
-
} catch (error) {
|
|
3895
|
-
logger.warn(`Failed to read Qwen Code memories directory ${memoriesDir}:`, error);
|
|
3813
|
+
return await this.loadToolRulesDefault({
|
|
3814
|
+
root: {
|
|
3815
|
+
relativeDirPath: ".",
|
|
3816
|
+
relativeFilePath: "QWEN.md",
|
|
3817
|
+
fromFile: (params) => QwencodeRule.fromFile(params)
|
|
3818
|
+
},
|
|
3819
|
+
nonRoot: {
|
|
3820
|
+
relativeFilePath: ".qwen/memories",
|
|
3821
|
+
fromFile: (params) => QwencodeRule.fromFile(params),
|
|
3822
|
+
extension: "md"
|
|
3896
3823
|
}
|
|
3897
|
-
}
|
|
3898
|
-
if (rules.length === 0) {
|
|
3899
|
-
logger.warn(`No Qwen Code rule files found`);
|
|
3900
|
-
}
|
|
3901
|
-
return rules;
|
|
3824
|
+
});
|
|
3902
3825
|
}
|
|
3903
3826
|
/**
|
|
3904
3827
|
* Load Roo Code rule configurations from .roo/rules/ directory
|
|
3905
3828
|
*/
|
|
3906
3829
|
async loadRooRules() {
|
|
3907
|
-
return this.
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
validate: true
|
|
3915
|
-
}),
|
|
3916
|
-
"Roo Code"
|
|
3917
|
-
);
|
|
3830
|
+
return await this.loadToolRulesDefault({
|
|
3831
|
+
nonRoot: {
|
|
3832
|
+
relativeFilePath: ".roo/rules",
|
|
3833
|
+
fromFile: (params) => RooRule.fromFile(params),
|
|
3834
|
+
extension: "md"
|
|
3835
|
+
}
|
|
3836
|
+
});
|
|
3918
3837
|
}
|
|
3919
3838
|
/**
|
|
3920
3839
|
* Load Windsurf rule configurations from .windsurf/rules/ directory
|
|
3921
3840
|
*/
|
|
3922
3841
|
async loadWindsurfRules() {
|
|
3923
|
-
return this.
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
relativeFilePath,
|
|
3929
|
-
filePath,
|
|
3930
|
-
validate: true
|
|
3931
|
-
}),
|
|
3932
|
-
"Windsurf"
|
|
3933
|
-
);
|
|
3934
|
-
}
|
|
3935
|
-
/**
|
|
3936
|
-
* Common helper method to load tool rules from a directory with parallel processing
|
|
3937
|
-
*/
|
|
3938
|
-
async loadToolRulesFromDirectory(dirPath, ruleFactory, toolName) {
|
|
3939
|
-
if (!await directoryExists(dirPath)) {
|
|
3940
|
-
logger.warn(`${toolName} rules directory not found: ${dirPath}`);
|
|
3941
|
-
return [];
|
|
3942
|
-
}
|
|
3943
|
-
const entries = await listDirectoryFiles(dirPath);
|
|
3944
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md") || file.endsWith(".mdc"));
|
|
3945
|
-
if (mdFiles.length === 0) {
|
|
3946
|
-
logger.info(`No rule files found in ${dirPath}`);
|
|
3947
|
-
return [];
|
|
3948
|
-
}
|
|
3949
|
-
logger.info(`Found ${mdFiles.length} ${toolName} rule files in ${dirPath}`);
|
|
3950
|
-
const results = await Promise.allSettled(
|
|
3951
|
-
mdFiles.map(async (mdFile) => {
|
|
3952
|
-
const filepath = join7(dirPath, mdFile);
|
|
3953
|
-
return {
|
|
3954
|
-
rule: await ruleFactory(filepath, mdFile),
|
|
3955
|
-
filename: mdFile
|
|
3956
|
-
};
|
|
3957
|
-
})
|
|
3958
|
-
);
|
|
3959
|
-
const toolRules = [];
|
|
3960
|
-
for (const [index, result] of results.entries()) {
|
|
3961
|
-
if (result.status === "fulfilled") {
|
|
3962
|
-
toolRules.push(result.value.rule);
|
|
3963
|
-
logger.debug(`Successfully loaded ${toolName} rule: ${result.value.filename}`);
|
|
3964
|
-
} else {
|
|
3965
|
-
logger.warn(`Failed to load ${toolName} rule file ${mdFiles[index]}:`, result.reason);
|
|
3842
|
+
return await this.loadToolRulesDefault({
|
|
3843
|
+
nonRoot: {
|
|
3844
|
+
relativeFilePath: ".windsurf/rules",
|
|
3845
|
+
fromFile: (params) => WindsurfRule.fromFile(params),
|
|
3846
|
+
extension: "md"
|
|
3966
3847
|
}
|
|
3967
|
-
}
|
|
3968
|
-
logger.info(`Successfully loaded ${toolRules.length} ${toolName} rules`);
|
|
3969
|
-
return toolRules;
|
|
3970
|
-
}
|
|
3971
|
-
async writeToolRulesFromRulesyncRules(rulesyncRules) {
|
|
3972
|
-
const toolRules = await this.convertRulesyncFilesToToolFiles(rulesyncRules);
|
|
3973
|
-
await this.writeAiFiles(toolRules);
|
|
3974
|
-
}
|
|
3975
|
-
async writeRulesyncRulesFromToolRules(toolRules) {
|
|
3976
|
-
const rulesyncRules = await this.convertToolFilesToRulesyncFiles(toolRules);
|
|
3977
|
-
await this.writeAiFiles(rulesyncRules);
|
|
3848
|
+
});
|
|
3978
3849
|
}
|
|
3979
3850
|
/**
|
|
3980
3851
|
* Implementation of abstract method from FeatureProcessor
|
|
@@ -3983,30 +3854,6 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3983
3854
|
static getToolTargets() {
|
|
3984
3855
|
return rulesProcessorToolTargets;
|
|
3985
3856
|
}
|
|
3986
|
-
/**
|
|
3987
|
-
* Get all supported tools
|
|
3988
|
-
*/
|
|
3989
|
-
static getSupportedTools() {
|
|
3990
|
-
const allTools = [
|
|
3991
|
-
"agentsmd",
|
|
3992
|
-
"amazonqcli",
|
|
3993
|
-
"augmentcode",
|
|
3994
|
-
"augmentcode-legacy",
|
|
3995
|
-
"claudecode",
|
|
3996
|
-
"cline",
|
|
3997
|
-
"codexcli",
|
|
3998
|
-
"copilot",
|
|
3999
|
-
"cursor",
|
|
4000
|
-
"geminicli",
|
|
4001
|
-
"junie",
|
|
4002
|
-
"kiro",
|
|
4003
|
-
"opencode",
|
|
4004
|
-
"qwencode",
|
|
4005
|
-
"roo",
|
|
4006
|
-
"windsurf"
|
|
4007
|
-
];
|
|
4008
|
-
return allTools;
|
|
4009
|
-
}
|
|
4010
3857
|
generateXmlReferencesSection(toolRules) {
|
|
4011
3858
|
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
4012
3859
|
if (toolRulesWithoutRoot.length === 0) {
|
|
@@ -4067,14 +3914,15 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
4067
3914
|
};
|
|
4068
3915
|
|
|
4069
3916
|
// src/subagents/subagents-processor.ts
|
|
4070
|
-
import { join as
|
|
3917
|
+
import { basename as basename11, join as join46 } from "path";
|
|
4071
3918
|
import { z as z19 } from "zod/mini";
|
|
4072
3919
|
|
|
4073
3920
|
// src/subagents/claudecode-subagent.ts
|
|
3921
|
+
import { join as join45 } from "path";
|
|
4074
3922
|
import { z as z18 } from "zod/mini";
|
|
4075
3923
|
|
|
4076
3924
|
// src/subagents/rulesync-subagent.ts
|
|
4077
|
-
import { basename as basename10 } from "path";
|
|
3925
|
+
import { basename as basename10, join as join44 } from "path";
|
|
4078
3926
|
import { z as z17 } from "zod/mini";
|
|
4079
3927
|
var RulesyncSubagentModelSchema = z17.enum(["opus", "sonnet", "haiku", "inherit"]);
|
|
4080
3928
|
var RulesyncSubagentFrontmatterSchema = z17.object({
|
|
@@ -4120,14 +3968,16 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
4120
3968
|
return { success: false, error: result.error };
|
|
4121
3969
|
}
|
|
4122
3970
|
}
|
|
4123
|
-
static async
|
|
4124
|
-
|
|
3971
|
+
static async fromFile({
|
|
3972
|
+
relativeFilePath
|
|
3973
|
+
}) {
|
|
3974
|
+
const fileContent = await readFileContent(join44(RULESYNC_SUBAGENTS_DIR, relativeFilePath));
|
|
4125
3975
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4126
3976
|
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
4127
3977
|
if (!result.success) {
|
|
4128
|
-
throw new Error(`Invalid frontmatter in ${
|
|
3978
|
+
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
|
|
4129
3979
|
}
|
|
4130
|
-
const filename = basename10(
|
|
3980
|
+
const filename = basename10(relativeFilePath);
|
|
4131
3981
|
return new _RulesyncSubagent({
|
|
4132
3982
|
baseDir: ".",
|
|
4133
3983
|
relativeDirPath: ".rulesync/subagents",
|
|
@@ -4141,7 +3991,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
4141
3991
|
|
|
4142
3992
|
// src/subagents/tool-subagent.ts
|
|
4143
3993
|
var ToolSubagent = class extends ToolFile {
|
|
4144
|
-
static async
|
|
3994
|
+
static async fromFile(_params) {
|
|
4145
3995
|
throw new Error("Please implement this method in the subclass.");
|
|
4146
3996
|
}
|
|
4147
3997
|
static fromRulesyncSubagent(_params) {
|
|
@@ -4202,7 +4052,6 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4202
4052
|
static fromRulesyncSubagent({
|
|
4203
4053
|
baseDir = ".",
|
|
4204
4054
|
rulesyncSubagent,
|
|
4205
|
-
relativeDirPath,
|
|
4206
4055
|
validate = true
|
|
4207
4056
|
}) {
|
|
4208
4057
|
const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
|
|
@@ -4217,7 +4066,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4217
4066
|
baseDir,
|
|
4218
4067
|
frontmatter: claudecodeFrontmatter,
|
|
4219
4068
|
body,
|
|
4220
|
-
relativeDirPath,
|
|
4069
|
+
relativeDirPath: ".claude/agents",
|
|
4221
4070
|
relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
|
|
4222
4071
|
fileContent,
|
|
4223
4072
|
validate
|
|
@@ -4234,22 +4083,20 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4234
4083
|
return { success: false, error: result.error };
|
|
4235
4084
|
}
|
|
4236
4085
|
}
|
|
4237
|
-
static async
|
|
4086
|
+
static async fromFile({
|
|
4238
4087
|
baseDir = ".",
|
|
4239
|
-
relativeDirPath,
|
|
4240
4088
|
relativeFilePath,
|
|
4241
|
-
filePath,
|
|
4242
4089
|
validate = true
|
|
4243
4090
|
}) {
|
|
4244
|
-
const fileContent = await readFileContent(
|
|
4091
|
+
const fileContent = await readFileContent(join45(baseDir, ".claude/agents", relativeFilePath));
|
|
4245
4092
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4246
4093
|
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
4247
4094
|
if (!result.success) {
|
|
4248
|
-
throw new Error(`Invalid frontmatter in ${
|
|
4095
|
+
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
|
|
4249
4096
|
}
|
|
4250
4097
|
return new _ClaudecodeSubagent({
|
|
4251
4098
|
baseDir,
|
|
4252
|
-
relativeDirPath,
|
|
4099
|
+
relativeDirPath: ".claude/agents",
|
|
4253
4100
|
relativeFilePath,
|
|
4254
4101
|
frontmatter: result.data,
|
|
4255
4102
|
body: content.trim(),
|
|
@@ -4303,7 +4150,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4303
4150
|
* Load and parse rulesync subagent files from .rulesync/subagents/ directory
|
|
4304
4151
|
*/
|
|
4305
4152
|
async loadRulesyncFiles() {
|
|
4306
|
-
const subagentsDir =
|
|
4153
|
+
const subagentsDir = join46(this.baseDir, ".rulesync", "subagents");
|
|
4307
4154
|
const dirExists = await directoryExists(subagentsDir);
|
|
4308
4155
|
if (!dirExists) {
|
|
4309
4156
|
logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
|
|
@@ -4318,10 +4165,11 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4318
4165
|
logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
|
|
4319
4166
|
const rulesyncSubagents = [];
|
|
4320
4167
|
for (const mdFile of mdFiles) {
|
|
4321
|
-
const filepath =
|
|
4168
|
+
const filepath = join46(subagentsDir, mdFile);
|
|
4322
4169
|
try {
|
|
4323
|
-
const rulesyncSubagent = await RulesyncSubagent.
|
|
4324
|
-
|
|
4170
|
+
const rulesyncSubagent = await RulesyncSubagent.fromFile({
|
|
4171
|
+
relativeFilePath: mdFile,
|
|
4172
|
+
validate: true
|
|
4325
4173
|
});
|
|
4326
4174
|
rulesyncSubagents.push(rulesyncSubagent);
|
|
4327
4175
|
logger.debug(`Successfully loaded subagent: ${mdFile}`);
|
|
@@ -4353,43 +4201,19 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4353
4201
|
* Load Claude Code subagent configurations from .claude/agents/ directory
|
|
4354
4202
|
*/
|
|
4355
4203
|
async loadClaudecodeSubagents() {
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
}
|
|
4368
|
-
|
|
4369
|
-
if (mdFiles.length === 0) {
|
|
4370
|
-
logger.info(`No JSON agent files found in ${agentsDir}`);
|
|
4371
|
-
return [];
|
|
4372
|
-
}
|
|
4373
|
-
logger.info(`Found ${mdFiles.length} Claude Code agent files in ${agentsDir}`);
|
|
4374
|
-
const toolSubagents = [];
|
|
4375
|
-
for (const mdFile of mdFiles) {
|
|
4376
|
-
const filepath = join8(agentsDir, mdFile);
|
|
4377
|
-
try {
|
|
4378
|
-
const claudecodeSubagent = await ClaudecodeSubagent.fromFilePath({
|
|
4379
|
-
baseDir: this.baseDir,
|
|
4380
|
-
relativeDirPath: ".claude/agents",
|
|
4381
|
-
relativeFilePath: mdFile,
|
|
4382
|
-
filePath: filepath
|
|
4383
|
-
});
|
|
4384
|
-
toolSubagents.push(claudecodeSubagent);
|
|
4385
|
-
logger.debug(`Successfully loaded Claude Code agent: ${mdFile}`);
|
|
4386
|
-
} catch (error) {
|
|
4387
|
-
logger.warn(`Failed to load Claude Code agent file ${filepath}:`, error);
|
|
4388
|
-
continue;
|
|
4389
|
-
}
|
|
4390
|
-
}
|
|
4391
|
-
logger.info(`Successfully loaded ${toolSubagents.length} Claude Code subagents`);
|
|
4392
|
-
return toolSubagents;
|
|
4204
|
+
return await this.loadToolSubagentsDefault({
|
|
4205
|
+
relativeDirPath: ".claude/agents",
|
|
4206
|
+
fromFile: (relativeFilePath) => ClaudecodeSubagent.fromFile({ relativeFilePath })
|
|
4207
|
+
});
|
|
4208
|
+
}
|
|
4209
|
+
async loadToolSubagentsDefault({
|
|
4210
|
+
relativeDirPath,
|
|
4211
|
+
fromFile
|
|
4212
|
+
}) {
|
|
4213
|
+
const paths = await findFilesByGlobs(join46(this.baseDir, relativeDirPath, "*.md"));
|
|
4214
|
+
const subagents = (await Promise.allSettled(paths.map((path2) => fromFile(basename11(path2))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
|
|
4215
|
+
logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
|
|
4216
|
+
return subagents;
|
|
4393
4217
|
}
|
|
4394
4218
|
/**
|
|
4395
4219
|
* Implementation of abstract method from FeatureProcessor
|
|
@@ -4425,7 +4249,7 @@ async function generateCommand(options) {
|
|
|
4425
4249
|
}
|
|
4426
4250
|
let rulesyncFiles = await processor.loadRulesyncFiles();
|
|
4427
4251
|
if (rulesyncFiles.length === 0) {
|
|
4428
|
-
rulesyncFiles = await processor.
|
|
4252
|
+
rulesyncFiles = await processor.loadRulesyncFilesLegacy();
|
|
4429
4253
|
}
|
|
4430
4254
|
const toolFiles = await processor.convertRulesyncFilesToToolFiles(rulesyncFiles);
|
|
4431
4255
|
const writtenCount = await processor.writeAiFiles(toolFiles);
|
|
@@ -4579,9 +4403,9 @@ async function generateCommand(options) {
|
|
|
4579
4403
|
}
|
|
4580
4404
|
|
|
4581
4405
|
// src/cli/commands/gitignore.ts
|
|
4582
|
-
import { join as
|
|
4406
|
+
import { join as join47 } from "path";
|
|
4583
4407
|
var gitignoreCommand = async () => {
|
|
4584
|
-
const gitignorePath =
|
|
4408
|
+
const gitignorePath = join47(process.cwd(), ".gitignore");
|
|
4585
4409
|
const rulesFilesToIgnore = [
|
|
4586
4410
|
"# Generated by rulesync - AI tool configuration files",
|
|
4587
4411
|
"**/.amazonq/rules/",
|
|
@@ -4710,6 +4534,24 @@ async function importCommand(options) {
|
|
|
4710
4534
|
logger.success(`Created ${ignoreFileCreated} ignore files`);
|
|
4711
4535
|
}
|
|
4712
4536
|
}
|
|
4537
|
+
let mcpCreated = 0;
|
|
4538
|
+
if (config.getFeatures().includes("mcp")) {
|
|
4539
|
+
if (McpProcessor.getToolTargets().includes(tool)) {
|
|
4540
|
+
const mcpProcessor = new McpProcessor({
|
|
4541
|
+
baseDir: ".",
|
|
4542
|
+
toolTarget: tool
|
|
4543
|
+
});
|
|
4544
|
+
const toolFiles = await mcpProcessor.loadToolFiles();
|
|
4545
|
+
if (toolFiles.length > 0) {
|
|
4546
|
+
const rulesyncFiles = await mcpProcessor.convertToolFilesToRulesyncFiles(toolFiles);
|
|
4547
|
+
const writtenCount = await mcpProcessor.writeAiFiles(rulesyncFiles);
|
|
4548
|
+
mcpCreated = writtenCount;
|
|
4549
|
+
}
|
|
4550
|
+
}
|
|
4551
|
+
}
|
|
4552
|
+
if (config.getVerbose() && mcpCreated > 0) {
|
|
4553
|
+
logger.success(`Created ${mcpCreated} MCP files`);
|
|
4554
|
+
}
|
|
4713
4555
|
let subagentsCreated = 0;
|
|
4714
4556
|
if (config.getFeatures().includes("subagents")) {
|
|
4715
4557
|
if (SubagentsProcessor.getToolTargets().includes(tool)) {
|
|
@@ -4750,7 +4592,7 @@ async function importCommand(options) {
|
|
|
4750
4592
|
}
|
|
4751
4593
|
|
|
4752
4594
|
// src/cli/commands/init.ts
|
|
4753
|
-
import { join as
|
|
4595
|
+
import { join as join48 } from "path";
|
|
4754
4596
|
async function initCommand() {
|
|
4755
4597
|
logger.info("Initializing rulesync...");
|
|
4756
4598
|
await ensureDir(RULESYNC_DIR);
|
|
@@ -4796,7 +4638,7 @@ globs: ["**/*"]
|
|
|
4796
4638
|
- Follow single responsibility principle
|
|
4797
4639
|
`
|
|
4798
4640
|
};
|
|
4799
|
-
const filepath =
|
|
4641
|
+
const filepath = join48(RULESYNC_RULES_DIR, sampleFile.filename);
|
|
4800
4642
|
await ensureDir(RULESYNC_RULES_DIR);
|
|
4801
4643
|
await ensureDir(RULESYNC_COMMANDS_DIR);
|
|
4802
4644
|
await ensureDir(RULESYNC_SUBAGENTS_DIR);
|
|
@@ -4814,15 +4656,15 @@ var getVersion = async () => {
|
|
|
4814
4656
|
let packageJsonPath;
|
|
4815
4657
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
4816
4658
|
const __filename = fileURLToPath(import.meta.url);
|
|
4817
|
-
const __dirname =
|
|
4818
|
-
packageJsonPath =
|
|
4659
|
+
const __dirname = join49(__filename, "..");
|
|
4660
|
+
packageJsonPath = join49(__dirname, "../../package.json");
|
|
4819
4661
|
} else {
|
|
4820
|
-
packageJsonPath =
|
|
4662
|
+
packageJsonPath = join49(process.cwd(), "package.json");
|
|
4821
4663
|
}
|
|
4822
4664
|
const packageJson = await readJsonFile(packageJsonPath);
|
|
4823
4665
|
return packageJson.version;
|
|
4824
4666
|
} catch {
|
|
4825
|
-
return "0.
|
|
4667
|
+
return "0.70.0";
|
|
4826
4668
|
}
|
|
4827
4669
|
};
|
|
4828
4670
|
var main = async () => {
|