rulesync 0.61.0 → 0.62.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 +32 -9
- package/dist/{chunk-C5LFJFPS.js → chunk-2CW2KFB3.js} +1 -1
- package/dist/{chunk-DA3XULAD.js → chunk-4PSTOKKD.js} +1 -1
- package/dist/{chunk-2KYIOT5S.js → chunk-GQTMTBX4.js} +2 -1
- package/dist/{chunk-U63N3YDS.js → chunk-M7NL7G7A.js} +1 -1
- package/dist/{chunk-LRYVNLH5.js → chunk-MDYDKNXQ.js} +1 -1
- package/dist/{chunk-ICMPPX55.js → chunk-NETSYSMD.js} +1 -1
- package/dist/{chunk-3ZLMXJTX.js → chunk-U4PLVMCG.js} +1 -1
- package/dist/{chunk-74TYZWHJ.js → chunk-UEAYL4NT.js} +1 -1
- package/dist/{claudecode-XKHMZT7R.js → claudecode-YTEFACCT.js} +2 -2
- package/dist/{cline-FNWPJ7K4.js → cline-CKNUDEA3.js} +2 -2
- package/dist/{codexcli-FDFHY66P.js → codexcli-7SDGYI7D.js} +2 -2
- package/dist/{cursor-WWHUW5AD.js → cursor-YJGH7W24.js} +2 -2
- package/dist/{geminicli-7TIDQ62D.js → geminicli-E7KZTZ2G.js} +2 -2
- package/dist/index.cjs +285 -210
- package/dist/index.js +283 -209
- package/dist/{junie-VMNDWBNB.js → junie-5LEQU4BO.js} +2 -2
- package/dist/{windsurf-KOSK4MZJ.js → windsurf-4P6HEUBV.js} +2 -2
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-M7NL7G7A.js";
|
|
3
3
|
import "./chunk-LXTA7DBA.js";
|
|
4
4
|
import "./chunk-PCATT4UZ.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-NETSYSMD.js";
|
|
6
6
|
import "./chunk-YTU3SCQO.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-U4PLVMCG.js";
|
|
8
|
+
import "./chunk-UEAYL4NT.js";
|
|
9
|
+
import "./chunk-2CW2KFB3.js";
|
|
10
10
|
import "./chunk-KUGTKMNW.js";
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-4PSTOKKD.js";
|
|
12
|
+
import "./chunk-MDYDKNXQ.js";
|
|
13
|
+
import "./chunk-GQTMTBX4.js";
|
|
14
14
|
import {
|
|
15
15
|
ALL_TOOL_TARGETS,
|
|
16
16
|
RulesyncTargetsSchema,
|
|
@@ -26,75 +26,9 @@ import { Command } from "commander";
|
|
|
26
26
|
import { mkdir, writeFile } from "fs/promises";
|
|
27
27
|
import * as path from "path";
|
|
28
28
|
|
|
29
|
-
// src/utils/config.ts
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
aiRulesDir: ".rulesync",
|
|
33
|
-
outputPaths: {
|
|
34
|
-
augmentcode: ".",
|
|
35
|
-
"augmentcode-legacy": ".",
|
|
36
|
-
copilot: ".github/instructions",
|
|
37
|
-
cursor: ".cursor/rules",
|
|
38
|
-
cline: ".clinerules",
|
|
39
|
-
claudecode: ".",
|
|
40
|
-
codexcli: ".",
|
|
41
|
-
roo: ".roo/rules",
|
|
42
|
-
geminicli: ".gemini/memories",
|
|
43
|
-
kiro: ".kiro/steering",
|
|
44
|
-
junie: ".",
|
|
45
|
-
windsurf: "."
|
|
46
|
-
},
|
|
47
|
-
watchEnabled: false,
|
|
48
|
-
defaultTargets: ALL_TOOL_TARGETS.filter((tool) => tool !== "augmentcode-legacy")
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
function resolveTargets(targets, config) {
|
|
52
|
-
if (targets.length === 1 && targets[0] === "*") {
|
|
53
|
-
return config.defaultTargets;
|
|
54
|
-
}
|
|
55
|
-
const validatedTargets = ToolTargetsSchema.parse(targets);
|
|
56
|
-
return validatedTargets;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// src/cli/commands/add.ts
|
|
60
|
-
function sanitizeFilename(filename) {
|
|
61
|
-
return filename.endsWith(".md") ? filename.slice(0, -3) : filename;
|
|
62
|
-
}
|
|
63
|
-
function generateRuleTemplate(filename) {
|
|
64
|
-
return `---
|
|
65
|
-
root: false
|
|
66
|
-
targets: ["*"]
|
|
67
|
-
description: "Rules for ${filename}"
|
|
68
|
-
globs: []
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
# ${filename.charAt(0).toUpperCase() + filename.slice(1)} Rules
|
|
72
|
-
|
|
73
|
-
Add your rules here.
|
|
74
|
-
`;
|
|
75
|
-
}
|
|
76
|
-
async function addCommand(filename) {
|
|
77
|
-
try {
|
|
78
|
-
const config = getDefaultConfig();
|
|
79
|
-
const sanitizedFilename = sanitizeFilename(filename);
|
|
80
|
-
const rulesDir = config.aiRulesDir;
|
|
81
|
-
const filePath = path.join(rulesDir, `${sanitizedFilename}.md`);
|
|
82
|
-
await mkdir(rulesDir, { recursive: true });
|
|
83
|
-
const template = generateRuleTemplate(sanitizedFilename);
|
|
84
|
-
await writeFile(filePath, template, "utf8");
|
|
85
|
-
console.log(`\u2705 Created rule file: ${filePath}`);
|
|
86
|
-
console.log(`\u{1F4DD} Edit the file to customize your rules.`);
|
|
87
|
-
} catch (error) {
|
|
88
|
-
console.error(
|
|
89
|
-
`\u274C Failed to create rule file: ${error instanceof Error ? error.message : String(error)}`
|
|
90
|
-
);
|
|
91
|
-
process.exit(3);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// src/cli/commands/config.ts
|
|
96
|
-
import { writeFileSync } from "fs";
|
|
97
|
-
import path2 from "path";
|
|
29
|
+
// src/utils/config-loader.ts
|
|
30
|
+
import { loadConfig as loadC12Config } from "c12";
|
|
31
|
+
import { $ZodError } from "zod/v4/core";
|
|
98
32
|
|
|
99
33
|
// src/types/claudecode.ts
|
|
100
34
|
import { z } from "zod/mini";
|
|
@@ -121,7 +55,8 @@ var ConfigSchema = z3.object({
|
|
|
121
55
|
watchEnabled: z3.boolean(),
|
|
122
56
|
defaultTargets: ToolTargetsSchema,
|
|
123
57
|
claudecodeCommands: z3.optional(z3.string()),
|
|
124
|
-
geminicliCommands: z3.optional(z3.string())
|
|
58
|
+
geminicliCommands: z3.optional(z3.string()),
|
|
59
|
+
legacy: z3.optional(z3.boolean())
|
|
125
60
|
});
|
|
126
61
|
|
|
127
62
|
// src/types/config-options.ts
|
|
@@ -150,6 +85,7 @@ var ConfigOptionsSchema = z4.object({
|
|
|
150
85
|
verbose: z4.optional(z4.boolean()),
|
|
151
86
|
delete: z4.optional(z4.boolean()),
|
|
152
87
|
baseDir: z4.optional(z4.union([z4.string(), z4.array(z4.string())])),
|
|
88
|
+
legacy: z4.optional(z4.boolean()),
|
|
153
89
|
watch: z4.optional(
|
|
154
90
|
z4.object({
|
|
155
91
|
enabled: z4.optional(z4.boolean()),
|
|
@@ -169,6 +105,7 @@ var MergedConfigSchema = z4.object({
|
|
|
169
105
|
delete: z4.optional(z4.boolean()),
|
|
170
106
|
baseDir: z4.optional(z4.union([z4.string(), z4.array(z4.string())])),
|
|
171
107
|
configPath: z4.optional(z4.string()),
|
|
108
|
+
legacy: z4.optional(z4.boolean()),
|
|
172
109
|
watch: z4.optional(
|
|
173
110
|
z4.object({
|
|
174
111
|
enabled: z4.optional(z4.boolean()),
|
|
@@ -233,9 +170,38 @@ var GenerateOptionsSchema = z6.object({
|
|
|
233
170
|
watch: z6.optional(z6.boolean())
|
|
234
171
|
});
|
|
235
172
|
|
|
173
|
+
// src/utils/config.ts
|
|
174
|
+
function getDefaultConfig() {
|
|
175
|
+
return {
|
|
176
|
+
aiRulesDir: ".rulesync",
|
|
177
|
+
outputPaths: {
|
|
178
|
+
augmentcode: ".",
|
|
179
|
+
"augmentcode-legacy": ".",
|
|
180
|
+
copilot: ".github/instructions",
|
|
181
|
+
cursor: ".cursor/rules",
|
|
182
|
+
cline: ".clinerules",
|
|
183
|
+
claudecode: ".",
|
|
184
|
+
codexcli: ".",
|
|
185
|
+
roo: ".roo/rules",
|
|
186
|
+
geminicli: ".gemini/memories",
|
|
187
|
+
kiro: ".kiro/steering",
|
|
188
|
+
junie: ".",
|
|
189
|
+
windsurf: "."
|
|
190
|
+
},
|
|
191
|
+
watchEnabled: false,
|
|
192
|
+
defaultTargets: ALL_TOOL_TARGETS.filter((tool) => tool !== "augmentcode-legacy"),
|
|
193
|
+
legacy: false
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function resolveTargets(targets, config) {
|
|
197
|
+
if (targets.length === 1 && targets[0] === "*") {
|
|
198
|
+
return config.defaultTargets;
|
|
199
|
+
}
|
|
200
|
+
const validatedTargets = ToolTargetsSchema.parse(targets);
|
|
201
|
+
return validatedTargets;
|
|
202
|
+
}
|
|
203
|
+
|
|
236
204
|
// src/utils/config-loader.ts
|
|
237
|
-
import { loadConfig as loadC12Config } from "c12";
|
|
238
|
-
import { $ZodError } from "zod/v4/core";
|
|
239
205
|
var MODULE_NAME = "rulesync";
|
|
240
206
|
async function loadConfig(options = {}) {
|
|
241
207
|
const defaultConfig = getDefaultConfig();
|
|
@@ -422,6 +388,49 @@ function mergeWithCliOptions(config, cliOptions) {
|
|
|
422
388
|
return merged;
|
|
423
389
|
}
|
|
424
390
|
|
|
391
|
+
// src/cli/commands/add.ts
|
|
392
|
+
function sanitizeFilename(filename) {
|
|
393
|
+
return filename.endsWith(".md") ? filename.slice(0, -3) : filename;
|
|
394
|
+
}
|
|
395
|
+
function generateRuleTemplate(filename) {
|
|
396
|
+
return `---
|
|
397
|
+
root: false
|
|
398
|
+
targets: ["*"]
|
|
399
|
+
description: "Rules for ${filename}"
|
|
400
|
+
globs: []
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
# ${filename.charAt(0).toUpperCase() + filename.slice(1)} Rules
|
|
404
|
+
|
|
405
|
+
Add your rules here.
|
|
406
|
+
`;
|
|
407
|
+
}
|
|
408
|
+
async function addCommand(filename, options = {}) {
|
|
409
|
+
try {
|
|
410
|
+
const configResult = await loadConfig();
|
|
411
|
+
const config = configResult.config;
|
|
412
|
+
const sanitizedFilename = sanitizeFilename(filename);
|
|
413
|
+
const aiRulesDir = config.aiRulesDir;
|
|
414
|
+
const useLegacy = options.legacy ?? config.legacy ?? false;
|
|
415
|
+
const rulesDir = useLegacy ? aiRulesDir : path.join(aiRulesDir, "rules");
|
|
416
|
+
const filePath = path.join(rulesDir, `${sanitizedFilename}.md`);
|
|
417
|
+
await mkdir(rulesDir, { recursive: true });
|
|
418
|
+
const template = generateRuleTemplate(sanitizedFilename);
|
|
419
|
+
await writeFile(filePath, template, "utf8");
|
|
420
|
+
console.log(`\u2705 Created rule file: ${filePath}`);
|
|
421
|
+
console.log(`\u{1F4DD} Edit the file to customize your rules.`);
|
|
422
|
+
} catch (error) {
|
|
423
|
+
console.error(
|
|
424
|
+
`\u274C Failed to create rule file: ${error instanceof Error ? error.message : String(error)}`
|
|
425
|
+
);
|
|
426
|
+
process.exit(3);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// src/cli/commands/config.ts
|
|
431
|
+
import { writeFileSync } from "fs";
|
|
432
|
+
import path2 from "path";
|
|
433
|
+
|
|
425
434
|
// src/utils/error.ts
|
|
426
435
|
function getErrorMessage(error) {
|
|
427
436
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -488,6 +497,19 @@ async function findFiles(dir, extension = ".md") {
|
|
|
488
497
|
return [];
|
|
489
498
|
}
|
|
490
499
|
}
|
|
500
|
+
async function findRuleFiles(aiRulesDir) {
|
|
501
|
+
const rulesDir = join2(aiRulesDir, "rules");
|
|
502
|
+
const newLocationFiles = await findFiles(rulesDir, ".md");
|
|
503
|
+
const legacyLocationFiles = await findFiles(aiRulesDir, ".md");
|
|
504
|
+
const newLocationBasenames = new Set(
|
|
505
|
+
newLocationFiles.map((file) => file.split("/").pop()?.replace(/\.md$/, ""))
|
|
506
|
+
);
|
|
507
|
+
const filteredLegacyFiles = legacyLocationFiles.filter((file) => {
|
|
508
|
+
const basename6 = file.split("/").pop()?.replace(/\.md$/, "");
|
|
509
|
+
return !newLocationBasenames.has(basename6);
|
|
510
|
+
});
|
|
511
|
+
return [...newLocationFiles, ...filteredLegacyFiles];
|
|
512
|
+
}
|
|
491
513
|
async function removeDirectory(dirPath) {
|
|
492
514
|
const dangerousPaths = [".", "/", "~", "src", "node_modules"];
|
|
493
515
|
if (dangerousPaths.includes(dirPath) || dirPath === "") {
|
|
@@ -522,6 +544,50 @@ async function removeClaudeGeneratedFiles() {
|
|
|
522
544
|
}
|
|
523
545
|
}
|
|
524
546
|
|
|
547
|
+
// src/utils/logger.ts
|
|
548
|
+
import { consola } from "consola";
|
|
549
|
+
var Logger = class {
|
|
550
|
+
_verbose = false;
|
|
551
|
+
console = consola.withDefaults({
|
|
552
|
+
tag: "rulesync"
|
|
553
|
+
});
|
|
554
|
+
setVerbose(verbose) {
|
|
555
|
+
this._verbose = verbose;
|
|
556
|
+
}
|
|
557
|
+
get verbose() {
|
|
558
|
+
return this._verbose;
|
|
559
|
+
}
|
|
560
|
+
// Regular log (always shown, regardless of verbose)
|
|
561
|
+
log(message, ...args) {
|
|
562
|
+
this.console.log(message, ...args);
|
|
563
|
+
}
|
|
564
|
+
// Info level (shown only in verbose mode)
|
|
565
|
+
info(message, ...args) {
|
|
566
|
+
if (this._verbose) {
|
|
567
|
+
this.console.info(message, ...args);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
// Success (always shown)
|
|
571
|
+
success(message, ...args) {
|
|
572
|
+
this.console.success(message, ...args);
|
|
573
|
+
}
|
|
574
|
+
// Warning (always shown)
|
|
575
|
+
warn(message, ...args) {
|
|
576
|
+
this.console.warn(message, ...args);
|
|
577
|
+
}
|
|
578
|
+
// Error (always shown)
|
|
579
|
+
error(message, ...args) {
|
|
580
|
+
this.console.error(message, ...args);
|
|
581
|
+
}
|
|
582
|
+
// Debug level (shown only in verbose mode)
|
|
583
|
+
debug(message, ...args) {
|
|
584
|
+
if (this._verbose) {
|
|
585
|
+
this.console.debug(message, ...args);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
var logger = new Logger();
|
|
590
|
+
|
|
525
591
|
// src/cli/commands/config.ts
|
|
526
592
|
async function configCommand(options = {}) {
|
|
527
593
|
if (options.init) {
|
|
@@ -531,50 +597,50 @@ async function configCommand(options = {}) {
|
|
|
531
597
|
await showConfig();
|
|
532
598
|
}
|
|
533
599
|
async function showConfig() {
|
|
534
|
-
|
|
600
|
+
logger.log("Loading configuration...\n");
|
|
535
601
|
try {
|
|
536
602
|
const result = await loadConfig();
|
|
537
603
|
if (result.isEmpty) {
|
|
538
|
-
|
|
604
|
+
logger.log("No configuration file found. Using default configuration.\n");
|
|
539
605
|
} else {
|
|
540
|
-
|
|
606
|
+
logger.log(`Configuration loaded from: ${result.filepath}
|
|
541
607
|
`);
|
|
542
608
|
}
|
|
543
|
-
|
|
544
|
-
|
|
609
|
+
logger.log("Current configuration:");
|
|
610
|
+
logger.log("=====================");
|
|
545
611
|
const config = result.config;
|
|
546
|
-
|
|
612
|
+
logger.log(`
|
|
547
613
|
AI Rules Directory: ${config.aiRulesDir}`);
|
|
548
|
-
|
|
614
|
+
logger.log(`
|
|
549
615
|
Default Targets: ${config.defaultTargets.join(", ")}`);
|
|
550
616
|
if (config.exclude && config.exclude.length > 0) {
|
|
551
|
-
|
|
617
|
+
logger.log(`Excluded Targets: ${config.exclude.join(", ")}`);
|
|
552
618
|
}
|
|
553
|
-
|
|
619
|
+
logger.log("\nOutput Paths:");
|
|
554
620
|
for (const [tool, outputPath] of Object.entries(config.outputPaths)) {
|
|
555
|
-
|
|
621
|
+
logger.log(` ${tool}: ${outputPath}`);
|
|
556
622
|
}
|
|
557
623
|
if (config.baseDir) {
|
|
558
624
|
const dirs = Array.isArray(config.baseDir) ? config.baseDir : [config.baseDir];
|
|
559
|
-
|
|
625
|
+
logger.log(`
|
|
560
626
|
Base Directories: ${dirs.join(", ")}`);
|
|
561
627
|
}
|
|
562
|
-
|
|
628
|
+
logger.log(`
|
|
563
629
|
Verbose: ${config.verbose || false}`);
|
|
564
|
-
|
|
630
|
+
logger.log(`Delete before generate: ${config.delete || false}`);
|
|
565
631
|
if (config.watch) {
|
|
566
|
-
|
|
567
|
-
|
|
632
|
+
logger.log("\nWatch Configuration:");
|
|
633
|
+
logger.log(` Enabled: ${config.watch.enabled || false}`);
|
|
568
634
|
if (config.watch.interval) {
|
|
569
|
-
|
|
635
|
+
logger.log(` Interval: ${config.watch.interval}ms`);
|
|
570
636
|
}
|
|
571
637
|
if (config.watch.ignore && config.watch.ignore.length > 0) {
|
|
572
|
-
|
|
638
|
+
logger.log(` Ignore patterns: ${config.watch.ignore.join(", ")}`);
|
|
573
639
|
}
|
|
574
640
|
}
|
|
575
|
-
|
|
641
|
+
logger.log("\nTip: Use 'rulesync config init' to create a configuration file.");
|
|
576
642
|
} catch (error) {
|
|
577
|
-
|
|
643
|
+
logger.error(
|
|
578
644
|
"\u274C Failed to load configuration:",
|
|
579
645
|
error instanceof Error ? error.message : String(error)
|
|
580
646
|
);
|
|
@@ -595,7 +661,7 @@ async function initConfig(options) {
|
|
|
595
661
|
const validFormats = Object.keys(FORMAT_CONFIG);
|
|
596
662
|
const selectedFormat = options.format || "jsonc";
|
|
597
663
|
if (!validFormats.includes(selectedFormat)) {
|
|
598
|
-
|
|
664
|
+
logger.error(
|
|
599
665
|
`\u274C Invalid format: ${selectedFormat}. Valid formats are: ${validFormats.join(", ")}`
|
|
600
666
|
);
|
|
601
667
|
process.exit(1);
|
|
@@ -611,7 +677,7 @@ async function initConfig(options) {
|
|
|
611
677
|
if (result.success) {
|
|
612
678
|
validTargets.push(result.data);
|
|
613
679
|
} else {
|
|
614
|
-
|
|
680
|
+
logger.error(`\u274C Invalid target: ${target}`);
|
|
615
681
|
process.exit(1);
|
|
616
682
|
}
|
|
617
683
|
}
|
|
@@ -625,7 +691,7 @@ async function initConfig(options) {
|
|
|
625
691
|
if (result.success) {
|
|
626
692
|
validExcludes.push(result.data);
|
|
627
693
|
} else {
|
|
628
|
-
|
|
694
|
+
logger.error(`\u274C Invalid exclude target: ${exclude}`);
|
|
629
695
|
process.exit(1);
|
|
630
696
|
}
|
|
631
697
|
}
|
|
@@ -648,18 +714,18 @@ async function initConfig(options) {
|
|
|
648
714
|
try {
|
|
649
715
|
const fs2 = await import("fs/promises");
|
|
650
716
|
await fs2.access(filepath);
|
|
651
|
-
|
|
652
|
-
|
|
717
|
+
logger.error(`\u274C Configuration file already exists: ${filepath}`);
|
|
718
|
+
logger.log("Remove the existing file or choose a different format.");
|
|
653
719
|
process.exit(1);
|
|
654
720
|
} catch {
|
|
655
721
|
}
|
|
656
722
|
try {
|
|
657
723
|
writeFileSync(filepath, content, "utf-8");
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
724
|
+
logger.success(`Created configuration file: ${filepath}`);
|
|
725
|
+
logger.log("\nYou can now customize the configuration to fit your needs.");
|
|
726
|
+
logger.log("Run 'rulesync generate' to use the new configuration.");
|
|
661
727
|
} catch (error) {
|
|
662
|
-
|
|
728
|
+
logger.error(
|
|
663
729
|
`\u274C Failed to create configuration file: ${error instanceof Error ? error.message : String(error)}`
|
|
664
730
|
);
|
|
665
731
|
process.exit(1);
|
|
@@ -792,12 +858,6 @@ var GeminiCliCommandGenerator = class {
|
|
|
792
858
|
let converted = content;
|
|
793
859
|
converted = converted.replace(/\$ARGUMENTS/g, "{{args}}");
|
|
794
860
|
converted = converted.replace(/!`([^`]+)`/g, "!{$1}");
|
|
795
|
-
const atSyntaxMatches = converted.match(/@[^\s]+/g);
|
|
796
|
-
if (atSyntaxMatches) {
|
|
797
|
-
console.warn(
|
|
798
|
-
`\u26A0\uFE0F Warning: @ syntax found (${atSyntaxMatches.join(", ")}). Gemini CLI does not support file content injection. Consider using shell commands or remove these references.`
|
|
799
|
-
);
|
|
800
|
-
}
|
|
801
861
|
return converted.trim();
|
|
802
862
|
}
|
|
803
863
|
escapeTomlString(str) {
|
|
@@ -2392,7 +2452,7 @@ import { basename as basename2 } from "path";
|
|
|
2392
2452
|
import matter2 from "gray-matter";
|
|
2393
2453
|
async function parseRulesFromDirectory(aiRulesDir) {
|
|
2394
2454
|
const ignorePatterns = await loadIgnorePatterns();
|
|
2395
|
-
const allRuleFiles = await
|
|
2455
|
+
const allRuleFiles = await findRuleFiles(aiRulesDir);
|
|
2396
2456
|
const ruleFiles = filterIgnoredFiles(allRuleFiles, ignorePatterns.patterns);
|
|
2397
2457
|
const rules = [];
|
|
2398
2458
|
const errors = [];
|
|
@@ -2548,22 +2608,22 @@ async function generateMcpConfigurations(mcpConfig, baseDir, targetTools) {
|
|
|
2548
2608
|
servers,
|
|
2549
2609
|
dir
|
|
2550
2610
|
),
|
|
2551
|
-
claudecode: async (servers, dir) => (await import("./claudecode-
|
|
2611
|
+
claudecode: async (servers, dir) => (await import("./claudecode-YTEFACCT.js")).generateClaudeMcpConfiguration(
|
|
2552
2612
|
servers,
|
|
2553
2613
|
dir
|
|
2554
2614
|
),
|
|
2555
2615
|
copilot: async (servers, dir) => (await import("./copilot-MOR3HHJX.js")).generateCopilotMcpConfiguration(servers, dir),
|
|
2556
|
-
cursor: async (servers, dir) => (await import("./cursor-
|
|
2557
|
-
cline: async (servers, dir) => (await import("./cline-
|
|
2558
|
-
codexcli: async (servers, dir) => (await import("./codexcli-
|
|
2616
|
+
cursor: async (servers, dir) => (await import("./cursor-YJGH7W24.js")).generateCursorMcpConfiguration(servers, dir),
|
|
2617
|
+
cline: async (servers, dir) => (await import("./cline-CKNUDEA3.js")).generateClineMcpConfiguration(servers, dir),
|
|
2618
|
+
codexcli: async (servers, dir) => (await import("./codexcli-7SDGYI7D.js")).generateCodexMcpConfiguration(servers, dir),
|
|
2559
2619
|
roo: async (servers, dir) => (await import("./roo-L3QTTIPO.js")).generateRooMcpConfiguration(servers, dir),
|
|
2560
|
-
geminicli: async (servers, dir) => (await import("./geminicli-
|
|
2620
|
+
geminicli: async (servers, dir) => (await import("./geminicli-E7KZTZ2G.js")).generateGeminiCliMcpConfiguration(
|
|
2561
2621
|
servers,
|
|
2562
2622
|
dir
|
|
2563
2623
|
),
|
|
2564
2624
|
kiro: async (servers, dir) => (await import("./kiro-YDHXY2MA.js")).generateKiroMcpConfiguration(servers, dir),
|
|
2565
|
-
junie: async (servers, dir) => (await import("./junie-
|
|
2566
|
-
windsurf: async (servers, dir) => (await import("./windsurf-
|
|
2625
|
+
junie: async (servers, dir) => (await import("./junie-5LEQU4BO.js")).generateJunieMcpConfiguration(servers, dir),
|
|
2626
|
+
windsurf: async (servers, dir) => (await import("./windsurf-4P6HEUBV.js")).generateWindsurfMcpConfiguration(
|
|
2567
2627
|
servers,
|
|
2568
2628
|
dir
|
|
2569
2629
|
)
|
|
@@ -2598,6 +2658,7 @@ async function generateCommand(options = {}) {
|
|
|
2598
2658
|
...options.baseDirs !== void 0 && { baseDirs: options.baseDirs }
|
|
2599
2659
|
};
|
|
2600
2660
|
const config = mergeWithCliOptions(configResult.config, cliOptions);
|
|
2661
|
+
logger.setVerbose(config.verbose || false);
|
|
2601
2662
|
if (options.tools && options.tools.length > 0) {
|
|
2602
2663
|
const configTargets = config.defaultTargets;
|
|
2603
2664
|
const cliTools = options.tools;
|
|
@@ -2606,18 +2667,18 @@ async function generateCommand(options = {}) {
|
|
|
2606
2667
|
const notInConfig = cliTools.filter((tool) => !configTargetsSet.has(tool));
|
|
2607
2668
|
const notInCli = configTargets.filter((tool) => !cliToolsSet.has(tool));
|
|
2608
2669
|
if (notInConfig.length > 0 || notInCli.length > 0) {
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2670
|
+
logger.warn("\u26A0\uFE0F Warning: CLI tool selection differs from configuration!");
|
|
2671
|
+
logger.warn(` Config targets: ${configTargets.join(", ")}`);
|
|
2672
|
+
logger.warn(` CLI specified: ${cliTools.join(", ")}`);
|
|
2612
2673
|
if (notInConfig.length > 0) {
|
|
2613
|
-
|
|
2674
|
+
logger.warn(` Tools specified but not in config: ${notInConfig.join(", ")}`);
|
|
2614
2675
|
}
|
|
2615
2676
|
if (notInCli.length > 0) {
|
|
2616
|
-
|
|
2677
|
+
logger.warn(` Tools in config but not specified: ${notInCli.join(", ")}`);
|
|
2617
2678
|
}
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2679
|
+
logger.warn("\n The configuration file targets will be used.");
|
|
2680
|
+
logger.warn(" To change targets, update your rulesync config file.");
|
|
2681
|
+
logger.warn("");
|
|
2621
2682
|
}
|
|
2622
2683
|
}
|
|
2623
2684
|
let baseDirs;
|
|
@@ -2628,33 +2689,37 @@ async function generateCommand(options = {}) {
|
|
|
2628
2689
|
} else {
|
|
2629
2690
|
baseDirs = [process.cwd()];
|
|
2630
2691
|
}
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
}
|
|
2634
|
-
console.log("Generating configuration files...");
|
|
2692
|
+
logger.info(`Loaded configuration from: ${configResult.filepath}`);
|
|
2693
|
+
logger.log("Generating configuration files...");
|
|
2635
2694
|
if (!await fileExists(config.aiRulesDir)) {
|
|
2636
|
-
|
|
2695
|
+
logger.error("\u274C .rulesync directory not found. Run 'rulesync init' first.");
|
|
2637
2696
|
process.exit(1);
|
|
2638
2697
|
}
|
|
2639
2698
|
try {
|
|
2640
|
-
|
|
2641
|
-
console.log(`Parsing rules from ${config.aiRulesDir}...`);
|
|
2642
|
-
}
|
|
2699
|
+
logger.info(`Parsing rules from ${config.aiRulesDir}...`);
|
|
2643
2700
|
const rules = await parseRulesFromDirectory(config.aiRulesDir);
|
|
2644
2701
|
if (rules.length === 0) {
|
|
2645
|
-
|
|
2702
|
+
logger.warn("\u26A0\uFE0F No rules found in .rulesync directory");
|
|
2646
2703
|
return;
|
|
2647
2704
|
}
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
console.log(`Base directories: ${baseDirs.join(", ")}`);
|
|
2651
|
-
}
|
|
2705
|
+
logger.info(`Found ${rules.length} rule(s)`);
|
|
2706
|
+
logger.info(`Base directories: ${baseDirs.join(", ")}`);
|
|
2652
2707
|
if (config.delete) {
|
|
2653
|
-
|
|
2654
|
-
console.log("Deleting existing output directories...");
|
|
2655
|
-
}
|
|
2708
|
+
logger.info("Deleting existing output directories...");
|
|
2656
2709
|
const targetTools = config.defaultTargets;
|
|
2657
2710
|
const deleteTasks = [];
|
|
2711
|
+
const commandsDir = join15(config.aiRulesDir, "commands");
|
|
2712
|
+
const hasCommands = await fileExists(commandsDir);
|
|
2713
|
+
let hasCommandFiles = false;
|
|
2714
|
+
if (hasCommands) {
|
|
2715
|
+
const { readdir: readdir2 } = await import("fs/promises");
|
|
2716
|
+
try {
|
|
2717
|
+
const files = await readdir2(commandsDir);
|
|
2718
|
+
hasCommandFiles = files.some((file) => file.endsWith(".md"));
|
|
2719
|
+
} catch {
|
|
2720
|
+
hasCommandFiles = false;
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2658
2723
|
for (const tool of targetTools) {
|
|
2659
2724
|
switch (tool) {
|
|
2660
2725
|
case "augmentcode":
|
|
@@ -2676,15 +2741,21 @@ async function generateCommand(options = {}) {
|
|
|
2676
2741
|
break;
|
|
2677
2742
|
case "claudecode":
|
|
2678
2743
|
deleteTasks.push(removeClaudeGeneratedFiles());
|
|
2679
|
-
|
|
2744
|
+
if (hasCommandFiles) {
|
|
2745
|
+
deleteTasks.push(removeDirectory(join15(".claude", "commands")));
|
|
2746
|
+
}
|
|
2680
2747
|
break;
|
|
2681
2748
|
case "roo":
|
|
2682
2749
|
deleteTasks.push(removeDirectory(config.outputPaths.roo));
|
|
2683
|
-
|
|
2750
|
+
if (hasCommandFiles) {
|
|
2751
|
+
deleteTasks.push(removeDirectory(join15(".roo", "commands")));
|
|
2752
|
+
}
|
|
2684
2753
|
break;
|
|
2685
2754
|
case "geminicli":
|
|
2686
2755
|
deleteTasks.push(removeDirectory(config.outputPaths.geminicli));
|
|
2687
|
-
|
|
2756
|
+
if (hasCommandFiles) {
|
|
2757
|
+
deleteTasks.push(removeDirectory(join15(".gemini", "commands")));
|
|
2758
|
+
}
|
|
2688
2759
|
break;
|
|
2689
2760
|
case "kiro":
|
|
2690
2761
|
deleteTasks.push(removeDirectory(config.outputPaths.kiro));
|
|
@@ -2695,44 +2766,34 @@ async function generateCommand(options = {}) {
|
|
|
2695
2766
|
}
|
|
2696
2767
|
}
|
|
2697
2768
|
await Promise.all(deleteTasks);
|
|
2698
|
-
|
|
2699
|
-
console.log("Deleted existing output directories");
|
|
2700
|
-
}
|
|
2769
|
+
logger.info("Deleted existing output directories");
|
|
2701
2770
|
}
|
|
2702
2771
|
let totalOutputs = 0;
|
|
2703
2772
|
for (const baseDir of baseDirs) {
|
|
2704
|
-
|
|
2705
|
-
console.log(`
|
|
2773
|
+
logger.info(`
|
|
2706
2774
|
Generating configurations for base directory: ${baseDir}`);
|
|
2707
|
-
}
|
|
2708
2775
|
const outputs = await generateConfigurations(rules, config, config.defaultTargets, baseDir);
|
|
2709
2776
|
if (outputs.length === 0) {
|
|
2710
|
-
|
|
2711
|
-
console.warn(`\u26A0\uFE0F No configurations generated for ${baseDir}`);
|
|
2712
|
-
}
|
|
2777
|
+
logger.warn(`\u26A0\uFE0F No configurations generated for ${baseDir}`);
|
|
2713
2778
|
continue;
|
|
2714
2779
|
}
|
|
2715
2780
|
for (const output of outputs) {
|
|
2716
2781
|
await writeFileContent(output.filepath, output.content);
|
|
2717
|
-
|
|
2782
|
+
logger.success(`Generated ${output.tool} configuration: ${output.filepath}`);
|
|
2718
2783
|
}
|
|
2719
2784
|
totalOutputs += outputs.length;
|
|
2720
2785
|
}
|
|
2721
2786
|
if (totalOutputs === 0) {
|
|
2722
|
-
|
|
2787
|
+
logger.warn("\u26A0\uFE0F No configurations generated");
|
|
2723
2788
|
return;
|
|
2724
2789
|
}
|
|
2725
|
-
|
|
2726
|
-
console.log("\nGenerating MCP configurations...");
|
|
2727
|
-
}
|
|
2790
|
+
logger.info("\nGenerating MCP configurations...");
|
|
2728
2791
|
let totalMcpOutputs = 0;
|
|
2729
2792
|
for (const baseDir of baseDirs) {
|
|
2730
2793
|
try {
|
|
2731
2794
|
const mcpConfig = parseMcpConfig(process.cwd());
|
|
2732
2795
|
if (!mcpConfig || !mcpConfig.mcpServers || Object.keys(mcpConfig.mcpServers).length === 0) {
|
|
2733
|
-
|
|
2734
|
-
console.log(`No MCP configuration found for ${baseDir}`);
|
|
2735
|
-
}
|
|
2796
|
+
logger.info(`No MCP configuration found for ${baseDir}`);
|
|
2736
2797
|
continue;
|
|
2737
2798
|
}
|
|
2738
2799
|
const mcpResults = await generateMcpConfigurations(
|
|
@@ -2741,27 +2802,21 @@ Generating configurations for base directory: ${baseDir}`);
|
|
|
2741
2802
|
config.defaultTargets
|
|
2742
2803
|
);
|
|
2743
2804
|
if (mcpResults.length === 0) {
|
|
2744
|
-
|
|
2745
|
-
console.log(`No MCP configurations generated for ${baseDir}`);
|
|
2746
|
-
}
|
|
2805
|
+
logger.info(`No MCP configurations generated for ${baseDir}`);
|
|
2747
2806
|
continue;
|
|
2748
2807
|
}
|
|
2749
2808
|
for (const result of mcpResults) {
|
|
2750
2809
|
await writeFileContent(result.filepath, result.content);
|
|
2751
|
-
|
|
2810
|
+
logger.success(`Generated ${result.tool} MCP configuration: ${result.filepath}`);
|
|
2752
2811
|
totalMcpOutputs++;
|
|
2753
2812
|
}
|
|
2754
2813
|
} catch (error) {
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
);
|
|
2759
|
-
}
|
|
2814
|
+
logger.error(
|
|
2815
|
+
`\u274C Failed to generate MCP configurations: ${error instanceof Error ? error.message : String(error)}`
|
|
2816
|
+
);
|
|
2760
2817
|
}
|
|
2761
2818
|
}
|
|
2762
|
-
|
|
2763
|
-
console.log("\nGenerating command files...");
|
|
2764
|
-
}
|
|
2819
|
+
logger.info("\nGenerating command files...");
|
|
2765
2820
|
let totalCommandOutputs = 0;
|
|
2766
2821
|
for (const baseDir of baseDirs) {
|
|
2767
2822
|
const commandResults = await generateCommands(
|
|
@@ -2770,14 +2825,12 @@ Generating configurations for base directory: ${baseDir}`);
|
|
|
2770
2825
|
config.defaultTargets
|
|
2771
2826
|
);
|
|
2772
2827
|
if (commandResults.length === 0) {
|
|
2773
|
-
|
|
2774
|
-
console.log(`No commands found for ${baseDir}`);
|
|
2775
|
-
}
|
|
2828
|
+
logger.info(`No commands found for ${baseDir}`);
|
|
2776
2829
|
continue;
|
|
2777
2830
|
}
|
|
2778
2831
|
for (const result of commandResults) {
|
|
2779
2832
|
await writeFileContent(result.filepath, result.content);
|
|
2780
|
-
|
|
2833
|
+
logger.success(`Generated ${result.tool} command: ${result.filepath}`);
|
|
2781
2834
|
totalCommandOutputs++;
|
|
2782
2835
|
}
|
|
2783
2836
|
}
|
|
@@ -2787,13 +2840,13 @@ Generating configurations for base directory: ${baseDir}`);
|
|
|
2787
2840
|
if (totalOutputs > 0) parts.push(`${totalOutputs} configurations`);
|
|
2788
2841
|
if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP configurations`);
|
|
2789
2842
|
if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
|
|
2790
|
-
|
|
2843
|
+
logger.success(
|
|
2791
2844
|
`
|
|
2792
2845
|
\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`
|
|
2793
2846
|
);
|
|
2794
2847
|
}
|
|
2795
2848
|
} catch (error) {
|
|
2796
|
-
|
|
2849
|
+
logger.error("\u274C Failed to generate configurations:", error);
|
|
2797
2850
|
process.exit(1);
|
|
2798
2851
|
}
|
|
2799
2852
|
}
|
|
@@ -3700,7 +3753,13 @@ import matter6 from "gray-matter";
|
|
|
3700
3753
|
|
|
3701
3754
|
// src/core/importer.ts
|
|
3702
3755
|
async function importConfiguration(options) {
|
|
3703
|
-
const {
|
|
3756
|
+
const {
|
|
3757
|
+
tool,
|
|
3758
|
+
baseDir = process.cwd(),
|
|
3759
|
+
rulesDir = ".rulesync",
|
|
3760
|
+
verbose = false,
|
|
3761
|
+
useLegacyLocation = false
|
|
3762
|
+
} = options;
|
|
3704
3763
|
const errors = [];
|
|
3705
3764
|
let rules = [];
|
|
3706
3765
|
let ignorePatterns;
|
|
@@ -3800,6 +3859,12 @@ async function importConfiguration(options) {
|
|
|
3800
3859
|
targetDir = join23(rulesDirPath, "commands");
|
|
3801
3860
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
3802
3861
|
await mkdir3(targetDir, { recursive: true });
|
|
3862
|
+
} else {
|
|
3863
|
+
if (!useLegacyLocation) {
|
|
3864
|
+
targetDir = join23(rulesDirPath, "rules");
|
|
3865
|
+
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
3866
|
+
await mkdir3(targetDir, { recursive: true });
|
|
3867
|
+
}
|
|
3803
3868
|
}
|
|
3804
3869
|
const filePath = join23(targetDir, `${baseFilename}.md`);
|
|
3805
3870
|
const content = generateRuleFileContent(rule);
|
|
@@ -3868,6 +3933,7 @@ function generateRuleFileContent(rule) {
|
|
|
3868
3933
|
|
|
3869
3934
|
// src/cli/commands/import.ts
|
|
3870
3935
|
async function importCommand(options = {}) {
|
|
3936
|
+
logger.setVerbose(options.verbose || false);
|
|
3871
3937
|
const tools = [];
|
|
3872
3938
|
if (options.augmentcode) tools.push("augmentcode");
|
|
3873
3939
|
if (options["augmentcode-legacy"]) tools.push("augmentcode-legacy");
|
|
@@ -3878,66 +3944,74 @@ async function importCommand(options = {}) {
|
|
|
3878
3944
|
if (options.roo) tools.push("roo");
|
|
3879
3945
|
if (options.geminicli) tools.push("geminicli");
|
|
3880
3946
|
if (tools.length === 0) {
|
|
3881
|
-
|
|
3947
|
+
logger.error(
|
|
3882
3948
|
"\u274C Please specify one tool to import from (--augmentcode, --augmentcode-legacy, --claudecode, --cursor, --copilot, --cline, --roo, --geminicli)"
|
|
3883
3949
|
);
|
|
3884
3950
|
process.exit(1);
|
|
3885
3951
|
}
|
|
3886
3952
|
if (tools.length > 1) {
|
|
3887
|
-
|
|
3953
|
+
logger.error(
|
|
3888
3954
|
"\u274C Only one tool can be specified at a time. Please run the import command separately for each tool."
|
|
3889
3955
|
);
|
|
3890
3956
|
process.exit(1);
|
|
3891
3957
|
}
|
|
3892
3958
|
const tool = tools[0];
|
|
3893
3959
|
if (!tool) {
|
|
3894
|
-
|
|
3960
|
+
logger.error("Error: No tool specified");
|
|
3895
3961
|
process.exit(1);
|
|
3896
3962
|
}
|
|
3897
|
-
|
|
3963
|
+
logger.log(`Importing configuration files from ${tool}...`);
|
|
3898
3964
|
try {
|
|
3899
3965
|
const result = await importConfiguration({
|
|
3900
3966
|
tool,
|
|
3901
|
-
verbose: options.verbose ?? false
|
|
3967
|
+
verbose: options.verbose ?? false,
|
|
3968
|
+
useLegacyLocation: options.legacy ?? false
|
|
3902
3969
|
});
|
|
3903
3970
|
if (result.success) {
|
|
3904
|
-
|
|
3971
|
+
logger.success(`Imported ${result.rulesCreated} rule(s) from ${tool}`);
|
|
3905
3972
|
if (result.ignoreFileCreated) {
|
|
3906
|
-
|
|
3973
|
+
logger.success("Created .rulesyncignore file from ignore patterns");
|
|
3907
3974
|
}
|
|
3908
3975
|
if (result.mcpFileCreated) {
|
|
3909
|
-
|
|
3976
|
+
logger.success("Created .rulesync/.mcp.json file from MCP configuration");
|
|
3910
3977
|
}
|
|
3911
|
-
|
|
3978
|
+
logger.log("You can now run 'rulesync generate' to create tool-specific configurations.");
|
|
3912
3979
|
} else if (result.errors.length > 0) {
|
|
3913
|
-
|
|
3914
|
-
if (
|
|
3915
|
-
|
|
3980
|
+
logger.warn(`\u26A0\uFE0F Failed to import from ${tool}: ${result.errors[0]}`);
|
|
3981
|
+
if (result.errors.length > 1) {
|
|
3982
|
+
logger.info("\nDetailed errors:");
|
|
3916
3983
|
for (const error of result.errors) {
|
|
3917
|
-
|
|
3984
|
+
logger.info(` - ${error}`);
|
|
3918
3985
|
}
|
|
3919
3986
|
}
|
|
3920
3987
|
}
|
|
3921
3988
|
} catch (error) {
|
|
3922
3989
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3923
|
-
|
|
3990
|
+
logger.error(`\u274C Error importing from ${tool}: ${errorMessage}`);
|
|
3924
3991
|
process.exit(1);
|
|
3925
3992
|
}
|
|
3926
3993
|
}
|
|
3927
3994
|
|
|
3928
3995
|
// src/cli/commands/init.ts
|
|
3929
3996
|
import { join as join24 } from "path";
|
|
3930
|
-
async function initCommand() {
|
|
3931
|
-
const
|
|
3997
|
+
async function initCommand(options = {}) {
|
|
3998
|
+
const configResult = await loadConfig();
|
|
3999
|
+
const config = configResult.config;
|
|
4000
|
+
const aiRulesDir = config.aiRulesDir;
|
|
3932
4001
|
console.log("Initializing rulesync...");
|
|
3933
4002
|
await ensureDir(aiRulesDir);
|
|
3934
|
-
|
|
4003
|
+
const useLegacy = options.legacy ?? config.legacy ?? false;
|
|
4004
|
+
const rulesDir = useLegacy ? aiRulesDir : join24(aiRulesDir, "rules");
|
|
4005
|
+
if (!useLegacy) {
|
|
4006
|
+
await ensureDir(rulesDir);
|
|
4007
|
+
}
|
|
4008
|
+
await createSampleFiles(rulesDir);
|
|
3935
4009
|
console.log("\u2705 rulesync initialized successfully!");
|
|
3936
4010
|
console.log("\nNext steps:");
|
|
3937
|
-
console.log(
|
|
4011
|
+
console.log(`1. Edit rule files in ${rulesDir}/`);
|
|
3938
4012
|
console.log("2. Run 'rulesync generate' to create configuration files");
|
|
3939
4013
|
}
|
|
3940
|
-
async function createSampleFiles(
|
|
4014
|
+
async function createSampleFiles(rulesDir) {
|
|
3941
4015
|
const sampleFile = {
|
|
3942
4016
|
filename: "overview.md",
|
|
3943
4017
|
content: `---
|
|
@@ -3973,7 +4047,7 @@ globs: ["**/*"]
|
|
|
3973
4047
|
- Follow single responsibility principle
|
|
3974
4048
|
`
|
|
3975
4049
|
};
|
|
3976
|
-
const filepath = join24(
|
|
4050
|
+
const filepath = join24(rulesDir, sampleFile.filename);
|
|
3977
4051
|
if (!await fileExists(filepath)) {
|
|
3978
4052
|
await writeFileContent(filepath, sampleFile.content);
|
|
3979
4053
|
console.log(`Created ${filepath}`);
|
|
@@ -4117,11 +4191,11 @@ async function watchCommand() {
|
|
|
4117
4191
|
|
|
4118
4192
|
// src/cli/index.ts
|
|
4119
4193
|
var program = new Command();
|
|
4120
|
-
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.
|
|
4121
|
-
program.command("init").description("Initialize rulesync in current directory").action(initCommand);
|
|
4122
|
-
program.command("add <filename>").description("Add a new rule file").action(addCommand);
|
|
4194
|
+
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.62.0");
|
|
4195
|
+
program.command("init").description("Initialize rulesync in current directory").option("--legacy", "Use legacy file location (.rulesync/*.md instead of .rulesync/rules/*.md)").action(initCommand);
|
|
4196
|
+
program.command("add <filename>").description("Add a new rule file").option("--legacy", "Use legacy file location (.rulesync/*.md instead of .rulesync/rules/*.md)").action(addCommand);
|
|
4123
4197
|
program.command("gitignore").description("Add generated files to .gitignore").action(gitignoreCommand);
|
|
4124
|
-
program.command("import").description("Import configurations from AI tools to rulesync format").option("--augmentcode", "Import from AugmentCode (.augment/rules/)").option("--augmentcode-legacy", "Import from AugmentCode legacy format (.augment-guidelines)").option("--claudecode", "Import from Claude Code (CLAUDE.md)").option("--cursor", "Import from Cursor (.cursorrules)").option("--copilot", "Import from GitHub Copilot (.github/copilot-instructions.md)").option("--cline", "Import from Cline (.cline/instructions.md)").option("--roo", "Import from Roo Code (.roo/instructions.md)").option("--geminicli", "Import from Gemini CLI (GEMINI.md)").option("--junie", "Import from JetBrains Junie (.junie/guidelines.md)").option("-v, --verbose", "Verbose output").action(importCommand);
|
|
4198
|
+
program.command("import").description("Import configurations from AI tools to rulesync format").option("--augmentcode", "Import from AugmentCode (.augment/rules/)").option("--augmentcode-legacy", "Import from AugmentCode legacy format (.augment-guidelines)").option("--claudecode", "Import from Claude Code (CLAUDE.md)").option("--cursor", "Import from Cursor (.cursorrules)").option("--copilot", "Import from GitHub Copilot (.github/copilot-instructions.md)").option("--cline", "Import from Cline (.cline/instructions.md)").option("--roo", "Import from Roo Code (.roo/instructions.md)").option("--geminicli", "Import from Gemini CLI (GEMINI.md)").option("--junie", "Import from JetBrains Junie (.junie/guidelines.md)").option("-v, --verbose", "Verbose output").option("--legacy", "Use legacy file location (.rulesync/*.md instead of .rulesync/rules/*.md)").action(importCommand);
|
|
4125
4199
|
program.command("generate").description("Generate configuration files for AI tools").option("--augmentcode", "Generate only for AugmentCode").option("--augmentcode-legacy", "Generate only for AugmentCode legacy format").option("--copilot", "Generate only for GitHub Copilot").option("--cursor", "Generate only for Cursor").option("--cline", "Generate only for Cline").option("--codexcli", "Generate only for OpenAI Codex CLI").option("--claudecode", "Generate only for Claude Code").option("--roo", "Generate only for Roo Code").option("--geminicli", "Generate only for Gemini CLI").option("--junie", "Generate only for JetBrains Junie").option("--kiro", "Generate only for Kiro IDE").option("--windsurf", "Generate only for Windsurf").option("--delete", "Delete all existing files in output directories before generating").option(
|
|
4126
4200
|
"-b, --base-dir <paths>",
|
|
4127
4201
|
"Base directories to generate files (comma-separated for multiple paths)"
|