rulesync 0.60.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 -11
- package/dist/{chunk-2TFEIJOG.js → chunk-2CW2KFB3.js} +1 -1
- package/dist/chunk-4PSTOKKD.js +12 -0
- package/dist/{chunk-YGX4XO3M.js → chunk-GQTMTBX4.js} +16 -1
- package/dist/{chunk-5BYJMDCI.js → chunk-M7NL7G7A.js} +1 -1
- package/dist/{chunk-7Q5JNJJW.js → chunk-MDYDKNXQ.js} +1 -1
- package/dist/{chunk-ZOVBWPWK.js → chunk-NETSYSMD.js} +1 -1
- package/dist/{chunk-GJ3NMGAT.js → chunk-U4PLVMCG.js} +1 -1
- package/dist/chunk-UEAYL4NT.js +12 -0
- package/dist/{claudecode-W56JJONQ.js → claudecode-YTEFACCT.js} +2 -2
- package/dist/{cline-SEVFH54V.js → cline-CKNUDEA3.js} +2 -2
- package/dist/{codexcli-Q34DZAEO.js → codexcli-7SDGYI7D.js} +2 -2
- package/dist/{cursor-PT2RUL4U.js → cursor-YJGH7W24.js} +2 -2
- package/dist/{geminicli-AUNY2MDS.js → geminicli-E7KZTZ2G.js} +2 -2
- package/dist/index.cjs +463 -370
- package/dist/index.js +434 -348
- package/dist/{junie-YL5UL6FE.js → junie-5LEQU4BO.js} +2 -2
- package/dist/{windsurf-RLTNFHLL.js → windsurf-4P6HEUBV.js} +2 -2
- package/package.json +2 -2
- package/dist/chunk-55OU7KJU.js +0 -17
- package/dist/chunk-QP2BI4DF.js +0 -17
package/dist/index.cjs
CHANGED
|
@@ -35,11 +35,11 @@ function isToolTarget(target) {
|
|
|
35
35
|
if (!target) return false;
|
|
36
36
|
return ALL_TOOL_TARGETS.some((validTarget) => validTarget === target);
|
|
37
37
|
}
|
|
38
|
-
var
|
|
38
|
+
var import_mini3, ALL_TOOL_TARGETS, ToolTargetSchema, ToolTargetsSchema, WildcardTargetSchema, RulesyncTargetsSchema;
|
|
39
39
|
var init_tool_targets = __esm({
|
|
40
40
|
"src/types/tool-targets.ts"() {
|
|
41
41
|
"use strict";
|
|
42
|
-
|
|
42
|
+
import_mini3 = require("zod/mini");
|
|
43
43
|
ALL_TOOL_TARGETS = [
|
|
44
44
|
"augmentcode",
|
|
45
45
|
"augmentcode-legacy",
|
|
@@ -54,10 +54,10 @@ var init_tool_targets = __esm({
|
|
|
54
54
|
"junie",
|
|
55
55
|
"windsurf"
|
|
56
56
|
];
|
|
57
|
-
ToolTargetSchema =
|
|
58
|
-
ToolTargetsSchema =
|
|
59
|
-
WildcardTargetSchema =
|
|
60
|
-
RulesyncTargetsSchema =
|
|
57
|
+
ToolTargetSchema = import_mini3.z.enum(ALL_TOOL_TARGETS);
|
|
58
|
+
ToolTargetsSchema = import_mini3.z.array(ToolTargetSchema);
|
|
59
|
+
WildcardTargetSchema = import_mini3.z.tuple([import_mini3.z.literal("*")]);
|
|
60
|
+
RulesyncTargetsSchema = import_mini3.z.union([ToolTargetsSchema, WildcardTargetSchema]);
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
63
|
|
|
@@ -230,6 +230,16 @@ function generateMcpFromRegistry(tool, config) {
|
|
|
230
230
|
}
|
|
231
231
|
return generateMcpConfig(config, generatorConfig);
|
|
232
232
|
}
|
|
233
|
+
function createMcpGenerator(toolName) {
|
|
234
|
+
return {
|
|
235
|
+
generateMcp: (config) => {
|
|
236
|
+
return generateMcpFromRegistry(toolName, config);
|
|
237
|
+
},
|
|
238
|
+
generateMcpConfiguration: (mcpServers, baseDir = "") => {
|
|
239
|
+
return generateMcpConfigurationFilesFromRegistry(toolName, mcpServers, baseDir);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
233
243
|
function generateMcpConfigurationFilesFromRegistry(tool, mcpServers, baseDir = "") {
|
|
234
244
|
const generatorConfig = MCP_GENERATOR_REGISTRY[tool];
|
|
235
245
|
if (!generatorConfig) {
|
|
@@ -247,7 +257,8 @@ function generateMcpConfigurationFilesFromRegistry(tool, mcpServers, baseDir = "
|
|
|
247
257
|
return generateMcpConfigurationFiles(mcpServers, generatorConfig, baseDir);
|
|
248
258
|
}
|
|
249
259
|
function generateJunieMcpConfigurationFiles(mcpServers, baseDir = "") {
|
|
250
|
-
const
|
|
260
|
+
const junieMcpPath = ".junie/mcp/mcp.json";
|
|
261
|
+
const filepath = baseDir ? `${baseDir}/${junieMcpPath}` : junieMcpPath;
|
|
251
262
|
const config = {
|
|
252
263
|
mcpServers: {}
|
|
253
264
|
};
|
|
@@ -282,7 +293,7 @@ function generateJunieMcpConfigurationFiles(mcpServers, baseDir = "") {
|
|
|
282
293
|
}
|
|
283
294
|
];
|
|
284
295
|
}
|
|
285
|
-
var serverTransforms, configWrappers, MCP_GENERATOR_REGISTRY;
|
|
296
|
+
var serverTransforms, configWrappers, MCP_GENERATOR_REGISTRY, cursorMcpGenerator, clineMcpGenerator;
|
|
286
297
|
var init_shared_factory = __esm({
|
|
287
298
|
"src/generators/mcp/shared-factory.ts"() {
|
|
288
299
|
"use strict";
|
|
@@ -484,6 +495,8 @@ var init_shared_factory = __esm({
|
|
|
484
495
|
configWrapper: configWrappers.mcpServers
|
|
485
496
|
}
|
|
486
497
|
};
|
|
498
|
+
cursorMcpGenerator = createMcpGenerator("cursor");
|
|
499
|
+
clineMcpGenerator = createMcpGenerator("cline");
|
|
487
500
|
}
|
|
488
501
|
});
|
|
489
502
|
|
|
@@ -512,16 +525,13 @@ __export(cline_exports, {
|
|
|
512
525
|
generateClineMcp: () => generateClineMcp,
|
|
513
526
|
generateClineMcpConfiguration: () => generateClineMcpConfiguration
|
|
514
527
|
});
|
|
515
|
-
|
|
516
|
-
return generateMcpFromRegistry("cline", config);
|
|
517
|
-
}
|
|
518
|
-
function generateClineMcpConfiguration(mcpServers, baseDir = "") {
|
|
519
|
-
return generateMcpConfigurationFilesFromRegistry("cline", mcpServers, baseDir);
|
|
520
|
-
}
|
|
528
|
+
var generateClineMcp, generateClineMcpConfiguration;
|
|
521
529
|
var init_cline = __esm({
|
|
522
530
|
"src/generators/mcp/cline.ts"() {
|
|
523
531
|
"use strict";
|
|
524
532
|
init_shared_factory();
|
|
533
|
+
generateClineMcp = clineMcpGenerator.generateMcp;
|
|
534
|
+
generateClineMcpConfiguration = clineMcpGenerator.generateMcpConfiguration;
|
|
525
535
|
}
|
|
526
536
|
});
|
|
527
537
|
|
|
@@ -759,16 +769,13 @@ __export(cursor_exports, {
|
|
|
759
769
|
generateCursorMcp: () => generateCursorMcp,
|
|
760
770
|
generateCursorMcpConfiguration: () => generateCursorMcpConfiguration
|
|
761
771
|
});
|
|
762
|
-
|
|
763
|
-
return generateMcpFromRegistry("cursor", config);
|
|
764
|
-
}
|
|
765
|
-
function generateCursorMcpConfiguration(mcpServers, baseDir = "") {
|
|
766
|
-
return generateMcpConfigurationFilesFromRegistry("cursor", mcpServers, baseDir);
|
|
767
|
-
}
|
|
772
|
+
var generateCursorMcp, generateCursorMcpConfiguration;
|
|
768
773
|
var init_cursor = __esm({
|
|
769
774
|
"src/generators/mcp/cursor.ts"() {
|
|
770
775
|
"use strict";
|
|
771
776
|
init_shared_factory();
|
|
777
|
+
generateCursorMcp = cursorMcpGenerator.generateMcp;
|
|
778
|
+
generateCursorMcpConfiguration = cursorMcpGenerator.generateMcpConfiguration;
|
|
772
779
|
}
|
|
773
780
|
});
|
|
774
781
|
|
|
@@ -1049,92 +1056,25 @@ var import_commander = require("commander");
|
|
|
1049
1056
|
var import_promises = require("fs/promises");
|
|
1050
1057
|
var path = __toESM(require("path"), 1);
|
|
1051
1058
|
|
|
1052
|
-
// src/utils/config.ts
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
return {
|
|
1056
|
-
aiRulesDir: ".rulesync",
|
|
1057
|
-
outputPaths: {
|
|
1058
|
-
augmentcode: ".",
|
|
1059
|
-
"augmentcode-legacy": ".",
|
|
1060
|
-
copilot: ".github/instructions",
|
|
1061
|
-
cursor: ".cursor/rules",
|
|
1062
|
-
cline: ".clinerules",
|
|
1063
|
-
claudecode: ".",
|
|
1064
|
-
codexcli: ".",
|
|
1065
|
-
roo: ".roo/rules",
|
|
1066
|
-
geminicli: ".gemini/memories",
|
|
1067
|
-
kiro: ".kiro/steering",
|
|
1068
|
-
junie: ".",
|
|
1069
|
-
windsurf: "."
|
|
1070
|
-
},
|
|
1071
|
-
watchEnabled: false,
|
|
1072
|
-
defaultTargets: ALL_TOOL_TARGETS.filter((tool) => tool !== "augmentcode-legacy")
|
|
1073
|
-
};
|
|
1074
|
-
}
|
|
1075
|
-
function resolveTargets(targets, config) {
|
|
1076
|
-
if (targets.length === 1 && targets[0] === "*") {
|
|
1077
|
-
return config.defaultTargets;
|
|
1078
|
-
}
|
|
1079
|
-
const validatedTargets = ToolTargetsSchema.parse(targets);
|
|
1080
|
-
return validatedTargets;
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
// src/cli/commands/add.ts
|
|
1084
|
-
function sanitizeFilename(filename) {
|
|
1085
|
-
return filename.endsWith(".md") ? filename.slice(0, -3) : filename;
|
|
1086
|
-
}
|
|
1087
|
-
function generateRuleTemplate(filename) {
|
|
1088
|
-
return `---
|
|
1089
|
-
root: false
|
|
1090
|
-
targets: ["*"]
|
|
1091
|
-
description: "Rules for ${filename}"
|
|
1092
|
-
globs: []
|
|
1093
|
-
---
|
|
1094
|
-
|
|
1095
|
-
# ${filename.charAt(0).toUpperCase() + filename.slice(1)} Rules
|
|
1096
|
-
|
|
1097
|
-
Add your rules here.
|
|
1098
|
-
`;
|
|
1099
|
-
}
|
|
1100
|
-
async function addCommand(filename) {
|
|
1101
|
-
try {
|
|
1102
|
-
const config = getDefaultConfig();
|
|
1103
|
-
const sanitizedFilename = sanitizeFilename(filename);
|
|
1104
|
-
const rulesDir = config.aiRulesDir;
|
|
1105
|
-
const filePath = path.join(rulesDir, `${sanitizedFilename}.md`);
|
|
1106
|
-
await (0, import_promises.mkdir)(rulesDir, { recursive: true });
|
|
1107
|
-
const template = generateRuleTemplate(sanitizedFilename);
|
|
1108
|
-
await (0, import_promises.writeFile)(filePath, template, "utf8");
|
|
1109
|
-
console.log(`\u2705 Created rule file: ${filePath}`);
|
|
1110
|
-
console.log(`\u{1F4DD} Edit the file to customize your rules.`);
|
|
1111
|
-
} catch (error) {
|
|
1112
|
-
console.error(
|
|
1113
|
-
`\u274C Failed to create rule file: ${error instanceof Error ? error.message : String(error)}`
|
|
1114
|
-
);
|
|
1115
|
-
process.exit(3);
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
// src/cli/commands/config.ts
|
|
1120
|
-
var import_node_fs = require("fs");
|
|
1121
|
-
var import_node_path2 = __toESM(require("path"), 1);
|
|
1059
|
+
// src/utils/config-loader.ts
|
|
1060
|
+
var import_c12 = require("c12");
|
|
1061
|
+
var import_core = require("zod/v4/core");
|
|
1122
1062
|
|
|
1123
1063
|
// src/types/claudecode.ts
|
|
1124
|
-
var
|
|
1125
|
-
var ClaudeSettingsSchema =
|
|
1126
|
-
permissions:
|
|
1127
|
-
|
|
1128
|
-
deny:
|
|
1064
|
+
var import_mini = require("zod/mini");
|
|
1065
|
+
var ClaudeSettingsSchema = import_mini.z.looseObject({
|
|
1066
|
+
permissions: import_mini.z._default(
|
|
1067
|
+
import_mini.z.looseObject({
|
|
1068
|
+
deny: import_mini.z._default(import_mini.z.array(import_mini.z.string()), [])
|
|
1129
1069
|
}),
|
|
1130
1070
|
{ deny: [] }
|
|
1131
1071
|
)
|
|
1132
1072
|
});
|
|
1133
1073
|
|
|
1134
1074
|
// src/types/commands.ts
|
|
1135
|
-
var
|
|
1136
|
-
var CommandFrontmatterSchema =
|
|
1137
|
-
description:
|
|
1075
|
+
var import_mini2 = require("zod/mini");
|
|
1076
|
+
var CommandFrontmatterSchema = import_mini2.z.object({
|
|
1077
|
+
description: import_mini2.z.optional(import_mini2.z.string())
|
|
1138
1078
|
});
|
|
1139
1079
|
|
|
1140
1080
|
// src/types/config.ts
|
|
@@ -1146,7 +1086,8 @@ var ConfigSchema = import_mini4.z.object({
|
|
|
1146
1086
|
watchEnabled: import_mini4.z.boolean(),
|
|
1147
1087
|
defaultTargets: ToolTargetsSchema,
|
|
1148
1088
|
claudecodeCommands: import_mini4.z.optional(import_mini4.z.string()),
|
|
1149
|
-
geminicliCommands: import_mini4.z.optional(import_mini4.z.string())
|
|
1089
|
+
geminicliCommands: import_mini4.z.optional(import_mini4.z.string()),
|
|
1090
|
+
legacy: import_mini4.z.optional(import_mini4.z.boolean())
|
|
1150
1091
|
});
|
|
1151
1092
|
|
|
1152
1093
|
// src/types/config-options.ts
|
|
@@ -1176,6 +1117,7 @@ var ConfigOptionsSchema = import_mini5.z.object({
|
|
|
1176
1117
|
verbose: import_mini5.z.optional(import_mini5.z.boolean()),
|
|
1177
1118
|
delete: import_mini5.z.optional(import_mini5.z.boolean()),
|
|
1178
1119
|
baseDir: import_mini5.z.optional(import_mini5.z.union([import_mini5.z.string(), import_mini5.z.array(import_mini5.z.string())])),
|
|
1120
|
+
legacy: import_mini5.z.optional(import_mini5.z.boolean()),
|
|
1179
1121
|
watch: import_mini5.z.optional(
|
|
1180
1122
|
import_mini5.z.object({
|
|
1181
1123
|
enabled: import_mini5.z.optional(import_mini5.z.boolean()),
|
|
@@ -1195,6 +1137,7 @@ var MergedConfigSchema = import_mini5.z.object({
|
|
|
1195
1137
|
delete: import_mini5.z.optional(import_mini5.z.boolean()),
|
|
1196
1138
|
baseDir: import_mini5.z.optional(import_mini5.z.union([import_mini5.z.string(), import_mini5.z.array(import_mini5.z.string())])),
|
|
1197
1139
|
configPath: import_mini5.z.optional(import_mini5.z.string()),
|
|
1140
|
+
legacy: import_mini5.z.optional(import_mini5.z.boolean()),
|
|
1198
1141
|
watch: import_mini5.z.optional(
|
|
1199
1142
|
import_mini5.z.object({
|
|
1200
1143
|
enabled: import_mini5.z.optional(import_mini5.z.boolean()),
|
|
@@ -1250,13 +1193,6 @@ var RuleFrontmatterSchema = import_mini7.z.object({
|
|
|
1250
1193
|
windsurfOutputFormat: import_mini7.z.optional(import_mini7.z.enum(["single-file", "directory"])),
|
|
1251
1194
|
tags: import_mini7.z.optional(import_mini7.z.array(import_mini7.z.string()))
|
|
1252
1195
|
});
|
|
1253
|
-
var ParsedRuleSchema = import_mini7.z.object({
|
|
1254
|
-
frontmatter: RuleFrontmatterSchema,
|
|
1255
|
-
content: import_mini7.z.string(),
|
|
1256
|
-
filename: import_mini7.z.string(),
|
|
1257
|
-
filepath: import_mini7.z.string(),
|
|
1258
|
-
type: import_mini7.z.optional(import_mini7.z.enum(["rule", "command"]))
|
|
1259
|
-
});
|
|
1260
1196
|
var GeneratedOutputSchema = import_mini7.z.object({
|
|
1261
1197
|
tool: ToolTargetSchema,
|
|
1262
1198
|
filepath: import_mini7.z.string(),
|
|
@@ -1271,9 +1207,39 @@ var GenerateOptionsSchema = import_mini7.z.object({
|
|
|
1271
1207
|
// src/types/index.ts
|
|
1272
1208
|
init_tool_targets();
|
|
1273
1209
|
|
|
1210
|
+
// src/utils/config.ts
|
|
1211
|
+
init_tool_targets();
|
|
1212
|
+
function getDefaultConfig() {
|
|
1213
|
+
return {
|
|
1214
|
+
aiRulesDir: ".rulesync",
|
|
1215
|
+
outputPaths: {
|
|
1216
|
+
augmentcode: ".",
|
|
1217
|
+
"augmentcode-legacy": ".",
|
|
1218
|
+
copilot: ".github/instructions",
|
|
1219
|
+
cursor: ".cursor/rules",
|
|
1220
|
+
cline: ".clinerules",
|
|
1221
|
+
claudecode: ".",
|
|
1222
|
+
codexcli: ".",
|
|
1223
|
+
roo: ".roo/rules",
|
|
1224
|
+
geminicli: ".gemini/memories",
|
|
1225
|
+
kiro: ".kiro/steering",
|
|
1226
|
+
junie: ".",
|
|
1227
|
+
windsurf: "."
|
|
1228
|
+
},
|
|
1229
|
+
watchEnabled: false,
|
|
1230
|
+
defaultTargets: ALL_TOOL_TARGETS.filter((tool) => tool !== "augmentcode-legacy"),
|
|
1231
|
+
legacy: false
|
|
1232
|
+
};
|
|
1233
|
+
}
|
|
1234
|
+
function resolveTargets(targets, config) {
|
|
1235
|
+
if (targets.length === 1 && targets[0] === "*") {
|
|
1236
|
+
return config.defaultTargets;
|
|
1237
|
+
}
|
|
1238
|
+
const validatedTargets = ToolTargetsSchema.parse(targets);
|
|
1239
|
+
return validatedTargets;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1274
1242
|
// src/utils/config-loader.ts
|
|
1275
|
-
var import_c12 = require("c12");
|
|
1276
|
-
var import_core = require("zod/v4/core");
|
|
1277
1243
|
var MODULE_NAME = "rulesync";
|
|
1278
1244
|
async function loadConfig(options = {}) {
|
|
1279
1245
|
const defaultConfig = getDefaultConfig();
|
|
@@ -1460,6 +1426,49 @@ function mergeWithCliOptions(config, cliOptions) {
|
|
|
1460
1426
|
return merged;
|
|
1461
1427
|
}
|
|
1462
1428
|
|
|
1429
|
+
// src/cli/commands/add.ts
|
|
1430
|
+
function sanitizeFilename(filename) {
|
|
1431
|
+
return filename.endsWith(".md") ? filename.slice(0, -3) : filename;
|
|
1432
|
+
}
|
|
1433
|
+
function generateRuleTemplate(filename) {
|
|
1434
|
+
return `---
|
|
1435
|
+
root: false
|
|
1436
|
+
targets: ["*"]
|
|
1437
|
+
description: "Rules for ${filename}"
|
|
1438
|
+
globs: []
|
|
1439
|
+
---
|
|
1440
|
+
|
|
1441
|
+
# ${filename.charAt(0).toUpperCase() + filename.slice(1)} Rules
|
|
1442
|
+
|
|
1443
|
+
Add your rules here.
|
|
1444
|
+
`;
|
|
1445
|
+
}
|
|
1446
|
+
async function addCommand(filename, options = {}) {
|
|
1447
|
+
try {
|
|
1448
|
+
const configResult = await loadConfig();
|
|
1449
|
+
const config = configResult.config;
|
|
1450
|
+
const sanitizedFilename = sanitizeFilename(filename);
|
|
1451
|
+
const aiRulesDir = config.aiRulesDir;
|
|
1452
|
+
const useLegacy = options.legacy ?? config.legacy ?? false;
|
|
1453
|
+
const rulesDir = useLegacy ? aiRulesDir : path.join(aiRulesDir, "rules");
|
|
1454
|
+
const filePath = path.join(rulesDir, `${sanitizedFilename}.md`);
|
|
1455
|
+
await (0, import_promises.mkdir)(rulesDir, { recursive: true });
|
|
1456
|
+
const template = generateRuleTemplate(sanitizedFilename);
|
|
1457
|
+
await (0, import_promises.writeFile)(filePath, template, "utf8");
|
|
1458
|
+
console.log(`\u2705 Created rule file: ${filePath}`);
|
|
1459
|
+
console.log(`\u{1F4DD} Edit the file to customize your rules.`);
|
|
1460
|
+
} catch (error) {
|
|
1461
|
+
console.error(
|
|
1462
|
+
`\u274C Failed to create rule file: ${error instanceof Error ? error.message : String(error)}`
|
|
1463
|
+
);
|
|
1464
|
+
process.exit(3);
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
// src/cli/commands/config.ts
|
|
1469
|
+
var import_node_fs = require("fs");
|
|
1470
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
1471
|
+
|
|
1463
1472
|
// src/utils/error.ts
|
|
1464
1473
|
function getErrorMessage(error) {
|
|
1465
1474
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -1526,6 +1535,19 @@ async function findFiles(dir, extension = ".md") {
|
|
|
1526
1535
|
return [];
|
|
1527
1536
|
}
|
|
1528
1537
|
}
|
|
1538
|
+
async function findRuleFiles(aiRulesDir) {
|
|
1539
|
+
const rulesDir = (0, import_node_path.join)(aiRulesDir, "rules");
|
|
1540
|
+
const newLocationFiles = await findFiles(rulesDir, ".md");
|
|
1541
|
+
const legacyLocationFiles = await findFiles(aiRulesDir, ".md");
|
|
1542
|
+
const newLocationBasenames = new Set(
|
|
1543
|
+
newLocationFiles.map((file) => file.split("/").pop()?.replace(/\.md$/, ""))
|
|
1544
|
+
);
|
|
1545
|
+
const filteredLegacyFiles = legacyLocationFiles.filter((file) => {
|
|
1546
|
+
const basename6 = file.split("/").pop()?.replace(/\.md$/, "");
|
|
1547
|
+
return !newLocationBasenames.has(basename6);
|
|
1548
|
+
});
|
|
1549
|
+
return [...newLocationFiles, ...filteredLegacyFiles];
|
|
1550
|
+
}
|
|
1529
1551
|
async function removeDirectory(dirPath) {
|
|
1530
1552
|
const dangerousPaths = [".", "/", "~", "src", "node_modules"];
|
|
1531
1553
|
if (dangerousPaths.includes(dirPath) || dirPath === "") {
|
|
@@ -1560,6 +1582,50 @@ async function removeClaudeGeneratedFiles() {
|
|
|
1560
1582
|
}
|
|
1561
1583
|
}
|
|
1562
1584
|
|
|
1585
|
+
// src/utils/logger.ts
|
|
1586
|
+
var import_consola = require("consola");
|
|
1587
|
+
var Logger = class {
|
|
1588
|
+
_verbose = false;
|
|
1589
|
+
console = import_consola.consola.withDefaults({
|
|
1590
|
+
tag: "rulesync"
|
|
1591
|
+
});
|
|
1592
|
+
setVerbose(verbose) {
|
|
1593
|
+
this._verbose = verbose;
|
|
1594
|
+
}
|
|
1595
|
+
get verbose() {
|
|
1596
|
+
return this._verbose;
|
|
1597
|
+
}
|
|
1598
|
+
// Regular log (always shown, regardless of verbose)
|
|
1599
|
+
log(message, ...args) {
|
|
1600
|
+
this.console.log(message, ...args);
|
|
1601
|
+
}
|
|
1602
|
+
// Info level (shown only in verbose mode)
|
|
1603
|
+
info(message, ...args) {
|
|
1604
|
+
if (this._verbose) {
|
|
1605
|
+
this.console.info(message, ...args);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
// Success (always shown)
|
|
1609
|
+
success(message, ...args) {
|
|
1610
|
+
this.console.success(message, ...args);
|
|
1611
|
+
}
|
|
1612
|
+
// Warning (always shown)
|
|
1613
|
+
warn(message, ...args) {
|
|
1614
|
+
this.console.warn(message, ...args);
|
|
1615
|
+
}
|
|
1616
|
+
// Error (always shown)
|
|
1617
|
+
error(message, ...args) {
|
|
1618
|
+
this.console.error(message, ...args);
|
|
1619
|
+
}
|
|
1620
|
+
// Debug level (shown only in verbose mode)
|
|
1621
|
+
debug(message, ...args) {
|
|
1622
|
+
if (this._verbose) {
|
|
1623
|
+
this.console.debug(message, ...args);
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
};
|
|
1627
|
+
var logger = new Logger();
|
|
1628
|
+
|
|
1563
1629
|
// src/cli/commands/config.ts
|
|
1564
1630
|
async function configCommand(options = {}) {
|
|
1565
1631
|
if (options.init) {
|
|
@@ -1569,50 +1635,50 @@ async function configCommand(options = {}) {
|
|
|
1569
1635
|
await showConfig();
|
|
1570
1636
|
}
|
|
1571
1637
|
async function showConfig() {
|
|
1572
|
-
|
|
1638
|
+
logger.log("Loading configuration...\n");
|
|
1573
1639
|
try {
|
|
1574
1640
|
const result = await loadConfig();
|
|
1575
1641
|
if (result.isEmpty) {
|
|
1576
|
-
|
|
1642
|
+
logger.log("No configuration file found. Using default configuration.\n");
|
|
1577
1643
|
} else {
|
|
1578
|
-
|
|
1644
|
+
logger.log(`Configuration loaded from: ${result.filepath}
|
|
1579
1645
|
`);
|
|
1580
1646
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1647
|
+
logger.log("Current configuration:");
|
|
1648
|
+
logger.log("=====================");
|
|
1583
1649
|
const config = result.config;
|
|
1584
|
-
|
|
1650
|
+
logger.log(`
|
|
1585
1651
|
AI Rules Directory: ${config.aiRulesDir}`);
|
|
1586
|
-
|
|
1652
|
+
logger.log(`
|
|
1587
1653
|
Default Targets: ${config.defaultTargets.join(", ")}`);
|
|
1588
1654
|
if (config.exclude && config.exclude.length > 0) {
|
|
1589
|
-
|
|
1655
|
+
logger.log(`Excluded Targets: ${config.exclude.join(", ")}`);
|
|
1590
1656
|
}
|
|
1591
|
-
|
|
1657
|
+
logger.log("\nOutput Paths:");
|
|
1592
1658
|
for (const [tool, outputPath] of Object.entries(config.outputPaths)) {
|
|
1593
|
-
|
|
1659
|
+
logger.log(` ${tool}: ${outputPath}`);
|
|
1594
1660
|
}
|
|
1595
1661
|
if (config.baseDir) {
|
|
1596
1662
|
const dirs = Array.isArray(config.baseDir) ? config.baseDir : [config.baseDir];
|
|
1597
|
-
|
|
1663
|
+
logger.log(`
|
|
1598
1664
|
Base Directories: ${dirs.join(", ")}`);
|
|
1599
1665
|
}
|
|
1600
|
-
|
|
1666
|
+
logger.log(`
|
|
1601
1667
|
Verbose: ${config.verbose || false}`);
|
|
1602
|
-
|
|
1668
|
+
logger.log(`Delete before generate: ${config.delete || false}`);
|
|
1603
1669
|
if (config.watch) {
|
|
1604
|
-
|
|
1605
|
-
|
|
1670
|
+
logger.log("\nWatch Configuration:");
|
|
1671
|
+
logger.log(` Enabled: ${config.watch.enabled || false}`);
|
|
1606
1672
|
if (config.watch.interval) {
|
|
1607
|
-
|
|
1673
|
+
logger.log(` Interval: ${config.watch.interval}ms`);
|
|
1608
1674
|
}
|
|
1609
1675
|
if (config.watch.ignore && config.watch.ignore.length > 0) {
|
|
1610
|
-
|
|
1676
|
+
logger.log(` Ignore patterns: ${config.watch.ignore.join(", ")}`);
|
|
1611
1677
|
}
|
|
1612
1678
|
}
|
|
1613
|
-
|
|
1679
|
+
logger.log("\nTip: Use 'rulesync config init' to create a configuration file.");
|
|
1614
1680
|
} catch (error) {
|
|
1615
|
-
|
|
1681
|
+
logger.error(
|
|
1616
1682
|
"\u274C Failed to load configuration:",
|
|
1617
1683
|
error instanceof Error ? error.message : String(error)
|
|
1618
1684
|
);
|
|
@@ -1633,7 +1699,7 @@ async function initConfig(options) {
|
|
|
1633
1699
|
const validFormats = Object.keys(FORMAT_CONFIG);
|
|
1634
1700
|
const selectedFormat = options.format || "jsonc";
|
|
1635
1701
|
if (!validFormats.includes(selectedFormat)) {
|
|
1636
|
-
|
|
1702
|
+
logger.error(
|
|
1637
1703
|
`\u274C Invalid format: ${selectedFormat}. Valid formats are: ${validFormats.join(", ")}`
|
|
1638
1704
|
);
|
|
1639
1705
|
process.exit(1);
|
|
@@ -1649,7 +1715,7 @@ async function initConfig(options) {
|
|
|
1649
1715
|
if (result.success) {
|
|
1650
1716
|
validTargets.push(result.data);
|
|
1651
1717
|
} else {
|
|
1652
|
-
|
|
1718
|
+
logger.error(`\u274C Invalid target: ${target}`);
|
|
1653
1719
|
process.exit(1);
|
|
1654
1720
|
}
|
|
1655
1721
|
}
|
|
@@ -1663,7 +1729,7 @@ async function initConfig(options) {
|
|
|
1663
1729
|
if (result.success) {
|
|
1664
1730
|
validExcludes.push(result.data);
|
|
1665
1731
|
} else {
|
|
1666
|
-
|
|
1732
|
+
logger.error(`\u274C Invalid exclude target: ${exclude}`);
|
|
1667
1733
|
process.exit(1);
|
|
1668
1734
|
}
|
|
1669
1735
|
}
|
|
@@ -1686,18 +1752,18 @@ async function initConfig(options) {
|
|
|
1686
1752
|
try {
|
|
1687
1753
|
const fs2 = await import("fs/promises");
|
|
1688
1754
|
await fs2.access(filepath);
|
|
1689
|
-
|
|
1690
|
-
|
|
1755
|
+
logger.error(`\u274C Configuration file already exists: ${filepath}`);
|
|
1756
|
+
logger.log("Remove the existing file or choose a different format.");
|
|
1691
1757
|
process.exit(1);
|
|
1692
1758
|
} catch {
|
|
1693
1759
|
}
|
|
1694
1760
|
try {
|
|
1695
1761
|
(0, import_node_fs.writeFileSync)(filepath, content, "utf-8");
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1762
|
+
logger.success(`Created configuration file: ${filepath}`);
|
|
1763
|
+
logger.log("\nYou can now customize the configuration to fit your needs.");
|
|
1764
|
+
logger.log("Run 'rulesync generate' to use the new configuration.");
|
|
1699
1765
|
} catch (error) {
|
|
1700
|
-
|
|
1766
|
+
logger.error(
|
|
1701
1767
|
`\u274C Failed to create configuration file: ${error instanceof Error ? error.message : String(error)}`
|
|
1702
1768
|
);
|
|
1703
1769
|
process.exit(1);
|
|
@@ -1771,10 +1837,10 @@ export default config;
|
|
|
1771
1837
|
}
|
|
1772
1838
|
|
|
1773
1839
|
// src/cli/commands/generate.ts
|
|
1774
|
-
var
|
|
1840
|
+
var import_node_path15 = require("path");
|
|
1775
1841
|
|
|
1776
1842
|
// src/core/command-generator.ts
|
|
1777
|
-
var
|
|
1843
|
+
var import_node_path7 = require("path");
|
|
1778
1844
|
|
|
1779
1845
|
// src/generators/commands/claudecode.ts
|
|
1780
1846
|
var import_node_path3 = require("path");
|
|
@@ -1830,12 +1896,6 @@ var GeminiCliCommandGenerator = class {
|
|
|
1830
1896
|
let converted = content;
|
|
1831
1897
|
converted = converted.replace(/\$ARGUMENTS/g, "{{args}}");
|
|
1832
1898
|
converted = converted.replace(/!`([^`]+)`/g, "!{$1}");
|
|
1833
|
-
const atSyntaxMatches = converted.match(/@[^\s]+/g);
|
|
1834
|
-
if (atSyntaxMatches) {
|
|
1835
|
-
console.warn(
|
|
1836
|
-
`\u26A0\uFE0F Warning: @ syntax found (${atSyntaxMatches.join(", ")}). Gemini CLI does not support file content injection. Consider using shell commands or remove these references.`
|
|
1837
|
-
);
|
|
1838
|
-
}
|
|
1839
1899
|
return converted.trim();
|
|
1840
1900
|
}
|
|
1841
1901
|
escapeTomlString(str) {
|
|
@@ -1843,17 +1903,44 @@ var GeminiCliCommandGenerator = class {
|
|
|
1843
1903
|
}
|
|
1844
1904
|
};
|
|
1845
1905
|
|
|
1906
|
+
// src/generators/commands/roo.ts
|
|
1907
|
+
var import_node_path5 = require("path");
|
|
1908
|
+
var RooCommandGenerator = class {
|
|
1909
|
+
generate(command, outputDir) {
|
|
1910
|
+
const filepath = this.getOutputPath(command.filename, outputDir);
|
|
1911
|
+
const frontmatter = ["---"];
|
|
1912
|
+
if (command.frontmatter.description) {
|
|
1913
|
+
frontmatter.push(`description: ${command.frontmatter.description}`);
|
|
1914
|
+
}
|
|
1915
|
+
frontmatter.push("---");
|
|
1916
|
+
const content = `${frontmatter.join("\n")}
|
|
1917
|
+
|
|
1918
|
+
${command.content.trim()}
|
|
1919
|
+
`;
|
|
1920
|
+
return {
|
|
1921
|
+
tool: "roo",
|
|
1922
|
+
filepath,
|
|
1923
|
+
content
|
|
1924
|
+
};
|
|
1925
|
+
}
|
|
1926
|
+
getOutputPath(filename, baseDir) {
|
|
1927
|
+
const flattenedName = filename.replace(/\//g, "-");
|
|
1928
|
+
return (0, import_node_path5.join)(baseDir, ".roo", "commands", `${flattenedName}.md`);
|
|
1929
|
+
}
|
|
1930
|
+
};
|
|
1931
|
+
|
|
1846
1932
|
// src/generators/commands/index.ts
|
|
1847
1933
|
var commandGenerators = {
|
|
1848
1934
|
claudecode: new ClaudeCodeCommandGenerator(),
|
|
1849
|
-
geminicli: new GeminiCliCommandGenerator()
|
|
1935
|
+
geminicli: new GeminiCliCommandGenerator(),
|
|
1936
|
+
roo: new RooCommandGenerator()
|
|
1850
1937
|
};
|
|
1851
1938
|
function getCommandGenerator(tool) {
|
|
1852
1939
|
return commandGenerators[tool];
|
|
1853
1940
|
}
|
|
1854
1941
|
|
|
1855
1942
|
// src/core/command-parser.ts
|
|
1856
|
-
var
|
|
1943
|
+
var import_node_path6 = require("path");
|
|
1857
1944
|
var import_gray_matter = __toESM(require("gray-matter"), 1);
|
|
1858
1945
|
async function parseCommandsFromDirectory(commandsDir) {
|
|
1859
1946
|
const commandFiles = await findFiles(commandsDir, ".md");
|
|
@@ -1879,7 +1966,7 @@ async function parseCommandFile(filepath) {
|
|
|
1879
1966
|
const parsed = (0, import_gray_matter.default)(content);
|
|
1880
1967
|
try {
|
|
1881
1968
|
const validatedData = CommandFrontmatterSchema.parse(parsed.data);
|
|
1882
|
-
const filename = (0,
|
|
1969
|
+
const filename = (0, import_node_path6.basename)(filepath, ".md");
|
|
1883
1970
|
return {
|
|
1884
1971
|
frontmatter: {
|
|
1885
1972
|
description: validatedData.description
|
|
@@ -1897,7 +1984,7 @@ async function parseCommandFile(filepath) {
|
|
|
1897
1984
|
|
|
1898
1985
|
// src/core/command-generator.ts
|
|
1899
1986
|
async function generateCommands(projectRoot, baseDir, targets) {
|
|
1900
|
-
const commandsDir = (0,
|
|
1987
|
+
const commandsDir = (0, import_node_path7.join)(projectRoot, ".rulesync", "commands");
|
|
1901
1988
|
if (!await fileExists(commandsDir)) {
|
|
1902
1989
|
return [];
|
|
1903
1990
|
}
|
|
@@ -1907,7 +1994,9 @@ async function generateCommands(projectRoot, baseDir, targets) {
|
|
|
1907
1994
|
}
|
|
1908
1995
|
const outputs = [];
|
|
1909
1996
|
const outputDir = baseDir || projectRoot;
|
|
1910
|
-
const supportedTargets = targets.filter(
|
|
1997
|
+
const supportedTargets = targets.filter(
|
|
1998
|
+
(target) => ["claudecode", "geminicli", "roo"].includes(target)
|
|
1999
|
+
);
|
|
1911
2000
|
for (const target of supportedTargets) {
|
|
1912
2001
|
const generator = getCommandGenerator(target);
|
|
1913
2002
|
if (!generator) {
|
|
@@ -1929,58 +2018,81 @@ async function generateCommands(projectRoot, baseDir, targets) {
|
|
|
1929
2018
|
}
|
|
1930
2019
|
|
|
1931
2020
|
// src/generators/ignore/shared-factory.ts
|
|
1932
|
-
var
|
|
2021
|
+
var import_node_path8 = require("path");
|
|
1933
2022
|
|
|
1934
2023
|
// src/generators/ignore/shared-helpers.ts
|
|
1935
2024
|
function extractIgnorePatternsFromRules(rules) {
|
|
1936
2025
|
const patterns = [];
|
|
1937
2026
|
for (const rule of rules) {
|
|
1938
2027
|
if (rule.frontmatter.globs && rule.frontmatter.globs.length > 0) {
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
}
|
|
2028
|
+
const sensitiveGlobs = rule.frontmatter.globs.filter(shouldExcludeFromAI);
|
|
2029
|
+
if (sensitiveGlobs.length > 0) {
|
|
2030
|
+
patterns.push(`# Exclude: ${rule.frontmatter.description}`);
|
|
2031
|
+
patterns.push(...sensitiveGlobs);
|
|
1944
2032
|
}
|
|
1945
2033
|
}
|
|
1946
|
-
const contentPatterns =
|
|
2034
|
+
const contentPatterns = extractBasicIgnorePatternsFromContent(rule.content);
|
|
1947
2035
|
patterns.push(...contentPatterns);
|
|
1948
2036
|
}
|
|
1949
2037
|
return patterns;
|
|
1950
2038
|
}
|
|
1951
2039
|
function shouldExcludeFromAI(glob) {
|
|
1952
|
-
const
|
|
1953
|
-
//
|
|
1954
|
-
"**/
|
|
1955
|
-
"**/
|
|
1956
|
-
|
|
1957
|
-
"**/
|
|
1958
|
-
"**/
|
|
1959
|
-
"
|
|
1960
|
-
|
|
2040
|
+
const sensitivePatterns = [
|
|
2041
|
+
// Security-related patterns
|
|
2042
|
+
"**/secret**",
|
|
2043
|
+
"**/credential**",
|
|
2044
|
+
"**/token**",
|
|
2045
|
+
"**/key**",
|
|
2046
|
+
"**/password**",
|
|
2047
|
+
"**/auth**",
|
|
2048
|
+
"**/private**",
|
|
2049
|
+
"**/confidential**",
|
|
2050
|
+
"**/internal**",
|
|
2051
|
+
"**/internal-docs/**",
|
|
2052
|
+
"**/admin**",
|
|
2053
|
+
// Configuration patterns that might contain secrets
|
|
2054
|
+
"**/config/prod**",
|
|
2055
|
+
"**/config/production**",
|
|
2056
|
+
"**/config/secret**",
|
|
2057
|
+
"**/config/secrets/**",
|
|
2058
|
+
"**/env/**",
|
|
2059
|
+
"**/.env**",
|
|
2060
|
+
// Build and deployment patterns
|
|
1961
2061
|
"**/dist/**",
|
|
1962
2062
|
"**/build/**",
|
|
1963
|
-
"**/
|
|
1964
|
-
|
|
1965
|
-
"**/
|
|
1966
|
-
|
|
1967
|
-
"**/
|
|
1968
|
-
"**/
|
|
1969
|
-
"
|
|
1970
|
-
|
|
1971
|
-
"**/
|
|
1972
|
-
"**/
|
|
1973
|
-
"**/
|
|
1974
|
-
"**/
|
|
1975
|
-
|
|
1976
|
-
"**/
|
|
2063
|
+
"**/target/**",
|
|
2064
|
+
"**/out/**",
|
|
2065
|
+
"**/node_modules/**",
|
|
2066
|
+
// Data and media patterns
|
|
2067
|
+
"**/data/**",
|
|
2068
|
+
"**/dataset**",
|
|
2069
|
+
"**/backup**",
|
|
2070
|
+
"**/logs/**",
|
|
2071
|
+
"**/log/**",
|
|
2072
|
+
"**/temp/**",
|
|
2073
|
+
"**/tmp/**",
|
|
2074
|
+
"**/cache/**",
|
|
2075
|
+
// Test fixtures that might contain sensitive data
|
|
2076
|
+
"**/test/fixtures/**",
|
|
2077
|
+
"**/test**/fixture**",
|
|
2078
|
+
"**/test**/mock**",
|
|
2079
|
+
"**/test**/data/**",
|
|
2080
|
+
// Database and infrastructure
|
|
2081
|
+
"**/*.sqlite",
|
|
2082
|
+
"**/*.db",
|
|
2083
|
+
"**/*.dump",
|
|
2084
|
+
// Production files
|
|
2085
|
+
"**/*.prod.json",
|
|
2086
|
+
"**/*.production.*"
|
|
1977
2087
|
];
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2088
|
+
const lowerGlob = glob.toLowerCase();
|
|
2089
|
+
return sensitivePatterns.some((pattern) => {
|
|
2090
|
+
const regexPattern = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\?/g, ".");
|
|
2091
|
+
const regex = new RegExp(`^${regexPattern}$`, "i");
|
|
2092
|
+
return regex.test(lowerGlob);
|
|
1981
2093
|
});
|
|
1982
2094
|
}
|
|
1983
|
-
function
|
|
2095
|
+
function extractBasicIgnorePatternsFromContent(content) {
|
|
1984
2096
|
const patterns = [];
|
|
1985
2097
|
const lines = content.split("\n");
|
|
1986
2098
|
for (const line of lines) {
|
|
@@ -1991,24 +2103,6 @@ function extractIgnorePatternsFromContent(content) {
|
|
|
1991
2103
|
patterns.push(pattern);
|
|
1992
2104
|
}
|
|
1993
2105
|
}
|
|
1994
|
-
if (trimmed.startsWith("# AUGMENT_IGNORE:") || trimmed.startsWith("# augmentignore:")) {
|
|
1995
|
-
const pattern = trimmed.replace(/^# (AUGMENT_IGNORE|augmentignore):\s*/, "").trim();
|
|
1996
|
-
if (pattern) {
|
|
1997
|
-
patterns.push(pattern);
|
|
1998
|
-
}
|
|
1999
|
-
}
|
|
2000
|
-
if (trimmed.startsWith("# AUGMENT_INCLUDE:") || trimmed.startsWith("# augmentinclude:")) {
|
|
2001
|
-
const pattern = trimmed.replace(/^# (AUGMENT_INCLUDE|augmentinclude):\s*/, "").trim();
|
|
2002
|
-
if (pattern) {
|
|
2003
|
-
patterns.push(`!${pattern}`);
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
if (trimmed.includes("exclude") || trimmed.includes("ignore")) {
|
|
2007
|
-
const matches = trimmed.match(/['"`]([^'"`]+\.(log|tmp|cache|temp))['"`]/g);
|
|
2008
|
-
if (matches) {
|
|
2009
|
-
patterns.push(...matches.map((m) => m.replace(/['"`]/g, "")));
|
|
2010
|
-
}
|
|
2011
|
-
}
|
|
2012
2106
|
}
|
|
2013
2107
|
return patterns;
|
|
2014
2108
|
}
|
|
@@ -2047,7 +2141,7 @@ function generateIgnoreFile(rules, config, ignoreConfig, baseDir) {
|
|
|
2047
2141
|
const outputs = [];
|
|
2048
2142
|
const content = generateIgnoreContent(rules, ignoreConfig);
|
|
2049
2143
|
const outputPath = baseDir || process.cwd();
|
|
2050
|
-
const filepath = (0,
|
|
2144
|
+
const filepath = (0, import_node_path8.join)(outputPath, ignoreConfig.filename);
|
|
2051
2145
|
outputs.push({
|
|
2052
2146
|
tool: ignoreConfig.tool,
|
|
2053
2147
|
filepath,
|
|
@@ -2635,20 +2729,20 @@ function generateWindsurfIgnore(rules, config, baseDir) {
|
|
|
2635
2729
|
}
|
|
2636
2730
|
|
|
2637
2731
|
// src/generators/rules/augmentcode.ts
|
|
2638
|
-
var
|
|
2732
|
+
var import_node_path11 = require("path");
|
|
2639
2733
|
|
|
2640
2734
|
// src/generators/rules/shared-helpers.ts
|
|
2641
|
-
var
|
|
2735
|
+
var import_node_path10 = require("path");
|
|
2642
2736
|
|
|
2643
2737
|
// src/utils/ignore.ts
|
|
2644
|
-
var
|
|
2738
|
+
var import_node_path9 = require("path");
|
|
2645
2739
|
var import_micromatch = __toESM(require("micromatch"), 1);
|
|
2646
2740
|
var cachedIgnorePatterns = null;
|
|
2647
2741
|
async function loadIgnorePatterns(baseDir = process.cwd()) {
|
|
2648
2742
|
if (cachedIgnorePatterns) {
|
|
2649
2743
|
return cachedIgnorePatterns;
|
|
2650
2744
|
}
|
|
2651
|
-
const ignorePath = (0,
|
|
2745
|
+
const ignorePath = (0, import_node_path9.join)(baseDir, ".rulesyncignore");
|
|
2652
2746
|
if (!await fileExists(ignorePath)) {
|
|
2653
2747
|
cachedIgnorePatterns = { patterns: [] };
|
|
2654
2748
|
return cachedIgnorePatterns;
|
|
@@ -2702,7 +2796,7 @@ function addOutput(outputs, tool, config, baseDir, relativePath, content) {
|
|
|
2702
2796
|
const outputDir = resolveOutputDir(config, tool, baseDir);
|
|
2703
2797
|
outputs.push({
|
|
2704
2798
|
tool,
|
|
2705
|
-
filepath: (0,
|
|
2799
|
+
filepath: (0, import_node_path10.join)(outputDir, relativePath),
|
|
2706
2800
|
content
|
|
2707
2801
|
});
|
|
2708
2802
|
}
|
|
@@ -2711,7 +2805,7 @@ async function generateRulesConfig(rules, config, generatorConfig, baseDir) {
|
|
|
2711
2805
|
for (const rule of rules) {
|
|
2712
2806
|
const content = generatorConfig.generateContent(rule);
|
|
2713
2807
|
const outputDir = resolveOutputDir(config, generatorConfig.tool, baseDir);
|
|
2714
|
-
const filepath = generatorConfig.pathResolver ? generatorConfig.pathResolver(rule, outputDir) : (0,
|
|
2808
|
+
const filepath = generatorConfig.pathResolver ? generatorConfig.pathResolver(rule, outputDir) : (0, import_node_path10.join)(outputDir, `${rule.filename}${generatorConfig.fileExtension}`);
|
|
2715
2809
|
outputs.push({
|
|
2716
2810
|
tool: generatorConfig.tool,
|
|
2717
2811
|
filepath,
|
|
@@ -2739,7 +2833,7 @@ async function generateComplexRules(rules, config, generatorConfig, baseDir) {
|
|
|
2739
2833
|
for (const rule of detailRules) {
|
|
2740
2834
|
const content = generatorConfig.generateDetailContent(rule);
|
|
2741
2835
|
const filepath = resolvePath(
|
|
2742
|
-
(0,
|
|
2836
|
+
(0, import_node_path10.join)(generatorConfig.detailSubDir, `${rule.filename}.md`),
|
|
2743
2837
|
baseDir
|
|
2744
2838
|
);
|
|
2745
2839
|
outputs.push({
|
|
@@ -2802,7 +2896,7 @@ async function generateAugmentcodeConfig(rules, config, baseDir) {
|
|
|
2802
2896
|
"augmentcode",
|
|
2803
2897
|
config,
|
|
2804
2898
|
baseDir,
|
|
2805
|
-
(0,
|
|
2899
|
+
(0, import_node_path11.join)(".augment", "rules", `${rule.filename}.md`),
|
|
2806
2900
|
generateRuleFile(rule)
|
|
2807
2901
|
);
|
|
2808
2902
|
});
|
|
@@ -2855,7 +2949,7 @@ function generateLegacyGuidelinesFile(allRules) {
|
|
|
2855
2949
|
}
|
|
2856
2950
|
|
|
2857
2951
|
// src/generators/rules/claudecode.ts
|
|
2858
|
-
var
|
|
2952
|
+
var import_node_path12 = require("path");
|
|
2859
2953
|
async function generateClaudecodeConfig(rules, config, baseDir) {
|
|
2860
2954
|
const generatorConfig = {
|
|
2861
2955
|
tool: "claudecode",
|
|
@@ -2867,7 +2961,7 @@ async function generateClaudecodeConfig(rules, config, baseDir) {
|
|
|
2867
2961
|
generateDetailContent: generateMemoryFile,
|
|
2868
2962
|
detailSubDir: ".claude/memories",
|
|
2869
2963
|
updateAdditionalConfig: async (ignorePatterns, baseDir2) => {
|
|
2870
|
-
const settingsPath = resolvePath((0,
|
|
2964
|
+
const settingsPath = resolvePath((0, import_node_path12.join)(".claude", "settings.json"), baseDir2);
|
|
2871
2965
|
await updateClaudeSettings(settingsPath, ignorePatterns);
|
|
2872
2966
|
return [];
|
|
2873
2967
|
}
|
|
@@ -2931,7 +3025,7 @@ async function updateClaudeSettings(settingsPath, ignorePatterns) {
|
|
|
2931
3025
|
}
|
|
2932
3026
|
|
|
2933
3027
|
// src/generators/rules/generator-registry.ts
|
|
2934
|
-
var
|
|
3028
|
+
var import_node_path13 = require("path");
|
|
2935
3029
|
function determineCursorRuleType(frontmatter) {
|
|
2936
3030
|
if (frontmatter.cursorRuleType) {
|
|
2937
3031
|
return frontmatter.cursorRuleType;
|
|
@@ -3011,7 +3105,7 @@ var GENERATOR_REGISTRY = {
|
|
|
3011
3105
|
},
|
|
3012
3106
|
pathResolver: (rule, outputDir) => {
|
|
3013
3107
|
const baseFilename = rule.filename.replace(/\.md$/, "");
|
|
3014
|
-
return (0,
|
|
3108
|
+
return (0, import_node_path13.join)(outputDir, `${baseFilename}.instructions.md`);
|
|
3015
3109
|
}
|
|
3016
3110
|
},
|
|
3017
3111
|
cursor: {
|
|
@@ -3051,7 +3145,7 @@ var GENERATOR_REGISTRY = {
|
|
|
3051
3145
|
return lines.join("\n");
|
|
3052
3146
|
},
|
|
3053
3147
|
pathResolver: (rule, outputDir) => {
|
|
3054
|
-
return (0,
|
|
3148
|
+
return (0, import_node_path13.join)(outputDir, `${rule.filename}.mdc`);
|
|
3055
3149
|
}
|
|
3056
3150
|
},
|
|
3057
3151
|
codexcli: {
|
|
@@ -3087,10 +3181,10 @@ var GENERATOR_REGISTRY = {
|
|
|
3087
3181
|
pathResolver: (rule, outputDir) => {
|
|
3088
3182
|
const outputFormat = rule.frontmatter.windsurfOutputFormat || "directory";
|
|
3089
3183
|
if (outputFormat === "single-file") {
|
|
3090
|
-
return (0,
|
|
3184
|
+
return (0, import_node_path13.join)(outputDir, ".windsurf-rules");
|
|
3091
3185
|
} else {
|
|
3092
|
-
const rulesDir = (0,
|
|
3093
|
-
return (0,
|
|
3186
|
+
const rulesDir = (0, import_node_path13.join)(outputDir, ".windsurf", "rules");
|
|
3187
|
+
return (0, import_node_path13.join)(rulesDir, `${rule.filename}.md`);
|
|
3094
3188
|
}
|
|
3095
3189
|
}
|
|
3096
3190
|
},
|
|
@@ -3181,10 +3275,18 @@ async function generateFromRegistry(tool, rules, config, baseDir) {
|
|
|
3181
3275
|
}
|
|
3182
3276
|
}
|
|
3183
3277
|
|
|
3184
|
-
// src/generators/rules/
|
|
3185
|
-
|
|
3186
|
-
return
|
|
3278
|
+
// src/generators/rules/generator-factory.ts
|
|
3279
|
+
function createSimpleGenerator(toolName) {
|
|
3280
|
+
return async function(rules, config, baseDir) {
|
|
3281
|
+
return generateFromRegistry(toolName, rules, config, baseDir);
|
|
3282
|
+
};
|
|
3187
3283
|
}
|
|
3284
|
+
var generateCursorConfig = createSimpleGenerator("cursor");
|
|
3285
|
+
var generateClineConfig = createSimpleGenerator("cline");
|
|
3286
|
+
var generateCopilotConfig = createSimpleGenerator("copilot");
|
|
3287
|
+
var generateWindsurfConfig = createSimpleGenerator("windsurf");
|
|
3288
|
+
var generateKiroConfig = createSimpleGenerator("kiro");
|
|
3289
|
+
var generateRooConfig = createSimpleGenerator("roo");
|
|
3188
3290
|
|
|
3189
3291
|
// src/generators/rules/codexcli.ts
|
|
3190
3292
|
async function generateCodexConfig(rules, config, baseDir) {
|
|
@@ -3231,16 +3333,6 @@ function generateConcatenatedCodexContent(rules) {
|
|
|
3231
3333
|
return sections.join("\n\n---\n\n");
|
|
3232
3334
|
}
|
|
3233
3335
|
|
|
3234
|
-
// src/generators/rules/copilot.ts
|
|
3235
|
-
async function generateCopilotConfig(rules, config, baseDir) {
|
|
3236
|
-
return generateFromRegistry("copilot", rules, config, baseDir);
|
|
3237
|
-
}
|
|
3238
|
-
|
|
3239
|
-
// src/generators/rules/cursor.ts
|
|
3240
|
-
async function generateCursorConfig(rules, config, baseDir) {
|
|
3241
|
-
return generateFromRegistry("cursor", rules, config, baseDir);
|
|
3242
|
-
}
|
|
3243
|
-
|
|
3244
3336
|
// src/generators/rules/geminicli.ts
|
|
3245
3337
|
async function generateGeminiConfig(rules, config, baseDir) {
|
|
3246
3338
|
const generatorConfig = {
|
|
@@ -3310,21 +3402,6 @@ function generateGuidelinesMarkdown(rootRule, detailRules) {
|
|
|
3310
3402
|
return lines.join("\n").trim();
|
|
3311
3403
|
}
|
|
3312
3404
|
|
|
3313
|
-
// src/generators/rules/kiro.ts
|
|
3314
|
-
async function generateKiroConfig(rules, config, baseDir) {
|
|
3315
|
-
return generateFromRegistry("kiro", rules, config, baseDir);
|
|
3316
|
-
}
|
|
3317
|
-
|
|
3318
|
-
// src/generators/rules/roo.ts
|
|
3319
|
-
async function generateRooConfig(rules, config, baseDir) {
|
|
3320
|
-
return generateFromRegistry("roo", rules, config, baseDir);
|
|
3321
|
-
}
|
|
3322
|
-
|
|
3323
|
-
// src/generators/rules/windsurf.ts
|
|
3324
|
-
async function generateWindsurfConfig(rules, config, baseDir) {
|
|
3325
|
-
return generateFromRegistry("windsurf", rules, config, baseDir);
|
|
3326
|
-
}
|
|
3327
|
-
|
|
3328
3405
|
// src/core/generator.ts
|
|
3329
3406
|
async function generateConfigurations(rules, config, targetTools, baseDir) {
|
|
3330
3407
|
const outputs = createOutputsArray();
|
|
@@ -3409,11 +3486,11 @@ async function generateForTool(tool, rules, config, baseDir) {
|
|
|
3409
3486
|
}
|
|
3410
3487
|
|
|
3411
3488
|
// src/core/parser.ts
|
|
3412
|
-
var
|
|
3489
|
+
var import_node_path14 = require("path");
|
|
3413
3490
|
var import_gray_matter2 = __toESM(require("gray-matter"), 1);
|
|
3414
3491
|
async function parseRulesFromDirectory(aiRulesDir) {
|
|
3415
3492
|
const ignorePatterns = await loadIgnorePatterns();
|
|
3416
|
-
const allRuleFiles = await
|
|
3493
|
+
const allRuleFiles = await findRuleFiles(aiRulesDir);
|
|
3417
3494
|
const ruleFiles = filterIgnoredFiles(allRuleFiles, ignorePatterns.patterns);
|
|
3418
3495
|
const rules = [];
|
|
3419
3496
|
const errors = [];
|
|
@@ -3463,7 +3540,7 @@ async function parseRuleFile(filepath) {
|
|
|
3463
3540
|
},
|
|
3464
3541
|
...validatedData.tags !== void 0 && { tags: validatedData.tags }
|
|
3465
3542
|
};
|
|
3466
|
-
const filename = (0,
|
|
3543
|
+
const filename = (0, import_node_path14.basename)(filepath, ".md");
|
|
3467
3544
|
return {
|
|
3468
3545
|
frontmatter,
|
|
3469
3546
|
content: parsed.content,
|
|
@@ -3632,6 +3709,7 @@ async function generateCommand(options = {}) {
|
|
|
3632
3709
|
...options.baseDirs !== void 0 && { baseDirs: options.baseDirs }
|
|
3633
3710
|
};
|
|
3634
3711
|
const config = mergeWithCliOptions(configResult.config, cliOptions);
|
|
3712
|
+
logger.setVerbose(config.verbose || false);
|
|
3635
3713
|
if (options.tools && options.tools.length > 0) {
|
|
3636
3714
|
const configTargets = config.defaultTargets;
|
|
3637
3715
|
const cliTools = options.tools;
|
|
@@ -3640,18 +3718,18 @@ async function generateCommand(options = {}) {
|
|
|
3640
3718
|
const notInConfig = cliTools.filter((tool) => !configTargetsSet.has(tool));
|
|
3641
3719
|
const notInCli = configTargets.filter((tool) => !cliToolsSet.has(tool));
|
|
3642
3720
|
if (notInConfig.length > 0 || notInCli.length > 0) {
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3721
|
+
logger.warn("\u26A0\uFE0F Warning: CLI tool selection differs from configuration!");
|
|
3722
|
+
logger.warn(` Config targets: ${configTargets.join(", ")}`);
|
|
3723
|
+
logger.warn(` CLI specified: ${cliTools.join(", ")}`);
|
|
3646
3724
|
if (notInConfig.length > 0) {
|
|
3647
|
-
|
|
3725
|
+
logger.warn(` Tools specified but not in config: ${notInConfig.join(", ")}`);
|
|
3648
3726
|
}
|
|
3649
3727
|
if (notInCli.length > 0) {
|
|
3650
|
-
|
|
3728
|
+
logger.warn(` Tools in config but not specified: ${notInCli.join(", ")}`);
|
|
3651
3729
|
}
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3730
|
+
logger.warn("\n The configuration file targets will be used.");
|
|
3731
|
+
logger.warn(" To change targets, update your rulesync config file.");
|
|
3732
|
+
logger.warn("");
|
|
3655
3733
|
}
|
|
3656
3734
|
}
|
|
3657
3735
|
let baseDirs;
|
|
@@ -3662,42 +3740,46 @@ async function generateCommand(options = {}) {
|
|
|
3662
3740
|
} else {
|
|
3663
3741
|
baseDirs = [process.cwd()];
|
|
3664
3742
|
}
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
}
|
|
3668
|
-
console.log("Generating configuration files...");
|
|
3743
|
+
logger.info(`Loaded configuration from: ${configResult.filepath}`);
|
|
3744
|
+
logger.log("Generating configuration files...");
|
|
3669
3745
|
if (!await fileExists(config.aiRulesDir)) {
|
|
3670
|
-
|
|
3746
|
+
logger.error("\u274C .rulesync directory not found. Run 'rulesync init' first.");
|
|
3671
3747
|
process.exit(1);
|
|
3672
3748
|
}
|
|
3673
3749
|
try {
|
|
3674
|
-
|
|
3675
|
-
console.log(`Parsing rules from ${config.aiRulesDir}...`);
|
|
3676
|
-
}
|
|
3750
|
+
logger.info(`Parsing rules from ${config.aiRulesDir}...`);
|
|
3677
3751
|
const rules = await parseRulesFromDirectory(config.aiRulesDir);
|
|
3678
3752
|
if (rules.length === 0) {
|
|
3679
|
-
|
|
3753
|
+
logger.warn("\u26A0\uFE0F No rules found in .rulesync directory");
|
|
3680
3754
|
return;
|
|
3681
3755
|
}
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
console.log(`Base directories: ${baseDirs.join(", ")}`);
|
|
3685
|
-
}
|
|
3756
|
+
logger.info(`Found ${rules.length} rule(s)`);
|
|
3757
|
+
logger.info(`Base directories: ${baseDirs.join(", ")}`);
|
|
3686
3758
|
if (config.delete) {
|
|
3687
|
-
|
|
3688
|
-
console.log("Deleting existing output directories...");
|
|
3689
|
-
}
|
|
3759
|
+
logger.info("Deleting existing output directories...");
|
|
3690
3760
|
const targetTools = config.defaultTargets;
|
|
3691
3761
|
const deleteTasks = [];
|
|
3762
|
+
const commandsDir = (0, import_node_path15.join)(config.aiRulesDir, "commands");
|
|
3763
|
+
const hasCommands = await fileExists(commandsDir);
|
|
3764
|
+
let hasCommandFiles = false;
|
|
3765
|
+
if (hasCommands) {
|
|
3766
|
+
const { readdir: readdir2 } = await import("fs/promises");
|
|
3767
|
+
try {
|
|
3768
|
+
const files = await readdir2(commandsDir);
|
|
3769
|
+
hasCommandFiles = files.some((file) => file.endsWith(".md"));
|
|
3770
|
+
} catch {
|
|
3771
|
+
hasCommandFiles = false;
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3692
3774
|
for (const tool of targetTools) {
|
|
3693
3775
|
switch (tool) {
|
|
3694
3776
|
case "augmentcode":
|
|
3695
|
-
deleteTasks.push(removeDirectory((0,
|
|
3696
|
-
deleteTasks.push(removeDirectory((0,
|
|
3777
|
+
deleteTasks.push(removeDirectory((0, import_node_path15.join)(".augment", "rules")));
|
|
3778
|
+
deleteTasks.push(removeDirectory((0, import_node_path15.join)(".augment", "ignore")));
|
|
3697
3779
|
break;
|
|
3698
3780
|
case "augmentcode-legacy":
|
|
3699
3781
|
deleteTasks.push(removeClaudeGeneratedFiles());
|
|
3700
|
-
deleteTasks.push(removeDirectory((0,
|
|
3782
|
+
deleteTasks.push(removeDirectory((0, import_node_path15.join)(".augment", "ignore")));
|
|
3701
3783
|
break;
|
|
3702
3784
|
case "copilot":
|
|
3703
3785
|
deleteTasks.push(removeDirectory(config.outputPaths.copilot));
|
|
@@ -3710,14 +3792,21 @@ async function generateCommand(options = {}) {
|
|
|
3710
3792
|
break;
|
|
3711
3793
|
case "claudecode":
|
|
3712
3794
|
deleteTasks.push(removeClaudeGeneratedFiles());
|
|
3713
|
-
|
|
3795
|
+
if (hasCommandFiles) {
|
|
3796
|
+
deleteTasks.push(removeDirectory((0, import_node_path15.join)(".claude", "commands")));
|
|
3797
|
+
}
|
|
3714
3798
|
break;
|
|
3715
3799
|
case "roo":
|
|
3716
3800
|
deleteTasks.push(removeDirectory(config.outputPaths.roo));
|
|
3801
|
+
if (hasCommandFiles) {
|
|
3802
|
+
deleteTasks.push(removeDirectory((0, import_node_path15.join)(".roo", "commands")));
|
|
3803
|
+
}
|
|
3717
3804
|
break;
|
|
3718
3805
|
case "geminicli":
|
|
3719
3806
|
deleteTasks.push(removeDirectory(config.outputPaths.geminicli));
|
|
3720
|
-
|
|
3807
|
+
if (hasCommandFiles) {
|
|
3808
|
+
deleteTasks.push(removeDirectory((0, import_node_path15.join)(".gemini", "commands")));
|
|
3809
|
+
}
|
|
3721
3810
|
break;
|
|
3722
3811
|
case "kiro":
|
|
3723
3812
|
deleteTasks.push(removeDirectory(config.outputPaths.kiro));
|
|
@@ -3728,44 +3817,34 @@ async function generateCommand(options = {}) {
|
|
|
3728
3817
|
}
|
|
3729
3818
|
}
|
|
3730
3819
|
await Promise.all(deleteTasks);
|
|
3731
|
-
|
|
3732
|
-
console.log("Deleted existing output directories");
|
|
3733
|
-
}
|
|
3820
|
+
logger.info("Deleted existing output directories");
|
|
3734
3821
|
}
|
|
3735
3822
|
let totalOutputs = 0;
|
|
3736
3823
|
for (const baseDir of baseDirs) {
|
|
3737
|
-
|
|
3738
|
-
console.log(`
|
|
3824
|
+
logger.info(`
|
|
3739
3825
|
Generating configurations for base directory: ${baseDir}`);
|
|
3740
|
-
}
|
|
3741
3826
|
const outputs = await generateConfigurations(rules, config, config.defaultTargets, baseDir);
|
|
3742
3827
|
if (outputs.length === 0) {
|
|
3743
|
-
|
|
3744
|
-
console.warn(`\u26A0\uFE0F No configurations generated for ${baseDir}`);
|
|
3745
|
-
}
|
|
3828
|
+
logger.warn(`\u26A0\uFE0F No configurations generated for ${baseDir}`);
|
|
3746
3829
|
continue;
|
|
3747
3830
|
}
|
|
3748
3831
|
for (const output of outputs) {
|
|
3749
3832
|
await writeFileContent(output.filepath, output.content);
|
|
3750
|
-
|
|
3833
|
+
logger.success(`Generated ${output.tool} configuration: ${output.filepath}`);
|
|
3751
3834
|
}
|
|
3752
3835
|
totalOutputs += outputs.length;
|
|
3753
3836
|
}
|
|
3754
3837
|
if (totalOutputs === 0) {
|
|
3755
|
-
|
|
3838
|
+
logger.warn("\u26A0\uFE0F No configurations generated");
|
|
3756
3839
|
return;
|
|
3757
3840
|
}
|
|
3758
|
-
|
|
3759
|
-
console.log("\nGenerating MCP configurations...");
|
|
3760
|
-
}
|
|
3841
|
+
logger.info("\nGenerating MCP configurations...");
|
|
3761
3842
|
let totalMcpOutputs = 0;
|
|
3762
3843
|
for (const baseDir of baseDirs) {
|
|
3763
3844
|
try {
|
|
3764
3845
|
const mcpConfig = parseMcpConfig(process.cwd());
|
|
3765
3846
|
if (!mcpConfig || !mcpConfig.mcpServers || Object.keys(mcpConfig.mcpServers).length === 0) {
|
|
3766
|
-
|
|
3767
|
-
console.log(`No MCP configuration found for ${baseDir}`);
|
|
3768
|
-
}
|
|
3847
|
+
logger.info(`No MCP configuration found for ${baseDir}`);
|
|
3769
3848
|
continue;
|
|
3770
3849
|
}
|
|
3771
3850
|
const mcpResults = await generateMcpConfigurations(
|
|
@@ -3774,27 +3853,21 @@ Generating configurations for base directory: ${baseDir}`);
|
|
|
3774
3853
|
config.defaultTargets
|
|
3775
3854
|
);
|
|
3776
3855
|
if (mcpResults.length === 0) {
|
|
3777
|
-
|
|
3778
|
-
console.log(`No MCP configurations generated for ${baseDir}`);
|
|
3779
|
-
}
|
|
3856
|
+
logger.info(`No MCP configurations generated for ${baseDir}`);
|
|
3780
3857
|
continue;
|
|
3781
3858
|
}
|
|
3782
3859
|
for (const result of mcpResults) {
|
|
3783
3860
|
await writeFileContent(result.filepath, result.content);
|
|
3784
|
-
|
|
3861
|
+
logger.success(`Generated ${result.tool} MCP configuration: ${result.filepath}`);
|
|
3785
3862
|
totalMcpOutputs++;
|
|
3786
3863
|
}
|
|
3787
3864
|
} catch (error) {
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
);
|
|
3792
|
-
}
|
|
3865
|
+
logger.error(
|
|
3866
|
+
`\u274C Failed to generate MCP configurations: ${error instanceof Error ? error.message : String(error)}`
|
|
3867
|
+
);
|
|
3793
3868
|
}
|
|
3794
3869
|
}
|
|
3795
|
-
|
|
3796
|
-
console.log("\nGenerating command files...");
|
|
3797
|
-
}
|
|
3870
|
+
logger.info("\nGenerating command files...");
|
|
3798
3871
|
let totalCommandOutputs = 0;
|
|
3799
3872
|
for (const baseDir of baseDirs) {
|
|
3800
3873
|
const commandResults = await generateCommands(
|
|
@@ -3803,14 +3876,12 @@ Generating configurations for base directory: ${baseDir}`);
|
|
|
3803
3876
|
config.defaultTargets
|
|
3804
3877
|
);
|
|
3805
3878
|
if (commandResults.length === 0) {
|
|
3806
|
-
|
|
3807
|
-
console.log(`No commands found for ${baseDir}`);
|
|
3808
|
-
}
|
|
3879
|
+
logger.info(`No commands found for ${baseDir}`);
|
|
3809
3880
|
continue;
|
|
3810
3881
|
}
|
|
3811
3882
|
for (const result of commandResults) {
|
|
3812
3883
|
await writeFileContent(result.filepath, result.content);
|
|
3813
|
-
|
|
3884
|
+
logger.success(`Generated ${result.tool} command: ${result.filepath}`);
|
|
3814
3885
|
totalCommandOutputs++;
|
|
3815
3886
|
}
|
|
3816
3887
|
}
|
|
@@ -3820,22 +3891,22 @@ Generating configurations for base directory: ${baseDir}`);
|
|
|
3820
3891
|
if (totalOutputs > 0) parts.push(`${totalOutputs} configurations`);
|
|
3821
3892
|
if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP configurations`);
|
|
3822
3893
|
if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
|
|
3823
|
-
|
|
3894
|
+
logger.success(
|
|
3824
3895
|
`
|
|
3825
3896
|
\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`
|
|
3826
3897
|
);
|
|
3827
3898
|
}
|
|
3828
3899
|
} catch (error) {
|
|
3829
|
-
|
|
3900
|
+
logger.error("\u274C Failed to generate configurations:", error);
|
|
3830
3901
|
process.exit(1);
|
|
3831
3902
|
}
|
|
3832
3903
|
}
|
|
3833
3904
|
|
|
3834
3905
|
// src/cli/commands/gitignore.ts
|
|
3835
3906
|
var import_node_fs2 = require("fs");
|
|
3836
|
-
var
|
|
3907
|
+
var import_node_path16 = require("path");
|
|
3837
3908
|
var gitignoreCommand = async () => {
|
|
3838
|
-
const gitignorePath = (0,
|
|
3909
|
+
const gitignorePath = (0, import_node_path16.join)(process.cwd(), ".gitignore");
|
|
3839
3910
|
const rulesFilesToIgnore = [
|
|
3840
3911
|
"# Generated by rulesync - AI tool configuration files",
|
|
3841
3912
|
"**/.github/copilot-instructions.md",
|
|
@@ -3901,11 +3972,11 @@ ${linesToAdd.join("\n")}
|
|
|
3901
3972
|
};
|
|
3902
3973
|
|
|
3903
3974
|
// src/core/importer.ts
|
|
3904
|
-
var
|
|
3975
|
+
var import_node_path23 = require("path");
|
|
3905
3976
|
var import_gray_matter7 = __toESM(require("gray-matter"), 1);
|
|
3906
3977
|
|
|
3907
3978
|
// src/parsers/augmentcode.ts
|
|
3908
|
-
var
|
|
3979
|
+
var import_node_path17 = require("path");
|
|
3909
3980
|
var import_gray_matter3 = __toESM(require("gray-matter"), 1);
|
|
3910
3981
|
|
|
3911
3982
|
// src/utils/parser-helpers.ts
|
|
@@ -3954,7 +4025,7 @@ async function parseAugmentcodeLegacyConfiguration(baseDir = process.cwd()) {
|
|
|
3954
4025
|
async function parseUnifiedAugmentcode(baseDir, config) {
|
|
3955
4026
|
const result = createParseResult();
|
|
3956
4027
|
if (config.rulesDir) {
|
|
3957
|
-
const rulesDir = (0,
|
|
4028
|
+
const rulesDir = (0, import_node_path17.join)(baseDir, config.rulesDir);
|
|
3958
4029
|
if (await fileExists(rulesDir)) {
|
|
3959
4030
|
const rulesResult = await parseAugmentRules(rulesDir, config);
|
|
3960
4031
|
addRules(result, rulesResult.rules);
|
|
@@ -3967,7 +4038,7 @@ async function parseUnifiedAugmentcode(baseDir, config) {
|
|
|
3967
4038
|
}
|
|
3968
4039
|
}
|
|
3969
4040
|
if (config.legacyFilePath) {
|
|
3970
|
-
const legacyPath = (0,
|
|
4041
|
+
const legacyPath = (0, import_node_path17.join)(baseDir, config.legacyFilePath);
|
|
3971
4042
|
if (await fileExists(legacyPath)) {
|
|
3972
4043
|
const legacyResult = await parseAugmentGuidelines(legacyPath, config);
|
|
3973
4044
|
if (legacyResult.rule) {
|
|
@@ -3991,7 +4062,7 @@ async function parseAugmentRules(rulesDir, config) {
|
|
|
3991
4062
|
const files = await readdir2(rulesDir);
|
|
3992
4063
|
for (const file of files) {
|
|
3993
4064
|
if (file.endsWith(".md") || file.endsWith(".mdc")) {
|
|
3994
|
-
const filePath = (0,
|
|
4065
|
+
const filePath = (0, import_node_path17.join)(rulesDir, file);
|
|
3995
4066
|
try {
|
|
3996
4067
|
const rawContent = await readFileContent(filePath);
|
|
3997
4068
|
const parsed = (0, import_gray_matter3.default)(rawContent);
|
|
@@ -4000,7 +4071,7 @@ async function parseAugmentRules(rulesDir, config) {
|
|
|
4000
4071
|
const description = frontmatterData.description || "";
|
|
4001
4072
|
const tags = Array.isArray(frontmatterData.tags) ? frontmatterData.tags : void 0;
|
|
4002
4073
|
const isRoot = ruleType === "always";
|
|
4003
|
-
const filename = (0,
|
|
4074
|
+
const filename = (0, import_node_path17.basename)(file, file.endsWith(".mdc") ? ".mdc" : ".md");
|
|
4004
4075
|
const frontmatter = {
|
|
4005
4076
|
root: isRoot,
|
|
4006
4077
|
targets: [config.targetName],
|
|
@@ -4058,7 +4129,7 @@ async function parseAugmentGuidelines(guidelinesPath, config) {
|
|
|
4058
4129
|
}
|
|
4059
4130
|
|
|
4060
4131
|
// src/parsers/shared-helpers.ts
|
|
4061
|
-
var
|
|
4132
|
+
var import_node_path18 = require("path");
|
|
4062
4133
|
var import_gray_matter4 = __toESM(require("gray-matter"), 1);
|
|
4063
4134
|
async function parseConfigurationFiles(baseDir = process.cwd(), config) {
|
|
4064
4135
|
const errors = [];
|
|
@@ -4114,7 +4185,7 @@ async function parseConfigurationFiles(baseDir = process.cwd(), config) {
|
|
|
4114
4185
|
const files = await readdir2(dirPath);
|
|
4115
4186
|
for (const file of files) {
|
|
4116
4187
|
if (file.endsWith(dirConfig.filePattern)) {
|
|
4117
|
-
const filePath = (0,
|
|
4188
|
+
const filePath = (0, import_node_path18.join)(dirPath, file);
|
|
4118
4189
|
const fileResult = await safeAsyncOperation(async () => {
|
|
4119
4190
|
const rawContent = await readFileContent(filePath);
|
|
4120
4191
|
let content;
|
|
@@ -4259,10 +4330,10 @@ async function parseMemoryFiles(memoryDir, config) {
|
|
|
4259
4330
|
const files = await readdir2(memoryDir);
|
|
4260
4331
|
for (const file of files) {
|
|
4261
4332
|
if (file.endsWith(".md")) {
|
|
4262
|
-
const filePath = (0,
|
|
4333
|
+
const filePath = (0, import_node_path18.join)(memoryDir, file);
|
|
4263
4334
|
const content = await readFileContent(filePath);
|
|
4264
4335
|
if (content.trim()) {
|
|
4265
|
-
const filename = (0,
|
|
4336
|
+
const filename = (0, import_node_path18.basename)(file, ".md");
|
|
4266
4337
|
const frontmatter = {
|
|
4267
4338
|
root: false,
|
|
4268
4339
|
targets: [config.tool],
|
|
@@ -4289,10 +4360,10 @@ async function parseCommandsFiles(commandsDir, config) {
|
|
|
4289
4360
|
const files = await readdir2(commandsDir);
|
|
4290
4361
|
for (const file of files) {
|
|
4291
4362
|
if (file.endsWith(".md")) {
|
|
4292
|
-
const filePath = (0,
|
|
4363
|
+
const filePath = (0, import_node_path18.join)(commandsDir, file);
|
|
4293
4364
|
const content = await readFileContent(filePath);
|
|
4294
4365
|
if (content.trim()) {
|
|
4295
|
-
const filename = (0,
|
|
4366
|
+
const filename = (0, import_node_path18.basename)(file, ".md");
|
|
4296
4367
|
let frontmatter;
|
|
4297
4368
|
let ruleContent;
|
|
4298
4369
|
try {
|
|
@@ -4403,7 +4474,7 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
|
|
|
4403
4474
|
}
|
|
4404
4475
|
|
|
4405
4476
|
// src/parsers/codexcli.ts
|
|
4406
|
-
var
|
|
4477
|
+
var import_node_path19 = require("path");
|
|
4407
4478
|
|
|
4408
4479
|
// src/parsers/copilot.ts
|
|
4409
4480
|
async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
@@ -4426,7 +4497,7 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
|
4426
4497
|
}
|
|
4427
4498
|
|
|
4428
4499
|
// src/parsers/cursor.ts
|
|
4429
|
-
var
|
|
4500
|
+
var import_node_path20 = require("path");
|
|
4430
4501
|
var import_gray_matter5 = __toESM(require("gray-matter"), 1);
|
|
4431
4502
|
var import_js_yaml = require("js-yaml");
|
|
4432
4503
|
var import_mini8 = require("zod/mini");
|
|
@@ -4551,7 +4622,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
4551
4622
|
const rules = [];
|
|
4552
4623
|
let ignorePatterns;
|
|
4553
4624
|
let mcpServers;
|
|
4554
|
-
const cursorFilePath = (0,
|
|
4625
|
+
const cursorFilePath = (0, import_node_path20.join)(baseDir, ".cursorrules");
|
|
4555
4626
|
if (await fileExists(cursorFilePath)) {
|
|
4556
4627
|
try {
|
|
4557
4628
|
const rawContent = await readFileContent(cursorFilePath);
|
|
@@ -4572,20 +4643,20 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
4572
4643
|
errors.push(`Failed to parse .cursorrules file: ${errorMessage}`);
|
|
4573
4644
|
}
|
|
4574
4645
|
}
|
|
4575
|
-
const cursorRulesDir = (0,
|
|
4646
|
+
const cursorRulesDir = (0, import_node_path20.join)(baseDir, ".cursor", "rules");
|
|
4576
4647
|
if (await fileExists(cursorRulesDir)) {
|
|
4577
4648
|
try {
|
|
4578
4649
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
4579
4650
|
const files = await readdir2(cursorRulesDir);
|
|
4580
4651
|
for (const file of files) {
|
|
4581
4652
|
if (file.endsWith(".mdc")) {
|
|
4582
|
-
const filePath = (0,
|
|
4653
|
+
const filePath = (0, import_node_path20.join)(cursorRulesDir, file);
|
|
4583
4654
|
try {
|
|
4584
4655
|
const rawContent = await readFileContent(filePath);
|
|
4585
4656
|
const parsed = (0, import_gray_matter5.default)(rawContent, customMatterOptions);
|
|
4586
4657
|
const content = parsed.content.trim();
|
|
4587
4658
|
if (content) {
|
|
4588
|
-
const filename = (0,
|
|
4659
|
+
const filename = (0, import_node_path20.basename)(file, ".mdc");
|
|
4589
4660
|
const frontmatter = convertCursorMdcFrontmatter(parsed.data, filename);
|
|
4590
4661
|
rules.push({
|
|
4591
4662
|
frontmatter,
|
|
@@ -4608,7 +4679,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
4608
4679
|
if (rules.length === 0) {
|
|
4609
4680
|
errors.push("No Cursor configuration files found (.cursorrules or .cursor/rules/*.mdc)");
|
|
4610
4681
|
}
|
|
4611
|
-
const cursorIgnorePath = (0,
|
|
4682
|
+
const cursorIgnorePath = (0, import_node_path20.join)(baseDir, ".cursorignore");
|
|
4612
4683
|
if (await fileExists(cursorIgnorePath)) {
|
|
4613
4684
|
try {
|
|
4614
4685
|
const content = await readFileContent(cursorIgnorePath);
|
|
@@ -4621,7 +4692,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
4621
4692
|
errors.push(`Failed to parse .cursorignore: ${errorMessage}`);
|
|
4622
4693
|
}
|
|
4623
4694
|
}
|
|
4624
|
-
const cursorMcpPath = (0,
|
|
4695
|
+
const cursorMcpPath = (0, import_node_path20.join)(baseDir, ".cursor", "mcp.json");
|
|
4625
4696
|
if (await fileExists(cursorMcpPath)) {
|
|
4626
4697
|
try {
|
|
4627
4698
|
const content = await readFileContent(cursorMcpPath);
|
|
@@ -4671,11 +4742,11 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
|
|
|
4671
4742
|
}
|
|
4672
4743
|
|
|
4673
4744
|
// src/parsers/junie.ts
|
|
4674
|
-
var
|
|
4745
|
+
var import_node_path21 = require("path");
|
|
4675
4746
|
async function parseJunieConfiguration(baseDir = process.cwd()) {
|
|
4676
4747
|
const errors = [];
|
|
4677
4748
|
const rules = [];
|
|
4678
|
-
const guidelinesPath = (0,
|
|
4749
|
+
const guidelinesPath = (0, import_node_path21.join)(baseDir, ".junie", "guidelines.md");
|
|
4679
4750
|
if (!await fileExists(guidelinesPath)) {
|
|
4680
4751
|
errors.push(".junie/guidelines.md file not found");
|
|
4681
4752
|
return { rules, errors };
|
|
@@ -4728,12 +4799,18 @@ async function parseRooConfiguration(baseDir = process.cwd()) {
|
|
|
4728
4799
|
|
|
4729
4800
|
// src/parsers/windsurf.ts
|
|
4730
4801
|
var import_promises3 = require("fs/promises");
|
|
4731
|
-
var
|
|
4802
|
+
var import_node_path22 = require("path");
|
|
4732
4803
|
var import_gray_matter6 = __toESM(require("gray-matter"), 1);
|
|
4733
4804
|
|
|
4734
4805
|
// src/core/importer.ts
|
|
4735
4806
|
async function importConfiguration(options) {
|
|
4736
|
-
const {
|
|
4807
|
+
const {
|
|
4808
|
+
tool,
|
|
4809
|
+
baseDir = process.cwd(),
|
|
4810
|
+
rulesDir = ".rulesync",
|
|
4811
|
+
verbose = false,
|
|
4812
|
+
useLegacyLocation = false
|
|
4813
|
+
} = options;
|
|
4737
4814
|
const errors = [];
|
|
4738
4815
|
let rules = [];
|
|
4739
4816
|
let ignorePatterns;
|
|
@@ -4815,7 +4892,7 @@ async function importConfiguration(options) {
|
|
|
4815
4892
|
if (rules.length === 0 && !ignorePatterns && !mcpServers) {
|
|
4816
4893
|
return { success: false, rulesCreated: 0, errors };
|
|
4817
4894
|
}
|
|
4818
|
-
const rulesDirPath = (0,
|
|
4895
|
+
const rulesDirPath = (0, import_node_path23.join)(baseDir, rulesDir);
|
|
4819
4896
|
try {
|
|
4820
4897
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
4821
4898
|
await mkdir3(rulesDirPath, { recursive: true });
|
|
@@ -4830,11 +4907,17 @@ async function importConfiguration(options) {
|
|
|
4830
4907
|
const baseFilename = rule.filename;
|
|
4831
4908
|
let targetDir = rulesDirPath;
|
|
4832
4909
|
if (rule.type === "command") {
|
|
4833
|
-
targetDir = (0,
|
|
4910
|
+
targetDir = (0, import_node_path23.join)(rulesDirPath, "commands");
|
|
4834
4911
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
4835
4912
|
await mkdir3(targetDir, { recursive: true });
|
|
4913
|
+
} else {
|
|
4914
|
+
if (!useLegacyLocation) {
|
|
4915
|
+
targetDir = (0, import_node_path23.join)(rulesDirPath, "rules");
|
|
4916
|
+
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
4917
|
+
await mkdir3(targetDir, { recursive: true });
|
|
4918
|
+
}
|
|
4836
4919
|
}
|
|
4837
|
-
const filePath = (0,
|
|
4920
|
+
const filePath = (0, import_node_path23.join)(targetDir, `${baseFilename}.md`);
|
|
4838
4921
|
const content = generateRuleFileContent(rule);
|
|
4839
4922
|
await writeFileContent(filePath, content);
|
|
4840
4923
|
rulesCreated++;
|
|
@@ -4849,7 +4932,7 @@ async function importConfiguration(options) {
|
|
|
4849
4932
|
let ignoreFileCreated = false;
|
|
4850
4933
|
if (ignorePatterns && ignorePatterns.length > 0) {
|
|
4851
4934
|
try {
|
|
4852
|
-
const rulesyncignorePath = (0,
|
|
4935
|
+
const rulesyncignorePath = (0, import_node_path23.join)(baseDir, ".rulesyncignore");
|
|
4853
4936
|
const ignoreContent = `${ignorePatterns.join("\n")}
|
|
4854
4937
|
`;
|
|
4855
4938
|
await writeFileContent(rulesyncignorePath, ignoreContent);
|
|
@@ -4865,7 +4948,7 @@ async function importConfiguration(options) {
|
|
|
4865
4948
|
let mcpFileCreated = false;
|
|
4866
4949
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
4867
4950
|
try {
|
|
4868
|
-
const mcpPath = (0,
|
|
4951
|
+
const mcpPath = (0, import_node_path23.join)(baseDir, rulesDir, ".mcp.json");
|
|
4869
4952
|
const mcpContent = `${JSON.stringify({ mcpServers }, null, 2)}
|
|
4870
4953
|
`;
|
|
4871
4954
|
await writeFileContent(mcpPath, mcpContent);
|
|
@@ -4901,6 +4984,7 @@ function generateRuleFileContent(rule) {
|
|
|
4901
4984
|
|
|
4902
4985
|
// src/cli/commands/import.ts
|
|
4903
4986
|
async function importCommand(options = {}) {
|
|
4987
|
+
logger.setVerbose(options.verbose || false);
|
|
4904
4988
|
const tools = [];
|
|
4905
4989
|
if (options.augmentcode) tools.push("augmentcode");
|
|
4906
4990
|
if (options["augmentcode-legacy"]) tools.push("augmentcode-legacy");
|
|
@@ -4911,66 +4995,74 @@ async function importCommand(options = {}) {
|
|
|
4911
4995
|
if (options.roo) tools.push("roo");
|
|
4912
4996
|
if (options.geminicli) tools.push("geminicli");
|
|
4913
4997
|
if (tools.length === 0) {
|
|
4914
|
-
|
|
4998
|
+
logger.error(
|
|
4915
4999
|
"\u274C Please specify one tool to import from (--augmentcode, --augmentcode-legacy, --claudecode, --cursor, --copilot, --cline, --roo, --geminicli)"
|
|
4916
5000
|
);
|
|
4917
5001
|
process.exit(1);
|
|
4918
5002
|
}
|
|
4919
5003
|
if (tools.length > 1) {
|
|
4920
|
-
|
|
5004
|
+
logger.error(
|
|
4921
5005
|
"\u274C Only one tool can be specified at a time. Please run the import command separately for each tool."
|
|
4922
5006
|
);
|
|
4923
5007
|
process.exit(1);
|
|
4924
5008
|
}
|
|
4925
5009
|
const tool = tools[0];
|
|
4926
5010
|
if (!tool) {
|
|
4927
|
-
|
|
5011
|
+
logger.error("Error: No tool specified");
|
|
4928
5012
|
process.exit(1);
|
|
4929
5013
|
}
|
|
4930
|
-
|
|
5014
|
+
logger.log(`Importing configuration files from ${tool}...`);
|
|
4931
5015
|
try {
|
|
4932
5016
|
const result = await importConfiguration({
|
|
4933
5017
|
tool,
|
|
4934
|
-
verbose: options.verbose ?? false
|
|
5018
|
+
verbose: options.verbose ?? false,
|
|
5019
|
+
useLegacyLocation: options.legacy ?? false
|
|
4935
5020
|
});
|
|
4936
5021
|
if (result.success) {
|
|
4937
|
-
|
|
5022
|
+
logger.success(`Imported ${result.rulesCreated} rule(s) from ${tool}`);
|
|
4938
5023
|
if (result.ignoreFileCreated) {
|
|
4939
|
-
|
|
5024
|
+
logger.success("Created .rulesyncignore file from ignore patterns");
|
|
4940
5025
|
}
|
|
4941
5026
|
if (result.mcpFileCreated) {
|
|
4942
|
-
|
|
5027
|
+
logger.success("Created .rulesync/.mcp.json file from MCP configuration");
|
|
4943
5028
|
}
|
|
4944
|
-
|
|
5029
|
+
logger.log("You can now run 'rulesync generate' to create tool-specific configurations.");
|
|
4945
5030
|
} else if (result.errors.length > 0) {
|
|
4946
|
-
|
|
4947
|
-
if (
|
|
4948
|
-
|
|
5031
|
+
logger.warn(`\u26A0\uFE0F Failed to import from ${tool}: ${result.errors[0]}`);
|
|
5032
|
+
if (result.errors.length > 1) {
|
|
5033
|
+
logger.info("\nDetailed errors:");
|
|
4949
5034
|
for (const error of result.errors) {
|
|
4950
|
-
|
|
5035
|
+
logger.info(` - ${error}`);
|
|
4951
5036
|
}
|
|
4952
5037
|
}
|
|
4953
5038
|
}
|
|
4954
5039
|
} catch (error) {
|
|
4955
5040
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
4956
|
-
|
|
5041
|
+
logger.error(`\u274C Error importing from ${tool}: ${errorMessage}`);
|
|
4957
5042
|
process.exit(1);
|
|
4958
5043
|
}
|
|
4959
5044
|
}
|
|
4960
5045
|
|
|
4961
5046
|
// src/cli/commands/init.ts
|
|
4962
|
-
var
|
|
4963
|
-
async function initCommand() {
|
|
4964
|
-
const
|
|
5047
|
+
var import_node_path24 = require("path");
|
|
5048
|
+
async function initCommand(options = {}) {
|
|
5049
|
+
const configResult = await loadConfig();
|
|
5050
|
+
const config = configResult.config;
|
|
5051
|
+
const aiRulesDir = config.aiRulesDir;
|
|
4965
5052
|
console.log("Initializing rulesync...");
|
|
4966
5053
|
await ensureDir(aiRulesDir);
|
|
4967
|
-
|
|
5054
|
+
const useLegacy = options.legacy ?? config.legacy ?? false;
|
|
5055
|
+
const rulesDir = useLegacy ? aiRulesDir : (0, import_node_path24.join)(aiRulesDir, "rules");
|
|
5056
|
+
if (!useLegacy) {
|
|
5057
|
+
await ensureDir(rulesDir);
|
|
5058
|
+
}
|
|
5059
|
+
await createSampleFiles(rulesDir);
|
|
4968
5060
|
console.log("\u2705 rulesync initialized successfully!");
|
|
4969
5061
|
console.log("\nNext steps:");
|
|
4970
|
-
console.log(
|
|
5062
|
+
console.log(`1. Edit rule files in ${rulesDir}/`);
|
|
4971
5063
|
console.log("2. Run 'rulesync generate' to create configuration files");
|
|
4972
5064
|
}
|
|
4973
|
-
async function createSampleFiles(
|
|
5065
|
+
async function createSampleFiles(rulesDir) {
|
|
4974
5066
|
const sampleFile = {
|
|
4975
5067
|
filename: "overview.md",
|
|
4976
5068
|
content: `---
|
|
@@ -5006,7 +5098,7 @@ globs: ["**/*"]
|
|
|
5006
5098
|
- Follow single responsibility principle
|
|
5007
5099
|
`
|
|
5008
5100
|
};
|
|
5009
|
-
const filepath = (0,
|
|
5101
|
+
const filepath = (0, import_node_path24.join)(rulesDir, sampleFile.filename);
|
|
5010
5102
|
if (!await fileExists(filepath)) {
|
|
5011
5103
|
await writeFileContent(filepath, sampleFile.content);
|
|
5012
5104
|
console.log(`Created ${filepath}`);
|
|
@@ -5150,12 +5242,12 @@ async function watchCommand() {
|
|
|
5150
5242
|
|
|
5151
5243
|
// src/cli/index.ts
|
|
5152
5244
|
var program = new import_commander.Command();
|
|
5153
|
-
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.
|
|
5154
|
-
program.command("init").description("Initialize rulesync in current directory").action(initCommand);
|
|
5155
|
-
program.command("add <filename>").description("Add a new rule file").action(addCommand);
|
|
5245
|
+
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.62.0");
|
|
5246
|
+
program.command("init").description("Initialize rulesync in current directory").option("--legacy", "Use legacy file location (.rulesync/*.md instead of .rulesync/rules/*.md)").action(initCommand);
|
|
5247
|
+
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);
|
|
5156
5248
|
program.command("gitignore").description("Add generated files to .gitignore").action(gitignoreCommand);
|
|
5157
|
-
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);
|
|
5158
|
-
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("--delete", "Delete all existing files in output directories before generating").option(
|
|
5249
|
+
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);
|
|
5250
|
+
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(
|
|
5159
5251
|
"-b, --base-dir <paths>",
|
|
5160
5252
|
"Base directories to generate files (comma-separated for multiple paths)"
|
|
5161
5253
|
).option("-v, --verbose", "Verbose output").option("-c, --config <path>", "Path to configuration file").option("--no-config", "Disable configuration file loading").action(async (options) => {
|
|
@@ -5171,6 +5263,7 @@ program.command("generate").description("Generate configuration files for AI too
|
|
|
5171
5263
|
if (options.geminicli) tools.push("geminicli");
|
|
5172
5264
|
if (options.junie) tools.push("junie");
|
|
5173
5265
|
if (options.kiro) tools.push("kiro");
|
|
5266
|
+
if (options.windsurf) tools.push("windsurf");
|
|
5174
5267
|
const generateOptions = {
|
|
5175
5268
|
verbose: options.verbose,
|
|
5176
5269
|
delete: options.delete,
|