rulesync 0.68.1 → 0.70.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -9
- package/dist/index.cjs +916 -983
- package/dist/index.js +912 -979
- 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
|
|
|
@@ -29,6 +29,7 @@ var ALL_TOOL_TARGETS = [
|
|
|
29
29
|
"geminicli",
|
|
30
30
|
"kiro",
|
|
31
31
|
"junie",
|
|
32
|
+
"warp",
|
|
32
33
|
"windsurf"
|
|
33
34
|
];
|
|
34
35
|
var ALL_TOOL_TARGETS_WITH_WILDCARD = [...ALL_TOOL_TARGETS, "*"];
|
|
@@ -193,14 +194,6 @@ async function listDirectoryFiles(dir) {
|
|
|
193
194
|
return [];
|
|
194
195
|
}
|
|
195
196
|
}
|
|
196
|
-
async function findFiles(dir, extension = ".md") {
|
|
197
|
-
try {
|
|
198
|
-
const files = await readdir(dir);
|
|
199
|
-
return files.filter((file) => file.endsWith(extension)).map((file) => join(dir, file));
|
|
200
|
-
} catch {
|
|
201
|
-
return [];
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
197
|
async function findFilesByGlobs(globs) {
|
|
205
198
|
return globSync(globs);
|
|
206
199
|
}
|
|
@@ -250,7 +243,7 @@ async function initConfig() {
|
|
|
250
243
|
import { intersection } from "es-toolkit";
|
|
251
244
|
|
|
252
245
|
// src/commands/commands-processor.ts
|
|
253
|
-
import { basename as basename6, join as
|
|
246
|
+
import { basename as basename6, join as join7 } from "path";
|
|
254
247
|
import { z as z7 } from "zod/mini";
|
|
255
248
|
|
|
256
249
|
// src/types/feature-processor.ts
|
|
@@ -283,15 +276,48 @@ var FeatureProcessor = class {
|
|
|
283
276
|
};
|
|
284
277
|
|
|
285
278
|
// src/commands/claudecode-command.ts
|
|
286
|
-
import { basename as basename3, join as
|
|
279
|
+
import { basename as basename3, join as join4 } from "path";
|
|
287
280
|
import { z as z4 } from "zod/mini";
|
|
288
281
|
|
|
289
282
|
// src/utils/frontmatter.ts
|
|
290
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
|
+
}
|
|
291
319
|
function stringifyFrontmatter(body, frontmatter) {
|
|
292
|
-
const cleanFrontmatter =
|
|
293
|
-
Object.entries(frontmatter).filter(([, value]) => value !== null && value !== void 0)
|
|
294
|
-
);
|
|
320
|
+
const cleanFrontmatter = deepRemoveNullishObject(frontmatter);
|
|
295
321
|
return matter.stringify(body, cleanFrontmatter);
|
|
296
322
|
}
|
|
297
323
|
function parseFrontmatter(content) {
|
|
@@ -300,9 +326,18 @@ function parseFrontmatter(content) {
|
|
|
300
326
|
}
|
|
301
327
|
|
|
302
328
|
// src/commands/rulesync-command.ts
|
|
303
|
-
import { basename as basename2 } from "path";
|
|
329
|
+
import { basename as basename2, join as join3 } from "path";
|
|
304
330
|
import { z as z3 } from "zod/mini";
|
|
305
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
|
+
|
|
306
341
|
// src/types/ai-file.ts
|
|
307
342
|
import path from "path";
|
|
308
343
|
var AiFile = class {
|
|
@@ -340,7 +375,7 @@ var AiFile = class {
|
|
|
340
375
|
}
|
|
341
376
|
}
|
|
342
377
|
}
|
|
343
|
-
static async
|
|
378
|
+
static async fromFile(_params) {
|
|
344
379
|
throw new Error("Please implement this method in the subclass.");
|
|
345
380
|
}
|
|
346
381
|
getBaseDir() {
|
|
@@ -368,13 +403,10 @@ var AiFile = class {
|
|
|
368
403
|
|
|
369
404
|
// src/types/rulesync-file.ts
|
|
370
405
|
var RulesyncFile = class extends AiFile {
|
|
371
|
-
static async fromFilePath(_params) {
|
|
372
|
-
throw new Error("Please implement this method in the subclass.");
|
|
373
|
-
}
|
|
374
406
|
static async fromFile(_params) {
|
|
375
407
|
throw new Error("Please implement this method in the subclass.");
|
|
376
408
|
}
|
|
377
|
-
static async
|
|
409
|
+
static async fromFileLegacy(_params) {
|
|
378
410
|
throw new Error("Please implement this method in the subclass.");
|
|
379
411
|
}
|
|
380
412
|
};
|
|
@@ -418,14 +450,16 @@ var RulesyncCommand = class _RulesyncCommand extends RulesyncFile {
|
|
|
418
450
|
return { success: false, error: result.error };
|
|
419
451
|
}
|
|
420
452
|
}
|
|
421
|
-
static async
|
|
422
|
-
|
|
453
|
+
static async fromFile({
|
|
454
|
+
relativeFilePath
|
|
455
|
+
}) {
|
|
456
|
+
const fileContent = await readFileContent(join3(RULESYNC_COMMANDS_DIR, relativeFilePath));
|
|
423
457
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
424
458
|
const result = RulesyncCommandFrontmatterSchema.safeParse(frontmatter);
|
|
425
459
|
if (!result.success) {
|
|
426
|
-
throw new Error(`Invalid frontmatter in ${
|
|
460
|
+
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
|
|
427
461
|
}
|
|
428
|
-
const filename = basename2(
|
|
462
|
+
const filename = basename2(relativeFilePath);
|
|
429
463
|
return new _RulesyncCommand({
|
|
430
464
|
baseDir: ".",
|
|
431
465
|
relativeDirPath: ".rulesync/commands",
|
|
@@ -451,7 +485,7 @@ var ToolCommand = class extends AiFile {
|
|
|
451
485
|
* @param params - Parameters including the file path to load
|
|
452
486
|
* @returns Promise resolving to a concrete ToolCommand instance
|
|
453
487
|
*/
|
|
454
|
-
static async
|
|
488
|
+
static async fromFile(_params) {
|
|
455
489
|
throw new Error("Please implement this method in the subclass.");
|
|
456
490
|
}
|
|
457
491
|
/**
|
|
@@ -528,7 +562,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
528
562
|
baseDir,
|
|
529
563
|
frontmatter: claudecodeFrontmatter,
|
|
530
564
|
body,
|
|
531
|
-
relativeDirPath:
|
|
565
|
+
relativeDirPath: join4(".claude", "commands"),
|
|
532
566
|
relativeFilePath: rulesyncCommand.getRelativeFilePath(),
|
|
533
567
|
validate
|
|
534
568
|
});
|
|
@@ -544,11 +578,12 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
544
578
|
return { success: false, error: result.error };
|
|
545
579
|
}
|
|
546
580
|
}
|
|
547
|
-
static async
|
|
581
|
+
static async fromFile({
|
|
548
582
|
baseDir = ".",
|
|
549
|
-
|
|
583
|
+
relativeFilePath,
|
|
550
584
|
validate = true
|
|
551
585
|
}) {
|
|
586
|
+
const filePath = join4(baseDir, ".claude", "commands", relativeFilePath);
|
|
552
587
|
const fileContent = await readFileContent(filePath);
|
|
553
588
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
554
589
|
const result = ClaudecodeCommandFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -558,7 +593,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
558
593
|
return new _ClaudecodeCommand({
|
|
559
594
|
baseDir,
|
|
560
595
|
relativeDirPath: ".claude/commands",
|
|
561
|
-
relativeFilePath: basename3(
|
|
596
|
+
relativeFilePath: basename3(relativeFilePath),
|
|
562
597
|
frontmatter: result.data,
|
|
563
598
|
body: content.trim(),
|
|
564
599
|
validate
|
|
@@ -567,7 +602,7 @@ var ClaudecodeCommand = class _ClaudecodeCommand extends ToolCommand {
|
|
|
567
602
|
};
|
|
568
603
|
|
|
569
604
|
// src/commands/geminicli-command.ts
|
|
570
|
-
import { basename as basename4 } from "path";
|
|
605
|
+
import { basename as basename4, join as join5 } from "path";
|
|
571
606
|
import { parse as parseToml } from "smol-toml";
|
|
572
607
|
import { z as z5 } from "zod/mini";
|
|
573
608
|
var GeminiCliCommandFrontmatterSchema = z5.object({
|
|
@@ -653,16 +688,17 @@ ${geminiFrontmatter.prompt}
|
|
|
653
688
|
validate
|
|
654
689
|
});
|
|
655
690
|
}
|
|
656
|
-
static async
|
|
691
|
+
static async fromFile({
|
|
657
692
|
baseDir = ".",
|
|
658
|
-
|
|
693
|
+
relativeFilePath,
|
|
659
694
|
validate = true
|
|
660
695
|
}) {
|
|
696
|
+
const filePath = join5(baseDir, ".gemini", "commands", relativeFilePath);
|
|
661
697
|
const fileContent = await readFileContent(filePath);
|
|
662
698
|
return new _GeminiCliCommand({
|
|
663
699
|
baseDir,
|
|
664
700
|
relativeDirPath: ".gemini/commands",
|
|
665
|
-
relativeFilePath: basename4(
|
|
701
|
+
relativeFilePath: basename4(relativeFilePath),
|
|
666
702
|
fileContent,
|
|
667
703
|
validate
|
|
668
704
|
});
|
|
@@ -675,26 +711,10 @@ ${geminiFrontmatter.prompt}
|
|
|
675
711
|
return { success: false, error: error instanceof Error ? error : new Error(String(error)) };
|
|
676
712
|
}
|
|
677
713
|
}
|
|
678
|
-
async processContent(content, args) {
|
|
679
|
-
let processedContent = content;
|
|
680
|
-
processedContent = this.processArgumentPlaceholder(processedContent, args);
|
|
681
|
-
return processedContent;
|
|
682
|
-
}
|
|
683
|
-
processArgumentPlaceholder(content, args) {
|
|
684
|
-
if (content.includes("{{args}}")) {
|
|
685
|
-
return content.replace(/\{\{args\}\}/g, args || "");
|
|
686
|
-
}
|
|
687
|
-
if (args) {
|
|
688
|
-
return `${content}
|
|
689
|
-
|
|
690
|
-
${args}`;
|
|
691
|
-
}
|
|
692
|
-
return content;
|
|
693
|
-
}
|
|
694
714
|
};
|
|
695
715
|
|
|
696
716
|
// src/commands/roo-command.ts
|
|
697
|
-
import { basename as basename5 } from "path";
|
|
717
|
+
import { basename as basename5, join as join6 } from "path";
|
|
698
718
|
import { optional, z as z6 } from "zod/mini";
|
|
699
719
|
var RooCommandFrontmatterSchema = z6.object({
|
|
700
720
|
description: z6.string(),
|
|
@@ -771,11 +791,12 @@ var RooCommand = class _RooCommand extends ToolCommand {
|
|
|
771
791
|
return { success: false, error: result.error };
|
|
772
792
|
}
|
|
773
793
|
}
|
|
774
|
-
static async
|
|
794
|
+
static async fromFile({
|
|
775
795
|
baseDir = ".",
|
|
776
|
-
|
|
796
|
+
relativeFilePath,
|
|
777
797
|
validate = true
|
|
778
798
|
}) {
|
|
799
|
+
const filePath = join6(baseDir, ".roo", "commands", relativeFilePath);
|
|
779
800
|
const fileContent = await readFileContent(filePath);
|
|
780
801
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
781
802
|
const result = RooCommandFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -785,7 +806,7 @@ var RooCommand = class _RooCommand extends ToolCommand {
|
|
|
785
806
|
return new _RooCommand({
|
|
786
807
|
baseDir,
|
|
787
808
|
relativeDirPath: ".roo/commands",
|
|
788
|
-
relativeFilePath: basename5(
|
|
809
|
+
relativeFilePath: basename5(relativeFilePath),
|
|
789
810
|
frontmatter: result.data,
|
|
790
811
|
body: content.trim(),
|
|
791
812
|
fileContent,
|
|
@@ -847,37 +868,12 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
847
868
|
* Load and parse rulesync command files from .rulesync/commands/ directory
|
|
848
869
|
*/
|
|
849
870
|
async loadRulesyncFiles() {
|
|
850
|
-
const
|
|
851
|
-
const
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
const allMdFiles = await findFiles(commandsDir, ".md");
|
|
857
|
-
const mdFiles = allMdFiles.map((f) => basename6(f));
|
|
858
|
-
if (mdFiles.length === 0) {
|
|
859
|
-
logger.debug(`No markdown files found in rulesync commands directory: ${commandsDir}`);
|
|
860
|
-
return [];
|
|
861
|
-
}
|
|
862
|
-
logger.info(`Found ${mdFiles.length} command files in ${commandsDir}`);
|
|
863
|
-
const rulesyncCommands = [];
|
|
864
|
-
for (const mdFile of mdFiles) {
|
|
865
|
-
const filepath = join3(commandsDir, mdFile);
|
|
866
|
-
try {
|
|
867
|
-
const rulesyncCommand = await RulesyncCommand.fromFilePath({
|
|
868
|
-
filePath: filepath
|
|
869
|
-
});
|
|
870
|
-
rulesyncCommands.push(rulesyncCommand);
|
|
871
|
-
logger.debug(`Successfully loaded command: ${mdFile}`);
|
|
872
|
-
} catch (error) {
|
|
873
|
-
logger.warn(`Failed to load command file ${filepath}:`, error);
|
|
874
|
-
continue;
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
if (rulesyncCommands.length === 0) {
|
|
878
|
-
logger.debug(`No valid commands found in ${commandsDir}`);
|
|
879
|
-
return [];
|
|
880
|
-
}
|
|
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);
|
|
881
877
|
logger.info(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
|
|
882
878
|
return rulesyncCommands;
|
|
883
879
|
}
|
|
@@ -890,122 +886,67 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
890
886
|
case "claudecode":
|
|
891
887
|
return await this.loadClaudecodeCommands();
|
|
892
888
|
case "geminicli":
|
|
893
|
-
return await this.
|
|
889
|
+
return await this.loadGeminicliCommands();
|
|
894
890
|
case "roo":
|
|
895
891
|
return await this.loadRooCommands();
|
|
896
892
|
default:
|
|
897
893
|
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
898
894
|
}
|
|
899
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
|
+
}
|
|
900
921
|
/**
|
|
901
922
|
* Load Claude Code command configurations from .claude/commands/ directory
|
|
902
923
|
*/
|
|
903
924
|
async loadClaudecodeCommands() {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
}
|
|
909
|
-
const allMdFiles = await findFiles(commandsDir, ".md");
|
|
910
|
-
const mdFiles = allMdFiles.map((f) => basename6(f));
|
|
911
|
-
if (mdFiles.length === 0) {
|
|
912
|
-
logger.info(`No markdown command files found in ${commandsDir}`);
|
|
913
|
-
return [];
|
|
914
|
-
}
|
|
915
|
-
logger.info(`Found ${mdFiles.length} Claude Code command files in ${commandsDir}`);
|
|
916
|
-
const toolCommands = [];
|
|
917
|
-
for (const mdFile of mdFiles) {
|
|
918
|
-
const filepath = join3(commandsDir, mdFile);
|
|
919
|
-
try {
|
|
920
|
-
const claudecodeCommand = await ClaudecodeCommand.fromFilePath({
|
|
921
|
-
baseDir: this.baseDir,
|
|
922
|
-
filePath: filepath
|
|
923
|
-
});
|
|
924
|
-
toolCommands.push(claudecodeCommand);
|
|
925
|
-
logger.debug(`Successfully loaded Claude Code command: ${mdFile}`);
|
|
926
|
-
} catch (error) {
|
|
927
|
-
logger.warn(`Failed to load Claude Code command file ${filepath}:`, error);
|
|
928
|
-
continue;
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
logger.info(`Successfully loaded ${toolCommands.length} Claude Code commands`);
|
|
932
|
-
return toolCommands;
|
|
925
|
+
return await this.loadToolCommandDefault({
|
|
926
|
+
toolTarget: "claudecode",
|
|
927
|
+
relativeDirPath: ".claude/commands",
|
|
928
|
+
extension: "md"
|
|
929
|
+
});
|
|
933
930
|
}
|
|
934
931
|
/**
|
|
935
932
|
* Load Gemini CLI command configurations from .gemini/commands/ directory
|
|
936
933
|
*/
|
|
937
|
-
async
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
}
|
|
943
|
-
const allFiles = await listDirectoryFiles(commandsDir);
|
|
944
|
-
const tomlFiles = allFiles.filter((file) => file.endsWith(".toml"));
|
|
945
|
-
if (tomlFiles.length === 0) {
|
|
946
|
-
logger.info(`No TOML command files found in ${commandsDir}`);
|
|
947
|
-
return [];
|
|
948
|
-
}
|
|
949
|
-
logger.info(`Found ${tomlFiles.length} Gemini CLI command files in ${commandsDir}`);
|
|
950
|
-
const toolCommands = [];
|
|
951
|
-
for (const tomlFile of tomlFiles) {
|
|
952
|
-
const filepath = join3(commandsDir, tomlFile);
|
|
953
|
-
try {
|
|
954
|
-
const geminiCliCommand = await GeminiCliCommand.fromFilePath({
|
|
955
|
-
baseDir: this.baseDir,
|
|
956
|
-
filePath: filepath
|
|
957
|
-
});
|
|
958
|
-
toolCommands.push(geminiCliCommand);
|
|
959
|
-
logger.debug(`Successfully loaded Gemini CLI command: ${tomlFile}`);
|
|
960
|
-
} catch (error) {
|
|
961
|
-
logger.warn(`Failed to load Gemini CLI command file ${filepath}:`, error);
|
|
962
|
-
continue;
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
logger.info(`Successfully loaded ${toolCommands.length} Gemini CLI commands`);
|
|
966
|
-
return toolCommands;
|
|
934
|
+
async loadGeminicliCommands() {
|
|
935
|
+
return await this.loadToolCommandDefault({
|
|
936
|
+
toolTarget: "geminicli",
|
|
937
|
+
relativeDirPath: ".gemini/commands",
|
|
938
|
+
extension: "md"
|
|
939
|
+
});
|
|
967
940
|
}
|
|
968
941
|
/**
|
|
969
942
|
* Load Roo Code command configurations from .roo/commands/ directory
|
|
970
943
|
*/
|
|
971
944
|
async loadRooCommands() {
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
}
|
|
977
|
-
const allMdFiles = await findFiles(commandsDir, ".md");
|
|
978
|
-
const mdFiles = allMdFiles.map((f) => basename6(f));
|
|
979
|
-
if (mdFiles.length === 0) {
|
|
980
|
-
logger.info(`No markdown command files found in ${commandsDir}`);
|
|
981
|
-
return [];
|
|
982
|
-
}
|
|
983
|
-
logger.info(`Found ${mdFiles.length} Roo Code command files in ${commandsDir}`);
|
|
984
|
-
const toolCommands = [];
|
|
985
|
-
for (const mdFile of mdFiles) {
|
|
986
|
-
const filepath = join3(commandsDir, mdFile);
|
|
987
|
-
try {
|
|
988
|
-
const rooCommand = await RooCommand.fromFilePath({
|
|
989
|
-
baseDir: this.baseDir,
|
|
990
|
-
filePath: filepath
|
|
991
|
-
});
|
|
992
|
-
toolCommands.push(rooCommand);
|
|
993
|
-
logger.debug(`Successfully loaded Roo Code command: ${mdFile}`);
|
|
994
|
-
} catch (error) {
|
|
995
|
-
logger.warn(`Failed to load Roo Code command file ${filepath}:`, error);
|
|
996
|
-
continue;
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
logger.info(`Successfully loaded ${toolCommands.length} Roo Code commands`);
|
|
1000
|
-
return toolCommands;
|
|
1001
|
-
}
|
|
1002
|
-
async writeToolCommandsFromRulesyncCommands(rulesyncCommands) {
|
|
1003
|
-
const toolCommands = await this.convertRulesyncFilesToToolFiles(rulesyncCommands);
|
|
1004
|
-
await this.writeAiFiles(toolCommands);
|
|
1005
|
-
}
|
|
1006
|
-
async writeRulesyncCommandsFromToolCommands(toolCommands) {
|
|
1007
|
-
const rulesyncCommands = await this.convertToolFilesToRulesyncFiles(toolCommands);
|
|
1008
|
-
await this.writeAiFiles(rulesyncCommands);
|
|
945
|
+
return await this.loadToolCommandDefault({
|
|
946
|
+
toolTarget: "roo",
|
|
947
|
+
relativeDirPath: ".roo/commands",
|
|
948
|
+
extension: "md"
|
|
949
|
+
});
|
|
1009
950
|
}
|
|
1010
951
|
/**
|
|
1011
952
|
* Implementation of abstract method from FeatureProcessor
|
|
@@ -1117,6 +1058,9 @@ var ConfigResolver = class {
|
|
|
1117
1058
|
// src/ignore/ignore-processor.ts
|
|
1118
1059
|
import { z as z9 } from "zod/mini";
|
|
1119
1060
|
|
|
1061
|
+
// src/ignore/augmentcode-ignore.ts
|
|
1062
|
+
import { join as join8 } from "path";
|
|
1063
|
+
|
|
1120
1064
|
// src/types/tool-file.ts
|
|
1121
1065
|
var ToolFile = class extends AiFile {
|
|
1122
1066
|
};
|
|
@@ -1135,9 +1079,6 @@ var RulesyncIgnore = class _RulesyncIgnore extends RulesyncFile {
|
|
|
1135
1079
|
fileContent
|
|
1136
1080
|
});
|
|
1137
1081
|
}
|
|
1138
|
-
static async fromFilePath(_params) {
|
|
1139
|
-
throw new Error("Please use the fromFile method instead.");
|
|
1140
|
-
}
|
|
1141
1082
|
};
|
|
1142
1083
|
|
|
1143
1084
|
// src/ignore/tool-ignore.ts
|
|
@@ -1174,12 +1115,9 @@ var ToolIgnore = class extends ToolFile {
|
|
|
1174
1115
|
fileContent: this.fileContent
|
|
1175
1116
|
});
|
|
1176
1117
|
}
|
|
1177
|
-
static async fromFile() {
|
|
1118
|
+
static async fromFile(_params) {
|
|
1178
1119
|
throw new Error("Please implement this method in the subclass.");
|
|
1179
1120
|
}
|
|
1180
|
-
static async fromFilePath(_params) {
|
|
1181
|
-
throw new Error("Please use the fromFile method instead.");
|
|
1182
|
-
}
|
|
1183
1121
|
};
|
|
1184
1122
|
|
|
1185
1123
|
// src/ignore/augmentcode-ignore.ts
|
|
@@ -1209,18 +1147,23 @@ var AugmentcodeIgnore = class _AugmentcodeIgnore extends ToolIgnore {
|
|
|
1209
1147
|
* Create AugmentcodeIgnore from file path
|
|
1210
1148
|
* Reads and parses .augmentignore file
|
|
1211
1149
|
*/
|
|
1212
|
-
static async fromFile(
|
|
1213
|
-
|
|
1150
|
+
static async fromFile({
|
|
1151
|
+
baseDir = ".",
|
|
1152
|
+
validate = true
|
|
1153
|
+
}) {
|
|
1154
|
+
const fileContent = await readFileContent(join8(baseDir, ".augmentignore"));
|
|
1214
1155
|
return new _AugmentcodeIgnore({
|
|
1215
|
-
baseDir
|
|
1156
|
+
baseDir,
|
|
1216
1157
|
relativeDirPath: ".",
|
|
1217
1158
|
relativeFilePath: ".augmentignore",
|
|
1218
|
-
fileContent
|
|
1159
|
+
fileContent,
|
|
1160
|
+
validate
|
|
1219
1161
|
});
|
|
1220
1162
|
}
|
|
1221
1163
|
};
|
|
1222
1164
|
|
|
1223
1165
|
// src/ignore/cline-ignore.ts
|
|
1166
|
+
import { join as join9 } from "path";
|
|
1224
1167
|
var ClineIgnore = class _ClineIgnore extends ToolIgnore {
|
|
1225
1168
|
/**
|
|
1226
1169
|
* Convert ClineIgnore to RulesyncIgnore format
|
|
@@ -1246,18 +1189,23 @@ var ClineIgnore = class _ClineIgnore extends ToolIgnore {
|
|
|
1246
1189
|
/**
|
|
1247
1190
|
* Load ClineIgnore from .clineignore file
|
|
1248
1191
|
*/
|
|
1249
|
-
static async fromFile(
|
|
1250
|
-
|
|
1192
|
+
static async fromFile({
|
|
1193
|
+
baseDir = ".",
|
|
1194
|
+
validate = true
|
|
1195
|
+
}) {
|
|
1196
|
+
const fileContent = await readFileContent(join9(baseDir, ".clineignore"));
|
|
1251
1197
|
return new _ClineIgnore({
|
|
1252
|
-
baseDir
|
|
1198
|
+
baseDir,
|
|
1253
1199
|
relativeDirPath: ".",
|
|
1254
1200
|
relativeFilePath: ".clineignore",
|
|
1255
|
-
fileContent
|
|
1201
|
+
fileContent,
|
|
1202
|
+
validate
|
|
1256
1203
|
});
|
|
1257
1204
|
}
|
|
1258
1205
|
};
|
|
1259
1206
|
|
|
1260
1207
|
// src/ignore/codexcli-ignore.ts
|
|
1208
|
+
import { join as join10 } from "path";
|
|
1261
1209
|
var CodexcliIgnore = class _CodexcliIgnore extends ToolIgnore {
|
|
1262
1210
|
toRulesyncIgnore() {
|
|
1263
1211
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1276,20 +1224,23 @@ var CodexcliIgnore = class _CodexcliIgnore extends ToolIgnore {
|
|
|
1276
1224
|
// Skip validation to allow empty patterns
|
|
1277
1225
|
});
|
|
1278
1226
|
}
|
|
1279
|
-
static async fromFile(
|
|
1280
|
-
|
|
1227
|
+
static async fromFile({
|
|
1228
|
+
baseDir = ".",
|
|
1229
|
+
validate = true
|
|
1230
|
+
}) {
|
|
1231
|
+
const fileContent = await readFileContent(join10(baseDir, ".codexignore"));
|
|
1281
1232
|
return new _CodexcliIgnore({
|
|
1282
|
-
baseDir
|
|
1233
|
+
baseDir,
|
|
1283
1234
|
relativeDirPath: ".",
|
|
1284
1235
|
relativeFilePath: ".codexignore",
|
|
1285
1236
|
fileContent,
|
|
1286
|
-
validate
|
|
1287
|
-
// Skip validation to allow empty patterns
|
|
1237
|
+
validate
|
|
1288
1238
|
});
|
|
1289
1239
|
}
|
|
1290
1240
|
};
|
|
1291
1241
|
|
|
1292
1242
|
// src/ignore/cursor-ignore.ts
|
|
1243
|
+
import { join as join11 } from "path";
|
|
1293
1244
|
var CursorIgnore = class _CursorIgnore extends ToolIgnore {
|
|
1294
1245
|
toRulesyncIgnore() {
|
|
1295
1246
|
return new RulesyncIgnore({
|
|
@@ -1311,18 +1262,23 @@ var CursorIgnore = class _CursorIgnore extends ToolIgnore {
|
|
|
1311
1262
|
fileContent: body
|
|
1312
1263
|
});
|
|
1313
1264
|
}
|
|
1314
|
-
static async fromFile(
|
|
1315
|
-
|
|
1265
|
+
static async fromFile({
|
|
1266
|
+
baseDir = ".",
|
|
1267
|
+
validate = true
|
|
1268
|
+
}) {
|
|
1269
|
+
const fileContent = await readFileContent(join11(baseDir, ".cursorignore"));
|
|
1316
1270
|
return new _CursorIgnore({
|
|
1317
|
-
baseDir
|
|
1271
|
+
baseDir,
|
|
1318
1272
|
relativeDirPath: ".",
|
|
1319
1273
|
relativeFilePath: ".cursorignore",
|
|
1320
|
-
fileContent
|
|
1274
|
+
fileContent,
|
|
1275
|
+
validate
|
|
1321
1276
|
});
|
|
1322
1277
|
}
|
|
1323
1278
|
};
|
|
1324
1279
|
|
|
1325
1280
|
// src/ignore/geminicli-ignore.ts
|
|
1281
|
+
import { join as join12 } from "path";
|
|
1326
1282
|
var GeminiCliIgnore = class _GeminiCliIgnore extends ToolIgnore {
|
|
1327
1283
|
toRulesyncIgnore() {
|
|
1328
1284
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1338,18 +1294,23 @@ var GeminiCliIgnore = class _GeminiCliIgnore extends ToolIgnore {
|
|
|
1338
1294
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1339
1295
|
});
|
|
1340
1296
|
}
|
|
1341
|
-
static async fromFile(
|
|
1342
|
-
|
|
1297
|
+
static async fromFile({
|
|
1298
|
+
baseDir = ".",
|
|
1299
|
+
validate = true
|
|
1300
|
+
}) {
|
|
1301
|
+
const fileContent = await readFileContent(join12(baseDir, ".aiexclude"));
|
|
1343
1302
|
return new _GeminiCliIgnore({
|
|
1344
|
-
baseDir
|
|
1303
|
+
baseDir,
|
|
1345
1304
|
relativeDirPath: ".",
|
|
1346
1305
|
relativeFilePath: ".aiexclude",
|
|
1347
|
-
fileContent
|
|
1306
|
+
fileContent,
|
|
1307
|
+
validate
|
|
1348
1308
|
});
|
|
1349
1309
|
}
|
|
1350
1310
|
};
|
|
1351
1311
|
|
|
1352
1312
|
// src/ignore/junie-ignore.ts
|
|
1313
|
+
import { join as join13 } from "path";
|
|
1353
1314
|
var JunieIgnore = class _JunieIgnore extends ToolIgnore {
|
|
1354
1315
|
toRulesyncIgnore() {
|
|
1355
1316
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1365,18 +1326,23 @@ var JunieIgnore = class _JunieIgnore extends ToolIgnore {
|
|
|
1365
1326
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1366
1327
|
});
|
|
1367
1328
|
}
|
|
1368
|
-
static async fromFile(
|
|
1369
|
-
|
|
1329
|
+
static async fromFile({
|
|
1330
|
+
baseDir = ".",
|
|
1331
|
+
validate = true
|
|
1332
|
+
}) {
|
|
1333
|
+
const fileContent = await readFileContent(join13(baseDir, ".junieignore"));
|
|
1370
1334
|
return new _JunieIgnore({
|
|
1371
|
-
baseDir
|
|
1335
|
+
baseDir,
|
|
1372
1336
|
relativeDirPath: ".",
|
|
1373
1337
|
relativeFilePath: ".junieignore",
|
|
1374
|
-
fileContent
|
|
1338
|
+
fileContent,
|
|
1339
|
+
validate
|
|
1375
1340
|
});
|
|
1376
1341
|
}
|
|
1377
1342
|
};
|
|
1378
1343
|
|
|
1379
1344
|
// src/ignore/kiro-ignore.ts
|
|
1345
|
+
import { join as join14 } from "path";
|
|
1380
1346
|
var KiroIgnore = class _KiroIgnore extends ToolIgnore {
|
|
1381
1347
|
toRulesyncIgnore() {
|
|
1382
1348
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1392,18 +1358,23 @@ var KiroIgnore = class _KiroIgnore extends ToolIgnore {
|
|
|
1392
1358
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1393
1359
|
});
|
|
1394
1360
|
}
|
|
1395
|
-
static async fromFile(
|
|
1396
|
-
|
|
1361
|
+
static async fromFile({
|
|
1362
|
+
baseDir = ".",
|
|
1363
|
+
validate = true
|
|
1364
|
+
}) {
|
|
1365
|
+
const fileContent = await readFileContent(join14(baseDir, ".aiignore"));
|
|
1397
1366
|
return new _KiroIgnore({
|
|
1398
|
-
baseDir
|
|
1367
|
+
baseDir,
|
|
1399
1368
|
relativeDirPath: ".",
|
|
1400
1369
|
relativeFilePath: ".aiignore",
|
|
1401
|
-
fileContent
|
|
1370
|
+
fileContent,
|
|
1371
|
+
validate
|
|
1402
1372
|
});
|
|
1403
1373
|
}
|
|
1404
1374
|
};
|
|
1405
1375
|
|
|
1406
1376
|
// src/ignore/qwencode-ignore.ts
|
|
1377
|
+
import { join as join15 } from "path";
|
|
1407
1378
|
var QwencodeIgnore = class _QwencodeIgnore extends ToolIgnore {
|
|
1408
1379
|
toRulesyncIgnore() {
|
|
1409
1380
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1419,18 +1390,23 @@ var QwencodeIgnore = class _QwencodeIgnore extends ToolIgnore {
|
|
|
1419
1390
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1420
1391
|
});
|
|
1421
1392
|
}
|
|
1422
|
-
static async fromFile(
|
|
1423
|
-
|
|
1393
|
+
static async fromFile({
|
|
1394
|
+
baseDir = ".",
|
|
1395
|
+
validate = true
|
|
1396
|
+
}) {
|
|
1397
|
+
const fileContent = await readFileContent(join15(baseDir, ".geminiignore"));
|
|
1424
1398
|
return new _QwencodeIgnore({
|
|
1425
|
-
baseDir
|
|
1399
|
+
baseDir,
|
|
1426
1400
|
relativeDirPath: ".",
|
|
1427
1401
|
relativeFilePath: ".geminiignore",
|
|
1428
|
-
fileContent
|
|
1402
|
+
fileContent,
|
|
1403
|
+
validate
|
|
1429
1404
|
});
|
|
1430
1405
|
}
|
|
1431
1406
|
};
|
|
1432
1407
|
|
|
1433
1408
|
// src/ignore/roo-ignore.ts
|
|
1409
|
+
import { join as join16 } from "path";
|
|
1434
1410
|
var RooIgnore = class _RooIgnore extends ToolIgnore {
|
|
1435
1411
|
toRulesyncIgnore() {
|
|
1436
1412
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1446,18 +1422,23 @@ var RooIgnore = class _RooIgnore extends ToolIgnore {
|
|
|
1446
1422
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1447
1423
|
});
|
|
1448
1424
|
}
|
|
1449
|
-
static async fromFile(
|
|
1450
|
-
|
|
1425
|
+
static async fromFile({
|
|
1426
|
+
baseDir = ".",
|
|
1427
|
+
validate = true
|
|
1428
|
+
}) {
|
|
1429
|
+
const fileContent = await readFileContent(join16(baseDir, ".rooignore"));
|
|
1451
1430
|
return new _RooIgnore({
|
|
1452
|
-
baseDir
|
|
1431
|
+
baseDir,
|
|
1453
1432
|
relativeDirPath: ".",
|
|
1454
1433
|
relativeFilePath: ".rooignore",
|
|
1455
|
-
fileContent
|
|
1434
|
+
fileContent,
|
|
1435
|
+
validate
|
|
1456
1436
|
});
|
|
1457
1437
|
}
|
|
1458
1438
|
};
|
|
1459
1439
|
|
|
1460
1440
|
// src/ignore/windsurf-ignore.ts
|
|
1441
|
+
import { join as join17 } from "path";
|
|
1461
1442
|
var WindsurfIgnore = class _WindsurfIgnore extends ToolIgnore {
|
|
1462
1443
|
toRulesyncIgnore() {
|
|
1463
1444
|
return this.toRulesyncIgnoreDefault();
|
|
@@ -1473,6 +1454,19 @@ var WindsurfIgnore = class _WindsurfIgnore extends ToolIgnore {
|
|
|
1473
1454
|
fileContent: rulesyncIgnore.getFileContent()
|
|
1474
1455
|
});
|
|
1475
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
|
+
}
|
|
1476
1470
|
};
|
|
1477
1471
|
|
|
1478
1472
|
// src/ignore/ignore-processor.ts
|
|
@@ -1530,25 +1524,25 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
1530
1524
|
async loadToolIgnores() {
|
|
1531
1525
|
switch (this.toolTarget) {
|
|
1532
1526
|
case "augmentcode":
|
|
1533
|
-
return [await AugmentcodeIgnore.fromFile()];
|
|
1527
|
+
return [await AugmentcodeIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1534
1528
|
case "cline":
|
|
1535
|
-
return [await ClineIgnore.fromFile()];
|
|
1529
|
+
return [await ClineIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1536
1530
|
case "codexcli":
|
|
1537
|
-
return [await CodexcliIgnore.fromFile()];
|
|
1531
|
+
return [await CodexcliIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1538
1532
|
case "cursor":
|
|
1539
|
-
return [await CursorIgnore.fromFile()];
|
|
1533
|
+
return [await CursorIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1540
1534
|
case "geminicli":
|
|
1541
|
-
return [await GeminiCliIgnore.fromFile()];
|
|
1535
|
+
return [await GeminiCliIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1542
1536
|
case "junie":
|
|
1543
|
-
return [await JunieIgnore.fromFile()];
|
|
1537
|
+
return [await JunieIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1544
1538
|
case "kiro":
|
|
1545
|
-
return [await KiroIgnore.fromFile()];
|
|
1539
|
+
return [await KiroIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1546
1540
|
case "qwencode":
|
|
1547
|
-
return [await QwencodeIgnore.fromFile()];
|
|
1541
|
+
return [await QwencodeIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1548
1542
|
case "roo":
|
|
1549
|
-
return [await RooIgnore.fromFile()];
|
|
1543
|
+
return [await RooIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1550
1544
|
case "windsurf":
|
|
1551
|
-
return [await WindsurfIgnore.fromFile()];
|
|
1545
|
+
return [await WindsurfIgnore.fromFile({ baseDir: this.baseDir })];
|
|
1552
1546
|
default:
|
|
1553
1547
|
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
1554
1548
|
}
|
|
@@ -1643,9 +1637,14 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
1643
1637
|
};
|
|
1644
1638
|
|
|
1645
1639
|
// src/mcp/mcp-processor.ts
|
|
1646
|
-
import { join as join4 } from "path";
|
|
1647
1640
|
import { z as z11 } from "zod/mini";
|
|
1648
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
|
+
|
|
1649
1648
|
// src/types/mcp.ts
|
|
1650
1649
|
import { z as z10 } from "zod/mini";
|
|
1651
1650
|
var McpTransportTypeSchema = z10.enum(["stdio", "sse", "http"]);
|
|
@@ -1694,14 +1693,14 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
|
|
|
1694
1693
|
validate() {
|
|
1695
1694
|
return { success: true, error: null };
|
|
1696
1695
|
}
|
|
1697
|
-
static async
|
|
1698
|
-
const fileContent = await readFileContent(
|
|
1696
|
+
static async fromFile({ validate = true }) {
|
|
1697
|
+
const fileContent = await readFileContent(join18(RULESYNC_DIR, ".mcp.json"));
|
|
1699
1698
|
return new _RulesyncMcp({
|
|
1700
1699
|
baseDir: ".",
|
|
1701
|
-
relativeDirPath:
|
|
1700
|
+
relativeDirPath: RULESYNC_DIR,
|
|
1702
1701
|
relativeFilePath: ".mcp.json",
|
|
1703
1702
|
fileContent,
|
|
1704
|
-
validate
|
|
1703
|
+
validate
|
|
1705
1704
|
});
|
|
1706
1705
|
}
|
|
1707
1706
|
getJson() {
|
|
@@ -1737,7 +1736,7 @@ var ToolMcp = class extends ToolFile {
|
|
|
1737
1736
|
fileContent: this.fileContent
|
|
1738
1737
|
});
|
|
1739
1738
|
}
|
|
1740
|
-
static async
|
|
1739
|
+
static async fromFile(_params) {
|
|
1741
1740
|
throw new Error("Please implement this method in the subclass.");
|
|
1742
1741
|
}
|
|
1743
1742
|
static fromRulesyncMcp(_params) {
|
|
@@ -1747,14 +1746,17 @@ var ToolMcp = class extends ToolFile {
|
|
|
1747
1746
|
|
|
1748
1747
|
// src/mcp/amazonqcli-mcp.ts
|
|
1749
1748
|
var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
|
|
1750
|
-
static async
|
|
1751
|
-
|
|
1749
|
+
static async fromFile({
|
|
1750
|
+
baseDir = ".",
|
|
1751
|
+
validate = true
|
|
1752
|
+
}) {
|
|
1753
|
+
const fileContent = await readFileContent(join19(baseDir, ".amazonq/mcp.json"));
|
|
1752
1754
|
return new _AmazonqcliMcp({
|
|
1753
|
-
baseDir
|
|
1755
|
+
baseDir,
|
|
1754
1756
|
relativeDirPath: ".amazonq",
|
|
1755
|
-
relativeFilePath: "
|
|
1757
|
+
relativeFilePath: "mcp.json",
|
|
1756
1758
|
fileContent,
|
|
1757
|
-
validate
|
|
1759
|
+
validate
|
|
1758
1760
|
});
|
|
1759
1761
|
}
|
|
1760
1762
|
static fromRulesyncMcp({
|
|
@@ -1779,15 +1781,19 @@ var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
|
|
|
1779
1781
|
};
|
|
1780
1782
|
|
|
1781
1783
|
// src/mcp/claudecode-mcp.ts
|
|
1784
|
+
import { join as join20 } from "path";
|
|
1782
1785
|
var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
|
|
1783
|
-
static async
|
|
1784
|
-
|
|
1786
|
+
static async fromFile({
|
|
1787
|
+
baseDir = ".",
|
|
1788
|
+
validate = true
|
|
1789
|
+
}) {
|
|
1790
|
+
const fileContent = await readFileContent(join20(baseDir, ".mcp.json"));
|
|
1785
1791
|
return new _ClaudecodeMcp({
|
|
1786
1792
|
baseDir: ".",
|
|
1787
1793
|
relativeDirPath: ".",
|
|
1788
1794
|
relativeFilePath: ".mcp.json",
|
|
1789
1795
|
fileContent,
|
|
1790
|
-
validate
|
|
1796
|
+
validate
|
|
1791
1797
|
});
|
|
1792
1798
|
}
|
|
1793
1799
|
static fromRulesyncMcp({
|
|
@@ -1812,15 +1818,19 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
|
|
|
1812
1818
|
};
|
|
1813
1819
|
|
|
1814
1820
|
// src/mcp/cline-mcp.ts
|
|
1821
|
+
import { join as join21 } from "path";
|
|
1815
1822
|
var ClineMcp = class _ClineMcp extends ToolMcp {
|
|
1816
|
-
static async
|
|
1817
|
-
|
|
1823
|
+
static async fromFile({
|
|
1824
|
+
baseDir = ".",
|
|
1825
|
+
validate = true
|
|
1826
|
+
}) {
|
|
1827
|
+
const fileContent = await readFileContent(join21(baseDir, ".cline/mcp.json"));
|
|
1818
1828
|
return new _ClineMcp({
|
|
1819
1829
|
baseDir: ".",
|
|
1820
1830
|
relativeDirPath: ".cline",
|
|
1821
1831
|
relativeFilePath: "mcp.json",
|
|
1822
1832
|
fileContent,
|
|
1823
|
-
validate
|
|
1833
|
+
validate
|
|
1824
1834
|
});
|
|
1825
1835
|
}
|
|
1826
1836
|
static fromRulesyncMcp({
|
|
@@ -1845,15 +1855,19 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
|
|
|
1845
1855
|
};
|
|
1846
1856
|
|
|
1847
1857
|
// src/mcp/copilot-mcp.ts
|
|
1858
|
+
import { join as join22 } from "path";
|
|
1848
1859
|
var CopilotMcp = class _CopilotMcp extends ToolMcp {
|
|
1849
|
-
static async fromFilePath({
|
|
1850
|
-
|
|
1860
|
+
static async fromFilePath({
|
|
1861
|
+
baseDir = ".",
|
|
1862
|
+
validate = true
|
|
1863
|
+
}) {
|
|
1864
|
+
const fileContent = await readFileContent(join22(baseDir, ".vscode/mcp.json"));
|
|
1851
1865
|
return new _CopilotMcp({
|
|
1852
1866
|
baseDir: ".",
|
|
1853
1867
|
relativeDirPath: ".vscode",
|
|
1854
1868
|
relativeFilePath: "mcp.json",
|
|
1855
1869
|
fileContent,
|
|
1856
|
-
validate
|
|
1870
|
+
validate
|
|
1857
1871
|
});
|
|
1858
1872
|
}
|
|
1859
1873
|
static fromRulesyncMcp({
|
|
@@ -1878,15 +1892,19 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
|
|
|
1878
1892
|
};
|
|
1879
1893
|
|
|
1880
1894
|
// src/mcp/cursor-mcp.ts
|
|
1895
|
+
import { join as join23 } from "path";
|
|
1881
1896
|
var CursorMcp = class _CursorMcp extends ToolMcp {
|
|
1882
|
-
static async
|
|
1883
|
-
|
|
1897
|
+
static async fromFile({
|
|
1898
|
+
baseDir = ".",
|
|
1899
|
+
validate = true
|
|
1900
|
+
}) {
|
|
1901
|
+
const fileContent = await readFileContent(join23(baseDir, ".cursor/mcp.json"));
|
|
1884
1902
|
return new _CursorMcp({
|
|
1885
1903
|
baseDir: ".",
|
|
1886
1904
|
relativeDirPath: ".cursor",
|
|
1887
1905
|
relativeFilePath: "mcp.json",
|
|
1888
1906
|
fileContent,
|
|
1889
|
-
validate
|
|
1907
|
+
validate
|
|
1890
1908
|
});
|
|
1891
1909
|
}
|
|
1892
1910
|
static fromRulesyncMcp({
|
|
@@ -1922,15 +1940,19 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
|
|
|
1922
1940
|
};
|
|
1923
1941
|
|
|
1924
1942
|
// src/mcp/roo-mcp.ts
|
|
1943
|
+
import { join as join24 } from "path";
|
|
1925
1944
|
var RooMcp = class _RooMcp extends ToolMcp {
|
|
1926
|
-
static async
|
|
1927
|
-
|
|
1928
|
-
|
|
1945
|
+
static async fromFile({
|
|
1946
|
+
baseDir = ".",
|
|
1947
|
+
validate = true
|
|
1948
|
+
}) {
|
|
1949
|
+
const fileContent = await readFileContent(join24(baseDir, ".roo/mcp.json"));
|
|
1950
|
+
return new _RooMcp({
|
|
1929
1951
|
baseDir: ".",
|
|
1930
1952
|
relativeDirPath: ".roo",
|
|
1931
1953
|
relativeFilePath: "mcp.json",
|
|
1932
1954
|
fileContent,
|
|
1933
|
-
validate
|
|
1955
|
+
validate
|
|
1934
1956
|
});
|
|
1935
1957
|
}
|
|
1936
1958
|
static fromRulesyncMcp({
|
|
@@ -1980,9 +2002,7 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
1980
2002
|
*/
|
|
1981
2003
|
async loadRulesyncFiles() {
|
|
1982
2004
|
try {
|
|
1983
|
-
return [
|
|
1984
|
-
await RulesyncMcp.fromFilePath({ filePath: join4(this.baseDir, ".rulesync", ".mcp.json") })
|
|
1985
|
-
];
|
|
2005
|
+
return [await RulesyncMcp.fromFile({})];
|
|
1986
2006
|
} catch (error) {
|
|
1987
2007
|
logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
|
|
1988
2008
|
return [];
|
|
@@ -1994,42 +2014,62 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
1994
2014
|
*/
|
|
1995
2015
|
async loadToolFiles() {
|
|
1996
2016
|
try {
|
|
1997
|
-
|
|
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
|
-
|
|
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}`);
|
|
2029
2069
|
}
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2070
|
+
})();
|
|
2071
|
+
logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
|
|
2072
|
+
return toolMcps;
|
|
2033
2073
|
} catch (error) {
|
|
2034
2074
|
logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
|
|
2035
2075
|
return [];
|
|
@@ -2105,21 +2145,15 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
2105
2145
|
};
|
|
2106
2146
|
|
|
2107
2147
|
// src/rules/rules-processor.ts
|
|
2108
|
-
import { basename as basename9, join as
|
|
2148
|
+
import { basename as basename9, join as join43 } from "path";
|
|
2109
2149
|
import { XMLBuilder } from "fast-xml-parser";
|
|
2110
2150
|
import { z as z16 } from "zod/mini";
|
|
2111
2151
|
|
|
2112
|
-
// src/
|
|
2113
|
-
import { join as
|
|
2114
|
-
var RULESYNC_DIR = ".rulesync";
|
|
2115
|
-
var RULESYNC_RULES_DIR = join5(".rulesync", "rules");
|
|
2116
|
-
var RULESYNC_RULES_DIR_LEGACY = ".rulesync";
|
|
2117
|
-
var RULESYNC_MCP_FILE = join5(".rulesync", ".mcp.json");
|
|
2118
|
-
var RULESYNC_COMMANDS_DIR = join5(".rulesync", "commands");
|
|
2119
|
-
var RULESYNC_SUBAGENTS_DIR = join5(".rulesync", "subagents");
|
|
2152
|
+
// src/rules/agentsmd-rule.ts
|
|
2153
|
+
import { join as join26 } from "path";
|
|
2120
2154
|
|
|
2121
2155
|
// src/rules/rulesync-rule.ts
|
|
2122
|
-
import { basename as basename7, join as
|
|
2156
|
+
import { basename as basename7, join as join25 } from "path";
|
|
2123
2157
|
import { z as z12 } from "zod/mini";
|
|
2124
2158
|
var RulesyncRuleFrontmatterSchema = z12.object({
|
|
2125
2159
|
root: z12.optional(z12.optional(z12.boolean())),
|
|
@@ -2165,10 +2199,11 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
2165
2199
|
return { success: false, error: result.error };
|
|
2166
2200
|
}
|
|
2167
2201
|
}
|
|
2168
|
-
static async
|
|
2169
|
-
relativeFilePath
|
|
2202
|
+
static async fromFileLegacy({
|
|
2203
|
+
relativeFilePath,
|
|
2204
|
+
validate = true
|
|
2170
2205
|
}) {
|
|
2171
|
-
const filePath =
|
|
2206
|
+
const filePath = join25(RULESYNC_RULES_DIR_LEGACY, relativeFilePath);
|
|
2172
2207
|
const fileContent = await readFileContent(filePath);
|
|
2173
2208
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
2174
2209
|
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -2188,10 +2223,15 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
2188
2223
|
relativeDirPath: RULESYNC_RULES_DIR,
|
|
2189
2224
|
relativeFilePath: filename,
|
|
2190
2225
|
frontmatter: validatedFrontmatter,
|
|
2191
|
-
body: content.trim()
|
|
2226
|
+
body: content.trim(),
|
|
2227
|
+
validate
|
|
2192
2228
|
});
|
|
2193
2229
|
}
|
|
2194
|
-
static async
|
|
2230
|
+
static async fromFile({
|
|
2231
|
+
relativeFilePath,
|
|
2232
|
+
validate = true
|
|
2233
|
+
}) {
|
|
2234
|
+
const filePath = join25(RULESYNC_RULES_DIR, relativeFilePath);
|
|
2195
2235
|
const fileContent = await readFileContent(filePath);
|
|
2196
2236
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
2197
2237
|
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -2211,7 +2251,8 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
2211
2251
|
relativeDirPath: RULESYNC_RULES_DIR,
|
|
2212
2252
|
relativeFilePath: filename,
|
|
2213
2253
|
frontmatter: validatedFrontmatter,
|
|
2214
|
-
body: content.trim()
|
|
2254
|
+
body: content.trim(),
|
|
2255
|
+
validate
|
|
2215
2256
|
});
|
|
2216
2257
|
}
|
|
2217
2258
|
getBody() {
|
|
@@ -2226,7 +2267,7 @@ var ToolRule = class extends ToolFile {
|
|
|
2226
2267
|
super(rest);
|
|
2227
2268
|
this.root = root;
|
|
2228
2269
|
}
|
|
2229
|
-
static async
|
|
2270
|
+
static async fromFile(_params) {
|
|
2230
2271
|
throw new Error("Please implement this method in the subclass.");
|
|
2231
2272
|
}
|
|
2232
2273
|
static fromRulesyncRule(_params) {
|
|
@@ -2277,19 +2318,18 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
2277
2318
|
root: root ?? false
|
|
2278
2319
|
});
|
|
2279
2320
|
}
|
|
2280
|
-
static async
|
|
2321
|
+
static async fromFile({
|
|
2281
2322
|
baseDir = ".",
|
|
2282
|
-
relativeDirPath,
|
|
2283
2323
|
relativeFilePath,
|
|
2284
|
-
filePath,
|
|
2285
2324
|
validate = true
|
|
2286
2325
|
}) {
|
|
2287
|
-
const fileContent = await readFileContent(filePath);
|
|
2288
2326
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
2327
|
+
const relativePath = isRoot ? "AGENTS.md" : join26(".agents/memories", relativeFilePath);
|
|
2328
|
+
const fileContent = await readFileContent(join26(baseDir, relativePath));
|
|
2289
2329
|
return new _AgentsMdRule({
|
|
2290
2330
|
baseDir,
|
|
2291
|
-
relativeDirPath,
|
|
2292
|
-
relativeFilePath,
|
|
2331
|
+
relativeDirPath: isRoot ? "." : ".agents/memories",
|
|
2332
|
+
relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
|
|
2293
2333
|
fileContent,
|
|
2294
2334
|
validate,
|
|
2295
2335
|
root: isRoot
|
|
@@ -2317,15 +2357,20 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
2317
2357
|
};
|
|
2318
2358
|
|
|
2319
2359
|
// src/rules/amazonqcli-rule.ts
|
|
2360
|
+
import { join as join27 } from "path";
|
|
2320
2361
|
var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
2321
|
-
static async
|
|
2322
|
-
|
|
2362
|
+
static async fromFile({
|
|
2363
|
+
baseDir = ".",
|
|
2364
|
+
relativeFilePath,
|
|
2365
|
+
validate = true
|
|
2366
|
+
}) {
|
|
2367
|
+
const fileContent = await readFileContent(join27(baseDir, ".amazonq/rules", relativeFilePath));
|
|
2323
2368
|
return new _AmazonQCliRule({
|
|
2324
|
-
baseDir
|
|
2325
|
-
relativeDirPath:
|
|
2326
|
-
relativeFilePath
|
|
2369
|
+
baseDir,
|
|
2370
|
+
relativeDirPath: ".amazonq/rules",
|
|
2371
|
+
relativeFilePath,
|
|
2327
2372
|
fileContent,
|
|
2328
|
-
validate
|
|
2373
|
+
validate,
|
|
2329
2374
|
root: false
|
|
2330
2375
|
});
|
|
2331
2376
|
}
|
|
@@ -2352,6 +2397,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
|
2352
2397
|
};
|
|
2353
2398
|
|
|
2354
2399
|
// src/rules/augmentcode-legacy-rule.ts
|
|
2400
|
+
import { join as join28 } from "path";
|
|
2355
2401
|
var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
2356
2402
|
toRulesyncRule() {
|
|
2357
2403
|
const rulesyncFrontmatter = {
|
|
@@ -2387,19 +2433,18 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
2387
2433
|
validate() {
|
|
2388
2434
|
return { success: true, error: null };
|
|
2389
2435
|
}
|
|
2390
|
-
static async
|
|
2436
|
+
static async fromFile({
|
|
2391
2437
|
baseDir = ".",
|
|
2392
|
-
relativeDirPath,
|
|
2393
2438
|
relativeFilePath,
|
|
2394
|
-
filePath,
|
|
2395
2439
|
validate = true
|
|
2396
2440
|
}) {
|
|
2397
|
-
const fileContent = await readFileContent(filePath);
|
|
2398
2441
|
const isRoot = relativeFilePath === ".augment-guidelines";
|
|
2442
|
+
const relativePath = isRoot ? ".augment-guidelines" : join28(".augment/rules", relativeFilePath);
|
|
2443
|
+
const fileContent = await readFileContent(join28(baseDir, relativePath));
|
|
2399
2444
|
return new _AugmentcodeLegacyRule({
|
|
2400
2445
|
baseDir,
|
|
2401
|
-
relativeDirPath,
|
|
2402
|
-
relativeFilePath,
|
|
2446
|
+
relativeDirPath: isRoot ? "." : ".augment/rules",
|
|
2447
|
+
relativeFilePath: isRoot ? ".augment-guidelines" : relativeFilePath,
|
|
2403
2448
|
fileContent,
|
|
2404
2449
|
validate,
|
|
2405
2450
|
root: isRoot
|
|
@@ -2408,6 +2453,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
2408
2453
|
};
|
|
2409
2454
|
|
|
2410
2455
|
// src/rules/augmentcode-rule.ts
|
|
2456
|
+
import { join as join29 } from "path";
|
|
2411
2457
|
var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
2412
2458
|
toRulesyncRule() {
|
|
2413
2459
|
return this.toRulesyncRuleDefault();
|
|
@@ -2426,18 +2472,16 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
2426
2472
|
})
|
|
2427
2473
|
);
|
|
2428
2474
|
}
|
|
2429
|
-
static async
|
|
2475
|
+
static async fromFile({
|
|
2430
2476
|
baseDir = ".",
|
|
2431
|
-
relativeDirPath,
|
|
2432
2477
|
relativeFilePath,
|
|
2433
|
-
filePath,
|
|
2434
2478
|
validate = true
|
|
2435
2479
|
}) {
|
|
2436
|
-
const fileContent = await readFileContent(
|
|
2480
|
+
const fileContent = await readFileContent(join29(baseDir, ".augment/rules", relativeFilePath));
|
|
2437
2481
|
const { body: content } = parseFrontmatter(fileContent);
|
|
2438
2482
|
return new _AugmentcodeRule({
|
|
2439
2483
|
baseDir,
|
|
2440
|
-
relativeDirPath,
|
|
2484
|
+
relativeDirPath: ".augment/rules",
|
|
2441
2485
|
relativeFilePath,
|
|
2442
2486
|
fileContent: content.trim(),
|
|
2443
2487
|
validate
|
|
@@ -2449,16 +2493,23 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
2449
2493
|
};
|
|
2450
2494
|
|
|
2451
2495
|
// src/rules/claudecode-rule.ts
|
|
2496
|
+
import { join as join30 } from "path";
|
|
2452
2497
|
var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
2453
|
-
static async
|
|
2454
|
-
|
|
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));
|
|
2455
2506
|
return new _ClaudecodeRule({
|
|
2456
|
-
baseDir
|
|
2457
|
-
relativeDirPath:
|
|
2458
|
-
relativeFilePath:
|
|
2507
|
+
baseDir,
|
|
2508
|
+
relativeDirPath: isRoot ? "." : ".claude/memories",
|
|
2509
|
+
relativeFilePath: isRoot ? "CLAUDE.md" : relativeFilePath,
|
|
2459
2510
|
fileContent,
|
|
2460
|
-
validate
|
|
2461
|
-
root:
|
|
2511
|
+
validate,
|
|
2512
|
+
root: isRoot
|
|
2462
2513
|
});
|
|
2463
2514
|
}
|
|
2464
2515
|
static fromRulesyncRule({
|
|
@@ -2485,6 +2536,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
2485
2536
|
};
|
|
2486
2537
|
|
|
2487
2538
|
// src/rules/cline-rule.ts
|
|
2539
|
+
import { join as join31 } from "path";
|
|
2488
2540
|
import { z as z13 } from "zod/mini";
|
|
2489
2541
|
var ClineRuleFrontmatterSchema = z13.object({
|
|
2490
2542
|
description: z13.string()
|
|
@@ -2510,17 +2562,15 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
2510
2562
|
validate() {
|
|
2511
2563
|
return { success: true, error: null };
|
|
2512
2564
|
}
|
|
2513
|
-
static async
|
|
2565
|
+
static async fromFile({
|
|
2514
2566
|
baseDir = ".",
|
|
2515
|
-
relativeDirPath,
|
|
2516
2567
|
relativeFilePath,
|
|
2517
|
-
filePath,
|
|
2518
2568
|
validate = true
|
|
2519
2569
|
}) {
|
|
2520
|
-
const fileContent = await readFileContent(
|
|
2570
|
+
const fileContent = await readFileContent(join31(baseDir, ".clinerules", relativeFilePath));
|
|
2521
2571
|
return new _ClineRule({
|
|
2522
2572
|
baseDir,
|
|
2523
|
-
relativeDirPath,
|
|
2573
|
+
relativeDirPath: ".clinerules",
|
|
2524
2574
|
relativeFilePath,
|
|
2525
2575
|
fileContent,
|
|
2526
2576
|
validate
|
|
@@ -2529,16 +2579,23 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
2529
2579
|
};
|
|
2530
2580
|
|
|
2531
2581
|
// src/rules/codexcli-rule.ts
|
|
2582
|
+
import { join as join32 } from "path";
|
|
2532
2583
|
var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
2533
|
-
static async
|
|
2534
|
-
|
|
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));
|
|
2535
2592
|
return new _CodexcliRule({
|
|
2536
|
-
baseDir
|
|
2537
|
-
relativeDirPath:
|
|
2538
|
-
relativeFilePath:
|
|
2593
|
+
baseDir,
|
|
2594
|
+
relativeDirPath: isRoot ? "." : ".codex/memories",
|
|
2595
|
+
relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
|
|
2539
2596
|
fileContent,
|
|
2540
|
-
validate
|
|
2541
|
-
root:
|
|
2597
|
+
validate,
|
|
2598
|
+
root: isRoot
|
|
2542
2599
|
});
|
|
2543
2600
|
}
|
|
2544
2601
|
static fromRulesyncRule({
|
|
@@ -2565,6 +2622,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
2565
2622
|
};
|
|
2566
2623
|
|
|
2567
2624
|
// src/rules/copilot-rule.ts
|
|
2625
|
+
import { join as join33 } from "path";
|
|
2568
2626
|
import { z as z14 } from "zod/mini";
|
|
2569
2627
|
var CopilotRuleFrontmatterSchema = z14.object({
|
|
2570
2628
|
description: z14.optional(z14.string()),
|
|
@@ -2639,45 +2697,43 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
2639
2697
|
root
|
|
2640
2698
|
});
|
|
2641
2699
|
}
|
|
2642
|
-
static async
|
|
2700
|
+
static async fromFile({
|
|
2643
2701
|
baseDir = ".",
|
|
2644
|
-
relativeDirPath,
|
|
2645
2702
|
relativeFilePath,
|
|
2646
|
-
filePath,
|
|
2647
2703
|
validate = true
|
|
2648
2704
|
}) {
|
|
2649
|
-
const
|
|
2650
|
-
const
|
|
2651
|
-
|
|
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) {
|
|
2652
2709
|
return new _CopilotRule({
|
|
2653
2710
|
baseDir,
|
|
2654
|
-
relativeDirPath,
|
|
2655
|
-
relativeFilePath,
|
|
2711
|
+
relativeDirPath: ".github",
|
|
2712
|
+
relativeFilePath: isRoot ? "copilot-instructions.md" : relativeFilePath,
|
|
2656
2713
|
frontmatter: {
|
|
2657
2714
|
description: "",
|
|
2658
2715
|
applyTo: "**"
|
|
2659
2716
|
},
|
|
2660
2717
|
body: fileContent.trim(),
|
|
2661
2718
|
validate,
|
|
2662
|
-
root
|
|
2719
|
+
root: isRoot
|
|
2663
2720
|
});
|
|
2664
2721
|
}
|
|
2665
2722
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
2666
2723
|
const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
|
|
2667
2724
|
if (!result.success) {
|
|
2668
|
-
throw new Error(
|
|
2725
|
+
throw new Error(
|
|
2726
|
+
`Invalid frontmatter in ${join33(baseDir, relativeFilePath)}: ${result.error.message}`
|
|
2727
|
+
);
|
|
2669
2728
|
}
|
|
2670
2729
|
return new _CopilotRule({
|
|
2671
2730
|
baseDir,
|
|
2672
|
-
relativeDirPath,
|
|
2673
|
-
relativeFilePath,
|
|
2674
|
-
frontmatter:
|
|
2675
|
-
...result.data,
|
|
2676
|
-
applyTo: result.data.applyTo || "**"
|
|
2677
|
-
},
|
|
2731
|
+
relativeDirPath: ".github/instructions",
|
|
2732
|
+
relativeFilePath: relativeFilePath.replace(/\.md$/, ".instructions.md"),
|
|
2733
|
+
frontmatter: result.data,
|
|
2678
2734
|
body: content.trim(),
|
|
2679
2735
|
validate,
|
|
2680
|
-
root
|
|
2736
|
+
root: isRoot
|
|
2681
2737
|
});
|
|
2682
2738
|
}
|
|
2683
2739
|
validate() {
|
|
@@ -2700,7 +2756,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
2700
2756
|
};
|
|
2701
2757
|
|
|
2702
2758
|
// src/rules/cursor-rule.ts
|
|
2703
|
-
import { basename as basename8 } from "path";
|
|
2759
|
+
import { basename as basename8, join as join34 } from "path";
|
|
2704
2760
|
import { z as z15 } from "zod/mini";
|
|
2705
2761
|
var CursorRuleFrontmatterSchema = z15.object({
|
|
2706
2762
|
description: z15.optional(z15.string()),
|
|
@@ -2719,11 +2775,49 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
2719
2775
|
}
|
|
2720
2776
|
super({
|
|
2721
2777
|
...rest,
|
|
2722
|
-
fileContent:
|
|
2778
|
+
fileContent: _CursorRule.stringifyCursorFrontmatter(body, frontmatter)
|
|
2723
2779
|
});
|
|
2724
2780
|
this.frontmatter = frontmatter;
|
|
2725
2781
|
this.body = body;
|
|
2726
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
|
+
}
|
|
2727
2821
|
toRulesyncRule() {
|
|
2728
2822
|
const targets = ["*"];
|
|
2729
2823
|
const isAlways = this.frontmatter.alwaysApply === true;
|
|
@@ -2740,13 +2834,18 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
2740
2834
|
targets,
|
|
2741
2835
|
root: false,
|
|
2742
2836
|
description: this.frontmatter.description,
|
|
2743
|
-
globs
|
|
2837
|
+
globs,
|
|
2838
|
+
cursor: {
|
|
2839
|
+
alwaysApply: this.frontmatter.alwaysApply,
|
|
2840
|
+
description: this.frontmatter.description,
|
|
2841
|
+
globs: globs.length > 0 ? globs : void 0
|
|
2842
|
+
}
|
|
2744
2843
|
};
|
|
2745
2844
|
return new RulesyncRule({
|
|
2746
2845
|
frontmatter: rulesyncFrontmatter,
|
|
2747
2846
|
body: this.body,
|
|
2748
2847
|
relativeDirPath: ".rulesync/rules",
|
|
2749
|
-
relativeFilePath: this.relativeFilePath,
|
|
2848
|
+
relativeFilePath: this.relativeFilePath.replace(/\.mdc$/, ".md"),
|
|
2750
2849
|
validate: true
|
|
2751
2850
|
});
|
|
2752
2851
|
}
|
|
@@ -2774,20 +2873,23 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
2774
2873
|
validate
|
|
2775
2874
|
});
|
|
2776
2875
|
}
|
|
2777
|
-
static async
|
|
2778
|
-
|
|
2876
|
+
static async fromFile({
|
|
2877
|
+
baseDir = ".",
|
|
2878
|
+
relativeFilePath,
|
|
2779
2879
|
validate = true
|
|
2780
2880
|
}) {
|
|
2781
|
-
const fileContent = await readFileContent(
|
|
2782
|
-
const { frontmatter, body: content } =
|
|
2881
|
+
const fileContent = await readFileContent(join34(baseDir, ".cursor/rules", relativeFilePath));
|
|
2882
|
+
const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
|
|
2783
2883
|
const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
|
|
2784
2884
|
if (!result.success) {
|
|
2785
|
-
throw new Error(
|
|
2885
|
+
throw new Error(
|
|
2886
|
+
`Invalid frontmatter in ${join34(baseDir, relativeFilePath)}: ${result.error.message}`
|
|
2887
|
+
);
|
|
2786
2888
|
}
|
|
2787
2889
|
return new _CursorRule({
|
|
2788
|
-
baseDir
|
|
2890
|
+
baseDir,
|
|
2789
2891
|
relativeDirPath: ".cursor/rules",
|
|
2790
|
-
relativeFilePath: basename8(
|
|
2892
|
+
relativeFilePath: basename8(relativeFilePath),
|
|
2791
2893
|
frontmatter: result.data,
|
|
2792
2894
|
body: content.trim(),
|
|
2793
2895
|
validate
|
|
@@ -2813,16 +2915,23 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
2813
2915
|
};
|
|
2814
2916
|
|
|
2815
2917
|
// src/rules/geminicli-rule.ts
|
|
2918
|
+
import { join as join35 } from "path";
|
|
2816
2919
|
var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
2817
|
-
static async
|
|
2818
|
-
|
|
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));
|
|
2819
2928
|
return new _GeminiCliRule({
|
|
2820
|
-
baseDir
|
|
2821
|
-
relativeDirPath:
|
|
2822
|
-
relativeFilePath:
|
|
2929
|
+
baseDir,
|
|
2930
|
+
relativeDirPath: isRoot ? "." : ".gemini/memories",
|
|
2931
|
+
relativeFilePath: isRoot ? "GEMINI.md" : relativeFilePath,
|
|
2823
2932
|
fileContent,
|
|
2824
|
-
validate
|
|
2825
|
-
root:
|
|
2933
|
+
validate,
|
|
2934
|
+
root: isRoot
|
|
2826
2935
|
});
|
|
2827
2936
|
}
|
|
2828
2937
|
static fromRulesyncRule({
|
|
@@ -2849,15 +2958,22 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
2849
2958
|
};
|
|
2850
2959
|
|
|
2851
2960
|
// src/rules/junie-rule.ts
|
|
2961
|
+
import { join as join36 } from "path";
|
|
2852
2962
|
var JunieRule = class _JunieRule extends ToolRule {
|
|
2853
|
-
static async
|
|
2854
|
-
|
|
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));
|
|
2855
2971
|
return new _JunieRule({
|
|
2856
|
-
baseDir
|
|
2857
|
-
relativeDirPath:
|
|
2858
|
-
relativeFilePath:
|
|
2972
|
+
baseDir,
|
|
2973
|
+
relativeDirPath: isRoot ? ".junie" : ".junie/memories",
|
|
2974
|
+
relativeFilePath: isRoot ? "guidelines.md" : relativeFilePath,
|
|
2859
2975
|
fileContent,
|
|
2860
|
-
validate
|
|
2976
|
+
validate
|
|
2861
2977
|
});
|
|
2862
2978
|
}
|
|
2863
2979
|
static fromRulesyncRule({
|
|
@@ -2870,8 +2986,8 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
2870
2986
|
baseDir,
|
|
2871
2987
|
rulesyncRule,
|
|
2872
2988
|
validate,
|
|
2873
|
-
rootPath: { relativeDirPath: ".", relativeFilePath: "guidelines.md" },
|
|
2874
|
-
nonRootPath: { relativeDirPath: ".junie/
|
|
2989
|
+
rootPath: { relativeDirPath: ".junie", relativeFilePath: "guidelines.md" },
|
|
2990
|
+
nonRootPath: { relativeDirPath: ".junie/memories" }
|
|
2875
2991
|
})
|
|
2876
2992
|
);
|
|
2877
2993
|
}
|
|
@@ -2884,15 +3000,20 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
2884
3000
|
};
|
|
2885
3001
|
|
|
2886
3002
|
// src/rules/kiro-rule.ts
|
|
3003
|
+
import { join as join37 } from "path";
|
|
2887
3004
|
var KiroRule = class _KiroRule extends ToolRule {
|
|
2888
|
-
static async
|
|
2889
|
-
|
|
3005
|
+
static async fromFile({
|
|
3006
|
+
baseDir = ".",
|
|
3007
|
+
relativeFilePath,
|
|
3008
|
+
validate = true
|
|
3009
|
+
}) {
|
|
3010
|
+
const fileContent = await readFileContent(join37(baseDir, ".kiro/steering", relativeFilePath));
|
|
2890
3011
|
return new _KiroRule({
|
|
2891
|
-
baseDir
|
|
2892
|
-
relativeDirPath:
|
|
2893
|
-
relativeFilePath
|
|
3012
|
+
baseDir,
|
|
3013
|
+
relativeDirPath: ".kiro/steering",
|
|
3014
|
+
relativeFilePath,
|
|
2894
3015
|
fileContent,
|
|
2895
|
-
validate
|
|
3016
|
+
validate,
|
|
2896
3017
|
root: false
|
|
2897
3018
|
});
|
|
2898
3019
|
}
|
|
@@ -2919,21 +3040,22 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
2919
3040
|
};
|
|
2920
3041
|
|
|
2921
3042
|
// src/rules/opencode-rule.ts
|
|
3043
|
+
import { join as join38 } from "path";
|
|
2922
3044
|
var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
2923
|
-
static async
|
|
3045
|
+
static async fromFile({
|
|
2924
3046
|
baseDir = ".",
|
|
2925
|
-
relativeDirPath,
|
|
2926
3047
|
relativeFilePath,
|
|
2927
|
-
filePath,
|
|
2928
3048
|
validate = true
|
|
2929
3049
|
}) {
|
|
2930
|
-
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));
|
|
2931
3053
|
return new _OpenCodeRule({
|
|
2932
3054
|
baseDir,
|
|
2933
|
-
relativeDirPath,
|
|
2934
|
-
relativeFilePath,
|
|
3055
|
+
relativeDirPath: isRoot ? "." : ".opencode/memories",
|
|
3056
|
+
relativeFilePath: isRoot ? "AGENTS.md" : relativeFilePath,
|
|
2935
3057
|
validate,
|
|
2936
|
-
root:
|
|
3058
|
+
root: isRoot,
|
|
2937
3059
|
fileContent
|
|
2938
3060
|
});
|
|
2939
3061
|
}
|
|
@@ -2959,16 +3081,23 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
2959
3081
|
};
|
|
2960
3082
|
|
|
2961
3083
|
// src/rules/qwencode-rule.ts
|
|
3084
|
+
import { join as join39 } from "path";
|
|
2962
3085
|
var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
2963
|
-
static async
|
|
2964
|
-
|
|
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));
|
|
2965
3094
|
return new _QwencodeRule({
|
|
2966
|
-
baseDir
|
|
2967
|
-
relativeDirPath:
|
|
2968
|
-
relativeFilePath:
|
|
3095
|
+
baseDir,
|
|
3096
|
+
relativeDirPath: isRoot ? "." : ".qwencode/memories",
|
|
3097
|
+
relativeFilePath: isRoot ? "QWEN.md" : relativeFilePath,
|
|
2969
3098
|
fileContent,
|
|
2970
|
-
validate
|
|
2971
|
-
root:
|
|
3099
|
+
validate,
|
|
3100
|
+
root: isRoot
|
|
2972
3101
|
});
|
|
2973
3102
|
}
|
|
2974
3103
|
static fromRulesyncRule(params) {
|
|
@@ -2989,15 +3118,21 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
2989
3118
|
};
|
|
2990
3119
|
|
|
2991
3120
|
// src/rules/roo-rule.ts
|
|
3121
|
+
import { join as join40 } from "path";
|
|
2992
3122
|
var RooRule = class _RooRule extends ToolRule {
|
|
2993
|
-
static async
|
|
2994
|
-
|
|
3123
|
+
static async fromFile({
|
|
3124
|
+
baseDir = ".",
|
|
3125
|
+
relativeFilePath,
|
|
3126
|
+
validate = true
|
|
3127
|
+
}) {
|
|
3128
|
+
const fileContent = await readFileContent(join40(baseDir, ".roo/rules", relativeFilePath));
|
|
2995
3129
|
return new _RooRule({
|
|
2996
|
-
baseDir
|
|
2997
|
-
relativeDirPath:
|
|
2998
|
-
relativeFilePath
|
|
3130
|
+
baseDir,
|
|
3131
|
+
relativeDirPath: ".roo/rules",
|
|
3132
|
+
relativeFilePath,
|
|
2999
3133
|
fileContent,
|
|
3000
|
-
validate
|
|
3134
|
+
validate,
|
|
3135
|
+
root: false
|
|
3001
3136
|
});
|
|
3002
3137
|
}
|
|
3003
3138
|
static fromRulesyncRule({
|
|
@@ -3037,15 +3172,71 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
3037
3172
|
}
|
|
3038
3173
|
};
|
|
3039
3174
|
|
|
3175
|
+
// src/rules/warp-rule.ts
|
|
3176
|
+
import { join as join41 } from "path";
|
|
3177
|
+
var WarpRule = class _WarpRule extends ToolRule {
|
|
3178
|
+
constructor({ fileContent, root, ...rest }) {
|
|
3179
|
+
super({
|
|
3180
|
+
...rest,
|
|
3181
|
+
fileContent,
|
|
3182
|
+
root: root ?? false
|
|
3183
|
+
});
|
|
3184
|
+
}
|
|
3185
|
+
static async fromFile({
|
|
3186
|
+
baseDir = ".",
|
|
3187
|
+
relativeFilePath,
|
|
3188
|
+
validate = true
|
|
3189
|
+
}) {
|
|
3190
|
+
const isRoot = relativeFilePath === "WARP.md";
|
|
3191
|
+
const relativePath = isRoot ? "WARP.md" : join41(".warp/memories", relativeFilePath);
|
|
3192
|
+
const fileContent = await readFileContent(join41(baseDir, relativePath));
|
|
3193
|
+
return new _WarpRule({
|
|
3194
|
+
baseDir,
|
|
3195
|
+
relativeDirPath: isRoot ? "." : ".warp",
|
|
3196
|
+
relativeFilePath: isRoot ? "WARP.md" : relativeFilePath,
|
|
3197
|
+
fileContent,
|
|
3198
|
+
validate,
|
|
3199
|
+
root: isRoot
|
|
3200
|
+
});
|
|
3201
|
+
}
|
|
3202
|
+
static fromRulesyncRule({
|
|
3203
|
+
baseDir = ".",
|
|
3204
|
+
rulesyncRule,
|
|
3205
|
+
validate = true
|
|
3206
|
+
}) {
|
|
3207
|
+
return new _WarpRule(
|
|
3208
|
+
this.buildToolRuleParamsDefault({
|
|
3209
|
+
baseDir,
|
|
3210
|
+
rulesyncRule,
|
|
3211
|
+
validate,
|
|
3212
|
+
rootPath: { relativeDirPath: ".", relativeFilePath: "WARP.md" },
|
|
3213
|
+
nonRootPath: { relativeDirPath: ".warp/memories" }
|
|
3214
|
+
})
|
|
3215
|
+
);
|
|
3216
|
+
}
|
|
3217
|
+
toRulesyncRule() {
|
|
3218
|
+
return this.toRulesyncRuleDefault();
|
|
3219
|
+
}
|
|
3220
|
+
validate() {
|
|
3221
|
+
return { success: true, error: null };
|
|
3222
|
+
}
|
|
3223
|
+
};
|
|
3224
|
+
|
|
3040
3225
|
// src/rules/windsurf-rule.ts
|
|
3226
|
+
import { join as join42 } from "path";
|
|
3041
3227
|
var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
3042
|
-
static async
|
|
3043
|
-
|
|
3228
|
+
static async fromFile({
|
|
3229
|
+
baseDir = ".",
|
|
3230
|
+
relativeFilePath,
|
|
3231
|
+
validate = true
|
|
3232
|
+
}) {
|
|
3233
|
+
const fileContent = await readFileContent(join42(baseDir, ".windsurf/rules", relativeFilePath));
|
|
3044
3234
|
return new _WindsurfRule({
|
|
3045
|
-
baseDir
|
|
3046
|
-
relativeDirPath:
|
|
3047
|
-
relativeFilePath
|
|
3048
|
-
fileContent
|
|
3235
|
+
baseDir,
|
|
3236
|
+
relativeDirPath: ".windsurf/rules",
|
|
3237
|
+
relativeFilePath,
|
|
3238
|
+
fileContent,
|
|
3239
|
+
validate
|
|
3049
3240
|
});
|
|
3050
3241
|
}
|
|
3051
3242
|
static fromRulesyncRule({
|
|
@@ -3087,6 +3278,7 @@ var rulesProcessorToolTargets = [
|
|
|
3087
3278
|
"opencode",
|
|
3088
3279
|
"qwencode",
|
|
3089
3280
|
"roo",
|
|
3281
|
+
"warp",
|
|
3090
3282
|
"windsurf"
|
|
3091
3283
|
];
|
|
3092
3284
|
var RulesProcessorToolTargetSchema = z16.enum(rulesProcessorToolTargets);
|
|
@@ -3195,6 +3387,12 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3195
3387
|
rulesyncRule,
|
|
3196
3388
|
validate: true
|
|
3197
3389
|
});
|
|
3390
|
+
case "warp":
|
|
3391
|
+
return WarpRule.fromRulesyncRule({
|
|
3392
|
+
baseDir: this.baseDir,
|
|
3393
|
+
rulesyncRule,
|
|
3394
|
+
validate: true
|
|
3395
|
+
});
|
|
3198
3396
|
case "windsurf":
|
|
3199
3397
|
return WindsurfRule.fromRulesyncRule({
|
|
3200
3398
|
baseDir: this.baseDir,
|
|
@@ -3273,6 +3471,13 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3273
3471
|
);
|
|
3274
3472
|
return toolRules;
|
|
3275
3473
|
}
|
|
3474
|
+
case "warp": {
|
|
3475
|
+
const rootRule = toolRules[rootRuleIndex];
|
|
3476
|
+
rootRule?.setFileContent(
|
|
3477
|
+
this.generateXmlReferencesSection(toolRules) + rootRule.getFileContent()
|
|
3478
|
+
);
|
|
3479
|
+
return toolRules;
|
|
3480
|
+
}
|
|
3276
3481
|
default:
|
|
3277
3482
|
return toolRules;
|
|
3278
3483
|
}
|
|
@@ -3289,57 +3494,18 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3289
3494
|
* Load and parse rulesync rule files from .rulesync/rules/ directory
|
|
3290
3495
|
*/
|
|
3291
3496
|
async loadRulesyncFiles() {
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
return [];
|
|
3298
|
-
}
|
|
3299
|
-
const entries = await listDirectoryFiles(rulesDir);
|
|
3300
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3301
|
-
if (mdFiles.length === 0) {
|
|
3302
|
-
logger.debug(`No markdown files found in rulesync rules directory: ${rulesDir}`);
|
|
3303
|
-
return [];
|
|
3304
|
-
}
|
|
3305
|
-
logger.info(`Found ${mdFiles.length} rule files in ${rulesDir}`);
|
|
3306
|
-
const rulesyncRules = [];
|
|
3307
|
-
for (const mdFile of mdFiles) {
|
|
3308
|
-
const filepath = join7(rulesDir, mdFile);
|
|
3309
|
-
try {
|
|
3310
|
-
const rulesyncRule = await RulesyncRule.fromFilePath({
|
|
3311
|
-
filePath: filepath
|
|
3312
|
-
});
|
|
3313
|
-
rulesyncRules.push(rulesyncRule);
|
|
3314
|
-
logger.debug(`Successfully loaded rule: ${mdFile}`);
|
|
3315
|
-
} catch (error) {
|
|
3316
|
-
logger.warn(`Failed to load rule file ${filepath}:`, error);
|
|
3317
|
-
continue;
|
|
3318
|
-
}
|
|
3319
|
-
}
|
|
3320
|
-
if (rulesyncRules.length === 0) {
|
|
3321
|
-
logger.debug(`No valid rules found in ${rulesDir}`);
|
|
3322
|
-
return [];
|
|
3323
|
-
}
|
|
3324
|
-
logger.info(`Successfully loaded ${rulesyncRules.length} rulesync rules`);
|
|
3325
|
-
return rulesyncRules;
|
|
3326
|
-
} catch (error) {
|
|
3327
|
-
logger.debug(`No rulesync files found`, error);
|
|
3328
|
-
return [];
|
|
3329
|
-
}
|
|
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
|
+
);
|
|
3330
3502
|
}
|
|
3331
|
-
async
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
)
|
|
3338
|
-
);
|
|
3339
|
-
} catch (error) {
|
|
3340
|
-
logger.debug(`No legacy rulesync files found`, error);
|
|
3341
|
-
return [];
|
|
3342
|
-
}
|
|
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
|
+
);
|
|
3343
3509
|
}
|
|
3344
3510
|
/**
|
|
3345
3511
|
* Implementation of abstract method from FeatureProcessor
|
|
@@ -3378,6 +3544,8 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3378
3544
|
return await this.loadQwencodeRules();
|
|
3379
3545
|
case "roo":
|
|
3380
3546
|
return await this.loadRooRules();
|
|
3547
|
+
case "warp":
|
|
3548
|
+
return await this.loadWarpRules();
|
|
3381
3549
|
case "windsurf":
|
|
3382
3550
|
return await this.loadWindsurfRules();
|
|
3383
3551
|
default:
|
|
@@ -3388,502 +3556,296 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3388
3556
|
return [];
|
|
3389
3557
|
}
|
|
3390
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
|
+
}
|
|
3391
3599
|
/**
|
|
3392
3600
|
* Load AGENTS.md rule configuration
|
|
3393
3601
|
*/
|
|
3394
3602
|
async loadAgentsmdRules() {
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
logger.warn(`AGENTS.md file not found: ${agentsFile}`);
|
|
3398
|
-
return [];
|
|
3399
|
-
}
|
|
3400
|
-
try {
|
|
3401
|
-
const agentsmdRule = await AgentsMdRule.fromFilePath({
|
|
3402
|
-
baseDir: this.baseDir,
|
|
3603
|
+
return await this.loadToolRulesDefault({
|
|
3604
|
+
root: {
|
|
3403
3605
|
relativeDirPath: ".",
|
|
3404
3606
|
relativeFilePath: "AGENTS.md",
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3607
|
+
fromFile: (params) => AgentsMdRule.fromFile(params)
|
|
3608
|
+
},
|
|
3609
|
+
nonRoot: {
|
|
3610
|
+
relativeFilePath: ".agents/memories",
|
|
3611
|
+
fromFile: (params) => AgentsMdRule.fromFile(params),
|
|
3612
|
+
extension: "md"
|
|
3613
|
+
}
|
|
3614
|
+
});
|
|
3615
|
+
}
|
|
3616
|
+
async loadWarpRules() {
|
|
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
|
+
});
|
|
3414
3629
|
}
|
|
3415
3630
|
/**
|
|
3416
3631
|
* Load Amazon Q Developer CLI rule configurations from .amazonq/rules/ directory
|
|
3417
3632
|
*/
|
|
3418
3633
|
async loadAmazonqcliRules() {
|
|
3419
|
-
return this.
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
validate: true
|
|
3427
|
-
}),
|
|
3428
|
-
"Amazon Q Developer CLI"
|
|
3429
|
-
);
|
|
3634
|
+
return await this.loadToolRulesDefault({
|
|
3635
|
+
nonRoot: {
|
|
3636
|
+
relativeFilePath: ".amazonq/rules",
|
|
3637
|
+
fromFile: (params) => AmazonQCliRule.fromFile(params),
|
|
3638
|
+
extension: "md"
|
|
3639
|
+
}
|
|
3640
|
+
});
|
|
3430
3641
|
}
|
|
3431
3642
|
/**
|
|
3432
3643
|
* Load AugmentCode rule configurations from .augment/rules/ directory
|
|
3433
3644
|
*/
|
|
3434
3645
|
async loadAugmentcodeRules() {
|
|
3435
|
-
return this.
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
validate: true
|
|
3443
|
-
}),
|
|
3444
|
-
"AugmentCode"
|
|
3445
|
-
);
|
|
3646
|
+
return await this.loadToolRulesDefault({
|
|
3647
|
+
nonRoot: {
|
|
3648
|
+
relativeFilePath: ".augment/rules",
|
|
3649
|
+
fromFile: (params) => AugmentcodeRule.fromFile(params),
|
|
3650
|
+
extension: "md"
|
|
3651
|
+
}
|
|
3652
|
+
});
|
|
3446
3653
|
}
|
|
3447
3654
|
/**
|
|
3448
3655
|
* Load AugmentCode legacy rule configuration from .augment-guidelines file and .augment/rules/ directory
|
|
3449
3656
|
*/
|
|
3450
3657
|
async loadAugmentcodeLegacyRules() {
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
});
|
|
3462
|
-
toolRules.push(augmentcodeLegacyRule);
|
|
3463
|
-
logger.info(`Successfully loaded AugmentCode legacy guidelines`);
|
|
3464
|
-
} catch (error) {
|
|
3465
|
-
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"
|
|
3466
3668
|
}
|
|
3467
|
-
}
|
|
3468
|
-
const rulesDir = join7(this.baseDir, ".augment", "rules");
|
|
3469
|
-
if (await directoryExists(rulesDir)) {
|
|
3470
|
-
const dirRules = await this.loadToolRulesFromDirectory(
|
|
3471
|
-
rulesDir,
|
|
3472
|
-
(filePath, relativeFilePath) => AugmentcodeLegacyRule.fromFilePath({
|
|
3473
|
-
baseDir: this.baseDir,
|
|
3474
|
-
relativeDirPath: join7(".augment", "rules"),
|
|
3475
|
-
relativeFilePath,
|
|
3476
|
-
filePath,
|
|
3477
|
-
validate: true
|
|
3478
|
-
}),
|
|
3479
|
-
"AugmentCode Legacy"
|
|
3480
|
-
);
|
|
3481
|
-
toolRules.push(...dirRules);
|
|
3482
|
-
}
|
|
3483
|
-
return toolRules;
|
|
3669
|
+
});
|
|
3484
3670
|
}
|
|
3485
3671
|
/**
|
|
3486
3672
|
* Load Claude Code rule configuration from CLAUDE.md file
|
|
3487
3673
|
*/
|
|
3488
3674
|
async loadClaudecodeRules() {
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
baseDir: this.baseDir,
|
|
3500
|
-
relativeDirPath: ".",
|
|
3501
|
-
relativeFilePath: "CLAUDE.md",
|
|
3502
|
-
filePath: claudeFile,
|
|
3503
|
-
validate: true
|
|
3504
|
-
});
|
|
3505
|
-
logger.info(`Successfully loaded Claude Code memory file`);
|
|
3506
|
-
return [claudecodeRule];
|
|
3507
|
-
} catch (error) {
|
|
3508
|
-
logger.warn(`Failed to load Claude Code memory file ${claudeFile}:`, error);
|
|
3509
|
-
return [];
|
|
3510
|
-
}
|
|
3511
|
-
}
|
|
3512
|
-
const entries = await listDirectoryFiles(claudeMemoriesDir);
|
|
3513
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3514
|
-
if (mdFiles.length === 0) {
|
|
3515
|
-
logger.debug(
|
|
3516
|
-
`No markdown files found in Claude Code memories directory: ${claudeMemoriesDir}`
|
|
3517
|
-
);
|
|
3518
|
-
return [];
|
|
3519
|
-
}
|
|
3520
|
-
logger.info(`Found ${mdFiles.length} Claude Code memory files in ${claudeMemoriesDir}`);
|
|
3521
|
-
const toolRules = [];
|
|
3522
|
-
for (const mdFile of mdFiles) {
|
|
3523
|
-
const filePath = join7(claudeMemoriesDir, mdFile);
|
|
3524
|
-
try {
|
|
3525
|
-
const claudecodeRule = await ClaudecodeRule.fromFilePath({
|
|
3526
|
-
baseDir: this.baseDir,
|
|
3527
|
-
relativeDirPath: join7(".claude", "memories"),
|
|
3528
|
-
relativeFilePath: mdFile,
|
|
3529
|
-
filePath,
|
|
3530
|
-
validate: true
|
|
3531
|
-
});
|
|
3532
|
-
toolRules.push(claudecodeRule);
|
|
3533
|
-
logger.debug(`Successfully loaded Claude Code memory file: ${mdFile}`);
|
|
3534
|
-
} catch (error) {
|
|
3535
|
-
logger.warn(`Failed to load Claude Code memory file ${filePath}:`, error);
|
|
3536
|
-
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"
|
|
3537
3685
|
}
|
|
3538
|
-
}
|
|
3539
|
-
logger.info(`Successfully loaded ${toolRules.length} Claude Code memory files`);
|
|
3540
|
-
return toolRules;
|
|
3686
|
+
});
|
|
3541
3687
|
}
|
|
3542
3688
|
/**
|
|
3543
3689
|
* Load Cline rule configurations from .clinerules/ directory
|
|
3544
3690
|
*/
|
|
3545
3691
|
async loadClineRules() {
|
|
3546
|
-
return this.
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
validate: true
|
|
3554
|
-
}),
|
|
3555
|
-
"Cline"
|
|
3556
|
-
);
|
|
3692
|
+
return await this.loadToolRulesDefault({
|
|
3693
|
+
nonRoot: {
|
|
3694
|
+
relativeFilePath: ".clinerules",
|
|
3695
|
+
fromFile: (params) => ClineRule.fromFile(params),
|
|
3696
|
+
extension: "md"
|
|
3697
|
+
}
|
|
3698
|
+
});
|
|
3557
3699
|
}
|
|
3558
3700
|
/**
|
|
3559
3701
|
* Load OpenAI Codex CLI rule configuration from AGENTS.md and .codex/memories/*.md files
|
|
3560
3702
|
*/
|
|
3561
3703
|
async loadCodexcliRules() {
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
});
|
|
3573
|
-
rules.push(codexcliRule);
|
|
3574
|
-
logger.info(`Successfully loaded OpenAI Codex CLI agents file`);
|
|
3575
|
-
} catch (error) {
|
|
3576
|
-
logger.warn(`Failed to load OpenAI Codex CLI agents file ${agentsFile}:`, error);
|
|
3577
|
-
}
|
|
3578
|
-
}
|
|
3579
|
-
const memoriesDir = join7(this.baseDir, ".codex", "memories");
|
|
3580
|
-
if (await directoryExists(memoriesDir)) {
|
|
3581
|
-
try {
|
|
3582
|
-
const entries = await listDirectoryFiles(memoriesDir);
|
|
3583
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3584
|
-
for (const mdFile of mdFiles) {
|
|
3585
|
-
const filePath = join7(memoriesDir, mdFile);
|
|
3586
|
-
try {
|
|
3587
|
-
const codexcliRule = await CodexcliRule.fromFilePath({
|
|
3588
|
-
baseDir: this.baseDir,
|
|
3589
|
-
relativeDirPath: join7(".codex", "memories"),
|
|
3590
|
-
relativeFilePath: mdFile,
|
|
3591
|
-
filePath,
|
|
3592
|
-
validate: true
|
|
3593
|
-
});
|
|
3594
|
-
rules.push(codexcliRule);
|
|
3595
|
-
} catch (error) {
|
|
3596
|
-
logger.warn(`Failed to load Codex CLI memories file ${filePath}:`, error);
|
|
3597
|
-
}
|
|
3598
|
-
}
|
|
3599
|
-
if (mdFiles.length > 0) {
|
|
3600
|
-
logger.info(`Successfully loaded ${mdFiles.length} OpenAI Codex CLI memory files`);
|
|
3601
|
-
}
|
|
3602
|
-
} catch (error) {
|
|
3603
|
-
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"
|
|
3604
3714
|
}
|
|
3605
|
-
}
|
|
3606
|
-
if (rules.length === 0) {
|
|
3607
|
-
logger.warn(`No OpenAI Codex CLI rule files found`);
|
|
3608
|
-
}
|
|
3609
|
-
return rules;
|
|
3715
|
+
});
|
|
3610
3716
|
}
|
|
3611
3717
|
/**
|
|
3612
3718
|
* Load GitHub Copilot rule configuration from .github/copilot-instructions.md file
|
|
3613
3719
|
*/
|
|
3614
3720
|
async loadCopilotRules() {
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
});
|
|
3628
|
-
logger.info(`Successfully loaded GitHub Copilot instructions file`);
|
|
3629
|
-
return [copilotRule];
|
|
3630
|
-
} catch (error) {
|
|
3631
|
-
logger.warn(`Failed to load GitHub Copilot instructions file ${copilotFile}:`, error);
|
|
3632
|
-
return [];
|
|
3633
|
-
}
|
|
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
|
+
});
|
|
3634
3733
|
}
|
|
3635
3734
|
/**
|
|
3636
3735
|
* Load Cursor rule configurations from .cursor/rules/ directory
|
|
3637
3736
|
*/
|
|
3638
3737
|
async loadCursorRules() {
|
|
3639
|
-
return this.
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
}
|
|
3645
|
-
|
|
3646
|
-
);
|
|
3738
|
+
return await this.loadToolRulesDefault({
|
|
3739
|
+
nonRoot: {
|
|
3740
|
+
relativeFilePath: ".cursor/rules",
|
|
3741
|
+
fromFile: (params) => CursorRule.fromFile(params),
|
|
3742
|
+
extension: "md"
|
|
3743
|
+
}
|
|
3744
|
+
});
|
|
3647
3745
|
}
|
|
3648
3746
|
/**
|
|
3649
3747
|
* Load Gemini CLI rule configuration from GEMINI.md file
|
|
3650
3748
|
*/
|
|
3651
3749
|
async loadGeminicliRules() {
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
logger.warn(`Gemini CLI memory file not found: ${geminiFile}`);
|
|
3655
|
-
return [];
|
|
3656
|
-
}
|
|
3657
|
-
try {
|
|
3658
|
-
const geminicliRule = await GeminiCliRule.fromFilePath({
|
|
3659
|
-
baseDir: this.baseDir,
|
|
3750
|
+
return await this.loadToolRulesDefault({
|
|
3751
|
+
root: {
|
|
3660
3752
|
relativeDirPath: ".",
|
|
3661
3753
|
relativeFilePath: "GEMINI.md",
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
}
|
|
3754
|
+
fromFile: (params) => GeminiCliRule.fromFile(params)
|
|
3755
|
+
},
|
|
3756
|
+
nonRoot: {
|
|
3757
|
+
relativeFilePath: ".gemini/memories",
|
|
3758
|
+
fromFile: (params) => GeminiCliRule.fromFile(params),
|
|
3759
|
+
extension: "md"
|
|
3760
|
+
}
|
|
3761
|
+
});
|
|
3671
3762
|
}
|
|
3672
3763
|
/**
|
|
3673
3764
|
* Load JetBrains Junie rule configuration from .junie/guidelines.md file
|
|
3674
3765
|
*/
|
|
3675
3766
|
async loadJunieRules() {
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
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
|
+
}
|
|
3686
3778
|
});
|
|
3687
|
-
logger.info(`Successfully loaded JetBrains Junie guidelines file`);
|
|
3688
|
-
return [junieRule];
|
|
3689
3779
|
}
|
|
3690
3780
|
/**
|
|
3691
3781
|
* Load Kiro rule configurations from .kiro/steering/ directory
|
|
3692
3782
|
*/
|
|
3693
3783
|
async loadKiroRules() {
|
|
3694
|
-
return this.
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
validate: true
|
|
3702
|
-
}),
|
|
3703
|
-
"Kiro"
|
|
3704
|
-
);
|
|
3784
|
+
return await this.loadToolRulesDefault({
|
|
3785
|
+
nonRoot: {
|
|
3786
|
+
relativeFilePath: ".kiro/steering",
|
|
3787
|
+
fromFile: (params) => KiroRule.fromFile(params),
|
|
3788
|
+
extension: "md"
|
|
3789
|
+
}
|
|
3790
|
+
});
|
|
3705
3791
|
}
|
|
3706
3792
|
/**
|
|
3707
3793
|
* Load OpenCode rule configuration from AGENTS.md file and .opencode/memories/*.md files
|
|
3708
3794
|
*/
|
|
3709
3795
|
async loadOpencodeRules() {
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
});
|
|
3721
|
-
rules.push(opencodeRule);
|
|
3722
|
-
logger.info(`Successfully loaded OpenCode agents file`);
|
|
3723
|
-
} catch (error) {
|
|
3724
|
-
logger.warn(`Failed to load OpenCode agents file ${agentsFile}:`, error);
|
|
3725
|
-
}
|
|
3726
|
-
}
|
|
3727
|
-
const memoriesDir = join7(this.baseDir, ".opencode", "memories");
|
|
3728
|
-
if (await directoryExists(memoriesDir)) {
|
|
3729
|
-
try {
|
|
3730
|
-
const entries = await listDirectoryFiles(memoriesDir);
|
|
3731
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3732
|
-
for (const mdFile of mdFiles) {
|
|
3733
|
-
const filePath = join7(memoriesDir, mdFile);
|
|
3734
|
-
try {
|
|
3735
|
-
const opencodeRule = await OpenCodeRule.fromFilePath({
|
|
3736
|
-
baseDir: this.baseDir,
|
|
3737
|
-
relativeDirPath: join7(".opencode", "memories"),
|
|
3738
|
-
relativeFilePath: mdFile,
|
|
3739
|
-
filePath,
|
|
3740
|
-
validate: true
|
|
3741
|
-
});
|
|
3742
|
-
rules.push(opencodeRule);
|
|
3743
|
-
} catch (error) {
|
|
3744
|
-
logger.warn(`Failed to load OpenCode memories file ${filePath}:`, error);
|
|
3745
|
-
}
|
|
3746
|
-
}
|
|
3747
|
-
if (mdFiles.length > 0) {
|
|
3748
|
-
logger.info(`Successfully loaded ${mdFiles.length} OpenCode memory files`);
|
|
3749
|
-
}
|
|
3750
|
-
} catch (error) {
|
|
3751
|
-
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"
|
|
3752
3806
|
}
|
|
3753
|
-
}
|
|
3754
|
-
if (rules.length === 0) {
|
|
3755
|
-
logger.warn(`No OpenCode rule files found`);
|
|
3756
|
-
}
|
|
3757
|
-
return rules;
|
|
3807
|
+
});
|
|
3758
3808
|
}
|
|
3759
3809
|
/**
|
|
3760
3810
|
* Load Qwen Code rule configuration from QWEN.md file and .qwen/memories/*.md files
|
|
3761
3811
|
*/
|
|
3762
3812
|
async loadQwencodeRules() {
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
});
|
|
3774
|
-
rules.push(qwencodeRule);
|
|
3775
|
-
logger.info(`Successfully loaded Qwen Code memory file`);
|
|
3776
|
-
} catch (error) {
|
|
3777
|
-
logger.warn(`Failed to load Qwen Code memory file ${qwenFile}:`, error);
|
|
3778
|
-
}
|
|
3779
|
-
}
|
|
3780
|
-
const memoriesDir = join7(this.baseDir, ".qwen", "memories");
|
|
3781
|
-
if (await directoryExists(memoriesDir)) {
|
|
3782
|
-
try {
|
|
3783
|
-
const entries = await listDirectoryFiles(memoriesDir);
|
|
3784
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md"));
|
|
3785
|
-
for (const mdFile of mdFiles) {
|
|
3786
|
-
const filePath = join7(memoriesDir, mdFile);
|
|
3787
|
-
try {
|
|
3788
|
-
const qwencodeRule = await QwencodeRule.fromFilePath({
|
|
3789
|
-
baseDir: this.baseDir,
|
|
3790
|
-
relativeDirPath: join7(".qwen", "memories"),
|
|
3791
|
-
relativeFilePath: mdFile,
|
|
3792
|
-
filePath,
|
|
3793
|
-
validate: true
|
|
3794
|
-
});
|
|
3795
|
-
rules.push(qwencodeRule);
|
|
3796
|
-
} catch (error) {
|
|
3797
|
-
logger.warn(`Failed to load Qwen Code memories file ${filePath}:`, error);
|
|
3798
|
-
}
|
|
3799
|
-
}
|
|
3800
|
-
if (mdFiles.length > 0) {
|
|
3801
|
-
logger.info(`Successfully loaded ${mdFiles.length} Qwen Code memory files`);
|
|
3802
|
-
}
|
|
3803
|
-
} catch (error) {
|
|
3804
|
-
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"
|
|
3805
3823
|
}
|
|
3806
|
-
}
|
|
3807
|
-
if (rules.length === 0) {
|
|
3808
|
-
logger.warn(`No Qwen Code rule files found`);
|
|
3809
|
-
}
|
|
3810
|
-
return rules;
|
|
3824
|
+
});
|
|
3811
3825
|
}
|
|
3812
3826
|
/**
|
|
3813
3827
|
* Load Roo Code rule configurations from .roo/rules/ directory
|
|
3814
3828
|
*/
|
|
3815
3829
|
async loadRooRules() {
|
|
3816
|
-
return this.
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
validate: true
|
|
3824
|
-
}),
|
|
3825
|
-
"Roo Code"
|
|
3826
|
-
);
|
|
3830
|
+
return await this.loadToolRulesDefault({
|
|
3831
|
+
nonRoot: {
|
|
3832
|
+
relativeFilePath: ".roo/rules",
|
|
3833
|
+
fromFile: (params) => RooRule.fromFile(params),
|
|
3834
|
+
extension: "md"
|
|
3835
|
+
}
|
|
3836
|
+
});
|
|
3827
3837
|
}
|
|
3828
3838
|
/**
|
|
3829
3839
|
* Load Windsurf rule configurations from .windsurf/rules/ directory
|
|
3830
3840
|
*/
|
|
3831
3841
|
async loadWindsurfRules() {
|
|
3832
|
-
return this.
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
relativeFilePath,
|
|
3838
|
-
filePath,
|
|
3839
|
-
validate: true
|
|
3840
|
-
}),
|
|
3841
|
-
"Windsurf"
|
|
3842
|
-
);
|
|
3843
|
-
}
|
|
3844
|
-
/**
|
|
3845
|
-
* Common helper method to load tool rules from a directory with parallel processing
|
|
3846
|
-
*/
|
|
3847
|
-
async loadToolRulesFromDirectory(dirPath, ruleFactory, toolName) {
|
|
3848
|
-
if (!await directoryExists(dirPath)) {
|
|
3849
|
-
logger.warn(`${toolName} rules directory not found: ${dirPath}`);
|
|
3850
|
-
return [];
|
|
3851
|
-
}
|
|
3852
|
-
const entries = await listDirectoryFiles(dirPath);
|
|
3853
|
-
const mdFiles = entries.filter((file) => file.endsWith(".md") || file.endsWith(".mdc"));
|
|
3854
|
-
if (mdFiles.length === 0) {
|
|
3855
|
-
logger.info(`No rule files found in ${dirPath}`);
|
|
3856
|
-
return [];
|
|
3857
|
-
}
|
|
3858
|
-
logger.info(`Found ${mdFiles.length} ${toolName} rule files in ${dirPath}`);
|
|
3859
|
-
const results = await Promise.allSettled(
|
|
3860
|
-
mdFiles.map(async (mdFile) => {
|
|
3861
|
-
const filepath = join7(dirPath, mdFile);
|
|
3862
|
-
return {
|
|
3863
|
-
rule: await ruleFactory(filepath, mdFile),
|
|
3864
|
-
filename: mdFile
|
|
3865
|
-
};
|
|
3866
|
-
})
|
|
3867
|
-
);
|
|
3868
|
-
const toolRules = [];
|
|
3869
|
-
for (const [index, result] of results.entries()) {
|
|
3870
|
-
if (result.status === "fulfilled") {
|
|
3871
|
-
toolRules.push(result.value.rule);
|
|
3872
|
-
logger.debug(`Successfully loaded ${toolName} rule: ${result.value.filename}`);
|
|
3873
|
-
} else {
|
|
3874
|
-
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"
|
|
3875
3847
|
}
|
|
3876
|
-
}
|
|
3877
|
-
logger.info(`Successfully loaded ${toolRules.length} ${toolName} rules`);
|
|
3878
|
-
return toolRules;
|
|
3879
|
-
}
|
|
3880
|
-
async writeToolRulesFromRulesyncRules(rulesyncRules) {
|
|
3881
|
-
const toolRules = await this.convertRulesyncFilesToToolFiles(rulesyncRules);
|
|
3882
|
-
await this.writeAiFiles(toolRules);
|
|
3883
|
-
}
|
|
3884
|
-
async writeRulesyncRulesFromToolRules(toolRules) {
|
|
3885
|
-
const rulesyncRules = await this.convertToolFilesToRulesyncFiles(toolRules);
|
|
3886
|
-
await this.writeAiFiles(rulesyncRules);
|
|
3848
|
+
});
|
|
3887
3849
|
}
|
|
3888
3850
|
/**
|
|
3889
3851
|
* Implementation of abstract method from FeatureProcessor
|
|
@@ -3892,30 +3854,6 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3892
3854
|
static getToolTargets() {
|
|
3893
3855
|
return rulesProcessorToolTargets;
|
|
3894
3856
|
}
|
|
3895
|
-
/**
|
|
3896
|
-
* Get all supported tools
|
|
3897
|
-
*/
|
|
3898
|
-
static getSupportedTools() {
|
|
3899
|
-
const allTools = [
|
|
3900
|
-
"agentsmd",
|
|
3901
|
-
"amazonqcli",
|
|
3902
|
-
"augmentcode",
|
|
3903
|
-
"augmentcode-legacy",
|
|
3904
|
-
"claudecode",
|
|
3905
|
-
"cline",
|
|
3906
|
-
"codexcli",
|
|
3907
|
-
"copilot",
|
|
3908
|
-
"cursor",
|
|
3909
|
-
"geminicli",
|
|
3910
|
-
"junie",
|
|
3911
|
-
"kiro",
|
|
3912
|
-
"opencode",
|
|
3913
|
-
"qwencode",
|
|
3914
|
-
"roo",
|
|
3915
|
-
"windsurf"
|
|
3916
|
-
];
|
|
3917
|
-
return allTools;
|
|
3918
|
-
}
|
|
3919
3857
|
generateXmlReferencesSection(toolRules) {
|
|
3920
3858
|
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
3921
3859
|
if (toolRulesWithoutRoot.length === 0) {
|
|
@@ -3976,14 +3914,15 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
3976
3914
|
};
|
|
3977
3915
|
|
|
3978
3916
|
// src/subagents/subagents-processor.ts
|
|
3979
|
-
import { join as
|
|
3917
|
+
import { basename as basename11, join as join46 } from "path";
|
|
3980
3918
|
import { z as z19 } from "zod/mini";
|
|
3981
3919
|
|
|
3982
3920
|
// src/subagents/claudecode-subagent.ts
|
|
3921
|
+
import { join as join45 } from "path";
|
|
3983
3922
|
import { z as z18 } from "zod/mini";
|
|
3984
3923
|
|
|
3985
3924
|
// src/subagents/rulesync-subagent.ts
|
|
3986
|
-
import { basename as basename10 } from "path";
|
|
3925
|
+
import { basename as basename10, join as join44 } from "path";
|
|
3987
3926
|
import { z as z17 } from "zod/mini";
|
|
3988
3927
|
var RulesyncSubagentModelSchema = z17.enum(["opus", "sonnet", "haiku", "inherit"]);
|
|
3989
3928
|
var RulesyncSubagentFrontmatterSchema = z17.object({
|
|
@@ -4029,14 +3968,16 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
4029
3968
|
return { success: false, error: result.error };
|
|
4030
3969
|
}
|
|
4031
3970
|
}
|
|
4032
|
-
static async
|
|
4033
|
-
|
|
3971
|
+
static async fromFile({
|
|
3972
|
+
relativeFilePath
|
|
3973
|
+
}) {
|
|
3974
|
+
const fileContent = await readFileContent(join44(RULESYNC_SUBAGENTS_DIR, relativeFilePath));
|
|
4034
3975
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4035
3976
|
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
4036
3977
|
if (!result.success) {
|
|
4037
|
-
throw new Error(`Invalid frontmatter in ${
|
|
3978
|
+
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
|
|
4038
3979
|
}
|
|
4039
|
-
const filename = basename10(
|
|
3980
|
+
const filename = basename10(relativeFilePath);
|
|
4040
3981
|
return new _RulesyncSubagent({
|
|
4041
3982
|
baseDir: ".",
|
|
4042
3983
|
relativeDirPath: ".rulesync/subagents",
|
|
@@ -4050,7 +3991,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
4050
3991
|
|
|
4051
3992
|
// src/subagents/tool-subagent.ts
|
|
4052
3993
|
var ToolSubagent = class extends ToolFile {
|
|
4053
|
-
static async
|
|
3994
|
+
static async fromFile(_params) {
|
|
4054
3995
|
throw new Error("Please implement this method in the subclass.");
|
|
4055
3996
|
}
|
|
4056
3997
|
static fromRulesyncSubagent(_params) {
|
|
@@ -4111,7 +4052,6 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4111
4052
|
static fromRulesyncSubagent({
|
|
4112
4053
|
baseDir = ".",
|
|
4113
4054
|
rulesyncSubagent,
|
|
4114
|
-
relativeDirPath,
|
|
4115
4055
|
validate = true
|
|
4116
4056
|
}) {
|
|
4117
4057
|
const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
|
|
@@ -4126,7 +4066,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4126
4066
|
baseDir,
|
|
4127
4067
|
frontmatter: claudecodeFrontmatter,
|
|
4128
4068
|
body,
|
|
4129
|
-
relativeDirPath,
|
|
4069
|
+
relativeDirPath: ".claude/agents",
|
|
4130
4070
|
relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
|
|
4131
4071
|
fileContent,
|
|
4132
4072
|
validate
|
|
@@ -4143,22 +4083,20 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4143
4083
|
return { success: false, error: result.error };
|
|
4144
4084
|
}
|
|
4145
4085
|
}
|
|
4146
|
-
static async
|
|
4086
|
+
static async fromFile({
|
|
4147
4087
|
baseDir = ".",
|
|
4148
|
-
relativeDirPath,
|
|
4149
4088
|
relativeFilePath,
|
|
4150
|
-
filePath,
|
|
4151
4089
|
validate = true
|
|
4152
4090
|
}) {
|
|
4153
|
-
const fileContent = await readFileContent(
|
|
4091
|
+
const fileContent = await readFileContent(join45(baseDir, ".claude/agents", relativeFilePath));
|
|
4154
4092
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4155
4093
|
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
4156
4094
|
if (!result.success) {
|
|
4157
|
-
throw new Error(`Invalid frontmatter in ${
|
|
4095
|
+
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${result.error.message}`);
|
|
4158
4096
|
}
|
|
4159
4097
|
return new _ClaudecodeSubagent({
|
|
4160
4098
|
baseDir,
|
|
4161
|
-
relativeDirPath,
|
|
4099
|
+
relativeDirPath: ".claude/agents",
|
|
4162
4100
|
relativeFilePath,
|
|
4163
4101
|
frontmatter: result.data,
|
|
4164
4102
|
body: content.trim(),
|
|
@@ -4212,7 +4150,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4212
4150
|
* Load and parse rulesync subagent files from .rulesync/subagents/ directory
|
|
4213
4151
|
*/
|
|
4214
4152
|
async loadRulesyncFiles() {
|
|
4215
|
-
const subagentsDir =
|
|
4153
|
+
const subagentsDir = join46(this.baseDir, ".rulesync", "subagents");
|
|
4216
4154
|
const dirExists = await directoryExists(subagentsDir);
|
|
4217
4155
|
if (!dirExists) {
|
|
4218
4156
|
logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
|
|
@@ -4227,10 +4165,11 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4227
4165
|
logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
|
|
4228
4166
|
const rulesyncSubagents = [];
|
|
4229
4167
|
for (const mdFile of mdFiles) {
|
|
4230
|
-
const filepath =
|
|
4168
|
+
const filepath = join46(subagentsDir, mdFile);
|
|
4231
4169
|
try {
|
|
4232
|
-
const rulesyncSubagent = await RulesyncSubagent.
|
|
4233
|
-
|
|
4170
|
+
const rulesyncSubagent = await RulesyncSubagent.fromFile({
|
|
4171
|
+
relativeFilePath: mdFile,
|
|
4172
|
+
validate: true
|
|
4234
4173
|
});
|
|
4235
4174
|
rulesyncSubagents.push(rulesyncSubagent);
|
|
4236
4175
|
logger.debug(`Successfully loaded subagent: ${mdFile}`);
|
|
@@ -4262,43 +4201,19 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4262
4201
|
* Load Claude Code subagent configurations from .claude/agents/ directory
|
|
4263
4202
|
*/
|
|
4264
4203
|
async loadClaudecodeSubagents() {
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
}
|
|
4277
|
-
|
|
4278
|
-
if (mdFiles.length === 0) {
|
|
4279
|
-
logger.info(`No JSON agent files found in ${agentsDir}`);
|
|
4280
|
-
return [];
|
|
4281
|
-
}
|
|
4282
|
-
logger.info(`Found ${mdFiles.length} Claude Code agent files in ${agentsDir}`);
|
|
4283
|
-
const toolSubagents = [];
|
|
4284
|
-
for (const mdFile of mdFiles) {
|
|
4285
|
-
const filepath = join8(agentsDir, mdFile);
|
|
4286
|
-
try {
|
|
4287
|
-
const claudecodeSubagent = await ClaudecodeSubagent.fromFilePath({
|
|
4288
|
-
baseDir: this.baseDir,
|
|
4289
|
-
relativeDirPath: ".claude/agents",
|
|
4290
|
-
relativeFilePath: mdFile,
|
|
4291
|
-
filePath: filepath
|
|
4292
|
-
});
|
|
4293
|
-
toolSubagents.push(claudecodeSubagent);
|
|
4294
|
-
logger.debug(`Successfully loaded Claude Code agent: ${mdFile}`);
|
|
4295
|
-
} catch (error) {
|
|
4296
|
-
logger.warn(`Failed to load Claude Code agent file ${filepath}:`, error);
|
|
4297
|
-
continue;
|
|
4298
|
-
}
|
|
4299
|
-
}
|
|
4300
|
-
logger.info(`Successfully loaded ${toolSubagents.length} Claude Code subagents`);
|
|
4301
|
-
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;
|
|
4302
4217
|
}
|
|
4303
4218
|
/**
|
|
4304
4219
|
* Implementation of abstract method from FeatureProcessor
|
|
@@ -4334,7 +4249,7 @@ async function generateCommand(options) {
|
|
|
4334
4249
|
}
|
|
4335
4250
|
let rulesyncFiles = await processor.loadRulesyncFiles();
|
|
4336
4251
|
if (rulesyncFiles.length === 0) {
|
|
4337
|
-
rulesyncFiles = await processor.
|
|
4252
|
+
rulesyncFiles = await processor.loadRulesyncFilesLegacy();
|
|
4338
4253
|
}
|
|
4339
4254
|
const toolFiles = await processor.convertRulesyncFilesToToolFiles(rulesyncFiles);
|
|
4340
4255
|
const writtenCount = await processor.writeAiFiles(toolFiles);
|
|
@@ -4488,9 +4403,9 @@ async function generateCommand(options) {
|
|
|
4488
4403
|
}
|
|
4489
4404
|
|
|
4490
4405
|
// src/cli/commands/gitignore.ts
|
|
4491
|
-
import { join as
|
|
4406
|
+
import { join as join47 } from "path";
|
|
4492
4407
|
var gitignoreCommand = async () => {
|
|
4493
|
-
const gitignorePath =
|
|
4408
|
+
const gitignorePath = join47(process.cwd(), ".gitignore");
|
|
4494
4409
|
const rulesFilesToIgnore = [
|
|
4495
4410
|
"# Generated by rulesync - AI tool configuration files",
|
|
4496
4411
|
"**/.amazonq/rules/",
|
|
@@ -4619,6 +4534,24 @@ async function importCommand(options) {
|
|
|
4619
4534
|
logger.success(`Created ${ignoreFileCreated} ignore files`);
|
|
4620
4535
|
}
|
|
4621
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
|
+
}
|
|
4622
4555
|
let subagentsCreated = 0;
|
|
4623
4556
|
if (config.getFeatures().includes("subagents")) {
|
|
4624
4557
|
if (SubagentsProcessor.getToolTargets().includes(tool)) {
|
|
@@ -4659,7 +4592,7 @@ async function importCommand(options) {
|
|
|
4659
4592
|
}
|
|
4660
4593
|
|
|
4661
4594
|
// src/cli/commands/init.ts
|
|
4662
|
-
import { join as
|
|
4595
|
+
import { join as join48 } from "path";
|
|
4663
4596
|
async function initCommand() {
|
|
4664
4597
|
logger.info("Initializing rulesync...");
|
|
4665
4598
|
await ensureDir(RULESYNC_DIR);
|
|
@@ -4705,7 +4638,7 @@ globs: ["**/*"]
|
|
|
4705
4638
|
- Follow single responsibility principle
|
|
4706
4639
|
`
|
|
4707
4640
|
};
|
|
4708
|
-
const filepath =
|
|
4641
|
+
const filepath = join48(RULESYNC_RULES_DIR, sampleFile.filename);
|
|
4709
4642
|
await ensureDir(RULESYNC_RULES_DIR);
|
|
4710
4643
|
await ensureDir(RULESYNC_COMMANDS_DIR);
|
|
4711
4644
|
await ensureDir(RULESYNC_SUBAGENTS_DIR);
|
|
@@ -4723,15 +4656,15 @@ var getVersion = async () => {
|
|
|
4723
4656
|
let packageJsonPath;
|
|
4724
4657
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
4725
4658
|
const __filename = fileURLToPath(import.meta.url);
|
|
4726
|
-
const __dirname =
|
|
4727
|
-
packageJsonPath =
|
|
4659
|
+
const __dirname = join49(__filename, "..");
|
|
4660
|
+
packageJsonPath = join49(__dirname, "../../package.json");
|
|
4728
4661
|
} else {
|
|
4729
|
-
packageJsonPath =
|
|
4662
|
+
packageJsonPath = join49(process.cwd(), "package.json");
|
|
4730
4663
|
}
|
|
4731
4664
|
const packageJson = await readJsonFile(packageJsonPath);
|
|
4732
4665
|
return packageJson.version;
|
|
4733
4666
|
} catch {
|
|
4734
|
-
return "0.
|
|
4667
|
+
return "0.70.0";
|
|
4735
4668
|
}
|
|
4736
4669
|
};
|
|
4737
4670
|
var main = async () => {
|