rulesync 0.42.0 → 0.43.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/dist/{chunk-SXEFNT27.js → chunk-2FR4Z37J.js} +1 -1
- package/dist/{chunk-HMMPZV7X.js → chunk-B3627VQY.js} +8 -6
- package/dist/{chunk-3NRSCDLQ.js → chunk-RL3TE3EZ.js} +5 -5
- package/dist/{chunk-2SPL7QTK.js → chunk-TCK42GOL.js} +1 -1
- package/dist/chunk-THWXK5Z2.js +35 -0
- package/dist/{chunk-X3FEMISQ.js → chunk-XHRBWFGI.js} +1 -1
- package/dist/{chunk-D3YGI36J.js → chunk-ZMAL5LIX.js} +7 -2
- package/dist/{claude-3YGZIO5F.js → claudecode-ITHKV345.js} +2 -2
- package/dist/{cline-ERYW7TOO.js → cline-PKE6TYNJ.js} +2 -2
- package/dist/{copilot-NLSI3ID7.js → copilot-5JP6D4NO.js} +2 -2
- package/dist/{cursor-CX55HMO4.js → cursor-RHFDG6T2.js} +2 -2
- package/dist/{geminicli-XHQR4RCQ.js → geminicli-B3FFO5WV.js} +2 -2
- package/dist/index.cjs +133 -152
- package/dist/index.js +106 -104
- package/dist/{roo-OKE7XF3B.js → roo-UOTKEOH7.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-6YNGMPAL.js +0 -56
package/dist/index.cjs
CHANGED
|
@@ -26,44 +26,23 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
mod
|
|
27
27
|
));
|
|
28
28
|
|
|
29
|
-
// src/
|
|
30
|
-
var
|
|
31
|
-
var
|
|
32
|
-
"src/
|
|
29
|
+
// src/types/tool-targets.ts
|
|
30
|
+
var import_v42, ToolTargetSchema, ToolTargetsSchema, WildcardTargetSchema, RulesyncTargetsSchema;
|
|
31
|
+
var init_tool_targets = __esm({
|
|
32
|
+
"src/types/tool-targets.ts"() {
|
|
33
33
|
"use strict";
|
|
34
|
-
|
|
35
|
-
ToolTargetSchema =
|
|
34
|
+
import_v42 = require("zod/v4");
|
|
35
|
+
ToolTargetSchema = import_v42.z.enum([
|
|
36
36
|
"copilot",
|
|
37
37
|
"cursor",
|
|
38
38
|
"cline",
|
|
39
39
|
"claudecode",
|
|
40
|
-
"claude",
|
|
41
40
|
"roo",
|
|
42
41
|
"geminicli"
|
|
43
42
|
]);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
RulesyncTargetsSchema =
|
|
47
|
-
McpTransportTypeSchema = import_zod.z.enum(["stdio", "sse", "http"]);
|
|
48
|
-
McpServerBaseSchema = import_zod.z.object({
|
|
49
|
-
command: import_zod.z.string().optional(),
|
|
50
|
-
args: import_zod.z.array(import_zod.z.string()).optional(),
|
|
51
|
-
url: import_zod.z.string().optional(),
|
|
52
|
-
httpUrl: import_zod.z.string().optional(),
|
|
53
|
-
env: import_zod.z.record(import_zod.z.string()).optional(),
|
|
54
|
-
disabled: import_zod.z.boolean().optional(),
|
|
55
|
-
networkTimeout: import_zod.z.number().optional(),
|
|
56
|
-
timeout: import_zod.z.number().optional(),
|
|
57
|
-
trust: import_zod.z.boolean().optional(),
|
|
58
|
-
cwd: import_zod.z.string().optional(),
|
|
59
|
-
transport: McpTransportTypeSchema.optional(),
|
|
60
|
-
type: import_zod.z.enum(["sse", "streamable-http"]).optional(),
|
|
61
|
-
alwaysAllow: import_zod.z.array(import_zod.z.string()).optional(),
|
|
62
|
-
tools: import_zod.z.array(import_zod.z.string()).optional()
|
|
63
|
-
});
|
|
64
|
-
RulesyncMcpServerSchema = McpServerBaseSchema.extend({
|
|
65
|
-
targets: RulesyncTargetsSchema.optional()
|
|
66
|
-
});
|
|
43
|
+
ToolTargetsSchema = import_v42.z.array(ToolTargetSchema);
|
|
44
|
+
WildcardTargetSchema = import_v42.z.tuple([import_v42.z.literal("*")]);
|
|
45
|
+
RulesyncTargetsSchema = import_v42.z.union([ToolTargetsSchema, WildcardTargetSchema]);
|
|
67
46
|
}
|
|
68
47
|
});
|
|
69
48
|
|
|
@@ -87,17 +66,17 @@ function shouldIncludeServer(server, targetTool) {
|
|
|
87
66
|
var init_mcp_helpers = __esm({
|
|
88
67
|
"src/utils/mcp-helpers.ts"() {
|
|
89
68
|
"use strict";
|
|
90
|
-
|
|
69
|
+
init_tool_targets();
|
|
91
70
|
}
|
|
92
71
|
});
|
|
93
72
|
|
|
94
|
-
// src/generators/mcp/
|
|
73
|
+
// src/generators/mcp/claudecode.ts
|
|
95
74
|
function generateClaudeMcp(config) {
|
|
96
75
|
const claudeSettings = {
|
|
97
76
|
mcpServers: {}
|
|
98
77
|
};
|
|
99
78
|
const shouldInclude = (server) => {
|
|
100
|
-
return shouldIncludeServer(server, "
|
|
79
|
+
return shouldIncludeServer(server, "claudecode");
|
|
101
80
|
};
|
|
102
81
|
for (const [serverName, server] of Object.entries(config.mcpServers)) {
|
|
103
82
|
if (!shouldInclude(server)) continue;
|
|
@@ -123,8 +102,8 @@ function generateClaudeMcp(config) {
|
|
|
123
102
|
}
|
|
124
103
|
return JSON.stringify(claudeSettings, null, 2);
|
|
125
104
|
}
|
|
126
|
-
var
|
|
127
|
-
"src/generators/mcp/
|
|
105
|
+
var init_claudecode = __esm({
|
|
106
|
+
"src/generators/mcp/claudecode.ts"() {
|
|
128
107
|
"use strict";
|
|
129
108
|
init_mcp_helpers();
|
|
130
109
|
}
|
|
@@ -370,7 +349,7 @@ var import_commander = require("commander");
|
|
|
370
349
|
|
|
371
350
|
// src/cli/commands/add.ts
|
|
372
351
|
var import_promises = require("fs/promises");
|
|
373
|
-
var
|
|
352
|
+
var path = __toESM(require("path"), 1);
|
|
374
353
|
|
|
375
354
|
// src/utils/config.ts
|
|
376
355
|
function getDefaultConfig() {
|
|
@@ -381,12 +360,11 @@ function getDefaultConfig() {
|
|
|
381
360
|
cursor: ".cursor/rules",
|
|
382
361
|
cline: ".clinerules",
|
|
383
362
|
claudecode: ".",
|
|
384
|
-
claude: ".",
|
|
385
363
|
roo: ".roo/rules",
|
|
386
364
|
geminicli: ".gemini/memories"
|
|
387
365
|
},
|
|
388
366
|
watchEnabled: false,
|
|
389
|
-
defaultTargets: ["copilot", "cursor", "cline", "claudecode", "
|
|
367
|
+
defaultTargets: ["copilot", "cursor", "cline", "claudecode", "roo", "geminicli"]
|
|
390
368
|
};
|
|
391
369
|
}
|
|
392
370
|
function resolveTargets(targets, config) {
|
|
@@ -418,7 +396,7 @@ async function addCommand(filename) {
|
|
|
418
396
|
const config = getDefaultConfig();
|
|
419
397
|
const sanitizedFilename = sanitizeFilename(filename);
|
|
420
398
|
const rulesDir = config.aiRulesDir;
|
|
421
|
-
const filePath =
|
|
399
|
+
const filePath = path.join(rulesDir, `${sanitizedFilename}.md`);
|
|
422
400
|
await (0, import_promises.mkdir)(rulesDir, { recursive: true });
|
|
423
401
|
const template = generateRuleTemplate(sanitizedFilename);
|
|
424
402
|
await (0, import_promises.writeFile)(filePath, template, "utf8");
|
|
@@ -433,15 +411,23 @@ async function addCommand(filename) {
|
|
|
433
411
|
}
|
|
434
412
|
|
|
435
413
|
// src/generators/rules/claudecode.ts
|
|
436
|
-
var
|
|
414
|
+
var import_node_path4 = require("path");
|
|
415
|
+
|
|
416
|
+
// src/types/claudecode.ts
|
|
417
|
+
var import_v4 = require("zod/v4");
|
|
418
|
+
var ClaudeSettingsSchema = import_v4.z.looseObject({
|
|
419
|
+
permissions: import_v4.z.looseObject({
|
|
420
|
+
deny: import_v4.z.array(import_v4.z.string()).default([])
|
|
421
|
+
}).default({ deny: [] })
|
|
422
|
+
});
|
|
437
423
|
|
|
438
424
|
// src/utils/file.ts
|
|
439
425
|
var import_promises3 = require("fs/promises");
|
|
440
|
-
var
|
|
426
|
+
var import_node_path3 = require("path");
|
|
441
427
|
|
|
442
428
|
// src/utils/file-ops.ts
|
|
443
429
|
var import_promises2 = require("fs/promises");
|
|
444
|
-
var
|
|
430
|
+
var import_node_path = require("path");
|
|
445
431
|
async function ensureDir(dirPath) {
|
|
446
432
|
try {
|
|
447
433
|
await (0, import_promises2.stat)(dirPath);
|
|
@@ -453,7 +439,7 @@ async function readFileContent(filepath) {
|
|
|
453
439
|
return (0, import_promises2.readFile)(filepath, "utf-8");
|
|
454
440
|
}
|
|
455
441
|
async function writeFileContent(filepath, content) {
|
|
456
|
-
await ensureDir((0,
|
|
442
|
+
await ensureDir((0, import_node_path.dirname)(filepath));
|
|
457
443
|
await (0, import_promises2.writeFile)(filepath, content, "utf-8");
|
|
458
444
|
}
|
|
459
445
|
async function fileExists(filepath) {
|
|
@@ -466,14 +452,14 @@ async function fileExists(filepath) {
|
|
|
466
452
|
}
|
|
467
453
|
|
|
468
454
|
// src/utils/ignore.ts
|
|
469
|
-
var
|
|
455
|
+
var import_node_path2 = require("path");
|
|
470
456
|
var import_micromatch = __toESM(require("micromatch"), 1);
|
|
471
457
|
var cachedIgnorePatterns = null;
|
|
472
458
|
async function loadIgnorePatterns(baseDir = process.cwd()) {
|
|
473
459
|
if (cachedIgnorePatterns) {
|
|
474
460
|
return cachedIgnorePatterns;
|
|
475
461
|
}
|
|
476
|
-
const ignorePath = (0,
|
|
462
|
+
const ignorePath = (0, import_node_path2.join)(baseDir, ".rulesyncignore");
|
|
477
463
|
if (!await fileExists(ignorePath)) {
|
|
478
464
|
cachedIgnorePatterns = { patterns: [] };
|
|
479
465
|
return cachedIgnorePatterns;
|
|
@@ -520,7 +506,7 @@ function filterIgnoredFiles(files, ignorePatterns) {
|
|
|
520
506
|
async function findFiles(dir, extension = ".md", ignorePatterns) {
|
|
521
507
|
try {
|
|
522
508
|
const files = await (0, import_promises3.readdir)(dir);
|
|
523
|
-
const filtered = files.filter((file) => file.endsWith(extension)).map((file) => (0,
|
|
509
|
+
const filtered = files.filter((file) => file.endsWith(extension)).map((file) => (0, import_node_path3.join)(dir, file));
|
|
524
510
|
if (ignorePatterns && ignorePatterns.length > 0) {
|
|
525
511
|
return filterIgnoredFiles(filtered, ignorePatterns);
|
|
526
512
|
}
|
|
@@ -569,23 +555,23 @@ async function generateClaudecodeConfig(rules, config, baseDir) {
|
|
|
569
555
|
const rootRules = rules.filter((r) => r.frontmatter.root === true);
|
|
570
556
|
const detailRules = rules.filter((r) => r.frontmatter.root === false);
|
|
571
557
|
const claudeMdContent = generateClaudeMarkdown(rootRules, detailRules);
|
|
572
|
-
const claudeOutputDir = baseDir ? (0,
|
|
558
|
+
const claudeOutputDir = baseDir ? (0, import_node_path4.join)(baseDir, config.outputPaths.claudecode) : config.outputPaths.claudecode;
|
|
573
559
|
outputs.push({
|
|
574
560
|
tool: "claudecode",
|
|
575
|
-
filepath: (0,
|
|
561
|
+
filepath: (0, import_node_path4.join)(claudeOutputDir, "CLAUDE.md"),
|
|
576
562
|
content: claudeMdContent
|
|
577
563
|
});
|
|
578
564
|
for (const rule of detailRules) {
|
|
579
565
|
const memoryContent = generateMemoryFile(rule);
|
|
580
566
|
outputs.push({
|
|
581
567
|
tool: "claudecode",
|
|
582
|
-
filepath: (0,
|
|
568
|
+
filepath: (0, import_node_path4.join)(claudeOutputDir, ".claude", "memories", `${rule.filename}.md`),
|
|
583
569
|
content: memoryContent
|
|
584
570
|
});
|
|
585
571
|
}
|
|
586
572
|
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
587
573
|
if (ignorePatterns.patterns.length > 0) {
|
|
588
|
-
const settingsPath = baseDir ? (0,
|
|
574
|
+
const settingsPath = baseDir ? (0, import_node_path4.join)(baseDir, ".claude", "settings.json") : (0, import_node_path4.join)(".claude", "settings.json");
|
|
589
575
|
await updateClaudeSettings(settingsPath, ignorePatterns.patterns);
|
|
590
576
|
}
|
|
591
577
|
return outputs;
|
|
@@ -617,51 +603,46 @@ function generateMemoryFile(rule) {
|
|
|
617
603
|
return rule.content.trim();
|
|
618
604
|
}
|
|
619
605
|
async function updateClaudeSettings(settingsPath, ignorePatterns) {
|
|
620
|
-
let
|
|
606
|
+
let rawSettings = {};
|
|
621
607
|
if (await fileExists(settingsPath)) {
|
|
622
608
|
try {
|
|
623
609
|
const content = await readFileContent(settingsPath);
|
|
624
|
-
|
|
610
|
+
rawSettings = JSON.parse(content);
|
|
625
611
|
} catch {
|
|
626
612
|
console.warn(`Failed to parse existing ${settingsPath}, creating new settings`);
|
|
627
|
-
|
|
613
|
+
rawSettings = {};
|
|
628
614
|
}
|
|
629
615
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
settingsObj.permissions = {};
|
|
616
|
+
const parseResult = ClaudeSettingsSchema.safeParse(rawSettings);
|
|
617
|
+
const settings = parseResult.success ? parseResult.data : ClaudeSettingsSchema.parse({});
|
|
618
|
+
const readDenyRules = ignorePatterns.map((pattern) => `Read(${pattern})`);
|
|
619
|
+
if (!settings.permissions) {
|
|
620
|
+
settings.permissions = { deny: [] };
|
|
636
621
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
permissions.deny = [];
|
|
622
|
+
if (!Array.isArray(settings.permissions.deny)) {
|
|
623
|
+
settings.permissions.deny = [];
|
|
640
624
|
}
|
|
641
|
-
const
|
|
642
|
-
const denyArray = permissions.deny;
|
|
643
|
-
const filteredDeny = denyArray.filter((rule) => {
|
|
644
|
-
if (typeof rule !== "string") return false;
|
|
625
|
+
const filteredDeny = settings.permissions.deny.filter((rule) => {
|
|
645
626
|
if (!rule.startsWith("Read(")) return true;
|
|
646
627
|
const match = rule.match(/^Read\((.*)\)$/);
|
|
647
628
|
if (!match) return true;
|
|
648
629
|
return !ignorePatterns.includes(match[1] ?? "");
|
|
649
630
|
});
|
|
650
631
|
filteredDeny.push(...readDenyRules);
|
|
651
|
-
permissions.deny =
|
|
652
|
-
const jsonContent = JSON.stringify(
|
|
632
|
+
settings.permissions.deny = Array.from(new Set(filteredDeny));
|
|
633
|
+
const jsonContent = JSON.stringify(settings, null, 2);
|
|
653
634
|
await writeFileContent(settingsPath, jsonContent);
|
|
654
635
|
console.log(`\u2705 Updated Claude Code settings: ${settingsPath}`);
|
|
655
636
|
}
|
|
656
637
|
|
|
657
638
|
// src/generators/rules/cline.ts
|
|
658
|
-
var
|
|
639
|
+
var import_node_path5 = require("path");
|
|
659
640
|
async function generateClineConfig(rules, config, baseDir) {
|
|
660
641
|
const outputs = [];
|
|
661
642
|
for (const rule of rules) {
|
|
662
643
|
const content = generateClineMarkdown(rule);
|
|
663
|
-
const outputDir = baseDir ? (0,
|
|
664
|
-
const filepath = (0,
|
|
644
|
+
const outputDir = baseDir ? (0, import_node_path5.join)(baseDir, config.outputPaths.cline) : config.outputPaths.cline;
|
|
645
|
+
const filepath = (0, import_node_path5.join)(outputDir, `${rule.filename}.md`);
|
|
665
646
|
outputs.push({
|
|
666
647
|
tool: "cline",
|
|
667
648
|
filepath,
|
|
@@ -670,7 +651,7 @@ async function generateClineConfig(rules, config, baseDir) {
|
|
|
670
651
|
}
|
|
671
652
|
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
672
653
|
if (ignorePatterns.patterns.length > 0) {
|
|
673
|
-
const clineIgnorePath = baseDir ? (0,
|
|
654
|
+
const clineIgnorePath = baseDir ? (0, import_node_path5.join)(baseDir, ".clineignore") : ".clineignore";
|
|
674
655
|
const clineIgnoreContent = generateClineIgnore(ignorePatterns.patterns);
|
|
675
656
|
outputs.push({
|
|
676
657
|
tool: "cline",
|
|
@@ -694,14 +675,14 @@ function generateClineIgnore(patterns) {
|
|
|
694
675
|
}
|
|
695
676
|
|
|
696
677
|
// src/generators/rules/copilot.ts
|
|
697
|
-
var
|
|
678
|
+
var import_node_path6 = require("path");
|
|
698
679
|
async function generateCopilotConfig(rules, config, baseDir) {
|
|
699
680
|
const outputs = [];
|
|
700
681
|
for (const rule of rules) {
|
|
701
682
|
const content = generateCopilotMarkdown(rule);
|
|
702
683
|
const baseFilename = rule.filename.replace(/\.md$/, "");
|
|
703
|
-
const outputDir = baseDir ? (0,
|
|
704
|
-
const filepath = (0,
|
|
684
|
+
const outputDir = baseDir ? (0, import_node_path6.join)(baseDir, config.outputPaths.copilot) : config.outputPaths.copilot;
|
|
685
|
+
const filepath = (0, import_node_path6.join)(outputDir, `${baseFilename}.instructions.md`);
|
|
705
686
|
outputs.push({
|
|
706
687
|
tool: "copilot",
|
|
707
688
|
filepath,
|
|
@@ -710,7 +691,7 @@ async function generateCopilotConfig(rules, config, baseDir) {
|
|
|
710
691
|
}
|
|
711
692
|
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
712
693
|
if (ignorePatterns.patterns.length > 0) {
|
|
713
|
-
const copilotIgnorePath = baseDir ? (0,
|
|
694
|
+
const copilotIgnorePath = baseDir ? (0, import_node_path6.join)(baseDir, ".copilotignore") : ".copilotignore";
|
|
714
695
|
const copilotIgnoreContent = generateCopilotIgnore(ignorePatterns.patterns);
|
|
715
696
|
outputs.push({
|
|
716
697
|
tool: "copilot",
|
|
@@ -746,13 +727,13 @@ function generateCopilotIgnore(patterns) {
|
|
|
746
727
|
}
|
|
747
728
|
|
|
748
729
|
// src/generators/rules/cursor.ts
|
|
749
|
-
var
|
|
730
|
+
var import_node_path7 = require("path");
|
|
750
731
|
async function generateCursorConfig(rules, config, baseDir) {
|
|
751
732
|
const outputs = [];
|
|
752
733
|
for (const rule of rules) {
|
|
753
734
|
const content = generateCursorMarkdown(rule);
|
|
754
|
-
const outputDir = baseDir ? (0,
|
|
755
|
-
const filepath = (0,
|
|
735
|
+
const outputDir = baseDir ? (0, import_node_path7.join)(baseDir, config.outputPaths.cursor) : config.outputPaths.cursor;
|
|
736
|
+
const filepath = (0, import_node_path7.join)(outputDir, `${rule.filename}.mdc`);
|
|
756
737
|
outputs.push({
|
|
757
738
|
tool: "cursor",
|
|
758
739
|
filepath,
|
|
@@ -761,7 +742,7 @@ async function generateCursorConfig(rules, config, baseDir) {
|
|
|
761
742
|
}
|
|
762
743
|
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
763
744
|
if (ignorePatterns.patterns.length > 0) {
|
|
764
|
-
const cursorIgnorePath = baseDir ? (0,
|
|
745
|
+
const cursorIgnorePath = baseDir ? (0, import_node_path7.join)(baseDir, ".cursorignore") : ".cursorignore";
|
|
765
746
|
const cursorIgnoreContent = generateCursorIgnore(ignorePatterns.patterns);
|
|
766
747
|
outputs.push({
|
|
767
748
|
tool: "cursor",
|
|
@@ -834,15 +815,15 @@ function generateCursorIgnore(patterns) {
|
|
|
834
815
|
}
|
|
835
816
|
|
|
836
817
|
// src/generators/rules/geminicli.ts
|
|
837
|
-
var
|
|
818
|
+
var import_node_path8 = require("path");
|
|
838
819
|
async function generateGeminiConfig(rules, config, baseDir) {
|
|
839
820
|
const outputs = [];
|
|
840
821
|
const rootRule = rules.find((rule) => rule.frontmatter.root === true);
|
|
841
822
|
const memoryRules = rules.filter((rule) => rule.frontmatter.root === false);
|
|
842
823
|
for (const rule of memoryRules) {
|
|
843
824
|
const content = generateGeminiMemoryMarkdown(rule);
|
|
844
|
-
const outputDir = baseDir ? (0,
|
|
845
|
-
const filepath = (0,
|
|
825
|
+
const outputDir = baseDir ? (0, import_node_path8.join)(baseDir, config.outputPaths.geminicli) : config.outputPaths.geminicli;
|
|
826
|
+
const filepath = (0, import_node_path8.join)(outputDir, `${rule.filename}.md`);
|
|
846
827
|
outputs.push({
|
|
847
828
|
tool: "geminicli",
|
|
848
829
|
filepath,
|
|
@@ -850,7 +831,7 @@ async function generateGeminiConfig(rules, config, baseDir) {
|
|
|
850
831
|
});
|
|
851
832
|
}
|
|
852
833
|
const rootContent = generateGeminiRootMarkdown(rootRule, memoryRules, baseDir);
|
|
853
|
-
const rootFilepath = baseDir ? (0,
|
|
834
|
+
const rootFilepath = baseDir ? (0, import_node_path8.join)(baseDir, "GEMINI.md") : "GEMINI.md";
|
|
854
835
|
outputs.push({
|
|
855
836
|
tool: "geminicli",
|
|
856
837
|
filepath: rootFilepath,
|
|
@@ -858,7 +839,7 @@ async function generateGeminiConfig(rules, config, baseDir) {
|
|
|
858
839
|
});
|
|
859
840
|
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
860
841
|
if (ignorePatterns.patterns.length > 0) {
|
|
861
|
-
const aiexcludePath = baseDir ? (0,
|
|
842
|
+
const aiexcludePath = baseDir ? (0, import_node_path8.join)(baseDir, ".aiexclude") : ".aiexclude";
|
|
862
843
|
const aiexcludeContent = generateAiexclude(ignorePatterns.patterns);
|
|
863
844
|
outputs.push({
|
|
864
845
|
tool: "geminicli",
|
|
@@ -906,13 +887,13 @@ function generateAiexclude(patterns) {
|
|
|
906
887
|
}
|
|
907
888
|
|
|
908
889
|
// src/generators/rules/roo.ts
|
|
909
|
-
var
|
|
890
|
+
var import_node_path9 = require("path");
|
|
910
891
|
async function generateRooConfig(rules, config, baseDir) {
|
|
911
892
|
const outputs = [];
|
|
912
893
|
for (const rule of rules) {
|
|
913
894
|
const content = generateRooMarkdown(rule);
|
|
914
|
-
const outputDir = baseDir ? (0,
|
|
915
|
-
const filepath = (0,
|
|
895
|
+
const outputDir = baseDir ? (0, import_node_path9.join)(baseDir, config.outputPaths.roo) : config.outputPaths.roo;
|
|
896
|
+
const filepath = (0, import_node_path9.join)(outputDir, `${rule.filename}.md`);
|
|
916
897
|
outputs.push({
|
|
917
898
|
tool: "roo",
|
|
918
899
|
filepath,
|
|
@@ -921,7 +902,7 @@ async function generateRooConfig(rules, config, baseDir) {
|
|
|
921
902
|
}
|
|
922
903
|
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
923
904
|
if (ignorePatterns.patterns.length > 0) {
|
|
924
|
-
const rooIgnorePath = baseDir ? (0,
|
|
905
|
+
const rooIgnorePath = baseDir ? (0, import_node_path9.join)(baseDir, ".rooignore") : ".rooignore";
|
|
925
906
|
const rooIgnoreContent = generateRooIgnore(ignorePatterns.patterns);
|
|
926
907
|
outputs.push({
|
|
927
908
|
tool: "roo",
|
|
@@ -994,7 +975,7 @@ async function generateForTool(tool, rules, config, baseDir) {
|
|
|
994
975
|
}
|
|
995
976
|
|
|
996
977
|
// src/core/parser.ts
|
|
997
|
-
var
|
|
978
|
+
var import_node_path10 = require("path");
|
|
998
979
|
var import_gray_matter = __toESM(require("gray-matter"), 1);
|
|
999
980
|
async function parseRulesFromDirectory(aiRulesDir) {
|
|
1000
981
|
const ignorePatterns = await loadIgnorePatterns();
|
|
@@ -1031,7 +1012,7 @@ async function parseRuleFile(filepath) {
|
|
|
1031
1012
|
const parsed = (0, import_gray_matter.default)(content);
|
|
1032
1013
|
validateFrontmatter(parsed.data, filepath);
|
|
1033
1014
|
const frontmatter = parsed.data;
|
|
1034
|
-
const filename = (0,
|
|
1015
|
+
const filename = (0, import_node_path10.basename)(filepath, ".md");
|
|
1035
1016
|
return {
|
|
1036
1017
|
frontmatter,
|
|
1037
1018
|
content: parsed.content,
|
|
@@ -1160,10 +1141,10 @@ async function validateRule(rule) {
|
|
|
1160
1141
|
}
|
|
1161
1142
|
|
|
1162
1143
|
// src/core/mcp-generator.ts
|
|
1163
|
-
var
|
|
1144
|
+
var path3 = __toESM(require("path"), 1);
|
|
1164
1145
|
|
|
1165
1146
|
// src/generators/mcp/index.ts
|
|
1166
|
-
|
|
1147
|
+
init_claudecode();
|
|
1167
1148
|
init_cline();
|
|
1168
1149
|
init_copilot();
|
|
1169
1150
|
init_cursor();
|
|
@@ -1171,15 +1152,15 @@ init_geminicli();
|
|
|
1171
1152
|
init_roo();
|
|
1172
1153
|
|
|
1173
1154
|
// src/core/mcp-parser.ts
|
|
1174
|
-
var
|
|
1175
|
-
var
|
|
1155
|
+
var fs = __toESM(require("fs"), 1);
|
|
1156
|
+
var path2 = __toESM(require("path"), 1);
|
|
1176
1157
|
function parseMcpConfig(projectRoot) {
|
|
1177
|
-
const mcpPath =
|
|
1178
|
-
if (!
|
|
1158
|
+
const mcpPath = path2.join(projectRoot, ".rulesync", ".mcp.json");
|
|
1159
|
+
if (!fs.existsSync(mcpPath)) {
|
|
1179
1160
|
return null;
|
|
1180
1161
|
}
|
|
1181
1162
|
try {
|
|
1182
|
-
const content =
|
|
1163
|
+
const content = fs.readFileSync(mcpPath, "utf-8");
|
|
1183
1164
|
const rawConfig = JSON.parse(content);
|
|
1184
1165
|
if (rawConfig.servers && !rawConfig.mcpServers) {
|
|
1185
1166
|
rawConfig.mcpServers = rawConfig.servers;
|
|
@@ -1210,32 +1191,32 @@ async function generateMcpConfigs(projectRoot, baseDir) {
|
|
|
1210
1191
|
const generators = [
|
|
1211
1192
|
{
|
|
1212
1193
|
tool: "claude-project",
|
|
1213
|
-
path:
|
|
1194
|
+
path: path3.join(targetRoot, ".mcp.json"),
|
|
1214
1195
|
generate: () => generateClaudeMcp(config)
|
|
1215
1196
|
},
|
|
1216
1197
|
{
|
|
1217
1198
|
tool: "copilot-editor",
|
|
1218
|
-
path:
|
|
1199
|
+
path: path3.join(targetRoot, ".vscode", "mcp.json"),
|
|
1219
1200
|
generate: () => generateCopilotMcp(config, "editor")
|
|
1220
1201
|
},
|
|
1221
1202
|
{
|
|
1222
1203
|
tool: "cursor-project",
|
|
1223
|
-
path:
|
|
1204
|
+
path: path3.join(targetRoot, ".cursor", "mcp.json"),
|
|
1224
1205
|
generate: () => generateCursorMcp(config)
|
|
1225
1206
|
},
|
|
1226
1207
|
{
|
|
1227
1208
|
tool: "cline-project",
|
|
1228
|
-
path:
|
|
1209
|
+
path: path3.join(targetRoot, ".cline", "mcp.json"),
|
|
1229
1210
|
generate: () => generateClineMcp(config)
|
|
1230
1211
|
},
|
|
1231
1212
|
{
|
|
1232
1213
|
tool: "gemini-project",
|
|
1233
|
-
path:
|
|
1214
|
+
path: path3.join(targetRoot, ".gemini", "settings.json"),
|
|
1234
1215
|
generate: () => generateGeminiCliMcp(config)
|
|
1235
1216
|
},
|
|
1236
1217
|
{
|
|
1237
1218
|
tool: "roo-project",
|
|
1238
|
-
path:
|
|
1219
|
+
path: path3.join(targetRoot, ".roo", "mcp.json"),
|
|
1239
1220
|
generate: () => generateRooMcp(config)
|
|
1240
1221
|
}
|
|
1241
1222
|
];
|
|
@@ -1392,10 +1373,10 @@ Generating configurations for base directory: ${baseDir}`);
|
|
|
1392
1373
|
}
|
|
1393
1374
|
|
|
1394
1375
|
// src/cli/commands/gitignore.ts
|
|
1395
|
-
var
|
|
1396
|
-
var
|
|
1376
|
+
var import_node_fs = require("fs");
|
|
1377
|
+
var import_node_path11 = require("path");
|
|
1397
1378
|
var gitignoreCommand = async () => {
|
|
1398
|
-
const gitignorePath = (0,
|
|
1379
|
+
const gitignorePath = (0, import_node_path11.join)(process.cwd(), ".gitignore");
|
|
1399
1380
|
const rulesFilesToIgnore = [
|
|
1400
1381
|
"# Generated by rulesync - AI tool configuration files",
|
|
1401
1382
|
"**/.github/copilot-instructions.md",
|
|
@@ -1421,8 +1402,8 @@ var gitignoreCommand = async () => {
|
|
|
1421
1402
|
"**/.roo/mcp.json"
|
|
1422
1403
|
];
|
|
1423
1404
|
let gitignoreContent = "";
|
|
1424
|
-
if ((0,
|
|
1425
|
-
gitignoreContent = (0,
|
|
1405
|
+
if ((0, import_node_fs.existsSync)(gitignorePath)) {
|
|
1406
|
+
gitignoreContent = (0, import_node_fs.readFileSync)(gitignorePath, "utf-8");
|
|
1426
1407
|
}
|
|
1427
1408
|
const linesToAdd = [];
|
|
1428
1409
|
for (const rule of rulesFilesToIgnore) {
|
|
@@ -1439,7 +1420,7 @@ var gitignoreCommand = async () => {
|
|
|
1439
1420
|
${linesToAdd.join("\n")}
|
|
1440
1421
|
` : `${linesToAdd.join("\n")}
|
|
1441
1422
|
`;
|
|
1442
|
-
(0,
|
|
1423
|
+
(0, import_node_fs.writeFileSync)(gitignorePath, newContent);
|
|
1443
1424
|
console.log(`\u2705 Added ${linesToAdd.length} rules to .gitignore:`);
|
|
1444
1425
|
for (const line of linesToAdd) {
|
|
1445
1426
|
if (!line.startsWith("#")) {
|
|
@@ -1449,17 +1430,17 @@ ${linesToAdd.join("\n")}
|
|
|
1449
1430
|
};
|
|
1450
1431
|
|
|
1451
1432
|
// src/core/importer.ts
|
|
1452
|
-
var
|
|
1433
|
+
var import_node_path18 = require("path");
|
|
1453
1434
|
var import_gray_matter4 = __toESM(require("gray-matter"), 1);
|
|
1454
1435
|
|
|
1455
1436
|
// src/parsers/claudecode.ts
|
|
1456
|
-
var
|
|
1437
|
+
var import_node_path12 = require("path");
|
|
1457
1438
|
async function parseClaudeConfiguration(baseDir = process.cwd()) {
|
|
1458
1439
|
const errors = [];
|
|
1459
1440
|
const rules = [];
|
|
1460
1441
|
let ignorePatterns;
|
|
1461
1442
|
let mcpServers;
|
|
1462
|
-
const claudeFilePath = (0,
|
|
1443
|
+
const claudeFilePath = (0, import_node_path12.join)(baseDir, "CLAUDE.md");
|
|
1463
1444
|
if (!await fileExists(claudeFilePath)) {
|
|
1464
1445
|
errors.push("CLAUDE.md file not found");
|
|
1465
1446
|
return { rules, errors };
|
|
@@ -1470,12 +1451,12 @@ async function parseClaudeConfiguration(baseDir = process.cwd()) {
|
|
|
1470
1451
|
if (mainRule) {
|
|
1471
1452
|
rules.push(mainRule);
|
|
1472
1453
|
}
|
|
1473
|
-
const memoryDir = (0,
|
|
1454
|
+
const memoryDir = (0, import_node_path12.join)(baseDir, ".claude", "memories");
|
|
1474
1455
|
if (await fileExists(memoryDir)) {
|
|
1475
1456
|
const memoryRules = await parseClaudeMemoryFiles(memoryDir);
|
|
1476
1457
|
rules.push(...memoryRules);
|
|
1477
1458
|
}
|
|
1478
|
-
const settingsPath = (0,
|
|
1459
|
+
const settingsPath = (0, import_node_path12.join)(baseDir, ".claude", "settings.json");
|
|
1479
1460
|
if (await fileExists(settingsPath)) {
|
|
1480
1461
|
const settingsResult = await parseClaudeSettings(settingsPath);
|
|
1481
1462
|
if (settingsResult.ignorePatterns) {
|
|
@@ -1532,10 +1513,10 @@ async function parseClaudeMemoryFiles(memoryDir) {
|
|
|
1532
1513
|
const files = await readdir2(memoryDir);
|
|
1533
1514
|
for (const file of files) {
|
|
1534
1515
|
if (file.endsWith(".md")) {
|
|
1535
|
-
const filePath = (0,
|
|
1516
|
+
const filePath = (0, import_node_path12.join)(memoryDir, file);
|
|
1536
1517
|
const content = await readFileContent(filePath);
|
|
1537
1518
|
if (content.trim()) {
|
|
1538
|
-
const filename = (0,
|
|
1519
|
+
const filename = (0, import_node_path12.basename)(file, ".md");
|
|
1539
1520
|
const frontmatter = {
|
|
1540
1521
|
root: false,
|
|
1541
1522
|
targets: ["claudecode"],
|
|
@@ -1594,11 +1575,11 @@ async function parseClaudeSettings(settingsPath) {
|
|
|
1594
1575
|
}
|
|
1595
1576
|
|
|
1596
1577
|
// src/parsers/cline.ts
|
|
1597
|
-
var
|
|
1578
|
+
var import_node_path13 = require("path");
|
|
1598
1579
|
async function parseClineConfiguration(baseDir = process.cwd()) {
|
|
1599
1580
|
const errors = [];
|
|
1600
1581
|
const rules = [];
|
|
1601
|
-
const clineFilePath = (0,
|
|
1582
|
+
const clineFilePath = (0, import_node_path13.join)(baseDir, ".cline", "instructions.md");
|
|
1602
1583
|
if (await fileExists(clineFilePath)) {
|
|
1603
1584
|
try {
|
|
1604
1585
|
const content = await readFileContent(clineFilePath);
|
|
@@ -1621,14 +1602,14 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
|
|
|
1621
1602
|
errors.push(`Failed to parse .cline/instructions.md: ${errorMessage}`);
|
|
1622
1603
|
}
|
|
1623
1604
|
}
|
|
1624
|
-
const clinerulesDirPath = (0,
|
|
1605
|
+
const clinerulesDirPath = (0, import_node_path13.join)(baseDir, ".clinerules");
|
|
1625
1606
|
if (await fileExists(clinerulesDirPath)) {
|
|
1626
1607
|
try {
|
|
1627
1608
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
1628
1609
|
const files = await readdir2(clinerulesDirPath);
|
|
1629
1610
|
for (const file of files) {
|
|
1630
1611
|
if (file.endsWith(".md")) {
|
|
1631
|
-
const filePath = (0,
|
|
1612
|
+
const filePath = (0, import_node_path13.join)(clinerulesDirPath, file);
|
|
1632
1613
|
try {
|
|
1633
1614
|
const content = await readFileContent(filePath);
|
|
1634
1615
|
if (content.trim()) {
|
|
@@ -1664,12 +1645,12 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
|
|
|
1664
1645
|
}
|
|
1665
1646
|
|
|
1666
1647
|
// src/parsers/copilot.ts
|
|
1667
|
-
var
|
|
1648
|
+
var import_node_path14 = require("path");
|
|
1668
1649
|
var import_gray_matter2 = __toESM(require("gray-matter"), 1);
|
|
1669
1650
|
async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
1670
1651
|
const errors = [];
|
|
1671
1652
|
const rules = [];
|
|
1672
|
-
const copilotFilePath = (0,
|
|
1653
|
+
const copilotFilePath = (0, import_node_path14.join)(baseDir, ".github", "copilot-instructions.md");
|
|
1673
1654
|
if (await fileExists(copilotFilePath)) {
|
|
1674
1655
|
try {
|
|
1675
1656
|
const rawContent = await readFileContent(copilotFilePath);
|
|
@@ -1694,19 +1675,19 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
|
1694
1675
|
errors.push(`Failed to parse copilot-instructions.md: ${errorMessage}`);
|
|
1695
1676
|
}
|
|
1696
1677
|
}
|
|
1697
|
-
const instructionsDir = (0,
|
|
1678
|
+
const instructionsDir = (0, import_node_path14.join)(baseDir, ".github", "instructions");
|
|
1698
1679
|
if (await fileExists(instructionsDir)) {
|
|
1699
1680
|
try {
|
|
1700
1681
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
1701
1682
|
const files = await readdir2(instructionsDir);
|
|
1702
1683
|
for (const file of files) {
|
|
1703
1684
|
if (file.endsWith(".instructions.md")) {
|
|
1704
|
-
const filePath = (0,
|
|
1685
|
+
const filePath = (0, import_node_path14.join)(instructionsDir, file);
|
|
1705
1686
|
const rawContent = await readFileContent(filePath);
|
|
1706
1687
|
const parsed = (0, import_gray_matter2.default)(rawContent);
|
|
1707
1688
|
const content = parsed.content.trim();
|
|
1708
1689
|
if (content) {
|
|
1709
|
-
const filename = (0,
|
|
1690
|
+
const filename = (0, import_node_path14.basename)(file, ".instructions.md");
|
|
1710
1691
|
const frontmatter = {
|
|
1711
1692
|
root: false,
|
|
1712
1693
|
targets: ["copilot"],
|
|
@@ -1736,7 +1717,7 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
|
1736
1717
|
}
|
|
1737
1718
|
|
|
1738
1719
|
// src/parsers/cursor.ts
|
|
1739
|
-
var
|
|
1720
|
+
var import_node_path15 = require("path");
|
|
1740
1721
|
var import_gray_matter3 = __toESM(require("gray-matter"), 1);
|
|
1741
1722
|
var import_js_yaml = require("js-yaml");
|
|
1742
1723
|
var customMatterOptions = {
|
|
@@ -1841,7 +1822,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
1841
1822
|
const rules = [];
|
|
1842
1823
|
let ignorePatterns;
|
|
1843
1824
|
let mcpServers;
|
|
1844
|
-
const cursorFilePath = (0,
|
|
1825
|
+
const cursorFilePath = (0, import_node_path15.join)(baseDir, ".cursorrules");
|
|
1845
1826
|
if (await fileExists(cursorFilePath)) {
|
|
1846
1827
|
try {
|
|
1847
1828
|
const rawContent = await readFileContent(cursorFilePath);
|
|
@@ -1862,20 +1843,20 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
1862
1843
|
errors.push(`Failed to parse .cursorrules file: ${errorMessage}`);
|
|
1863
1844
|
}
|
|
1864
1845
|
}
|
|
1865
|
-
const cursorRulesDir = (0,
|
|
1846
|
+
const cursorRulesDir = (0, import_node_path15.join)(baseDir, ".cursor", "rules");
|
|
1866
1847
|
if (await fileExists(cursorRulesDir)) {
|
|
1867
1848
|
try {
|
|
1868
1849
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
1869
1850
|
const files = await readdir2(cursorRulesDir);
|
|
1870
1851
|
for (const file of files) {
|
|
1871
1852
|
if (file.endsWith(".mdc")) {
|
|
1872
|
-
const filePath = (0,
|
|
1853
|
+
const filePath = (0, import_node_path15.join)(cursorRulesDir, file);
|
|
1873
1854
|
try {
|
|
1874
1855
|
const rawContent = await readFileContent(filePath);
|
|
1875
1856
|
const parsed = (0, import_gray_matter3.default)(rawContent, customMatterOptions);
|
|
1876
1857
|
const content = parsed.content.trim();
|
|
1877
1858
|
if (content) {
|
|
1878
|
-
const filename = (0,
|
|
1859
|
+
const filename = (0, import_node_path15.basename)(file, ".mdc");
|
|
1879
1860
|
const frontmatter = convertCursorMdcFrontmatter(parsed.data, filename);
|
|
1880
1861
|
rules.push({
|
|
1881
1862
|
frontmatter,
|
|
@@ -1898,7 +1879,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
1898
1879
|
if (rules.length === 0) {
|
|
1899
1880
|
errors.push("No Cursor configuration files found (.cursorrules or .cursor/rules/*.mdc)");
|
|
1900
1881
|
}
|
|
1901
|
-
const cursorIgnorePath = (0,
|
|
1882
|
+
const cursorIgnorePath = (0, import_node_path15.join)(baseDir, ".cursorignore");
|
|
1902
1883
|
if (await fileExists(cursorIgnorePath)) {
|
|
1903
1884
|
try {
|
|
1904
1885
|
const content = await readFileContent(cursorIgnorePath);
|
|
@@ -1911,7 +1892,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
1911
1892
|
errors.push(`Failed to parse .cursorignore: ${errorMessage}`);
|
|
1912
1893
|
}
|
|
1913
1894
|
}
|
|
1914
|
-
const cursorMcpPath = (0,
|
|
1895
|
+
const cursorMcpPath = (0, import_node_path15.join)(baseDir, ".cursor", "mcp.json");
|
|
1915
1896
|
if (await fileExists(cursorMcpPath)) {
|
|
1916
1897
|
try {
|
|
1917
1898
|
const content = await readFileContent(cursorMcpPath);
|
|
@@ -1933,13 +1914,13 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
1933
1914
|
}
|
|
1934
1915
|
|
|
1935
1916
|
// src/parsers/geminicli.ts
|
|
1936
|
-
var
|
|
1917
|
+
var import_node_path16 = require("path");
|
|
1937
1918
|
async function parseGeminiConfiguration(baseDir = process.cwd()) {
|
|
1938
1919
|
const errors = [];
|
|
1939
1920
|
const rules = [];
|
|
1940
1921
|
let ignorePatterns;
|
|
1941
1922
|
let mcpServers;
|
|
1942
|
-
const geminiFilePath = (0,
|
|
1923
|
+
const geminiFilePath = (0, import_node_path16.join)(baseDir, "GEMINI.md");
|
|
1943
1924
|
if (!await fileExists(geminiFilePath)) {
|
|
1944
1925
|
errors.push("GEMINI.md file not found");
|
|
1945
1926
|
return { rules, errors };
|
|
@@ -1950,12 +1931,12 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
|
|
|
1950
1931
|
if (mainRule) {
|
|
1951
1932
|
rules.push(mainRule);
|
|
1952
1933
|
}
|
|
1953
|
-
const memoryDir = (0,
|
|
1934
|
+
const memoryDir = (0, import_node_path16.join)(baseDir, ".gemini", "memories");
|
|
1954
1935
|
if (await fileExists(memoryDir)) {
|
|
1955
1936
|
const memoryRules = await parseGeminiMemoryFiles(memoryDir);
|
|
1956
1937
|
rules.push(...memoryRules);
|
|
1957
1938
|
}
|
|
1958
|
-
const settingsPath = (0,
|
|
1939
|
+
const settingsPath = (0, import_node_path16.join)(baseDir, ".gemini", "settings.json");
|
|
1959
1940
|
if (await fileExists(settingsPath)) {
|
|
1960
1941
|
const settingsResult = await parseGeminiSettings(settingsPath);
|
|
1961
1942
|
if (settingsResult.ignorePatterns) {
|
|
@@ -1966,7 +1947,7 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
|
|
|
1966
1947
|
}
|
|
1967
1948
|
errors.push(...settingsResult.errors);
|
|
1968
1949
|
}
|
|
1969
|
-
const aiexcludePath = (0,
|
|
1950
|
+
const aiexcludePath = (0, import_node_path16.join)(baseDir, ".aiexclude");
|
|
1970
1951
|
if (await fileExists(aiexcludePath)) {
|
|
1971
1952
|
const aiexcludePatterns = await parseAiexclude(aiexcludePath);
|
|
1972
1953
|
if (aiexcludePatterns.length > 0) {
|
|
@@ -2019,10 +2000,10 @@ async function parseGeminiMemoryFiles(memoryDir) {
|
|
|
2019
2000
|
const files = await readdir2(memoryDir);
|
|
2020
2001
|
for (const file of files) {
|
|
2021
2002
|
if (file.endsWith(".md")) {
|
|
2022
|
-
const filePath = (0,
|
|
2003
|
+
const filePath = (0, import_node_path16.join)(memoryDir, file);
|
|
2023
2004
|
const content = await readFileContent(filePath);
|
|
2024
2005
|
if (content.trim()) {
|
|
2025
|
-
const filename = (0,
|
|
2006
|
+
const filename = (0, import_node_path16.basename)(file, ".md");
|
|
2026
2007
|
const frontmatter = {
|
|
2027
2008
|
root: false,
|
|
2028
2009
|
targets: ["geminicli"],
|
|
@@ -2071,11 +2052,11 @@ async function parseAiexclude(aiexcludePath) {
|
|
|
2071
2052
|
}
|
|
2072
2053
|
|
|
2073
2054
|
// src/parsers/roo.ts
|
|
2074
|
-
var
|
|
2055
|
+
var import_node_path17 = require("path");
|
|
2075
2056
|
async function parseRooConfiguration(baseDir = process.cwd()) {
|
|
2076
2057
|
const errors = [];
|
|
2077
2058
|
const rules = [];
|
|
2078
|
-
const rooFilePath = (0,
|
|
2059
|
+
const rooFilePath = (0, import_node_path17.join)(baseDir, ".roo", "instructions.md");
|
|
2079
2060
|
if (await fileExists(rooFilePath)) {
|
|
2080
2061
|
try {
|
|
2081
2062
|
const content = await readFileContent(rooFilePath);
|
|
@@ -2098,14 +2079,14 @@ async function parseRooConfiguration(baseDir = process.cwd()) {
|
|
|
2098
2079
|
errors.push(`Failed to parse .roo/instructions.md: ${errorMessage}`);
|
|
2099
2080
|
}
|
|
2100
2081
|
}
|
|
2101
|
-
const rooRulesDir = (0,
|
|
2082
|
+
const rooRulesDir = (0, import_node_path17.join)(baseDir, ".roo", "rules");
|
|
2102
2083
|
if (await fileExists(rooRulesDir)) {
|
|
2103
2084
|
try {
|
|
2104
2085
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
2105
2086
|
const files = await readdir2(rooRulesDir);
|
|
2106
2087
|
for (const file of files) {
|
|
2107
2088
|
if (file.endsWith(".md")) {
|
|
2108
|
-
const filePath = (0,
|
|
2089
|
+
const filePath = (0, import_node_path17.join)(rooRulesDir, file);
|
|
2109
2090
|
try {
|
|
2110
2091
|
const content = await readFileContent(filePath);
|
|
2111
2092
|
if (content.trim()) {
|
|
@@ -2206,7 +2187,7 @@ async function importConfiguration(options) {
|
|
|
2206
2187
|
if (rules.length === 0 && !ignorePatterns && !mcpServers) {
|
|
2207
2188
|
return { success: false, rulesCreated: 0, errors };
|
|
2208
2189
|
}
|
|
2209
|
-
const rulesDirPath = (0,
|
|
2190
|
+
const rulesDirPath = (0, import_node_path18.join)(baseDir, rulesDir);
|
|
2210
2191
|
try {
|
|
2211
2192
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
2212
2193
|
await mkdir3(rulesDirPath, { recursive: true });
|
|
@@ -2220,7 +2201,7 @@ async function importConfiguration(options) {
|
|
|
2220
2201
|
try {
|
|
2221
2202
|
const baseFilename = `${tool}__${rule.filename}`;
|
|
2222
2203
|
const filename = await generateUniqueFilename(rulesDirPath, baseFilename);
|
|
2223
|
-
const filePath = (0,
|
|
2204
|
+
const filePath = (0, import_node_path18.join)(rulesDirPath, `${filename}.md`);
|
|
2224
2205
|
const content = generateRuleFileContent(rule);
|
|
2225
2206
|
await writeFileContent(filePath, content);
|
|
2226
2207
|
rulesCreated++;
|
|
@@ -2235,7 +2216,7 @@ async function importConfiguration(options) {
|
|
|
2235
2216
|
let ignoreFileCreated = false;
|
|
2236
2217
|
if (ignorePatterns && ignorePatterns.length > 0) {
|
|
2237
2218
|
try {
|
|
2238
|
-
const rulesyncignorePath = (0,
|
|
2219
|
+
const rulesyncignorePath = (0, import_node_path18.join)(baseDir, ".rulesyncignore");
|
|
2239
2220
|
const ignoreContent = `${ignorePatterns.join("\n")}
|
|
2240
2221
|
`;
|
|
2241
2222
|
await writeFileContent(rulesyncignorePath, ignoreContent);
|
|
@@ -2251,7 +2232,7 @@ async function importConfiguration(options) {
|
|
|
2251
2232
|
let mcpFileCreated = false;
|
|
2252
2233
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
2253
2234
|
try {
|
|
2254
|
-
const mcpPath = (0,
|
|
2235
|
+
const mcpPath = (0, import_node_path18.join)(baseDir, rulesDir, ".mcp.json");
|
|
2255
2236
|
const mcpContent = `${JSON.stringify({ mcpServers }, null, 2)}
|
|
2256
2237
|
`;
|
|
2257
2238
|
await writeFileContent(mcpPath, mcpContent);
|
|
@@ -2279,7 +2260,7 @@ function generateRuleFileContent(rule) {
|
|
|
2279
2260
|
async function generateUniqueFilename(rulesDir, baseFilename) {
|
|
2280
2261
|
let filename = baseFilename;
|
|
2281
2262
|
let counter = 1;
|
|
2282
|
-
while (await fileExists((0,
|
|
2263
|
+
while (await fileExists((0, import_node_path18.join)(rulesDir, `${filename}.md`))) {
|
|
2283
2264
|
filename = `${baseFilename}-${counter}`;
|
|
2284
2265
|
counter++;
|
|
2285
2266
|
}
|
|
@@ -2344,7 +2325,7 @@ async function importCommand(options = {}) {
|
|
|
2344
2325
|
}
|
|
2345
2326
|
|
|
2346
2327
|
// src/cli/commands/init.ts
|
|
2347
|
-
var
|
|
2328
|
+
var import_node_path19 = require("path");
|
|
2348
2329
|
async function initCommand() {
|
|
2349
2330
|
const aiRulesDir = ".rulesync";
|
|
2350
2331
|
console.log("Initializing rulesync...");
|
|
@@ -2474,7 +2455,7 @@ globs: ["src/api/**/*.ts", "src/services/**/*.ts", "src/models/**/*.ts"]
|
|
|
2474
2455
|
}
|
|
2475
2456
|
];
|
|
2476
2457
|
for (const file of sampleFiles) {
|
|
2477
|
-
const filepath = (0,
|
|
2458
|
+
const filepath = (0, import_node_path19.join)(aiRulesDir, file.filename);
|
|
2478
2459
|
if (!await fileExists(filepath)) {
|
|
2479
2460
|
await writeFileContent(filepath, file.content);
|
|
2480
2461
|
console.log(`Created ${filepath}`);
|
|
@@ -2617,7 +2598,7 @@ async function watchCommand() {
|
|
|
2617
2598
|
|
|
2618
2599
|
// src/cli/index.ts
|
|
2619
2600
|
var program = new import_commander.Command();
|
|
2620
|
-
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.
|
|
2601
|
+
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.43.0");
|
|
2621
2602
|
program.command("init").description("Initialize rulesync in current directory").action(initCommand);
|
|
2622
2603
|
program.command("add <filename>").description("Add a new rule file").action(addCommand);
|
|
2623
2604
|
program.command("gitignore").description("Add generated files to .gitignore").action(gitignoreCommand);
|