rulesync 0.63.0 → 0.65.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 +21 -3
- package/dist/amazonqcli-MW7XTVPN.js +9 -0
- package/dist/{augmentcode-HIZIQG2W.js → augmentcode-WCZCL7VR.js} +2 -2
- package/dist/{chunk-KUGTKMNW.js → chunk-4NWMCTN5.js} +5 -2
- package/dist/chunk-6AXPFPKI.js +17 -0
- package/dist/{chunk-LXTA7DBA.js → chunk-6SLEITCQ.js} +1 -1
- package/dist/chunk-DM2B7XUB.js +210 -0
- package/dist/{chunk-UEAYL4NT.js → chunk-FL5BF6JM.js} +1 -1
- package/dist/{chunk-4PSTOKKD.js → chunk-GIAQWZQ4.js} +1 -1
- package/dist/{chunk-YTU3SCQO.js → chunk-I4NVS7GE.js} +9 -3
- package/dist/{chunk-GQTMTBX4.js → chunk-JXOLLTNV.js} +89 -4
- package/dist/{chunk-NETSYSMD.js → chunk-LTWEI4PW.js} +1 -1
- package/dist/{chunk-AUUSMVCT.js → chunk-M2AUM37M.js} +3 -0
- package/dist/{chunk-M7NL7G7A.js → chunk-N6DASHJL.js} +1 -1
- package/dist/chunk-TX2CE4RR.js +17 -0
- package/dist/{chunk-2CW2KFB3.js → chunk-UGY5ALND.js} +1 -1
- package/dist/chunk-VRWNZTGW.js +17 -0
- package/dist/{chunk-U4PLVMCG.js → chunk-YC2BC7Z2.js} +1 -1
- package/dist/{claudecode-YTEFACCT.js → claudecode-RZSJPPBU.js} +3 -3
- package/dist/{cline-CKNUDEA3.js → cline-JTWWBQQ4.js} +3 -3
- package/dist/{codexcli-7SDGYI7D.js → codexcli-ATMFGRJR.js} +3 -3
- package/dist/{copilot-MOR3HHJX.js → copilot-H3CLGKDP.js} +2 -2
- package/dist/{cursor-YJGH7W24.js → cursor-ZUN5RZU6.js} +3 -3
- package/dist/{geminicli-E7KZTZ2G.js → geminicli-Q5HPIQCU.js} +3 -3
- package/dist/index.cjs +1213 -619
- package/dist/index.js +806 -488
- package/dist/{junie-5LEQU4BO.js → junie-JCLVC3MI.js} +3 -3
- package/dist/{kiro-YDHXY2MA.js → kiro-CNF6433S.js} +2 -2
- package/dist/opencode-EBS3CED2.js +17 -0
- package/dist/qwencode-JIT6KW7E.js +10 -0
- package/dist/{roo-L3QTTIPO.js → roo-KBTRH4TZ.js} +3 -2
- package/dist/{windsurf-4P6HEUBV.js → windsurf-ZAAWL6JJ.js} +3 -3
- package/package.json +2 -1
- package/dist/chunk-MDYDKNXQ.js +0 -61
- package/dist/chunk-PCATT4UZ.js +0 -78
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ var init_tool_targets = __esm({
|
|
|
41
41
|
"use strict";
|
|
42
42
|
import_mini2 = require("zod/mini");
|
|
43
43
|
ALL_TOOL_TARGETS = [
|
|
44
|
+
"amazonqcli",
|
|
44
45
|
"augmentcode",
|
|
45
46
|
"augmentcode-legacy",
|
|
46
47
|
"copilot",
|
|
@@ -48,6 +49,8 @@ var init_tool_targets = __esm({
|
|
|
48
49
|
"cline",
|
|
49
50
|
"claudecode",
|
|
50
51
|
"codexcli",
|
|
52
|
+
"opencode",
|
|
53
|
+
"qwencode",
|
|
51
54
|
"roo",
|
|
52
55
|
"geminicli",
|
|
53
56
|
"kiro",
|
|
@@ -61,6 +64,152 @@ var init_tool_targets = __esm({
|
|
|
61
64
|
}
|
|
62
65
|
});
|
|
63
66
|
|
|
67
|
+
// src/utils/logger.ts
|
|
68
|
+
var import_consola, Logger, logger;
|
|
69
|
+
var init_logger = __esm({
|
|
70
|
+
"src/utils/logger.ts"() {
|
|
71
|
+
"use strict";
|
|
72
|
+
import_consola = require("consola");
|
|
73
|
+
Logger = class {
|
|
74
|
+
_verbose = false;
|
|
75
|
+
console = import_consola.consola.withDefaults({
|
|
76
|
+
tag: "rulesync"
|
|
77
|
+
});
|
|
78
|
+
setVerbose(verbose) {
|
|
79
|
+
this._verbose = verbose;
|
|
80
|
+
}
|
|
81
|
+
get verbose() {
|
|
82
|
+
return this._verbose;
|
|
83
|
+
}
|
|
84
|
+
// Regular log (always shown, regardless of verbose)
|
|
85
|
+
log(message, ...args) {
|
|
86
|
+
this.console.log(message, ...args);
|
|
87
|
+
}
|
|
88
|
+
// Info level (shown only in verbose mode)
|
|
89
|
+
info(message, ...args) {
|
|
90
|
+
if (this._verbose) {
|
|
91
|
+
this.console.info(message, ...args);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Success (always shown)
|
|
95
|
+
success(message, ...args) {
|
|
96
|
+
this.console.success(message, ...args);
|
|
97
|
+
}
|
|
98
|
+
// Warning (always shown)
|
|
99
|
+
warn(message, ...args) {
|
|
100
|
+
this.console.warn(message, ...args);
|
|
101
|
+
}
|
|
102
|
+
// Error (always shown)
|
|
103
|
+
error(message, ...args) {
|
|
104
|
+
this.console.error(message, ...args);
|
|
105
|
+
}
|
|
106
|
+
// Debug level (shown only in verbose mode)
|
|
107
|
+
debug(message, ...args) {
|
|
108
|
+
if (this._verbose) {
|
|
109
|
+
this.console.debug(message, ...args);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
logger = new Logger();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// src/utils/file.ts
|
|
118
|
+
async function ensureDir(dirPath) {
|
|
119
|
+
try {
|
|
120
|
+
await (0, import_promises2.stat)(dirPath);
|
|
121
|
+
} catch {
|
|
122
|
+
await (0, import_promises2.mkdir)(dirPath, { recursive: true });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function resolvePath(relativePath, baseDir) {
|
|
126
|
+
if (!baseDir) return relativePath;
|
|
127
|
+
const resolved = (0, import_node_path.resolve)(baseDir, relativePath);
|
|
128
|
+
const rel = (0, import_node_path.relative)(baseDir, resolved);
|
|
129
|
+
if (rel.startsWith("..") || (0, import_node_path.resolve)(resolved) !== resolved) {
|
|
130
|
+
throw new Error(`Path traversal detected: ${relativePath}`);
|
|
131
|
+
}
|
|
132
|
+
return resolved;
|
|
133
|
+
}
|
|
134
|
+
async function readFileContent(filepath) {
|
|
135
|
+
return (0, import_promises2.readFile)(filepath, "utf-8");
|
|
136
|
+
}
|
|
137
|
+
async function writeFileContent(filepath, content) {
|
|
138
|
+
await ensureDir((0, import_node_path.dirname)(filepath));
|
|
139
|
+
await (0, import_promises2.writeFile)(filepath, content, "utf-8");
|
|
140
|
+
}
|
|
141
|
+
async function fileExists(filepath) {
|
|
142
|
+
try {
|
|
143
|
+
await (0, import_promises2.stat)(filepath);
|
|
144
|
+
return true;
|
|
145
|
+
} catch {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async function findFiles(dir, extension = ".md") {
|
|
150
|
+
try {
|
|
151
|
+
const files = await (0, import_promises2.readdir)(dir);
|
|
152
|
+
return files.filter((file) => file.endsWith(extension)).map((file) => (0, import_node_path.join)(dir, file));
|
|
153
|
+
} catch {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function findRuleFiles(aiRulesDir) {
|
|
158
|
+
const rulesDir = (0, import_node_path.join)(aiRulesDir, "rules");
|
|
159
|
+
const newLocationFiles = await findFiles(rulesDir, ".md");
|
|
160
|
+
const legacyLocationFiles = await findFiles(aiRulesDir, ".md");
|
|
161
|
+
const newLocationBasenames = new Set(
|
|
162
|
+
newLocationFiles.map((file) => file.split("/").pop()?.replace(/\.md$/, ""))
|
|
163
|
+
);
|
|
164
|
+
const filteredLegacyFiles = legacyLocationFiles.filter((file) => {
|
|
165
|
+
const basename6 = file.split("/").pop()?.replace(/\.md$/, "");
|
|
166
|
+
return !newLocationBasenames.has(basename6);
|
|
167
|
+
});
|
|
168
|
+
return [...newLocationFiles, ...filteredLegacyFiles];
|
|
169
|
+
}
|
|
170
|
+
async function removeDirectory(dirPath) {
|
|
171
|
+
const dangerousPaths = [".", "/", "~", "src", "node_modules"];
|
|
172
|
+
if (dangerousPaths.includes(dirPath) || dirPath === "") {
|
|
173
|
+
logger.warn(`Skipping deletion of dangerous path: ${dirPath}`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
if (await fileExists(dirPath)) {
|
|
178
|
+
await (0, import_promises2.rm)(dirPath, { recursive: true, force: true });
|
|
179
|
+
}
|
|
180
|
+
} catch (error) {
|
|
181
|
+
logger.warn(`Failed to remove directory ${dirPath}:`, error);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async function removeFile(filepath) {
|
|
185
|
+
try {
|
|
186
|
+
if (await fileExists(filepath)) {
|
|
187
|
+
await (0, import_promises2.rm)(filepath);
|
|
188
|
+
}
|
|
189
|
+
} catch (error) {
|
|
190
|
+
logger.warn(`Failed to remove file ${filepath}:`, error);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
async function removeClaudeGeneratedFiles() {
|
|
194
|
+
const filesToRemove = ["CLAUDE.md", ".claude/memories"];
|
|
195
|
+
for (const fileOrDir of filesToRemove) {
|
|
196
|
+
if (fileOrDir.endsWith("/memories")) {
|
|
197
|
+
await removeDirectory(fileOrDir);
|
|
198
|
+
} else {
|
|
199
|
+
await removeFile(fileOrDir);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
var import_promises2, import_node_path;
|
|
204
|
+
var init_file = __esm({
|
|
205
|
+
"src/utils/file.ts"() {
|
|
206
|
+
"use strict";
|
|
207
|
+
import_promises2 = require("fs/promises");
|
|
208
|
+
import_node_path = require("path");
|
|
209
|
+
init_logger();
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
64
213
|
// src/utils/mcp-helpers.ts
|
|
65
214
|
function shouldIncludeServer(server, targetTool) {
|
|
66
215
|
if (!server.targets || server.targets.length === 0) {
|
|
@@ -85,6 +234,75 @@ var init_mcp_helpers = __esm({
|
|
|
85
234
|
}
|
|
86
235
|
});
|
|
87
236
|
|
|
237
|
+
// src/generators/mcp/amazonqcli.ts
|
|
238
|
+
var amazonqcli_exports = {};
|
|
239
|
+
__export(amazonqcli_exports, {
|
|
240
|
+
generateAmazonqcliMcp: () => generateAmazonqcliMcp,
|
|
241
|
+
generateAmazonqcliMcpString: () => generateAmazonqcliMcpString
|
|
242
|
+
});
|
|
243
|
+
async function generateAmazonqcliMcp(mcpServers, config, baseDir) {
|
|
244
|
+
const outputs = [];
|
|
245
|
+
const configPaths = [
|
|
246
|
+
".amazonq/mcp.json"
|
|
247
|
+
// Workspace configuration
|
|
248
|
+
// Note: Global configuration is ~/.aws/amazonq/mcp.json but is user-specific
|
|
249
|
+
// According to precautions.md, we should not create user-level files
|
|
250
|
+
];
|
|
251
|
+
for (const configPath of configPaths) {
|
|
252
|
+
const filepath = resolvePath(configPath, baseDir);
|
|
253
|
+
const content = generateAmazonqcliMcpConfig({ mcpServers });
|
|
254
|
+
outputs.push({
|
|
255
|
+
tool: "amazonqcli",
|
|
256
|
+
filepath,
|
|
257
|
+
content
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
return outputs;
|
|
261
|
+
}
|
|
262
|
+
function generateAmazonqcliMcpString(config) {
|
|
263
|
+
return generateAmazonqcliMcpConfig(config);
|
|
264
|
+
}
|
|
265
|
+
function generateAmazonqcliMcpConfig(config) {
|
|
266
|
+
const servers = {};
|
|
267
|
+
for (const [serverName, server] of Object.entries(config.mcpServers)) {
|
|
268
|
+
if (!shouldIncludeServer(server, "amazonqcli")) {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
const amazonqServer = {};
|
|
272
|
+
if (server.command) {
|
|
273
|
+
amazonqServer.command = server.command;
|
|
274
|
+
if (server.args) {
|
|
275
|
+
amazonqServer.args = server.args;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (server.env) {
|
|
279
|
+
amazonqServer.env = server.env;
|
|
280
|
+
}
|
|
281
|
+
if (server.timeout !== void 0) {
|
|
282
|
+
amazonqServer.timeout = server.timeout;
|
|
283
|
+
}
|
|
284
|
+
if (server.disabled !== void 0) {
|
|
285
|
+
amazonqServer.disabled = server.disabled;
|
|
286
|
+
}
|
|
287
|
+
if (server.alwaysAllow) {
|
|
288
|
+
amazonqServer.autoApprove = server.alwaysAllow;
|
|
289
|
+
}
|
|
290
|
+
servers[serverName] = amazonqServer;
|
|
291
|
+
}
|
|
292
|
+
const finalConfig = {
|
|
293
|
+
mcpServers: servers
|
|
294
|
+
};
|
|
295
|
+
return `${JSON.stringify(finalConfig, null, 2)}
|
|
296
|
+
`;
|
|
297
|
+
}
|
|
298
|
+
var init_amazonqcli = __esm({
|
|
299
|
+
"src/generators/mcp/amazonqcli.ts"() {
|
|
300
|
+
"use strict";
|
|
301
|
+
init_file();
|
|
302
|
+
init_mcp_helpers();
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
|
|
88
306
|
// src/generators/mcp/augmentcode.ts
|
|
89
307
|
var augmentcode_exports = {};
|
|
90
308
|
__export(augmentcode_exports, {
|
|
@@ -104,7 +322,10 @@ function generateAugmentcodeMcp(config) {
|
|
|
104
322
|
name: serverName
|
|
105
323
|
};
|
|
106
324
|
if (server.command) {
|
|
107
|
-
|
|
325
|
+
const command = Array.isArray(server.command) ? server.command[0] : server.command;
|
|
326
|
+
if (command) {
|
|
327
|
+
augmentServer.command = command;
|
|
328
|
+
}
|
|
108
329
|
if (server.args) {
|
|
109
330
|
augmentServer.args = server.args;
|
|
110
331
|
}
|
|
@@ -152,7 +373,10 @@ function generateAugmentcodeMcpConfiguration(mcpServers, baseDir = "") {
|
|
|
152
373
|
const { targets: _, ...serverConfig } = server;
|
|
153
374
|
const augmentServer = {};
|
|
154
375
|
if (serverConfig.command) {
|
|
155
|
-
|
|
376
|
+
const command = Array.isArray(serverConfig.command) ? serverConfig.command[0] : serverConfig.command;
|
|
377
|
+
if (command) {
|
|
378
|
+
augmentServer.command = command;
|
|
379
|
+
}
|
|
156
380
|
if (serverConfig.args) {
|
|
157
381
|
augmentServer.args = serverConfig.args;
|
|
158
382
|
}
|
|
@@ -199,6 +423,17 @@ var init_augmentcode = __esm({
|
|
|
199
423
|
}
|
|
200
424
|
});
|
|
201
425
|
|
|
426
|
+
// src/constants/schemas.ts
|
|
427
|
+
var SCHEMA_URLS;
|
|
428
|
+
var init_schemas = __esm({
|
|
429
|
+
"src/constants/schemas.ts"() {
|
|
430
|
+
"use strict";
|
|
431
|
+
SCHEMA_URLS = {
|
|
432
|
+
OPENCODE: "https://opencode.ai/config.json"
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
|
|
202
437
|
// src/generators/mcp/shared-factory.ts
|
|
203
438
|
function generateMcpConfig(config, toolConfig) {
|
|
204
439
|
const servers = {};
|
|
@@ -248,7 +483,7 @@ function generateMcpConfigurationFilesFromRegistry(tool, mcpServers, baseDir = "
|
|
|
248
483
|
if (tool === "junie") {
|
|
249
484
|
return generateJunieMcpConfigurationFiles(mcpServers, baseDir);
|
|
250
485
|
}
|
|
251
|
-
const customTools = ["copilot", "augmentcode", "
|
|
486
|
+
const customTools = ["copilot", "augmentcode", "codexcli", "kiro"];
|
|
252
487
|
if (customTools.includes(tool)) {
|
|
253
488
|
throw new Error(
|
|
254
489
|
`Tool ${tool} uses custom configuration logic - use its specific generator function instead`
|
|
@@ -297,6 +532,7 @@ var serverTransforms, configWrappers, MCP_GENERATOR_REGISTRY, cursorMcpGenerator
|
|
|
297
532
|
var init_shared_factory = __esm({
|
|
298
533
|
"src/generators/mcp/shared-factory.ts"() {
|
|
299
534
|
"use strict";
|
|
535
|
+
init_schemas();
|
|
300
536
|
init_mcp_helpers();
|
|
301
537
|
serverTransforms = {
|
|
302
538
|
/**
|
|
@@ -307,7 +543,8 @@ var init_shared_factory = __esm({
|
|
|
307
543
|
if (server.command) {
|
|
308
544
|
result.command = server.command;
|
|
309
545
|
if (server.args) result.args = server.args;
|
|
310
|
-
}
|
|
546
|
+
}
|
|
547
|
+
if (server.url || server.httpUrl) {
|
|
311
548
|
const url = server.httpUrl || server.url;
|
|
312
549
|
if (url) result.url = url;
|
|
313
550
|
}
|
|
@@ -316,6 +553,25 @@ var init_shared_factory = __esm({
|
|
|
316
553
|
}
|
|
317
554
|
return result;
|
|
318
555
|
},
|
|
556
|
+
/**
|
|
557
|
+
* Roo-specific server transformation (preserves httpUrl, transport, type, etc.)
|
|
558
|
+
*/
|
|
559
|
+
roo: (server) => {
|
|
560
|
+
const result = serverTransforms.extended(server);
|
|
561
|
+
if (server.httpUrl) {
|
|
562
|
+
if (!server.url) {
|
|
563
|
+
result.httpUrl = server.httpUrl;
|
|
564
|
+
delete result.url;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (server.transport) {
|
|
568
|
+
result.transport = server.transport;
|
|
569
|
+
}
|
|
570
|
+
if (server.type) {
|
|
571
|
+
result.type = server.type;
|
|
572
|
+
}
|
|
573
|
+
return result;
|
|
574
|
+
},
|
|
319
575
|
/**
|
|
320
576
|
* Extended server transformation (includes disabled, alwaysAllow, etc.)
|
|
321
577
|
*/
|
|
@@ -367,6 +623,12 @@ var init_shared_factory = __esm({
|
|
|
367
623
|
})
|
|
368
624
|
};
|
|
369
625
|
MCP_GENERATOR_REGISTRY = {
|
|
626
|
+
roo: {
|
|
627
|
+
target: "roo",
|
|
628
|
+
configPaths: [".roo/mcp.json"],
|
|
629
|
+
serverTransform: serverTransforms.roo,
|
|
630
|
+
configWrapper: configWrappers.mcpServers
|
|
631
|
+
},
|
|
370
632
|
claudecode: {
|
|
371
633
|
target: "claudecode",
|
|
372
634
|
configPaths: [".mcp.json"],
|
|
@@ -493,6 +755,61 @@ var init_shared_factory = __esm({
|
|
|
493
755
|
configPaths: [".cline/mcp.json"],
|
|
494
756
|
serverTransform: serverTransforms.extended,
|
|
495
757
|
configWrapper: configWrappers.mcpServers
|
|
758
|
+
},
|
|
759
|
+
geminicli: {
|
|
760
|
+
target: "geminicli",
|
|
761
|
+
configPaths: [".gemini/settings.json"],
|
|
762
|
+
serverTransform: (server) => {
|
|
763
|
+
const { targets: _, ...serverConfig } = server;
|
|
764
|
+
const geminiServer = { ...serverConfig };
|
|
765
|
+
if (server.env) {
|
|
766
|
+
geminiServer.env = server.env;
|
|
767
|
+
}
|
|
768
|
+
return geminiServer;
|
|
769
|
+
},
|
|
770
|
+
configWrapper: configWrappers.mcpServers
|
|
771
|
+
},
|
|
772
|
+
opencode: {
|
|
773
|
+
target: "opencode",
|
|
774
|
+
configPaths: ["opencode.json"],
|
|
775
|
+
serverTransform: (server) => {
|
|
776
|
+
const opencodeServer = {};
|
|
777
|
+
if (server.command) {
|
|
778
|
+
opencodeServer.type = "local";
|
|
779
|
+
opencodeServer.command = Array.isArray(server.command) ? server.command : [server.command];
|
|
780
|
+
if (server.args) opencodeServer.args = server.args;
|
|
781
|
+
if (server.env) opencodeServer.environment = server.env;
|
|
782
|
+
if (server.cwd) opencodeServer.cwd = server.cwd;
|
|
783
|
+
} else if (server.url || server.httpUrl) {
|
|
784
|
+
opencodeServer.type = "remote";
|
|
785
|
+
const url = server.httpUrl || server.url;
|
|
786
|
+
if (url) opencodeServer.url = url;
|
|
787
|
+
if (server.headers) opencodeServer.headers = server.headers;
|
|
788
|
+
}
|
|
789
|
+
if (server.disabled !== void 0) {
|
|
790
|
+
opencodeServer.enabled = !server.disabled;
|
|
791
|
+
} else {
|
|
792
|
+
opencodeServer.enabled = true;
|
|
793
|
+
}
|
|
794
|
+
return opencodeServer;
|
|
795
|
+
},
|
|
796
|
+
configWrapper: (servers) => ({
|
|
797
|
+
$schema: SCHEMA_URLS.OPENCODE,
|
|
798
|
+
mcp: servers
|
|
799
|
+
})
|
|
800
|
+
},
|
|
801
|
+
qwencode: {
|
|
802
|
+
target: "qwencode",
|
|
803
|
+
configPaths: [".qwen/settings.json"],
|
|
804
|
+
serverTransform: (server) => {
|
|
805
|
+
const { targets: _, ...serverConfig } = server;
|
|
806
|
+
const qwenServer = { ...serverConfig };
|
|
807
|
+
if (server.env) {
|
|
808
|
+
qwenServer.env = server.env;
|
|
809
|
+
}
|
|
810
|
+
return qwenServer;
|
|
811
|
+
},
|
|
812
|
+
configWrapper: configWrappers.mcpServers
|
|
496
813
|
}
|
|
497
814
|
};
|
|
498
815
|
cursorMcpGenerator = createMcpGenerator("cursor");
|
|
@@ -696,7 +1013,10 @@ function generateCopilotMcp(config, target) {
|
|
|
696
1013
|
if (!shouldIncludeServer(server, "copilot")) continue;
|
|
697
1014
|
const copilotServer = {};
|
|
698
1015
|
if (server.command) {
|
|
699
|
-
|
|
1016
|
+
const command = Array.isArray(server.command) ? server.command[0] : server.command;
|
|
1017
|
+
if (command) {
|
|
1018
|
+
copilotServer.command = command;
|
|
1019
|
+
}
|
|
700
1020
|
if (server.args) copilotServer.args = server.args;
|
|
701
1021
|
} else if (server.url || server.httpUrl) {
|
|
702
1022
|
const url = server.httpUrl || server.url;
|
|
@@ -786,53 +1106,10 @@ __export(geminicli_exports, {
|
|
|
786
1106
|
generateGeminiCliMcpConfiguration: () => generateGeminiCliMcpConfiguration
|
|
787
1107
|
});
|
|
788
1108
|
function generateGeminiCliMcp(config) {
|
|
789
|
-
return
|
|
790
|
-
target: "geminicli",
|
|
791
|
-
configPaths: [".gemini/settings.json"],
|
|
792
|
-
serverTransform: (server) => {
|
|
793
|
-
const geminiServer = {};
|
|
794
|
-
if (server.command) {
|
|
795
|
-
geminiServer.command = server.command;
|
|
796
|
-
if (server.args) geminiServer.args = server.args;
|
|
797
|
-
} else if (server.url || server.httpUrl) {
|
|
798
|
-
if (server.httpUrl) {
|
|
799
|
-
geminiServer.httpUrl = server.httpUrl;
|
|
800
|
-
} else if (server.url) {
|
|
801
|
-
geminiServer.url = server.url;
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
if (server.env) {
|
|
805
|
-
geminiServer.env = server.env;
|
|
806
|
-
}
|
|
807
|
-
if (server.timeout !== void 0) {
|
|
808
|
-
geminiServer.timeout = server.timeout;
|
|
809
|
-
}
|
|
810
|
-
if (server.trust !== void 0) {
|
|
811
|
-
geminiServer.trust = server.trust;
|
|
812
|
-
}
|
|
813
|
-
return geminiServer;
|
|
814
|
-
},
|
|
815
|
-
configWrapper: configWrappers.mcpServers
|
|
816
|
-
});
|
|
1109
|
+
return generateMcpFromRegistry("geminicli", config);
|
|
817
1110
|
}
|
|
818
1111
|
function generateGeminiCliMcpConfiguration(mcpServers, baseDir = "") {
|
|
819
|
-
return
|
|
820
|
-
mcpServers,
|
|
821
|
-
{
|
|
822
|
-
target: "geminicli",
|
|
823
|
-
configPaths: [".gemini/settings.json"],
|
|
824
|
-
serverTransform: (server) => {
|
|
825
|
-
const { targets: _, ...serverConfig } = server;
|
|
826
|
-
const geminiServer = { ...serverConfig };
|
|
827
|
-
if (server.env) {
|
|
828
|
-
geminiServer.env = server.env;
|
|
829
|
-
}
|
|
830
|
-
return geminiServer;
|
|
831
|
-
},
|
|
832
|
-
configWrapper: configWrappers.mcpServers
|
|
833
|
-
},
|
|
834
|
-
baseDir
|
|
835
|
-
);
|
|
1112
|
+
return generateMcpConfigurationFilesFromRegistry("geminicli", mcpServers, baseDir);
|
|
836
1113
|
}
|
|
837
1114
|
var init_geminicli = __esm({
|
|
838
1115
|
"src/generators/mcp/geminicli.ts"() {
|
|
@@ -949,6 +1226,25 @@ var init_kiro = __esm({
|
|
|
949
1226
|
}
|
|
950
1227
|
});
|
|
951
1228
|
|
|
1229
|
+
// src/generators/mcp/qwencode.ts
|
|
1230
|
+
var qwencode_exports = {};
|
|
1231
|
+
__export(qwencode_exports, {
|
|
1232
|
+
generateQwenCodeMcp: () => generateQwenCodeMcp,
|
|
1233
|
+
generateQwenCodeMcpConfiguration: () => generateQwenCodeMcpConfiguration
|
|
1234
|
+
});
|
|
1235
|
+
function generateQwenCodeMcp(config) {
|
|
1236
|
+
return generateMcpFromRegistry("qwencode", config);
|
|
1237
|
+
}
|
|
1238
|
+
function generateQwenCodeMcpConfiguration(mcpServers, baseDir = "") {
|
|
1239
|
+
return generateMcpConfigurationFilesFromRegistry("qwencode", mcpServers, baseDir);
|
|
1240
|
+
}
|
|
1241
|
+
var init_qwencode = __esm({
|
|
1242
|
+
"src/generators/mcp/qwencode.ts"() {
|
|
1243
|
+
"use strict";
|
|
1244
|
+
init_shared_factory();
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
|
|
952
1248
|
// src/generators/mcp/roo.ts
|
|
953
1249
|
var roo_exports = {};
|
|
954
1250
|
__export(roo_exports, {
|
|
@@ -956,77 +1252,15 @@ __export(roo_exports, {
|
|
|
956
1252
|
generateRooMcpConfiguration: () => generateRooMcpConfiguration
|
|
957
1253
|
});
|
|
958
1254
|
function generateRooMcp(config) {
|
|
959
|
-
|
|
960
|
-
mcpServers: {}
|
|
961
|
-
};
|
|
962
|
-
for (const [serverName, server] of Object.entries(config.mcpServers)) {
|
|
963
|
-
if (!shouldIncludeServer(server, "roo")) continue;
|
|
964
|
-
const rooServer = {};
|
|
965
|
-
if (server.command) {
|
|
966
|
-
rooServer.command = server.command;
|
|
967
|
-
if (server.args) rooServer.args = server.args;
|
|
968
|
-
} else if (server.url || server.httpUrl) {
|
|
969
|
-
const url = server.httpUrl || server.url;
|
|
970
|
-
if (url) {
|
|
971
|
-
rooServer.url = url;
|
|
972
|
-
}
|
|
973
|
-
if (server.httpUrl || server.transport === "http") {
|
|
974
|
-
rooServer.type = "streamable-http";
|
|
975
|
-
} else if (server.transport === "sse" || server.type === "sse") {
|
|
976
|
-
rooServer.type = "sse";
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
if (server.env) {
|
|
980
|
-
rooServer.env = {};
|
|
981
|
-
for (const [key, value] of Object.entries(server.env)) {
|
|
982
|
-
if (value.startsWith("${env:") && value.endsWith("}")) {
|
|
983
|
-
rooServer.env[key] = value;
|
|
984
|
-
} else {
|
|
985
|
-
rooServer.env[key] = `\${env:${value}}`;
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
if (server.disabled !== void 0) {
|
|
990
|
-
rooServer.disabled = server.disabled;
|
|
991
|
-
}
|
|
992
|
-
if (server.alwaysAllow) {
|
|
993
|
-
rooServer.alwaysAllow = server.alwaysAllow;
|
|
994
|
-
}
|
|
995
|
-
if (server.networkTimeout !== void 0) {
|
|
996
|
-
rooServer.networkTimeout = Math.max(3e4, Math.min(3e5, server.networkTimeout));
|
|
997
|
-
}
|
|
998
|
-
rooConfig.mcpServers[serverName] = rooServer;
|
|
999
|
-
}
|
|
1000
|
-
return JSON.stringify(rooConfig, null, 2);
|
|
1255
|
+
return generateMcpFromRegistry("roo", config);
|
|
1001
1256
|
}
|
|
1002
1257
|
function generateRooMcpConfiguration(mcpServers, baseDir = "") {
|
|
1003
|
-
|
|
1004
|
-
const config = {
|
|
1005
|
-
mcpServers: {}
|
|
1006
|
-
};
|
|
1007
|
-
for (const [serverName, server] of Object.entries(mcpServers)) {
|
|
1008
|
-
if (!shouldIncludeServer(server, "roo")) {
|
|
1009
|
-
continue;
|
|
1010
|
-
}
|
|
1011
|
-
const { targets: _targets, ...serverConfig } = server;
|
|
1012
|
-
const rooServer = { ...serverConfig };
|
|
1013
|
-
if (serverConfig.httpUrl !== void 0 && serverConfig.url !== void 0) {
|
|
1014
|
-
rooServer.url = serverConfig.httpUrl;
|
|
1015
|
-
}
|
|
1016
|
-
config.mcpServers[serverName] = rooServer;
|
|
1017
|
-
}
|
|
1018
|
-
return [
|
|
1019
|
-
{
|
|
1020
|
-
filepath,
|
|
1021
|
-
content: `${JSON.stringify(config, null, 2)}
|
|
1022
|
-
`
|
|
1023
|
-
}
|
|
1024
|
-
];
|
|
1258
|
+
return generateMcpConfigurationFilesFromRegistry("roo", mcpServers, baseDir);
|
|
1025
1259
|
}
|
|
1026
1260
|
var init_roo = __esm({
|
|
1027
1261
|
"src/generators/mcp/roo.ts"() {
|
|
1028
1262
|
"use strict";
|
|
1029
|
-
|
|
1263
|
+
init_shared_factory();
|
|
1030
1264
|
}
|
|
1031
1265
|
});
|
|
1032
1266
|
|
|
@@ -1049,16 +1283,27 @@ var init_windsurf = __esm({
|
|
|
1049
1283
|
}
|
|
1050
1284
|
});
|
|
1051
1285
|
|
|
1052
|
-
// src/
|
|
1053
|
-
var
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1286
|
+
// src/generators/mcp/opencode.ts
|
|
1287
|
+
var opencode_exports = {};
|
|
1288
|
+
__export(opencode_exports, {
|
|
1289
|
+
generateOpenCodeMcp: () => generateOpenCodeMcp,
|
|
1290
|
+
generateOpenCodeMcpConfiguration: () => generateOpenCodeMcpConfiguration
|
|
1291
|
+
});
|
|
1292
|
+
function generateOpenCodeMcp(config) {
|
|
1293
|
+
return generateMcpFromRegistry("opencode", config);
|
|
1294
|
+
}
|
|
1295
|
+
function generateOpenCodeMcpConfiguration(mcpServers, baseDir = "") {
|
|
1296
|
+
return generateMcpConfigurationFilesFromRegistry("opencode", mcpServers, baseDir);
|
|
1297
|
+
}
|
|
1298
|
+
var init_opencode = __esm({
|
|
1299
|
+
"src/generators/mcp/opencode.ts"() {
|
|
1300
|
+
"use strict";
|
|
1301
|
+
init_shared_factory();
|
|
1302
|
+
}
|
|
1303
|
+
});
|
|
1304
|
+
|
|
1305
|
+
// src/cli/index.ts
|
|
1306
|
+
var import_commander = require("commander");
|
|
1062
1307
|
|
|
1063
1308
|
// src/types/claudecode.ts
|
|
1064
1309
|
var import_mini = require("zod/mini");
|
|
@@ -1103,6 +1348,7 @@ var ConfigSchema = import_mini4.z.object({
|
|
|
1103
1348
|
var import_mini5 = require("zod/mini");
|
|
1104
1349
|
init_tool_targets();
|
|
1105
1350
|
var OutputPathsSchema = import_mini5.z.object({
|
|
1351
|
+
amazonqcli: import_mini5.z.optional(import_mini5.z.string()),
|
|
1106
1352
|
augmentcode: import_mini5.z.optional(import_mini5.z.string()),
|
|
1107
1353
|
"augmentcode-legacy": import_mini5.z.optional(import_mini5.z.string()),
|
|
1108
1354
|
copilot: import_mini5.z.optional(import_mini5.z.string()),
|
|
@@ -1110,6 +1356,8 @@ var OutputPathsSchema = import_mini5.z.object({
|
|
|
1110
1356
|
cline: import_mini5.z.optional(import_mini5.z.string()),
|
|
1111
1357
|
claudecode: import_mini5.z.optional(import_mini5.z.string()),
|
|
1112
1358
|
codexcli: import_mini5.z.optional(import_mini5.z.string()),
|
|
1359
|
+
opencode: import_mini5.z.optional(import_mini5.z.string()),
|
|
1360
|
+
qwencode: import_mini5.z.optional(import_mini5.z.string()),
|
|
1113
1361
|
roo: import_mini5.z.optional(import_mini5.z.string()),
|
|
1114
1362
|
geminicli: import_mini5.z.optional(import_mini5.z.string()),
|
|
1115
1363
|
kiro: import_mini5.z.optional(import_mini5.z.string()),
|
|
@@ -1161,7 +1409,7 @@ var import_mini6 = require("zod/mini");
|
|
|
1161
1409
|
init_tool_targets();
|
|
1162
1410
|
var McpTransportTypeSchema = import_mini6.z.enum(["stdio", "sse", "http"]);
|
|
1163
1411
|
var McpServerBaseSchema = import_mini6.z.object({
|
|
1164
|
-
command: import_mini6.z.optional(import_mini6.z.string()),
|
|
1412
|
+
command: import_mini6.z.optional(import_mini6.z.union([import_mini6.z.string(), import_mini6.z.array(import_mini6.z.string())])),
|
|
1165
1413
|
args: import_mini6.z.optional(import_mini6.z.array(import_mini6.z.string())),
|
|
1166
1414
|
url: import_mini6.z.optional(import_mini6.z.string()),
|
|
1167
1415
|
httpUrl: import_mini6.z.optional(import_mini6.z.string()),
|
|
@@ -1211,12 +1459,21 @@ var GenerateOptionsSchema = import_mini7.z.object({
|
|
|
1211
1459
|
// src/types/index.ts
|
|
1212
1460
|
init_tool_targets();
|
|
1213
1461
|
|
|
1462
|
+
// src/cli/commands/add.ts
|
|
1463
|
+
var import_promises = require("fs/promises");
|
|
1464
|
+
var path = __toESM(require("path"), 1);
|
|
1465
|
+
|
|
1466
|
+
// src/utils/config-loader.ts
|
|
1467
|
+
var import_c12 = require("c12");
|
|
1468
|
+
var import_core = require("zod/v4/core");
|
|
1469
|
+
|
|
1214
1470
|
// src/utils/config.ts
|
|
1215
1471
|
init_tool_targets();
|
|
1216
1472
|
function getDefaultConfig() {
|
|
1217
1473
|
return {
|
|
1218
1474
|
aiRulesDir: ".rulesync",
|
|
1219
1475
|
outputPaths: {
|
|
1476
|
+
amazonqcli: ".amazonq/rules",
|
|
1220
1477
|
augmentcode: ".",
|
|
1221
1478
|
"augmentcode-legacy": ".",
|
|
1222
1479
|
copilot: ".github/instructions",
|
|
@@ -1224,6 +1481,8 @@ function getDefaultConfig() {
|
|
|
1224
1481
|
cline: ".clinerules",
|
|
1225
1482
|
claudecode: ".",
|
|
1226
1483
|
codexcli: ".",
|
|
1484
|
+
opencode: ".",
|
|
1485
|
+
qwencode: ".qwen/memories",
|
|
1227
1486
|
roo: ".roo/rules",
|
|
1228
1487
|
geminicli: ".gemini/memories",
|
|
1229
1488
|
kiro: ".kiro/steering",
|
|
@@ -1430,51 +1689,8 @@ function mergeWithCliOptions(config, cliOptions) {
|
|
|
1430
1689
|
return merged;
|
|
1431
1690
|
}
|
|
1432
1691
|
|
|
1433
|
-
// src/utils/logger.ts
|
|
1434
|
-
var import_consola = require("consola");
|
|
1435
|
-
var Logger = class {
|
|
1436
|
-
_verbose = false;
|
|
1437
|
-
console = import_consola.consola.withDefaults({
|
|
1438
|
-
tag: "rulesync"
|
|
1439
|
-
});
|
|
1440
|
-
setVerbose(verbose) {
|
|
1441
|
-
this._verbose = verbose;
|
|
1442
|
-
}
|
|
1443
|
-
get verbose() {
|
|
1444
|
-
return this._verbose;
|
|
1445
|
-
}
|
|
1446
|
-
// Regular log (always shown, regardless of verbose)
|
|
1447
|
-
log(message, ...args) {
|
|
1448
|
-
this.console.log(message, ...args);
|
|
1449
|
-
}
|
|
1450
|
-
// Info level (shown only in verbose mode)
|
|
1451
|
-
info(message, ...args) {
|
|
1452
|
-
if (this._verbose) {
|
|
1453
|
-
this.console.info(message, ...args);
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
// Success (always shown)
|
|
1457
|
-
success(message, ...args) {
|
|
1458
|
-
this.console.success(message, ...args);
|
|
1459
|
-
}
|
|
1460
|
-
// Warning (always shown)
|
|
1461
|
-
warn(message, ...args) {
|
|
1462
|
-
this.console.warn(message, ...args);
|
|
1463
|
-
}
|
|
1464
|
-
// Error (always shown)
|
|
1465
|
-
error(message, ...args) {
|
|
1466
|
-
this.console.error(message, ...args);
|
|
1467
|
-
}
|
|
1468
|
-
// Debug level (shown only in verbose mode)
|
|
1469
|
-
debug(message, ...args) {
|
|
1470
|
-
if (this._verbose) {
|
|
1471
|
-
this.console.debug(message, ...args);
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
};
|
|
1475
|
-
var logger = new Logger();
|
|
1476
|
-
|
|
1477
1692
|
// src/cli/commands/add.ts
|
|
1693
|
+
init_logger();
|
|
1478
1694
|
function sanitizeFilename(filename) {
|
|
1479
1695
|
return filename.endsWith(".md") ? filename.slice(0, -3) : filename;
|
|
1480
1696
|
}
|
|
@@ -1518,6 +1734,7 @@ var import_node_fs = require("fs");
|
|
|
1518
1734
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
1519
1735
|
|
|
1520
1736
|
// src/utils/error.ts
|
|
1737
|
+
init_logger();
|
|
1521
1738
|
function getErrorMessage(error) {
|
|
1522
1739
|
return error instanceof Error ? error.message : String(error);
|
|
1523
1740
|
}
|
|
@@ -1547,90 +1764,11 @@ async function safeAsyncOperation(operation, errorContext) {
|
|
|
1547
1764
|
}
|
|
1548
1765
|
}
|
|
1549
1766
|
|
|
1550
|
-
// src/utils/
|
|
1551
|
-
|
|
1552
|
-
var import_node_path = require("path");
|
|
1553
|
-
async function ensureDir(dirPath) {
|
|
1554
|
-
try {
|
|
1555
|
-
await (0, import_promises2.stat)(dirPath);
|
|
1556
|
-
} catch {
|
|
1557
|
-
await (0, import_promises2.mkdir)(dirPath, { recursive: true });
|
|
1558
|
-
}
|
|
1559
|
-
}
|
|
1560
|
-
function resolvePath(relativePath, baseDir) {
|
|
1561
|
-
return baseDir ? (0, import_node_path.join)(baseDir, relativePath) : relativePath;
|
|
1562
|
-
}
|
|
1563
|
-
async function readFileContent(filepath) {
|
|
1564
|
-
return (0, import_promises2.readFile)(filepath, "utf-8");
|
|
1565
|
-
}
|
|
1566
|
-
async function writeFileContent(filepath, content) {
|
|
1567
|
-
await ensureDir((0, import_node_path.dirname)(filepath));
|
|
1568
|
-
await (0, import_promises2.writeFile)(filepath, content, "utf-8");
|
|
1569
|
-
}
|
|
1570
|
-
async function fileExists(filepath) {
|
|
1571
|
-
try {
|
|
1572
|
-
await (0, import_promises2.stat)(filepath);
|
|
1573
|
-
return true;
|
|
1574
|
-
} catch {
|
|
1575
|
-
return false;
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
async function findFiles(dir, extension = ".md") {
|
|
1579
|
-
try {
|
|
1580
|
-
const files = await (0, import_promises2.readdir)(dir);
|
|
1581
|
-
return files.filter((file) => file.endsWith(extension)).map((file) => (0, import_node_path.join)(dir, file));
|
|
1582
|
-
} catch {
|
|
1583
|
-
return [];
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
async function findRuleFiles(aiRulesDir) {
|
|
1587
|
-
const rulesDir = (0, import_node_path.join)(aiRulesDir, "rules");
|
|
1588
|
-
const newLocationFiles = await findFiles(rulesDir, ".md");
|
|
1589
|
-
const legacyLocationFiles = await findFiles(aiRulesDir, ".md");
|
|
1590
|
-
const newLocationBasenames = new Set(
|
|
1591
|
-
newLocationFiles.map((file) => file.split("/").pop()?.replace(/\.md$/, ""))
|
|
1592
|
-
);
|
|
1593
|
-
const filteredLegacyFiles = legacyLocationFiles.filter((file) => {
|
|
1594
|
-
const basename6 = file.split("/").pop()?.replace(/\.md$/, "");
|
|
1595
|
-
return !newLocationBasenames.has(basename6);
|
|
1596
|
-
});
|
|
1597
|
-
return [...newLocationFiles, ...filteredLegacyFiles];
|
|
1598
|
-
}
|
|
1599
|
-
async function removeDirectory(dirPath) {
|
|
1600
|
-
const dangerousPaths = [".", "/", "~", "src", "node_modules"];
|
|
1601
|
-
if (dangerousPaths.includes(dirPath) || dirPath === "") {
|
|
1602
|
-
logger.warn(`Skipping deletion of dangerous path: ${dirPath}`);
|
|
1603
|
-
return;
|
|
1604
|
-
}
|
|
1605
|
-
try {
|
|
1606
|
-
if (await fileExists(dirPath)) {
|
|
1607
|
-
await (0, import_promises2.rm)(dirPath, { recursive: true, force: true });
|
|
1608
|
-
}
|
|
1609
|
-
} catch (error) {
|
|
1610
|
-
logger.warn(`Failed to remove directory ${dirPath}:`, error);
|
|
1611
|
-
}
|
|
1612
|
-
}
|
|
1613
|
-
async function removeFile(filepath) {
|
|
1614
|
-
try {
|
|
1615
|
-
if (await fileExists(filepath)) {
|
|
1616
|
-
await (0, import_promises2.rm)(filepath);
|
|
1617
|
-
}
|
|
1618
|
-
} catch (error) {
|
|
1619
|
-
logger.warn(`Failed to remove file ${filepath}:`, error);
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
async function removeClaudeGeneratedFiles() {
|
|
1623
|
-
const filesToRemove = ["CLAUDE.md", ".claude/memories"];
|
|
1624
|
-
for (const fileOrDir of filesToRemove) {
|
|
1625
|
-
if (fileOrDir.endsWith("/memories")) {
|
|
1626
|
-
await removeDirectory(fileOrDir);
|
|
1627
|
-
} else {
|
|
1628
|
-
await removeFile(fileOrDir);
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1767
|
+
// src/utils/index.ts
|
|
1768
|
+
init_file();
|
|
1632
1769
|
|
|
1633
1770
|
// src/cli/commands/config.ts
|
|
1771
|
+
init_logger();
|
|
1634
1772
|
async function configCommand(options = {}) {
|
|
1635
1773
|
if (options.init) {
|
|
1636
1774
|
await initConfig(options);
|
|
@@ -1841,25 +1979,25 @@ export default config;
|
|
|
1841
1979
|
}
|
|
1842
1980
|
|
|
1843
1981
|
// src/cli/commands/generate.ts
|
|
1844
|
-
var
|
|
1982
|
+
var import_node_path14 = require("path");
|
|
1845
1983
|
|
|
1846
1984
|
// src/core/command-generator.ts
|
|
1847
1985
|
var import_node_path5 = require("path");
|
|
1848
1986
|
|
|
1849
1987
|
// src/utils/command-generators.ts
|
|
1850
1988
|
var import_node_path3 = require("path");
|
|
1851
|
-
function generateYamlFrontmatter(command, options
|
|
1852
|
-
const
|
|
1853
|
-
if (options
|
|
1854
|
-
|
|
1989
|
+
function generateYamlFrontmatter(command, options) {
|
|
1990
|
+
const frontmatterLines = ["---"];
|
|
1991
|
+
if (options?.includeDescription && command.frontmatter.description) {
|
|
1992
|
+
frontmatterLines.push(`description: ${command.frontmatter.description}`);
|
|
1855
1993
|
}
|
|
1856
|
-
if (options
|
|
1994
|
+
if (options?.additionalFields) {
|
|
1857
1995
|
for (const field of options.additionalFields) {
|
|
1858
|
-
|
|
1996
|
+
frontmatterLines.push(`${field.key}: ${field.value}`);
|
|
1859
1997
|
}
|
|
1860
1998
|
}
|
|
1861
|
-
|
|
1862
|
-
return
|
|
1999
|
+
frontmatterLines.push("---");
|
|
2000
|
+
return frontmatterLines;
|
|
1863
2001
|
}
|
|
1864
2002
|
function buildCommandContent(command, frontmatterOptions) {
|
|
1865
2003
|
const frontmatter = generateYamlFrontmatter(command, frontmatterOptions);
|
|
@@ -1898,26 +2036,75 @@ var syntaxConverters = {
|
|
|
1898
2036
|
}
|
|
1899
2037
|
};
|
|
1900
2038
|
|
|
1901
|
-
// src/generators/commands/
|
|
1902
|
-
var
|
|
2039
|
+
// src/generators/commands/base.ts
|
|
2040
|
+
var BaseCommandGenerator = class {
|
|
2041
|
+
/**
|
|
2042
|
+
* Generate command output for the specified tool
|
|
2043
|
+
*/
|
|
1903
2044
|
generate(command, outputDir) {
|
|
1904
2045
|
const filepath = this.getOutputPath(command.filename, outputDir);
|
|
1905
|
-
const content =
|
|
2046
|
+
const content = this.processContent(command);
|
|
1906
2047
|
return {
|
|
1907
|
-
tool:
|
|
2048
|
+
tool: this.getToolName(),
|
|
1908
2049
|
filepath,
|
|
1909
2050
|
content
|
|
1910
2051
|
};
|
|
1911
2052
|
}
|
|
2053
|
+
/**
|
|
2054
|
+
* Get the output path for the command file
|
|
2055
|
+
* Override this method if custom path logic is needed
|
|
2056
|
+
*/
|
|
1912
2057
|
getOutputPath(filename, baseDir) {
|
|
1913
|
-
|
|
2058
|
+
if (this.supportsHierarchy()) {
|
|
2059
|
+
return getHierarchicalCommandPath(
|
|
2060
|
+
filename,
|
|
2061
|
+
baseDir,
|
|
2062
|
+
this.getCommandsDirectory(),
|
|
2063
|
+
this.getFileExtension()
|
|
2064
|
+
);
|
|
2065
|
+
} else {
|
|
2066
|
+
return getFlattenedCommandPath(filename, baseDir, this.getCommandsDirectory());
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
/**
|
|
2070
|
+
* Whether this tool supports hierarchical directory structure
|
|
2071
|
+
* Override to return true for tools that support nested commands
|
|
2072
|
+
*/
|
|
2073
|
+
supportsHierarchy() {
|
|
2074
|
+
return false;
|
|
1914
2075
|
}
|
|
2076
|
+
/**
|
|
2077
|
+
* Get file extension for the target tool
|
|
2078
|
+
* Override if tool uses different extension than .md
|
|
2079
|
+
*/
|
|
2080
|
+
getFileExtension() {
|
|
2081
|
+
return "md";
|
|
2082
|
+
}
|
|
2083
|
+
};
|
|
2084
|
+
|
|
2085
|
+
// src/generators/commands/claudecode.ts
|
|
2086
|
+
var ClaudeCodeCommandGenerator = class extends BaseCommandGenerator {
|
|
2087
|
+
getToolName() {
|
|
2088
|
+
return "claudecode";
|
|
2089
|
+
}
|
|
2090
|
+
getCommandsDirectory() {
|
|
2091
|
+
return ".claude/commands";
|
|
2092
|
+
}
|
|
2093
|
+
processContent(command) {
|
|
2094
|
+
return buildCommandContent(command, { includeDescription: true });
|
|
2095
|
+
}
|
|
2096
|
+
// Uses flattened structure by default (supportsHierarchy returns false)
|
|
1915
2097
|
};
|
|
1916
2098
|
|
|
1917
2099
|
// src/generators/commands/geminicli.ts
|
|
1918
|
-
var GeminiCliCommandGenerator = class {
|
|
1919
|
-
|
|
1920
|
-
|
|
2100
|
+
var GeminiCliCommandGenerator = class extends BaseCommandGenerator {
|
|
2101
|
+
getToolName() {
|
|
2102
|
+
return "geminicli";
|
|
2103
|
+
}
|
|
2104
|
+
getCommandsDirectory() {
|
|
2105
|
+
return ".gemini/commands";
|
|
2106
|
+
}
|
|
2107
|
+
processContent(command) {
|
|
1921
2108
|
const convertedContent = syntaxConverters.toGeminiCli(command.content);
|
|
1922
2109
|
const tomlLines = [];
|
|
1923
2110
|
if (command.frontmatter.description) {
|
|
@@ -1925,32 +2112,28 @@ var GeminiCliCommandGenerator = class {
|
|
|
1925
2112
|
tomlLines.push("");
|
|
1926
2113
|
}
|
|
1927
2114
|
tomlLines.push(`prompt = """${convertedContent}"""`);
|
|
1928
|
-
|
|
1929
|
-
return {
|
|
1930
|
-
tool: "geminicli",
|
|
1931
|
-
filepath,
|
|
1932
|
-
content
|
|
1933
|
-
};
|
|
2115
|
+
return tomlLines.join("\n") + "\n";
|
|
1934
2116
|
}
|
|
1935
|
-
|
|
1936
|
-
return
|
|
2117
|
+
supportsHierarchy() {
|
|
2118
|
+
return true;
|
|
2119
|
+
}
|
|
2120
|
+
getFileExtension() {
|
|
2121
|
+
return "toml";
|
|
1937
2122
|
}
|
|
1938
2123
|
};
|
|
1939
2124
|
|
|
1940
2125
|
// src/generators/commands/roo.ts
|
|
1941
|
-
var RooCommandGenerator = class {
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
const content = buildCommandContent(command);
|
|
1945
|
-
return {
|
|
1946
|
-
tool: "roo",
|
|
1947
|
-
filepath,
|
|
1948
|
-
content
|
|
1949
|
-
};
|
|
2126
|
+
var RooCommandGenerator = class extends BaseCommandGenerator {
|
|
2127
|
+
getToolName() {
|
|
2128
|
+
return "roo";
|
|
1950
2129
|
}
|
|
1951
|
-
|
|
1952
|
-
return
|
|
2130
|
+
getCommandsDirectory() {
|
|
2131
|
+
return ".roo/commands";
|
|
2132
|
+
}
|
|
2133
|
+
processContent(command) {
|
|
2134
|
+
return buildCommandContent(command, { includeDescription: true });
|
|
1953
2135
|
}
|
|
2136
|
+
// Uses flattened structure by default (supportsHierarchy returns false)
|
|
1954
2137
|
};
|
|
1955
2138
|
|
|
1956
2139
|
// src/generators/commands/index.ts
|
|
@@ -1963,6 +2146,10 @@ function getCommandGenerator(tool) {
|
|
|
1963
2146
|
return commandGenerators[tool];
|
|
1964
2147
|
}
|
|
1965
2148
|
|
|
2149
|
+
// src/core/command-generator.ts
|
|
2150
|
+
init_file();
|
|
2151
|
+
init_logger();
|
|
2152
|
+
|
|
1966
2153
|
// src/core/command-parser.ts
|
|
1967
2154
|
var import_node_path4 = require("path");
|
|
1968
2155
|
|
|
@@ -1985,6 +2172,7 @@ function extractStringField(data, key, defaultValue) {
|
|
|
1985
2172
|
}
|
|
1986
2173
|
|
|
1987
2174
|
// src/core/command-parser.ts
|
|
2175
|
+
init_logger();
|
|
1988
2176
|
async function parseCommandsFromDirectory(commandsDir) {
|
|
1989
2177
|
const commandFiles = await findFiles(commandsDir, ".md");
|
|
1990
2178
|
const commands = [];
|
|
@@ -2766,26 +2954,87 @@ async function generateKiroIgnoreFiles(rules, config, baseDir) {
|
|
|
2766
2954
|
return generateIgnoreFile(rules, config, ignoreConfigs.kiro, baseDir);
|
|
2767
2955
|
}
|
|
2768
2956
|
|
|
2957
|
+
// src/generators/ignore/qwencode.ts
|
|
2958
|
+
var import_node_path7 = require("path");
|
|
2959
|
+
function extractQwenCodeFileFilteringPatterns(content) {
|
|
2960
|
+
const filtering = {};
|
|
2961
|
+
const configBlocks = content.match(/```(?:json|javascript)\s*\n([\s\S]*?)\n```/g);
|
|
2962
|
+
if (configBlocks) {
|
|
2963
|
+
for (const block of configBlocks) {
|
|
2964
|
+
try {
|
|
2965
|
+
const jsonContent = block.replace(/```(?:json|javascript)\s*\n/, "").replace(/\n```$/, "");
|
|
2966
|
+
const parsed = JSON.parse(jsonContent);
|
|
2967
|
+
if (parsed.fileFiltering) {
|
|
2968
|
+
Object.assign(filtering, parsed.fileFiltering);
|
|
2969
|
+
}
|
|
2970
|
+
} catch {
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
if (content.includes("respectGitIgnore")) {
|
|
2975
|
+
if (content.includes("respectGitIgnore: false") || content.includes('"respectGitIgnore": false')) {
|
|
2976
|
+
filtering.respectGitIgnore = false;
|
|
2977
|
+
} else {
|
|
2978
|
+
filtering.respectGitIgnore = true;
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
if (content.includes("enableRecursiveFileSearch")) {
|
|
2982
|
+
if (content.includes("enableRecursiveFileSearch: false") || content.includes('"enableRecursiveFileSearch": false')) {
|
|
2983
|
+
filtering.enableRecursiveFileSearch = false;
|
|
2984
|
+
} else {
|
|
2985
|
+
filtering.enableRecursiveFileSearch = true;
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
return Object.keys(filtering).length > 0 ? filtering : void 0;
|
|
2989
|
+
}
|
|
2990
|
+
function generateQwenCodeConfiguration(rules) {
|
|
2991
|
+
const config = {};
|
|
2992
|
+
config.fileFiltering = {
|
|
2993
|
+
respectGitIgnore: true,
|
|
2994
|
+
enableRecursiveFileSearch: true
|
|
2995
|
+
};
|
|
2996
|
+
for (const rule of rules) {
|
|
2997
|
+
const ruleFiltering = extractQwenCodeFileFilteringPatterns(rule.content);
|
|
2998
|
+
if (ruleFiltering) {
|
|
2999
|
+
Object.assign(config.fileFiltering, ruleFiltering);
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
return config;
|
|
3003
|
+
}
|
|
3004
|
+
async function generateQwenCodeIgnoreFiles(rules, config, baseDir) {
|
|
3005
|
+
const outputs = [];
|
|
3006
|
+
const outputPath = baseDir || process.cwd();
|
|
3007
|
+
const qwenConfig = generateQwenCodeConfiguration(rules);
|
|
3008
|
+
const settingsPath = (0, import_node_path7.join)(outputPath, ".qwen", "settings.json");
|
|
3009
|
+
outputs.push({
|
|
3010
|
+
tool: "qwencode",
|
|
3011
|
+
filepath: settingsPath,
|
|
3012
|
+
content: `${JSON.stringify(qwenConfig, null, 2)}
|
|
3013
|
+
`
|
|
3014
|
+
});
|
|
3015
|
+
return outputs;
|
|
3016
|
+
}
|
|
3017
|
+
|
|
2769
3018
|
// src/generators/ignore/windsurf.ts
|
|
2770
3019
|
function generateWindsurfIgnore(rules, config, baseDir) {
|
|
2771
3020
|
return generateIgnoreFile(rules, config, ignoreConfigs.windsurf, baseDir);
|
|
2772
3021
|
}
|
|
2773
3022
|
|
|
2774
|
-
// src/generators/rules/augmentcode.ts
|
|
2775
|
-
var import_node_path9 = require("path");
|
|
2776
|
-
|
|
2777
3023
|
// src/generators/rules/shared-helpers.ts
|
|
2778
|
-
var
|
|
3024
|
+
var import_node_path9 = require("path");
|
|
3025
|
+
init_file();
|
|
2779
3026
|
|
|
2780
3027
|
// src/utils/ignore.ts
|
|
2781
|
-
var
|
|
3028
|
+
var import_node_path8 = require("path");
|
|
2782
3029
|
var import_micromatch = __toESM(require("micromatch"), 1);
|
|
3030
|
+
init_file();
|
|
3031
|
+
init_logger();
|
|
2783
3032
|
var cachedIgnorePatterns = null;
|
|
2784
3033
|
async function loadIgnorePatterns(baseDir = process.cwd()) {
|
|
2785
3034
|
if (cachedIgnorePatterns) {
|
|
2786
3035
|
return cachedIgnorePatterns;
|
|
2787
3036
|
}
|
|
2788
|
-
const ignorePath = (0,
|
|
3037
|
+
const ignorePath = (0, import_node_path8.join)(baseDir, ".rulesyncignore");
|
|
2789
3038
|
if (!await fileExists(ignorePath)) {
|
|
2790
3039
|
cachedIgnorePatterns = { patterns: [] };
|
|
2791
3040
|
return cachedIgnorePatterns;
|
|
@@ -2839,7 +3088,7 @@ function addOutput(outputs, tool, config, baseDir, relativePath, content) {
|
|
|
2839
3088
|
const outputDir = resolveOutputDir(config, tool, baseDir);
|
|
2840
3089
|
outputs.push({
|
|
2841
3090
|
tool,
|
|
2842
|
-
filepath: (0,
|
|
3091
|
+
filepath: (0, import_node_path9.join)(outputDir, relativePath),
|
|
2843
3092
|
content
|
|
2844
3093
|
});
|
|
2845
3094
|
}
|
|
@@ -2848,7 +3097,7 @@ async function generateRulesConfig(rules, config, generatorConfig, baseDir) {
|
|
|
2848
3097
|
for (const rule of rules) {
|
|
2849
3098
|
const content = generatorConfig.generateContent(rule);
|
|
2850
3099
|
const outputDir = resolveOutputDir(config, generatorConfig.tool, baseDir);
|
|
2851
|
-
const filepath = generatorConfig.pathResolver ? generatorConfig.pathResolver(rule, outputDir) : (0,
|
|
3100
|
+
const filepath = generatorConfig.pathResolver ? generatorConfig.pathResolver(rule, outputDir) : (0, import_node_path9.join)(outputDir, `${rule.filename}${generatorConfig.fileExtension}`);
|
|
2852
3101
|
outputs.push({
|
|
2853
3102
|
tool: generatorConfig.tool,
|
|
2854
3103
|
filepath,
|
|
@@ -2876,7 +3125,7 @@ async function generateComplexRules(rules, config, generatorConfig, baseDir) {
|
|
|
2876
3125
|
for (const rule of detailRules) {
|
|
2877
3126
|
const content = generatorConfig.generateDetailContent(rule);
|
|
2878
3127
|
const filepath = resolvePath(
|
|
2879
|
-
(0,
|
|
3128
|
+
(0, import_node_path9.join)(generatorConfig.detailSubDir, `${rule.filename}.md`),
|
|
2880
3129
|
baseDir
|
|
2881
3130
|
);
|
|
2882
3131
|
outputs.push({
|
|
@@ -2930,7 +3179,61 @@ function generateIgnoreFile2(patterns, tool) {
|
|
|
2930
3179
|
return lines.join("\n");
|
|
2931
3180
|
}
|
|
2932
3181
|
|
|
3182
|
+
// src/generators/rules/amazonqcli.ts
|
|
3183
|
+
async function generateAmazonqcliConfig(rules, config, baseDir) {
|
|
3184
|
+
const generatorConfig = {
|
|
3185
|
+
tool: "amazonqcli",
|
|
3186
|
+
fileExtension: ".md",
|
|
3187
|
+
generateContent: generateRuleFile,
|
|
3188
|
+
generateRootContent: generateMainRulesFile,
|
|
3189
|
+
rootFilePath: ".amazonq/rules/main.md",
|
|
3190
|
+
generateDetailContent: generateRuleFile,
|
|
3191
|
+
detailSubDir: ".amazonq/rules"
|
|
3192
|
+
};
|
|
3193
|
+
return generateComplexRules(rules, config, generatorConfig, baseDir);
|
|
3194
|
+
}
|
|
3195
|
+
function generateMainRulesFile(rootRule, detailRules) {
|
|
3196
|
+
const lines = [];
|
|
3197
|
+
if (detailRules.length > 0) {
|
|
3198
|
+
lines.push("# Amazon Q Developer CLI Project Rules");
|
|
3199
|
+
lines.push("");
|
|
3200
|
+
lines.push("This file contains the main project rules. See also:");
|
|
3201
|
+
lines.push("");
|
|
3202
|
+
for (const rule of detailRules) {
|
|
3203
|
+
lines.push(`- ${rule.filename}.md: ${rule.frontmatter.description}`);
|
|
3204
|
+
}
|
|
3205
|
+
lines.push("");
|
|
3206
|
+
}
|
|
3207
|
+
if (rootRule) {
|
|
3208
|
+
if (detailRules.length > 0) {
|
|
3209
|
+
lines.push("## Overview");
|
|
3210
|
+
lines.push("");
|
|
3211
|
+
}
|
|
3212
|
+
lines.push(rootRule.content);
|
|
3213
|
+
lines.push("");
|
|
3214
|
+
} else if (detailRules.length === 0) {
|
|
3215
|
+
lines.push("# Amazon Q Developer CLI Project Rules");
|
|
3216
|
+
lines.push("");
|
|
3217
|
+
lines.push("This file contains project-specific rules and context for Amazon Q Developer CLI.");
|
|
3218
|
+
lines.push("");
|
|
3219
|
+
lines.push("## Development Standards");
|
|
3220
|
+
lines.push("");
|
|
3221
|
+
lines.push("Add your project-specific development standards here.");
|
|
3222
|
+
lines.push("");
|
|
3223
|
+
}
|
|
3224
|
+
return lines.join("\n").trim() + "\n";
|
|
3225
|
+
}
|
|
3226
|
+
function generateRuleFile(rule) {
|
|
3227
|
+
const lines = [];
|
|
3228
|
+
lines.push(`# ${rule.frontmatter.description || rule.filename}`);
|
|
3229
|
+
lines.push("");
|
|
3230
|
+
lines.push(rule.content.trim());
|
|
3231
|
+
lines.push("");
|
|
3232
|
+
return lines.join("\n");
|
|
3233
|
+
}
|
|
3234
|
+
|
|
2933
3235
|
// src/generators/rules/augmentcode.ts
|
|
3236
|
+
var import_node_path10 = require("path");
|
|
2934
3237
|
async function generateAugmentcodeConfig(rules, config, baseDir) {
|
|
2935
3238
|
const outputs = createOutputsArray();
|
|
2936
3239
|
rules.forEach((rule) => {
|
|
@@ -2939,13 +3242,13 @@ async function generateAugmentcodeConfig(rules, config, baseDir) {
|
|
|
2939
3242
|
"augmentcode",
|
|
2940
3243
|
config,
|
|
2941
3244
|
baseDir,
|
|
2942
|
-
(0,
|
|
2943
|
-
|
|
3245
|
+
(0, import_node_path10.join)(".augment", "rules", `${rule.filename}.md`),
|
|
3246
|
+
generateRuleFile2(rule)
|
|
2944
3247
|
);
|
|
2945
3248
|
});
|
|
2946
3249
|
return outputs;
|
|
2947
3250
|
}
|
|
2948
|
-
function
|
|
3251
|
+
function generateRuleFile2(rule) {
|
|
2949
3252
|
const lines = [];
|
|
2950
3253
|
lines.push("---");
|
|
2951
3254
|
let ruleType = "manual";
|
|
@@ -2992,7 +3295,9 @@ function generateLegacyGuidelinesFile(allRules) {
|
|
|
2992
3295
|
}
|
|
2993
3296
|
|
|
2994
3297
|
// src/generators/rules/claudecode.ts
|
|
2995
|
-
var
|
|
3298
|
+
var import_node_path11 = require("path");
|
|
3299
|
+
init_file();
|
|
3300
|
+
init_logger();
|
|
2996
3301
|
async function generateClaudecodeConfig(rules, config, baseDir) {
|
|
2997
3302
|
const generatorConfig = {
|
|
2998
3303
|
tool: "claudecode",
|
|
@@ -3004,7 +3309,7 @@ async function generateClaudecodeConfig(rules, config, baseDir) {
|
|
|
3004
3309
|
generateDetailContent: generateMemoryFile,
|
|
3005
3310
|
detailSubDir: ".claude/memories",
|
|
3006
3311
|
updateAdditionalConfig: async (ignorePatterns, baseDir2) => {
|
|
3007
|
-
const settingsPath = resolvePath((0,
|
|
3312
|
+
const settingsPath = resolvePath((0, import_node_path11.join)(".claude", "settings.json"), baseDir2);
|
|
3008
3313
|
await updateClaudeSettings(settingsPath, ignorePatterns);
|
|
3009
3314
|
return [];
|
|
3010
3315
|
}
|
|
@@ -3068,7 +3373,7 @@ async function updateClaudeSettings(settingsPath, ignorePatterns) {
|
|
|
3068
3373
|
}
|
|
3069
3374
|
|
|
3070
3375
|
// src/generators/rules/generator-registry.ts
|
|
3071
|
-
var
|
|
3376
|
+
var import_node_path12 = require("path");
|
|
3072
3377
|
function determineCursorRuleType(frontmatter) {
|
|
3073
3378
|
if (frontmatter.cursorRuleType) {
|
|
3074
3379
|
return frontmatter.cursorRuleType;
|
|
@@ -3092,6 +3397,22 @@ function determineCursorRuleType(frontmatter) {
|
|
|
3092
3397
|
}
|
|
3093
3398
|
var GENERATOR_REGISTRY = {
|
|
3094
3399
|
// Simple generators - generate one file per rule
|
|
3400
|
+
amazonqcli: {
|
|
3401
|
+
type: "complex",
|
|
3402
|
+
tool: "amazonqcli",
|
|
3403
|
+
fileExtension: ".md",
|
|
3404
|
+
// ignoreFileName omitted - Amazon Q CLI doesn't have native ignore file support yet
|
|
3405
|
+
generateContent: (rule) => {
|
|
3406
|
+
const lines = [];
|
|
3407
|
+
if (rule.frontmatter.description) {
|
|
3408
|
+
lines.push(`# ${rule.frontmatter.description}
|
|
3409
|
+
`);
|
|
3410
|
+
}
|
|
3411
|
+
lines.push(rule.content.trim());
|
|
3412
|
+
return lines.join("\n");
|
|
3413
|
+
}
|
|
3414
|
+
// Complex generation handled by existing generator
|
|
3415
|
+
},
|
|
3095
3416
|
cline: {
|
|
3096
3417
|
type: "simple",
|
|
3097
3418
|
tool: "cline",
|
|
@@ -3148,7 +3469,7 @@ var GENERATOR_REGISTRY = {
|
|
|
3148
3469
|
},
|
|
3149
3470
|
pathResolver: (rule, outputDir) => {
|
|
3150
3471
|
const baseFilename = rule.filename.replace(/\.md$/, "");
|
|
3151
|
-
return (0,
|
|
3472
|
+
return (0, import_node_path12.join)(outputDir, `${baseFilename}.instructions.md`);
|
|
3152
3473
|
}
|
|
3153
3474
|
},
|
|
3154
3475
|
cursor: {
|
|
@@ -3188,7 +3509,7 @@ var GENERATOR_REGISTRY = {
|
|
|
3188
3509
|
return lines.join("\n");
|
|
3189
3510
|
},
|
|
3190
3511
|
pathResolver: (rule, outputDir) => {
|
|
3191
|
-
return (0,
|
|
3512
|
+
return (0, import_node_path12.join)(outputDir, `${rule.filename}.mdc`);
|
|
3192
3513
|
}
|
|
3193
3514
|
},
|
|
3194
3515
|
codexcli: {
|
|
@@ -3224,10 +3545,10 @@ var GENERATOR_REGISTRY = {
|
|
|
3224
3545
|
pathResolver: (rule, outputDir) => {
|
|
3225
3546
|
const outputFormat = rule.frontmatter.windsurfOutputFormat || "directory";
|
|
3226
3547
|
if (outputFormat === "single-file") {
|
|
3227
|
-
return (0,
|
|
3548
|
+
return (0, import_node_path12.join)(outputDir, ".windsurf-rules");
|
|
3228
3549
|
} else {
|
|
3229
|
-
const rulesDir = (0,
|
|
3230
|
-
return (0,
|
|
3550
|
+
const rulesDir = (0, import_node_path12.join)(outputDir, ".windsurf", "rules");
|
|
3551
|
+
return (0, import_node_path12.join)(rulesDir, `${rule.filename}.md`);
|
|
3231
3552
|
}
|
|
3232
3553
|
}
|
|
3233
3554
|
},
|
|
@@ -3258,6 +3579,22 @@ var GENERATOR_REGISTRY = {
|
|
|
3258
3579
|
const lines = [];
|
|
3259
3580
|
if (rule.frontmatter.description) {
|
|
3260
3581
|
lines.push(`# ${rule.frontmatter.description}
|
|
3582
|
+
`);
|
|
3583
|
+
}
|
|
3584
|
+
lines.push(rule.content.trim());
|
|
3585
|
+
return lines.join("\n");
|
|
3586
|
+
}
|
|
3587
|
+
// Complex generation handled by existing generator
|
|
3588
|
+
},
|
|
3589
|
+
opencode: {
|
|
3590
|
+
type: "complex",
|
|
3591
|
+
tool: "opencode",
|
|
3592
|
+
fileExtension: ".md",
|
|
3593
|
+
// ignoreFileName omitted - OpenCode doesn't use dedicated ignore files
|
|
3594
|
+
generateContent: (rule) => {
|
|
3595
|
+
const lines = [];
|
|
3596
|
+
if (rule.frontmatter.description) {
|
|
3597
|
+
lines.push(`# ${rule.frontmatter.description}
|
|
3261
3598
|
`);
|
|
3262
3599
|
}
|
|
3263
3600
|
lines.push(rule.content.trim());
|
|
@@ -3280,7 +3617,23 @@ var GENERATOR_REGISTRY = {
|
|
|
3280
3617
|
return lines.join("\n");
|
|
3281
3618
|
}
|
|
3282
3619
|
// Complex generation handled by existing generator
|
|
3283
|
-
}
|
|
3620
|
+
},
|
|
3621
|
+
qwencode: {
|
|
3622
|
+
type: "complex",
|
|
3623
|
+
tool: "qwencode",
|
|
3624
|
+
fileExtension: ".md",
|
|
3625
|
+
// ignoreFileName omitted - Qwen Code uses git-aware filtering instead of dedicated ignore files
|
|
3626
|
+
generateContent: (rule) => {
|
|
3627
|
+
const lines = [];
|
|
3628
|
+
if (rule.frontmatter.description) {
|
|
3629
|
+
lines.push(`# ${rule.frontmatter.description}
|
|
3630
|
+
`);
|
|
3631
|
+
}
|
|
3632
|
+
lines.push(rule.content.trim());
|
|
3633
|
+
return lines.join("\n");
|
|
3634
|
+
}
|
|
3635
|
+
// Complex generation handled by existing generator
|
|
3636
|
+
}
|
|
3284
3637
|
};
|
|
3285
3638
|
async function generateFromRegistry(tool, rules, config, baseDir) {
|
|
3286
3639
|
const generatorConfig = GENERATOR_REGISTRY[tool];
|
|
@@ -3300,8 +3653,8 @@ async function generateFromRegistry(tool, rules, config, baseDir) {
|
|
|
3300
3653
|
const enhancedConfig = {
|
|
3301
3654
|
tool: generatorConfig.tool,
|
|
3302
3655
|
fileExtension: generatorConfig.fileExtension,
|
|
3303
|
-
ignoreFileName: generatorConfig.ignoreFileName,
|
|
3304
3656
|
generateContent: generatorConfig.generateContent,
|
|
3657
|
+
...generatorConfig.ignoreFileName && { ignoreFileName: generatorConfig.ignoreFileName },
|
|
3305
3658
|
...generatorConfig.generateRootContent && {
|
|
3306
3659
|
generateRootContent: generatorConfig.generateRootContent
|
|
3307
3660
|
},
|
|
@@ -3330,50 +3683,94 @@ var generateCopilotConfig = createSimpleGenerator("copilot");
|
|
|
3330
3683
|
var generateWindsurfConfig = createSimpleGenerator("windsurf");
|
|
3331
3684
|
var generateKiroConfig = createSimpleGenerator("kiro");
|
|
3332
3685
|
var generateRooConfig = createSimpleGenerator("roo");
|
|
3686
|
+
var generateQwencodeConfig = createSimpleGenerator("qwencode");
|
|
3333
3687
|
|
|
3334
3688
|
// src/generators/rules/codexcli.ts
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
const
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3689
|
+
init_file();
|
|
3690
|
+
|
|
3691
|
+
// src/utils/xml-document-generator.ts
|
|
3692
|
+
var import_fast_xml_parser = require("fast-xml-parser");
|
|
3693
|
+
function generateRootMarkdownWithXmlDocs(rootRule, memoryRules, config) {
|
|
3694
|
+
const lines = [];
|
|
3695
|
+
if (memoryRules.length > 0) {
|
|
3696
|
+
lines.push(
|
|
3697
|
+
"Please also reference the following documents as needed. In this case, `@` stands for the project root directory."
|
|
3698
|
+
);
|
|
3699
|
+
lines.push("");
|
|
3700
|
+
const documentsData = {
|
|
3701
|
+
Documents: {
|
|
3702
|
+
Document: memoryRules.map((rule) => {
|
|
3703
|
+
const relativePath = `@${config.memorySubDir}/${rule.filename}.md`;
|
|
3704
|
+
const document = {
|
|
3705
|
+
Path: relativePath,
|
|
3706
|
+
Description: rule.frontmatter.description
|
|
3707
|
+
};
|
|
3708
|
+
if (rule.frontmatter.globs.length > 0) {
|
|
3709
|
+
document.FilePatterns = rule.frontmatter.globs.join(", ");
|
|
3710
|
+
}
|
|
3711
|
+
return document;
|
|
3712
|
+
})
|
|
3713
|
+
}
|
|
3714
|
+
};
|
|
3715
|
+
const builder = new import_fast_xml_parser.XMLBuilder({
|
|
3716
|
+
format: true,
|
|
3717
|
+
ignoreAttributes: false,
|
|
3718
|
+
suppressEmptyNode: false
|
|
3353
3719
|
});
|
|
3720
|
+
const xmlContent = builder.build(documentsData);
|
|
3721
|
+
lines.push(xmlContent);
|
|
3722
|
+
lines.push("");
|
|
3723
|
+
lines.push("");
|
|
3354
3724
|
}
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
filepath: ignorePath,
|
|
3362
|
-
content: ignoreContent
|
|
3363
|
-
});
|
|
3725
|
+
if (rootRule) {
|
|
3726
|
+
lines.push(rootRule.content.trim());
|
|
3727
|
+
} else if (memoryRules.length === 0) {
|
|
3728
|
+
lines.push(`# ${config.fallbackTitle}`);
|
|
3729
|
+
lines.push("");
|
|
3730
|
+
lines.push("No configuration rules have been defined yet.");
|
|
3364
3731
|
}
|
|
3365
|
-
return
|
|
3732
|
+
return lines.join("\n");
|
|
3366
3733
|
}
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3734
|
+
|
|
3735
|
+
// src/generators/rules/codexcli.ts
|
|
3736
|
+
async function generateCodexConfig(rules, config, baseDir) {
|
|
3737
|
+
const outputs = [];
|
|
3738
|
+
const nonEmptyRules = rules.filter((rule) => rule.content.trim().length > 0);
|
|
3739
|
+
if (nonEmptyRules.length > 0) {
|
|
3740
|
+
const generatorConfig = {
|
|
3741
|
+
tool: "codexcli",
|
|
3742
|
+
fileExtension: ".md",
|
|
3743
|
+
ignoreFileName: ".codexignore",
|
|
3744
|
+
generateContent: generateCodexMemoryMarkdown,
|
|
3745
|
+
generateDetailContent: generateCodexMemoryMarkdown,
|
|
3746
|
+
generateRootContent: generateCodexRootMarkdown,
|
|
3747
|
+
rootFilePath: "AGENTS.md",
|
|
3748
|
+
detailSubDir: ".codex/memories"
|
|
3749
|
+
};
|
|
3750
|
+
const ruleOutputs = await generateComplexRules(nonEmptyRules, config, generatorConfig, baseDir);
|
|
3751
|
+
outputs.push(...ruleOutputs);
|
|
3752
|
+
} else {
|
|
3753
|
+
const ignorePatterns = await loadIgnorePatterns(baseDir);
|
|
3754
|
+
if (ignorePatterns.patterns.length > 0) {
|
|
3755
|
+
const ignorePath = resolvePath(".codexignore", baseDir);
|
|
3756
|
+
const ignoreContent = generateIgnoreFile2(ignorePatterns.patterns, "codexcli");
|
|
3757
|
+
outputs.push({
|
|
3758
|
+
tool: "codexcli",
|
|
3759
|
+
filepath: ignorePath,
|
|
3760
|
+
content: ignoreContent
|
|
3761
|
+
});
|
|
3373
3762
|
}
|
|
3374
|
-
sections.push(content);
|
|
3375
3763
|
}
|
|
3376
|
-
return
|
|
3764
|
+
return outputs;
|
|
3765
|
+
}
|
|
3766
|
+
function generateCodexMemoryMarkdown(rule) {
|
|
3767
|
+
return rule.content.trim();
|
|
3768
|
+
}
|
|
3769
|
+
function generateCodexRootMarkdown(rootRule, memoryRules, _baseDir) {
|
|
3770
|
+
return generateRootMarkdownWithXmlDocs(rootRule, memoryRules, {
|
|
3771
|
+
memorySubDir: ".codex/memories",
|
|
3772
|
+
fallbackTitle: "OpenAI Codex CLI Configuration"
|
|
3773
|
+
});
|
|
3377
3774
|
}
|
|
3378
3775
|
|
|
3379
3776
|
// src/generators/rules/geminicli.ts
|
|
@@ -3394,28 +3791,10 @@ function generateGeminiMemoryMarkdown(rule) {
|
|
|
3394
3791
|
return rule.content.trim();
|
|
3395
3792
|
}
|
|
3396
3793
|
function generateGeminiRootMarkdown(rootRule, memoryRules, _baseDir) {
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
lines.push("| Document | Description | File Patterns |");
|
|
3402
|
-
lines.push("|----------|-------------|---------------|");
|
|
3403
|
-
for (const rule of memoryRules) {
|
|
3404
|
-
const relativePath = `@.gemini/memories/${rule.filename}.md`;
|
|
3405
|
-
const filePatterns = rule.frontmatter.globs.length > 0 ? rule.frontmatter.globs.join(", ") : "-";
|
|
3406
|
-
lines.push(`| ${relativePath} | ${rule.frontmatter.description} | ${filePatterns} |`);
|
|
3407
|
-
}
|
|
3408
|
-
lines.push("");
|
|
3409
|
-
lines.push("");
|
|
3410
|
-
}
|
|
3411
|
-
if (rootRule) {
|
|
3412
|
-
lines.push(rootRule.content.trim());
|
|
3413
|
-
} else if (memoryRules.length === 0) {
|
|
3414
|
-
lines.push("# Gemini CLI Configuration");
|
|
3415
|
-
lines.push("");
|
|
3416
|
-
lines.push("No configuration rules have been defined yet.");
|
|
3417
|
-
}
|
|
3418
|
-
return lines.join("\n");
|
|
3794
|
+
return generateRootMarkdownWithXmlDocs(rootRule, memoryRules, {
|
|
3795
|
+
memorySubDir: ".gemini/memories",
|
|
3796
|
+
fallbackTitle: "Gemini CLI Configuration"
|
|
3797
|
+
});
|
|
3419
3798
|
}
|
|
3420
3799
|
|
|
3421
3800
|
// src/generators/rules/junie.ts
|
|
@@ -3445,7 +3824,56 @@ function generateGuidelinesMarkdown(rootRule, detailRules) {
|
|
|
3445
3824
|
return lines.join("\n").trim();
|
|
3446
3825
|
}
|
|
3447
3826
|
|
|
3827
|
+
// src/generators/rules/opencode.ts
|
|
3828
|
+
async function generateOpenCodeConfig(rules, config, baseDir) {
|
|
3829
|
+
const generatorConfig = {
|
|
3830
|
+
tool: "opencode",
|
|
3831
|
+
fileExtension: ".md",
|
|
3832
|
+
// ignoreFileName omitted - OpenCode doesn't use dedicated ignore files
|
|
3833
|
+
generateContent: generateOpenCodeMarkdown,
|
|
3834
|
+
generateDetailContent: generateOpenCodeMarkdown,
|
|
3835
|
+
generateRootContent: generateOpenCodeRootMarkdown,
|
|
3836
|
+
rootFilePath: "AGENTS.md",
|
|
3837
|
+
detailSubDir: ".opencode/memories"
|
|
3838
|
+
};
|
|
3839
|
+
return generateComplexRules(rules, config, generatorConfig, baseDir);
|
|
3840
|
+
}
|
|
3841
|
+
function generateOpenCodeMarkdown(rule) {
|
|
3842
|
+
return rule.content.trim();
|
|
3843
|
+
}
|
|
3844
|
+
function generateOpenCodeRootMarkdown(rootRule, memoryRules, _baseDir) {
|
|
3845
|
+
return generateRootMarkdownWithXmlDocs(rootRule, memoryRules, {
|
|
3846
|
+
memorySubDir: ".opencode/memories",
|
|
3847
|
+
fallbackTitle: "OpenCode Configuration"
|
|
3848
|
+
});
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3851
|
+
// src/generators/rules/qwencode.ts
|
|
3852
|
+
async function generateQwencodeConfig2(rules, config, baseDir) {
|
|
3853
|
+
const generatorConfig = {
|
|
3854
|
+
tool: "qwencode",
|
|
3855
|
+
fileExtension: ".md",
|
|
3856
|
+
// ignoreFileName omitted - Qwen Code uses git-aware filtering instead of dedicated ignore files
|
|
3857
|
+
generateContent: generateQwenMemoryMarkdown,
|
|
3858
|
+
generateDetailContent: generateQwenMemoryMarkdown,
|
|
3859
|
+
generateRootContent: generateQwenRootMarkdown,
|
|
3860
|
+
rootFilePath: "QWEN.md",
|
|
3861
|
+
detailSubDir: ".qwen/memories"
|
|
3862
|
+
};
|
|
3863
|
+
return generateComplexRules(rules, config, generatorConfig, baseDir);
|
|
3864
|
+
}
|
|
3865
|
+
function generateQwenMemoryMarkdown(rule) {
|
|
3866
|
+
return rule.content.trim();
|
|
3867
|
+
}
|
|
3868
|
+
function generateQwenRootMarkdown(rootRule, memoryRules, _baseDir) {
|
|
3869
|
+
return generateRootMarkdownWithXmlDocs(rootRule, memoryRules, {
|
|
3870
|
+
memorySubDir: ".qwen/memories",
|
|
3871
|
+
fallbackTitle: "Qwen Code Configuration"
|
|
3872
|
+
});
|
|
3873
|
+
}
|
|
3874
|
+
|
|
3448
3875
|
// src/core/generator.ts
|
|
3876
|
+
init_logger();
|
|
3449
3877
|
async function generateConfigurations(rules, config, targetTools, baseDir) {
|
|
3450
3878
|
const outputs = createOutputsArray();
|
|
3451
3879
|
const toolsToGenerate = targetTools || config.defaultTargets;
|
|
@@ -3477,6 +3905,8 @@ function filterRulesForTool(rules, tool, config) {
|
|
|
3477
3905
|
}
|
|
3478
3906
|
async function generateForTool(tool, rules, config, baseDir) {
|
|
3479
3907
|
switch (tool) {
|
|
3908
|
+
case "amazonqcli":
|
|
3909
|
+
return await generateAmazonqcliConfig(rules, config, baseDir);
|
|
3480
3910
|
case "augmentcode": {
|
|
3481
3911
|
const augmentRulesOutputs = await generateAugmentcodeConfig(rules, config, baseDir);
|
|
3482
3912
|
const augmentIgnoreOutputs = await generateAugmentCodeIgnoreFiles(rules, config, baseDir);
|
|
@@ -3515,6 +3945,13 @@ async function generateForTool(tool, rules, config, baseDir) {
|
|
|
3515
3945
|
const kiroIgnoreOutputs = await generateKiroIgnoreFiles(rules, config, baseDir);
|
|
3516
3946
|
return [...kiroRulesOutputs, ...kiroIgnoreOutputs];
|
|
3517
3947
|
}
|
|
3948
|
+
case "opencode":
|
|
3949
|
+
return generateOpenCodeConfig(rules, config, baseDir);
|
|
3950
|
+
case "qwencode": {
|
|
3951
|
+
const qwenRulesOutputs = await generateQwencodeConfig2(rules, config, baseDir);
|
|
3952
|
+
const qwenIgnoreOutputs = await generateQwenCodeIgnoreFiles(rules, config, baseDir);
|
|
3953
|
+
return [...qwenRulesOutputs, ...qwenIgnoreOutputs];
|
|
3954
|
+
}
|
|
3518
3955
|
case "windsurf": {
|
|
3519
3956
|
const windsurfRulesOutputs = await generateWindsurfConfig(rules, config, baseDir);
|
|
3520
3957
|
const windsurfIgnoreOutputs = await generateWindsurfIgnore(rules, config, baseDir);
|
|
@@ -3527,7 +3964,8 @@ async function generateForTool(tool, rules, config, baseDir) {
|
|
|
3527
3964
|
}
|
|
3528
3965
|
|
|
3529
3966
|
// src/core/parser.ts
|
|
3530
|
-
var
|
|
3967
|
+
var import_node_path13 = require("path");
|
|
3968
|
+
init_logger();
|
|
3531
3969
|
async function parseRulesFromDirectory(aiRulesDir) {
|
|
3532
3970
|
const ignorePatterns = await loadIgnorePatterns();
|
|
3533
3971
|
const allRuleFiles = await findRuleFiles(aiRulesDir);
|
|
@@ -3580,7 +4018,7 @@ async function parseRuleFile(filepath) {
|
|
|
3580
4018
|
},
|
|
3581
4019
|
...validatedData.tags !== void 0 && { tags: validatedData.tags }
|
|
3582
4020
|
};
|
|
3583
|
-
const filename = (0,
|
|
4021
|
+
const filename = (0, import_node_path13.basename)(filepath, ".md");
|
|
3584
4022
|
return {
|
|
3585
4023
|
frontmatter,
|
|
3586
4024
|
content: parsed.content,
|
|
@@ -3648,6 +4086,7 @@ async function validateRule(rule) {
|
|
|
3648
4086
|
var path4 = __toESM(require("path"), 1);
|
|
3649
4087
|
|
|
3650
4088
|
// src/generators/mcp/index.ts
|
|
4089
|
+
init_amazonqcli();
|
|
3651
4090
|
init_augmentcode();
|
|
3652
4091
|
init_claudecode();
|
|
3653
4092
|
init_cline();
|
|
@@ -3657,9 +4096,13 @@ init_cursor();
|
|
|
3657
4096
|
init_geminicli();
|
|
3658
4097
|
init_junie();
|
|
3659
4098
|
init_kiro();
|
|
4099
|
+
init_qwencode();
|
|
3660
4100
|
init_roo();
|
|
3661
4101
|
init_windsurf();
|
|
3662
4102
|
|
|
4103
|
+
// src/core/mcp-generator.ts
|
|
4104
|
+
init_file();
|
|
4105
|
+
|
|
3663
4106
|
// src/core/mcp-parser.ts
|
|
3664
4107
|
var fs = __toESM(require("fs"), 1);
|
|
3665
4108
|
var path3 = __toESM(require("path"), 1);
|
|
@@ -3691,6 +4134,36 @@ function parseMcpConfig(projectRoot) {
|
|
|
3691
4134
|
async function generateMcpConfigurations(mcpConfig, baseDir, targetTools) {
|
|
3692
4135
|
const outputs = [];
|
|
3693
4136
|
const toolMap = {
|
|
4137
|
+
amazonqcli: async (servers, dir) => {
|
|
4138
|
+
const config = {
|
|
4139
|
+
aiRulesDir: ".rulesync",
|
|
4140
|
+
outputPaths: {
|
|
4141
|
+
amazonqcli: ".amazonq/rules",
|
|
4142
|
+
augmentcode: ".",
|
|
4143
|
+
"augmentcode-legacy": ".",
|
|
4144
|
+
copilot: ".github/instructions",
|
|
4145
|
+
cursor: ".cursor/rules",
|
|
4146
|
+
cline: ".clinerules",
|
|
4147
|
+
claudecode: ".",
|
|
4148
|
+
codexcli: ".",
|
|
4149
|
+
opencode: ".",
|
|
4150
|
+
qwencode: ".qwen/memories",
|
|
4151
|
+
roo: ".roo/rules",
|
|
4152
|
+
geminicli: ".gemini/memories",
|
|
4153
|
+
kiro: ".kiro/steering",
|
|
4154
|
+
junie: ".",
|
|
4155
|
+
windsurf: "."
|
|
4156
|
+
},
|
|
4157
|
+
watchEnabled: false,
|
|
4158
|
+
defaultTargets: []
|
|
4159
|
+
};
|
|
4160
|
+
const results = await (await Promise.resolve().then(() => (init_amazonqcli(), amazonqcli_exports))).generateAmazonqcliMcp(
|
|
4161
|
+
servers,
|
|
4162
|
+
config,
|
|
4163
|
+
dir
|
|
4164
|
+
);
|
|
4165
|
+
return results.map((result) => ({ filepath: result.filepath, content: result.content }));
|
|
4166
|
+
},
|
|
3694
4167
|
augmentcode: async (servers, dir) => (await Promise.resolve().then(() => (init_augmentcode(), augmentcode_exports))).generateAugmentcodeMcpConfiguration(
|
|
3695
4168
|
servers,
|
|
3696
4169
|
dir
|
|
@@ -3707,6 +4180,10 @@ async function generateMcpConfigurations(mcpConfig, baseDir, targetTools) {
|
|
|
3707
4180
|
cursor: async (servers, dir) => (await Promise.resolve().then(() => (init_cursor(), cursor_exports))).generateCursorMcpConfiguration(servers, dir),
|
|
3708
4181
|
cline: async (servers, dir) => (await Promise.resolve().then(() => (init_cline(), cline_exports))).generateClineMcpConfiguration(servers, dir),
|
|
3709
4182
|
codexcli: async (servers, dir) => (await Promise.resolve().then(() => (init_codexcli(), codexcli_exports))).generateCodexMcpConfiguration(servers, dir),
|
|
4183
|
+
opencode: async (servers, dir) => (await Promise.resolve().then(() => (init_opencode(), opencode_exports))).generateOpenCodeMcpConfiguration(
|
|
4184
|
+
servers,
|
|
4185
|
+
dir
|
|
4186
|
+
),
|
|
3710
4187
|
roo: async (servers, dir) => (await Promise.resolve().then(() => (init_roo(), roo_exports))).generateRooMcpConfiguration(servers, dir),
|
|
3711
4188
|
geminicli: async (servers, dir) => (await Promise.resolve().then(() => (init_geminicli(), geminicli_exports))).generateGeminiCliMcpConfiguration(
|
|
3712
4189
|
servers,
|
|
@@ -3714,6 +4191,10 @@ async function generateMcpConfigurations(mcpConfig, baseDir, targetTools) {
|
|
|
3714
4191
|
),
|
|
3715
4192
|
kiro: async (servers, dir) => (await Promise.resolve().then(() => (init_kiro(), kiro_exports))).generateKiroMcpConfiguration(servers, dir),
|
|
3716
4193
|
junie: async (servers, dir) => (await Promise.resolve().then(() => (init_junie(), junie_exports))).generateJunieMcpConfiguration(servers, dir),
|
|
4194
|
+
qwencode: async (servers, dir) => (await Promise.resolve().then(() => (init_qwencode(), qwencode_exports))).generateQwenCodeMcpConfiguration(
|
|
4195
|
+
servers,
|
|
4196
|
+
dir
|
|
4197
|
+
),
|
|
3717
4198
|
windsurf: async (servers, dir) => (await Promise.resolve().then(() => (init_windsurf(), windsurf_exports))).generateWindsurfMcpConfiguration(
|
|
3718
4199
|
servers,
|
|
3719
4200
|
dir
|
|
@@ -3736,6 +4217,7 @@ async function generateMcpConfigurations(mcpConfig, baseDir, targetTools) {
|
|
|
3736
4217
|
}
|
|
3737
4218
|
|
|
3738
4219
|
// src/cli/commands/generate.ts
|
|
4220
|
+
init_logger();
|
|
3739
4221
|
async function generateCommand(options = {}) {
|
|
3740
4222
|
const configLoaderOptions = {
|
|
3741
4223
|
...options.config !== void 0 && { configPath: options.config },
|
|
@@ -3743,35 +4225,40 @@ async function generateCommand(options = {}) {
|
|
|
3743
4225
|
};
|
|
3744
4226
|
const configResult = await loadConfig(configLoaderOptions);
|
|
3745
4227
|
const cliOptions = {
|
|
3746
|
-
|
|
4228
|
+
tools: options.tools,
|
|
3747
4229
|
...options.verbose !== void 0 && { verbose: options.verbose },
|
|
3748
4230
|
...options.delete !== void 0 && { delete: options.delete },
|
|
3749
4231
|
...options.baseDirs !== void 0 && { baseDirs: options.baseDirs }
|
|
3750
4232
|
};
|
|
3751
4233
|
const config = mergeWithCliOptions(configResult.config, cliOptions);
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
4234
|
+
if (!config.defaultTargets || config.defaultTargets.length === 0) {
|
|
4235
|
+
const errorMessage = `\u274C Error: At least one tool must be specified.
|
|
4236
|
+
|
|
4237
|
+
Available tools:
|
|
4238
|
+
--augmentcode Generate for AugmentCode
|
|
4239
|
+
--augmentcode-legacy Generate for AugmentCode legacy format
|
|
4240
|
+
--copilot Generate for GitHub Copilot
|
|
4241
|
+
--cursor Generate for Cursor
|
|
4242
|
+
--cline Generate for Cline
|
|
4243
|
+
--codexcli Generate for OpenAI Codex CLI
|
|
4244
|
+
--claudecode Generate for Claude Code
|
|
4245
|
+
--roo Generate for Roo Code
|
|
4246
|
+
--geminicli Generate for Gemini CLI
|
|
4247
|
+
--junie Generate for JetBrains Junie
|
|
4248
|
+
--qwencode Generate for Qwen Code
|
|
4249
|
+
--kiro Generate for Kiro IDE
|
|
4250
|
+
--opencode Generate for OpenCode
|
|
4251
|
+
--windsurf Generate for Windsurf
|
|
4252
|
+
|
|
4253
|
+
Example:
|
|
4254
|
+
rulesync generate --copilot --cursor
|
|
4255
|
+
|
|
4256
|
+
Or specify tools in rulesync.jsonc:
|
|
4257
|
+
"tools": ["copilot", "cursor"]`;
|
|
4258
|
+
logger.error(errorMessage);
|
|
4259
|
+
process.exit(1);
|
|
3774
4260
|
}
|
|
4261
|
+
logger.setVerbose(config.verbose || false);
|
|
3775
4262
|
let baseDirs;
|
|
3776
4263
|
if (config.baseDir) {
|
|
3777
4264
|
baseDirs = Array.isArray(config.baseDir) ? config.baseDir : [config.baseDir];
|
|
@@ -3799,7 +4286,7 @@ async function generateCommand(options = {}) {
|
|
|
3799
4286
|
logger.info("Deleting existing output directories...");
|
|
3800
4287
|
const targetTools = config.defaultTargets;
|
|
3801
4288
|
const deleteTasks = [];
|
|
3802
|
-
const commandsDir = (0,
|
|
4289
|
+
const commandsDir = (0, import_node_path14.join)(config.aiRulesDir, "commands");
|
|
3803
4290
|
const hasCommands = await fileExists(commandsDir);
|
|
3804
4291
|
let hasCommandFiles = false;
|
|
3805
4292
|
if (hasCommands) {
|
|
@@ -3814,12 +4301,12 @@ async function generateCommand(options = {}) {
|
|
|
3814
4301
|
for (const tool of targetTools) {
|
|
3815
4302
|
switch (tool) {
|
|
3816
4303
|
case "augmentcode":
|
|
3817
|
-
deleteTasks.push(removeDirectory((0,
|
|
3818
|
-
deleteTasks.push(removeDirectory((0,
|
|
4304
|
+
deleteTasks.push(removeDirectory((0, import_node_path14.join)(".augment", "rules")));
|
|
4305
|
+
deleteTasks.push(removeDirectory((0, import_node_path14.join)(".augment", "ignore")));
|
|
3819
4306
|
break;
|
|
3820
4307
|
case "augmentcode-legacy":
|
|
3821
4308
|
deleteTasks.push(removeClaudeGeneratedFiles());
|
|
3822
|
-
deleteTasks.push(removeDirectory((0,
|
|
4309
|
+
deleteTasks.push(removeDirectory((0, import_node_path14.join)(".augment", "ignore")));
|
|
3823
4310
|
break;
|
|
3824
4311
|
case "copilot":
|
|
3825
4312
|
deleteTasks.push(removeDirectory(config.outputPaths.copilot));
|
|
@@ -3833,24 +4320,30 @@ async function generateCommand(options = {}) {
|
|
|
3833
4320
|
case "claudecode":
|
|
3834
4321
|
deleteTasks.push(removeClaudeGeneratedFiles());
|
|
3835
4322
|
if (hasCommandFiles) {
|
|
3836
|
-
deleteTasks.push(removeDirectory((0,
|
|
4323
|
+
deleteTasks.push(removeDirectory((0, import_node_path14.join)(".claude", "commands")));
|
|
3837
4324
|
}
|
|
3838
4325
|
break;
|
|
3839
4326
|
case "roo":
|
|
3840
4327
|
deleteTasks.push(removeDirectory(config.outputPaths.roo));
|
|
3841
4328
|
if (hasCommandFiles) {
|
|
3842
|
-
deleteTasks.push(removeDirectory((0,
|
|
4329
|
+
deleteTasks.push(removeDirectory((0, import_node_path14.join)(".roo", "commands")));
|
|
3843
4330
|
}
|
|
3844
4331
|
break;
|
|
3845
4332
|
case "geminicli":
|
|
3846
4333
|
deleteTasks.push(removeDirectory(config.outputPaths.geminicli));
|
|
3847
4334
|
if (hasCommandFiles) {
|
|
3848
|
-
deleteTasks.push(removeDirectory((0,
|
|
4335
|
+
deleteTasks.push(removeDirectory((0, import_node_path14.join)(".gemini", "commands")));
|
|
3849
4336
|
}
|
|
3850
4337
|
break;
|
|
3851
4338
|
case "kiro":
|
|
3852
4339
|
deleteTasks.push(removeDirectory(config.outputPaths.kiro));
|
|
3853
4340
|
break;
|
|
4341
|
+
case "opencode":
|
|
4342
|
+
deleteTasks.push(removeDirectory(config.outputPaths.opencode));
|
|
4343
|
+
break;
|
|
4344
|
+
case "qwencode":
|
|
4345
|
+
deleteTasks.push(removeDirectory(config.outputPaths.qwencode));
|
|
4346
|
+
break;
|
|
3854
4347
|
case "windsurf":
|
|
3855
4348
|
deleteTasks.push(removeDirectory(config.outputPaths.windsurf));
|
|
3856
4349
|
break;
|
|
@@ -3944,11 +4437,14 @@ Generating configurations for base directory: ${baseDir}`);
|
|
|
3944
4437
|
|
|
3945
4438
|
// src/cli/commands/gitignore.ts
|
|
3946
4439
|
var import_node_fs2 = require("fs");
|
|
3947
|
-
var
|
|
4440
|
+
var import_node_path15 = require("path");
|
|
4441
|
+
init_logger();
|
|
3948
4442
|
var gitignoreCommand = async () => {
|
|
3949
|
-
const gitignorePath = (0,
|
|
4443
|
+
const gitignorePath = (0, import_node_path15.join)(process.cwd(), ".gitignore");
|
|
3950
4444
|
const rulesFilesToIgnore = [
|
|
3951
4445
|
"# Generated by rulesync - AI tool configuration files",
|
|
4446
|
+
"**/.amazonq/rules/",
|
|
4447
|
+
"**/.amazonq/mcp.json",
|
|
3952
4448
|
"**/.github/copilot-instructions.md",
|
|
3953
4449
|
"**/.github/instructions/",
|
|
3954
4450
|
"**/.cursor/rules/",
|
|
@@ -3966,6 +4462,8 @@ var gitignoreCommand = async () => {
|
|
|
3966
4462
|
"**/GEMINI.md",
|
|
3967
4463
|
"**/.gemini/memories/",
|
|
3968
4464
|
"**/.gemini/commands/",
|
|
4465
|
+
"**/QWEN.md",
|
|
4466
|
+
"**/.qwen/memories/",
|
|
3969
4467
|
"**/.aiexclude",
|
|
3970
4468
|
"**/.aiignore",
|
|
3971
4469
|
"**/.augmentignore",
|
|
@@ -3974,6 +4472,9 @@ var gitignoreCommand = async () => {
|
|
|
3974
4472
|
"**/.augment-guidelines",
|
|
3975
4473
|
"**/.junie/guidelines.md",
|
|
3976
4474
|
"**/.noai",
|
|
4475
|
+
"**/.opencode/memories/",
|
|
4476
|
+
"**/.opencode/commands/",
|
|
4477
|
+
"**/opencode.json",
|
|
3977
4478
|
"**/.mcp.json",
|
|
3978
4479
|
"!.rulesync/.mcp.json",
|
|
3979
4480
|
"**/.cursor/mcp.json",
|
|
@@ -3981,193 +4482,44 @@ var gitignoreCommand = async () => {
|
|
|
3981
4482
|
"**/.vscode/mcp.json",
|
|
3982
4483
|
"**/.codex/mcp-config.json",
|
|
3983
4484
|
"**/.gemini/settings.json",
|
|
4485
|
+
"**/.qwen/settings.json",
|
|
3984
4486
|
"**/.roo/mcp.json"
|
|
3985
4487
|
];
|
|
3986
4488
|
let gitignoreContent = "";
|
|
3987
|
-
if ((0, import_node_fs2.existsSync)(gitignorePath)) {
|
|
3988
|
-
gitignoreContent = (0, import_node_fs2.readFileSync)(gitignorePath, "utf-8");
|
|
3989
|
-
}
|
|
3990
|
-
const linesToAdd = [];
|
|
3991
|
-
for (const rule of rulesFilesToIgnore) {
|
|
3992
|
-
if (!gitignoreContent.includes(rule)) {
|
|
3993
|
-
linesToAdd.push(rule);
|
|
3994
|
-
}
|
|
3995
|
-
}
|
|
3996
|
-
if (linesToAdd.length === 0) {
|
|
3997
|
-
logger.success(".gitignore is already up to date");
|
|
3998
|
-
return;
|
|
3999
|
-
}
|
|
4000
|
-
const newContent = gitignoreContent ? `${gitignoreContent.trimEnd()}
|
|
4001
|
-
|
|
4002
|
-
${linesToAdd.join("\n")}
|
|
4003
|
-
` : `${linesToAdd.join("\n")}
|
|
4004
|
-
`;
|
|
4005
|
-
(0, import_node_fs2.writeFileSync)(gitignorePath, newContent);
|
|
4006
|
-
logger.success(`Added ${linesToAdd.length} rules to .gitignore:`);
|
|
4007
|
-
for (const line of linesToAdd) {
|
|
4008
|
-
if (!line.startsWith("#")) {
|
|
4009
|
-
logger.log(` ${line}`);
|
|
4010
|
-
}
|
|
4011
|
-
}
|
|
4012
|
-
};
|
|
4013
|
-
|
|
4014
|
-
// src/core/importer.ts
|
|
4015
|
-
var import_node_path21 = require("path");
|
|
4016
|
-
var import_gray_matter2 = __toESM(require("gray-matter"), 1);
|
|
4017
|
-
|
|
4018
|
-
// src/parsers/augmentcode.ts
|
|
4019
|
-
var import_node_path15 = require("path");
|
|
4020
|
-
|
|
4021
|
-
// src/utils/parser-helpers.ts
|
|
4022
|
-
function createParseResult() {
|
|
4023
|
-
return { rules: [], errors: [] };
|
|
4024
|
-
}
|
|
4025
|
-
function addError(result, error) {
|
|
4026
|
-
result.errors.push(error);
|
|
4027
|
-
}
|
|
4028
|
-
function addRule(result, rule) {
|
|
4029
|
-
if (!result.rules) {
|
|
4030
|
-
result.rules = [];
|
|
4031
|
-
}
|
|
4032
|
-
result.rules.push(rule);
|
|
4033
|
-
}
|
|
4034
|
-
function addRules(result, rules) {
|
|
4035
|
-
if (!result.rules) {
|
|
4036
|
-
result.rules = [];
|
|
4037
|
-
}
|
|
4038
|
-
result.rules.push(...rules);
|
|
4039
|
-
}
|
|
4040
|
-
async function safeReadFile(operation, errorContext) {
|
|
4041
|
-
try {
|
|
4042
|
-
const result = await operation();
|
|
4043
|
-
return createSuccessResult(result);
|
|
4044
|
-
} catch (error) {
|
|
4045
|
-
return createErrorResult(error, errorContext);
|
|
4046
|
-
}
|
|
4047
|
-
}
|
|
4048
|
-
|
|
4049
|
-
// src/parsers/augmentcode.ts
|
|
4050
|
-
async function parseAugmentcodeConfiguration(baseDir = process.cwd()) {
|
|
4051
|
-
return parseUnifiedAugmentcode(baseDir, {
|
|
4052
|
-
rulesDir: ".augment/rules",
|
|
4053
|
-
targetName: "augmentcode",
|
|
4054
|
-
filenamePrefix: "augmentcode"
|
|
4055
|
-
});
|
|
4056
|
-
}
|
|
4057
|
-
async function parseAugmentcodeLegacyConfiguration(baseDir = process.cwd()) {
|
|
4058
|
-
return parseUnifiedAugmentcode(baseDir, {
|
|
4059
|
-
legacyFilePath: ".augment-guidelines",
|
|
4060
|
-
targetName: "augmentcode-legacy",
|
|
4061
|
-
filenamePrefix: "augmentcode-legacy"
|
|
4062
|
-
});
|
|
4063
|
-
}
|
|
4064
|
-
async function parseUnifiedAugmentcode(baseDir, config) {
|
|
4065
|
-
const result = createParseResult();
|
|
4066
|
-
if (config.rulesDir) {
|
|
4067
|
-
const rulesDir = (0, import_node_path15.join)(baseDir, config.rulesDir);
|
|
4068
|
-
if (await fileExists(rulesDir)) {
|
|
4069
|
-
const rulesResult = await parseAugmentRules(rulesDir, config);
|
|
4070
|
-
addRules(result, rulesResult.rules);
|
|
4071
|
-
result.errors.push(...rulesResult.errors);
|
|
4072
|
-
} else {
|
|
4073
|
-
addError(
|
|
4074
|
-
result,
|
|
4075
|
-
`No AugmentCode configuration found. Expected ${config.rulesDir} directory.`
|
|
4076
|
-
);
|
|
4077
|
-
}
|
|
4078
|
-
}
|
|
4079
|
-
if (config.legacyFilePath) {
|
|
4080
|
-
const legacyPath = (0, import_node_path15.join)(baseDir, config.legacyFilePath);
|
|
4081
|
-
if (await fileExists(legacyPath)) {
|
|
4082
|
-
const legacyResult = await parseAugmentGuidelines(legacyPath, config);
|
|
4083
|
-
if (legacyResult.rule) {
|
|
4084
|
-
addRule(result, legacyResult.rule);
|
|
4085
|
-
}
|
|
4086
|
-
result.errors.push(...legacyResult.errors);
|
|
4087
|
-
} else {
|
|
4088
|
-
addError(
|
|
4089
|
-
result,
|
|
4090
|
-
`No AugmentCode legacy configuration found. Expected ${config.legacyFilePath} file.`
|
|
4091
|
-
);
|
|
4092
|
-
}
|
|
4093
|
-
}
|
|
4094
|
-
return { rules: result.rules || [], errors: result.errors };
|
|
4095
|
-
}
|
|
4096
|
-
async function parseAugmentRules(rulesDir, config) {
|
|
4097
|
-
const rules = [];
|
|
4098
|
-
const errors = [];
|
|
4099
|
-
try {
|
|
4100
|
-
const { readdir: readdir2 } = await import("fs/promises");
|
|
4101
|
-
const files = await readdir2(rulesDir);
|
|
4102
|
-
for (const file of files) {
|
|
4103
|
-
if (file.endsWith(".md") || file.endsWith(".mdc")) {
|
|
4104
|
-
const filePath = (0, import_node_path15.join)(rulesDir, file);
|
|
4105
|
-
try {
|
|
4106
|
-
const rawContent = await readFileContent(filePath);
|
|
4107
|
-
const parsed = parseFrontmatter(rawContent);
|
|
4108
|
-
const ruleType = extractStringField(parsed.data, "type", "manual");
|
|
4109
|
-
const description = extractStringField(parsed.data, "description", "");
|
|
4110
|
-
const tags = extractArrayField(parsed.data, "tags");
|
|
4111
|
-
const isRoot = ruleType === "always";
|
|
4112
|
-
const filename = (0, import_node_path15.basename)(file, file.endsWith(".mdc") ? ".mdc" : ".md");
|
|
4113
|
-
const frontmatter = {
|
|
4114
|
-
root: isRoot,
|
|
4115
|
-
targets: [config.targetName],
|
|
4116
|
-
description,
|
|
4117
|
-
globs: ["**/*"],
|
|
4118
|
-
// AugmentCode doesn't use specific globs in the same way
|
|
4119
|
-
...tags.length > 0 && { tags }
|
|
4120
|
-
};
|
|
4121
|
-
rules.push({
|
|
4122
|
-
frontmatter,
|
|
4123
|
-
content: parsed.content.trim(),
|
|
4124
|
-
filename: `${config.filenamePrefix}-${ruleType}-${filename}`,
|
|
4125
|
-
filepath: filePath
|
|
4126
|
-
});
|
|
4127
|
-
} catch (error) {
|
|
4128
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
4129
|
-
errors.push(`Failed to parse ${filePath}: ${errorMessage}`);
|
|
4130
|
-
}
|
|
4131
|
-
}
|
|
4489
|
+
if ((0, import_node_fs2.existsSync)(gitignorePath)) {
|
|
4490
|
+
gitignoreContent = (0, import_node_fs2.readFileSync)(gitignorePath, "utf-8");
|
|
4491
|
+
}
|
|
4492
|
+
const linesToAdd = [];
|
|
4493
|
+
for (const rule of rulesFilesToIgnore) {
|
|
4494
|
+
if (!gitignoreContent.includes(rule)) {
|
|
4495
|
+
linesToAdd.push(rule);
|
|
4132
4496
|
}
|
|
4133
|
-
} catch (error) {
|
|
4134
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
4135
|
-
errors.push(`Failed to read ${config.rulesDir || rulesDir} directory: ${errorMessage}`);
|
|
4136
4497
|
}
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
const parseResult = await safeReadFile(
|
|
4141
|
-
async () => {
|
|
4142
|
-
const content = await readFileContent(guidelinesPath);
|
|
4143
|
-
if (content.trim()) {
|
|
4144
|
-
const frontmatter = {
|
|
4145
|
-
root: true,
|
|
4146
|
-
// Legacy guidelines become root rules
|
|
4147
|
-
targets: [config.targetName],
|
|
4148
|
-
description: "Legacy AugmentCode guidelines",
|
|
4149
|
-
globs: ["**/*"]
|
|
4150
|
-
};
|
|
4151
|
-
return {
|
|
4152
|
-
frontmatter,
|
|
4153
|
-
content: content.trim(),
|
|
4154
|
-
filename: `${config.filenamePrefix}-guidelines`,
|
|
4155
|
-
filepath: guidelinesPath
|
|
4156
|
-
};
|
|
4157
|
-
}
|
|
4158
|
-
return null;
|
|
4159
|
-
},
|
|
4160
|
-
`Failed to parse ${config.legacyFilePath || guidelinesPath}`
|
|
4161
|
-
);
|
|
4162
|
-
if (parseResult.success) {
|
|
4163
|
-
return { rule: parseResult.result || null, errors: [] };
|
|
4164
|
-
} else {
|
|
4165
|
-
return { rule: null, errors: [parseResult.error || "Unknown error"] };
|
|
4498
|
+
if (linesToAdd.length === 0) {
|
|
4499
|
+
logger.success(".gitignore is already up to date");
|
|
4500
|
+
return;
|
|
4166
4501
|
}
|
|
4167
|
-
}
|
|
4502
|
+
const newContent = gitignoreContent ? `${gitignoreContent.trimEnd()}
|
|
4503
|
+
|
|
4504
|
+
${linesToAdd.join("\n")}
|
|
4505
|
+
` : `${linesToAdd.join("\n")}
|
|
4506
|
+
`;
|
|
4507
|
+
(0, import_node_fs2.writeFileSync)(gitignorePath, newContent);
|
|
4508
|
+
logger.success(`Added ${linesToAdd.length} rules to .gitignore:`);
|
|
4509
|
+
for (const line of linesToAdd) {
|
|
4510
|
+
if (!line.startsWith("#")) {
|
|
4511
|
+
logger.log(` ${line}`);
|
|
4512
|
+
}
|
|
4513
|
+
}
|
|
4514
|
+
};
|
|
4515
|
+
|
|
4516
|
+
// src/core/importer.ts
|
|
4517
|
+
var import_node_path22 = require("path");
|
|
4518
|
+
var import_gray_matter2 = __toESM(require("gray-matter"), 1);
|
|
4168
4519
|
|
|
4169
4520
|
// src/parsers/shared-helpers.ts
|
|
4170
4521
|
var import_node_path16 = require("path");
|
|
4522
|
+
init_file();
|
|
4171
4523
|
async function parseConfigurationFiles(baseDir = process.cwd(), config) {
|
|
4172
4524
|
const errors = [];
|
|
4173
4525
|
const rules = [];
|
|
@@ -4483,6 +4835,170 @@ async function parseSettingsFile(settingsPath, tool) {
|
|
|
4483
4835
|
};
|
|
4484
4836
|
}
|
|
4485
4837
|
|
|
4838
|
+
// src/parsers/amazonqcli.ts
|
|
4839
|
+
async function parseAmazonqcliConfiguration(baseDir = process.cwd()) {
|
|
4840
|
+
return parseMemoryBasedConfiguration(baseDir, {
|
|
4841
|
+
tool: "amazonqcli",
|
|
4842
|
+
mainFileName: ".amazonq/rules/main.md",
|
|
4843
|
+
memoryDirPath: ".amazonq/rules",
|
|
4844
|
+
settingsPath: ".amazonq/mcp.json",
|
|
4845
|
+
mainDescription: "Main Amazon Q Developer CLI configuration",
|
|
4846
|
+
memoryDescription: "Amazon Q rule",
|
|
4847
|
+
filenamePrefix: "amazonq"
|
|
4848
|
+
});
|
|
4849
|
+
}
|
|
4850
|
+
|
|
4851
|
+
// src/parsers/augmentcode.ts
|
|
4852
|
+
var import_node_path17 = require("path");
|
|
4853
|
+
|
|
4854
|
+
// src/utils/parser-helpers.ts
|
|
4855
|
+
function createParseResult() {
|
|
4856
|
+
return { rules: [], errors: [] };
|
|
4857
|
+
}
|
|
4858
|
+
function addError(result, error) {
|
|
4859
|
+
result.errors.push(error);
|
|
4860
|
+
}
|
|
4861
|
+
function addRule(result, rule) {
|
|
4862
|
+
if (!result.rules) {
|
|
4863
|
+
result.rules = [];
|
|
4864
|
+
}
|
|
4865
|
+
result.rules.push(rule);
|
|
4866
|
+
}
|
|
4867
|
+
function addRules(result, rules) {
|
|
4868
|
+
if (!result.rules) {
|
|
4869
|
+
result.rules = [];
|
|
4870
|
+
}
|
|
4871
|
+
result.rules.push(...rules);
|
|
4872
|
+
}
|
|
4873
|
+
async function safeReadFile(operation, errorContext) {
|
|
4874
|
+
try {
|
|
4875
|
+
const result = await operation();
|
|
4876
|
+
return createSuccessResult(result);
|
|
4877
|
+
} catch (error) {
|
|
4878
|
+
return createErrorResult(error, errorContext);
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
|
|
4882
|
+
// src/parsers/augmentcode.ts
|
|
4883
|
+
async function parseAugmentcodeConfiguration(baseDir = process.cwd()) {
|
|
4884
|
+
return parseUnifiedAugmentcode(baseDir, {
|
|
4885
|
+
rulesDir: ".augment/rules",
|
|
4886
|
+
targetName: "augmentcode",
|
|
4887
|
+
filenamePrefix: "augmentcode"
|
|
4888
|
+
});
|
|
4889
|
+
}
|
|
4890
|
+
async function parseAugmentcodeLegacyConfiguration(baseDir = process.cwd()) {
|
|
4891
|
+
return parseUnifiedAugmentcode(baseDir, {
|
|
4892
|
+
legacyFilePath: ".augment-guidelines",
|
|
4893
|
+
targetName: "augmentcode-legacy",
|
|
4894
|
+
filenamePrefix: "augmentcode-legacy"
|
|
4895
|
+
});
|
|
4896
|
+
}
|
|
4897
|
+
async function parseUnifiedAugmentcode(baseDir, config) {
|
|
4898
|
+
const result = createParseResult();
|
|
4899
|
+
if (config.rulesDir) {
|
|
4900
|
+
const rulesDir = (0, import_node_path17.join)(baseDir, config.rulesDir);
|
|
4901
|
+
if (await fileExists(rulesDir)) {
|
|
4902
|
+
const rulesResult = await parseAugmentRules(rulesDir, config);
|
|
4903
|
+
addRules(result, rulesResult.rules);
|
|
4904
|
+
result.errors.push(...rulesResult.errors);
|
|
4905
|
+
} else {
|
|
4906
|
+
addError(
|
|
4907
|
+
result,
|
|
4908
|
+
`No AugmentCode configuration found. Expected ${config.rulesDir} directory.`
|
|
4909
|
+
);
|
|
4910
|
+
}
|
|
4911
|
+
}
|
|
4912
|
+
if (config.legacyFilePath) {
|
|
4913
|
+
const legacyPath = (0, import_node_path17.join)(baseDir, config.legacyFilePath);
|
|
4914
|
+
if (await fileExists(legacyPath)) {
|
|
4915
|
+
const legacyResult = await parseAugmentGuidelines(legacyPath, config);
|
|
4916
|
+
if (legacyResult.rule) {
|
|
4917
|
+
addRule(result, legacyResult.rule);
|
|
4918
|
+
}
|
|
4919
|
+
result.errors.push(...legacyResult.errors);
|
|
4920
|
+
} else {
|
|
4921
|
+
addError(
|
|
4922
|
+
result,
|
|
4923
|
+
`No AugmentCode legacy configuration found. Expected ${config.legacyFilePath} file.`
|
|
4924
|
+
);
|
|
4925
|
+
}
|
|
4926
|
+
}
|
|
4927
|
+
return { rules: result.rules || [], errors: result.errors };
|
|
4928
|
+
}
|
|
4929
|
+
async function parseAugmentRules(rulesDir, config) {
|
|
4930
|
+
const rules = [];
|
|
4931
|
+
const errors = [];
|
|
4932
|
+
try {
|
|
4933
|
+
const { readdir: readdir2 } = await import("fs/promises");
|
|
4934
|
+
const files = await readdir2(rulesDir);
|
|
4935
|
+
for (const file of files) {
|
|
4936
|
+
if (file.endsWith(".md") || file.endsWith(".mdc")) {
|
|
4937
|
+
const filePath = (0, import_node_path17.join)(rulesDir, file);
|
|
4938
|
+
try {
|
|
4939
|
+
const rawContent = await readFileContent(filePath);
|
|
4940
|
+
const parsed = parseFrontmatter(rawContent);
|
|
4941
|
+
const ruleType = extractStringField(parsed.data, "type", "manual");
|
|
4942
|
+
const description = extractStringField(parsed.data, "description", "");
|
|
4943
|
+
const tags = extractArrayField(parsed.data, "tags");
|
|
4944
|
+
const isRoot = ruleType === "always";
|
|
4945
|
+
const filename = (0, import_node_path17.basename)(file, file.endsWith(".mdc") ? ".mdc" : ".md");
|
|
4946
|
+
const frontmatter = {
|
|
4947
|
+
root: isRoot,
|
|
4948
|
+
targets: [config.targetName],
|
|
4949
|
+
description,
|
|
4950
|
+
globs: ["**/*"],
|
|
4951
|
+
// AugmentCode doesn't use specific globs in the same way
|
|
4952
|
+
...tags.length > 0 && { tags }
|
|
4953
|
+
};
|
|
4954
|
+
rules.push({
|
|
4955
|
+
frontmatter,
|
|
4956
|
+
content: parsed.content.trim(),
|
|
4957
|
+
filename: `${config.filenamePrefix}-${ruleType}-${filename}`,
|
|
4958
|
+
filepath: filePath
|
|
4959
|
+
});
|
|
4960
|
+
} catch (error) {
|
|
4961
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
4962
|
+
errors.push(`Failed to parse ${filePath}: ${errorMessage}`);
|
|
4963
|
+
}
|
|
4964
|
+
}
|
|
4965
|
+
}
|
|
4966
|
+
} catch (error) {
|
|
4967
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
4968
|
+
errors.push(`Failed to read ${config.rulesDir || rulesDir} directory: ${errorMessage}`);
|
|
4969
|
+
}
|
|
4970
|
+
return { rules, errors };
|
|
4971
|
+
}
|
|
4972
|
+
async function parseAugmentGuidelines(guidelinesPath, config) {
|
|
4973
|
+
const parseResult = await safeReadFile(
|
|
4974
|
+
async () => {
|
|
4975
|
+
const content = await readFileContent(guidelinesPath);
|
|
4976
|
+
if (content.trim()) {
|
|
4977
|
+
const frontmatter = {
|
|
4978
|
+
root: true,
|
|
4979
|
+
// Legacy guidelines become root rules
|
|
4980
|
+
targets: [config.targetName],
|
|
4981
|
+
description: "Legacy AugmentCode guidelines",
|
|
4982
|
+
globs: ["**/*"]
|
|
4983
|
+
};
|
|
4984
|
+
return {
|
|
4985
|
+
frontmatter,
|
|
4986
|
+
content: content.trim(),
|
|
4987
|
+
filename: `${config.filenamePrefix}-guidelines`,
|
|
4988
|
+
filepath: guidelinesPath
|
|
4989
|
+
};
|
|
4990
|
+
}
|
|
4991
|
+
return null;
|
|
4992
|
+
},
|
|
4993
|
+
`Failed to parse ${config.legacyFilePath || guidelinesPath}`
|
|
4994
|
+
);
|
|
4995
|
+
if (parseResult.success) {
|
|
4996
|
+
return { rule: parseResult.result || null, errors: [] };
|
|
4997
|
+
} else {
|
|
4998
|
+
return { rule: null, errors: [parseResult.error || "Unknown error"] };
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
5001
|
+
|
|
4486
5002
|
// src/parsers/claudecode.ts
|
|
4487
5003
|
async function parseClaudeConfiguration(baseDir = process.cwd()) {
|
|
4488
5004
|
return parseMemoryBasedConfiguration(baseDir, {
|
|
@@ -4518,7 +5034,7 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
|
|
|
4518
5034
|
}
|
|
4519
5035
|
|
|
4520
5036
|
// src/parsers/codexcli.ts
|
|
4521
|
-
var
|
|
5037
|
+
var import_node_path18 = require("path");
|
|
4522
5038
|
|
|
4523
5039
|
// src/parsers/copilot.ts
|
|
4524
5040
|
async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
@@ -4541,7 +5057,7 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
|
4541
5057
|
}
|
|
4542
5058
|
|
|
4543
5059
|
// src/parsers/cursor.ts
|
|
4544
|
-
var
|
|
5060
|
+
var import_node_path19 = require("path");
|
|
4545
5061
|
var import_js_yaml = require("js-yaml");
|
|
4546
5062
|
var import_mini8 = require("zod/mini");
|
|
4547
5063
|
var customMatterOptions = {
|
|
@@ -4665,7 +5181,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
4665
5181
|
const rules = [];
|
|
4666
5182
|
let ignorePatterns;
|
|
4667
5183
|
let mcpServers;
|
|
4668
|
-
const cursorFilePath = (0,
|
|
5184
|
+
const cursorFilePath = (0, import_node_path19.join)(baseDir, ".cursorrules");
|
|
4669
5185
|
if (await fileExists(cursorFilePath)) {
|
|
4670
5186
|
try {
|
|
4671
5187
|
const rawContent = await readFileContent(cursorFilePath);
|
|
@@ -4686,20 +5202,20 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
4686
5202
|
errors.push(`Failed to parse .cursorrules file: ${errorMessage}`);
|
|
4687
5203
|
}
|
|
4688
5204
|
}
|
|
4689
|
-
const cursorRulesDir = (0,
|
|
5205
|
+
const cursorRulesDir = (0, import_node_path19.join)(baseDir, ".cursor", "rules");
|
|
4690
5206
|
if (await fileExists(cursorRulesDir)) {
|
|
4691
5207
|
try {
|
|
4692
5208
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
4693
5209
|
const files = await readdir2(cursorRulesDir);
|
|
4694
5210
|
for (const file of files) {
|
|
4695
5211
|
if (file.endsWith(".mdc")) {
|
|
4696
|
-
const filePath = (0,
|
|
5212
|
+
const filePath = (0, import_node_path19.join)(cursorRulesDir, file);
|
|
4697
5213
|
try {
|
|
4698
5214
|
const rawContent = await readFileContent(filePath);
|
|
4699
5215
|
const parsed = parseFrontmatter(rawContent, { matterOptions: customMatterOptions });
|
|
4700
5216
|
const content = parsed.content;
|
|
4701
5217
|
if (content) {
|
|
4702
|
-
const filename = (0,
|
|
5218
|
+
const filename = (0, import_node_path19.basename)(file, ".mdc");
|
|
4703
5219
|
const frontmatter = convertCursorMdcFrontmatter(parsed.data, filename);
|
|
4704
5220
|
rules.push({
|
|
4705
5221
|
frontmatter,
|
|
@@ -4722,7 +5238,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
4722
5238
|
if (rules.length === 0) {
|
|
4723
5239
|
errors.push("No Cursor configuration files found (.cursorrules or .cursor/rules/*.mdc)");
|
|
4724
5240
|
}
|
|
4725
|
-
const cursorIgnorePath = (0,
|
|
5241
|
+
const cursorIgnorePath = (0, import_node_path19.join)(baseDir, ".cursorignore");
|
|
4726
5242
|
if (await fileExists(cursorIgnorePath)) {
|
|
4727
5243
|
try {
|
|
4728
5244
|
const content = await readFileContent(cursorIgnorePath);
|
|
@@ -4735,7 +5251,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
4735
5251
|
errors.push(`Failed to parse .cursorignore: ${errorMessage}`);
|
|
4736
5252
|
}
|
|
4737
5253
|
}
|
|
4738
|
-
const cursorMcpPath = (0,
|
|
5254
|
+
const cursorMcpPath = (0, import_node_path19.join)(baseDir, ".cursor", "mcp.json");
|
|
4739
5255
|
if (await fileExists(cursorMcpPath)) {
|
|
4740
5256
|
try {
|
|
4741
5257
|
const content = await readFileContent(cursorMcpPath);
|
|
@@ -4785,11 +5301,11 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
|
|
|
4785
5301
|
}
|
|
4786
5302
|
|
|
4787
5303
|
// src/parsers/junie.ts
|
|
4788
|
-
var
|
|
5304
|
+
var import_node_path20 = require("path");
|
|
4789
5305
|
async function parseJunieConfiguration(baseDir = process.cwd()) {
|
|
4790
5306
|
const errors = [];
|
|
4791
5307
|
const rules = [];
|
|
4792
|
-
const guidelinesPath = (0,
|
|
5308
|
+
const guidelinesPath = (0, import_node_path20.join)(baseDir, ".junie", "guidelines.md");
|
|
4793
5309
|
if (!await fileExists(guidelinesPath)) {
|
|
4794
5310
|
errors.push(".junie/guidelines.md file not found");
|
|
4795
5311
|
return { rules, errors };
|
|
@@ -4820,6 +5336,48 @@ async function parseJunieConfiguration(baseDir = process.cwd()) {
|
|
|
4820
5336
|
return { rules, errors };
|
|
4821
5337
|
}
|
|
4822
5338
|
|
|
5339
|
+
// src/parsers/opencode.ts
|
|
5340
|
+
async function parseOpCodeIgnore(opcodeignorePath) {
|
|
5341
|
+
try {
|
|
5342
|
+
const content = await readFileContent(opcodeignorePath);
|
|
5343
|
+
const patterns = content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
5344
|
+
return patterns;
|
|
5345
|
+
} catch {
|
|
5346
|
+
return [];
|
|
5347
|
+
}
|
|
5348
|
+
}
|
|
5349
|
+
async function parseOpenCodeConfiguration(baseDir = process.cwd()) {
|
|
5350
|
+
return parseMemoryBasedConfiguration(baseDir, {
|
|
5351
|
+
tool: "opencode",
|
|
5352
|
+
mainFileName: "AGENTS.md",
|
|
5353
|
+
memoryDirPath: ".opencode/memories",
|
|
5354
|
+
settingsPath: "opencode.json",
|
|
5355
|
+
mainDescription: "Main OpenCode configuration",
|
|
5356
|
+
memoryDescription: "Memory file",
|
|
5357
|
+
filenamePrefix: "opencode",
|
|
5358
|
+
additionalIgnoreFile: {
|
|
5359
|
+
path: ".opcodeignore",
|
|
5360
|
+
parser: parseOpCodeIgnore
|
|
5361
|
+
}
|
|
5362
|
+
});
|
|
5363
|
+
}
|
|
5364
|
+
|
|
5365
|
+
// src/parsers/qwencode.ts
|
|
5366
|
+
async function parseQwenConfiguration(baseDir = process.cwd()) {
|
|
5367
|
+
return parseMemoryBasedConfiguration(baseDir, {
|
|
5368
|
+
tool: "qwencode",
|
|
5369
|
+
mainFileName: "QWEN.md",
|
|
5370
|
+
memoryDirPath: ".qwen/memories",
|
|
5371
|
+
settingsPath: ".qwen/settings.json",
|
|
5372
|
+
mainDescription: "Main Qwen Code configuration",
|
|
5373
|
+
memoryDescription: "Memory file",
|
|
5374
|
+
filenamePrefix: "qwen",
|
|
5375
|
+
// Qwen Code uses git-aware filtering instead of dedicated ignore files
|
|
5376
|
+
// additionalIgnoreFile is omitted
|
|
5377
|
+
commandsDirPath: ".qwen/commands"
|
|
5378
|
+
});
|
|
5379
|
+
}
|
|
5380
|
+
|
|
4823
5381
|
// src/parsers/roo.ts
|
|
4824
5382
|
async function parseRooConfiguration(baseDir = process.cwd()) {
|
|
4825
5383
|
return parseConfigurationFiles(baseDir, {
|
|
@@ -4842,9 +5400,11 @@ async function parseRooConfiguration(baseDir = process.cwd()) {
|
|
|
4842
5400
|
|
|
4843
5401
|
// src/parsers/windsurf.ts
|
|
4844
5402
|
var import_promises3 = require("fs/promises");
|
|
4845
|
-
var
|
|
5403
|
+
var import_node_path21 = require("path");
|
|
5404
|
+
init_logger();
|
|
4846
5405
|
|
|
4847
5406
|
// src/core/importer.ts
|
|
5407
|
+
init_logger();
|
|
4848
5408
|
async function importConfiguration(options) {
|
|
4849
5409
|
const {
|
|
4850
5410
|
tool,
|
|
@@ -4862,6 +5422,13 @@ async function importConfiguration(options) {
|
|
|
4862
5422
|
}
|
|
4863
5423
|
try {
|
|
4864
5424
|
switch (tool) {
|
|
5425
|
+
case "amazonqcli": {
|
|
5426
|
+
const amazonqResult = await parseAmazonqcliConfiguration(baseDir);
|
|
5427
|
+
rules = amazonqResult.rules;
|
|
5428
|
+
errors.push(...amazonqResult.errors);
|
|
5429
|
+
mcpServers = amazonqResult.mcpServers;
|
|
5430
|
+
break;
|
|
5431
|
+
}
|
|
4865
5432
|
case "augmentcode": {
|
|
4866
5433
|
const augmentResult = await parseAugmentcodeConfiguration(baseDir);
|
|
4867
5434
|
rules = augmentResult.rules;
|
|
@@ -4922,6 +5489,21 @@ async function importConfiguration(options) {
|
|
|
4922
5489
|
errors.push(...junieResult.errors);
|
|
4923
5490
|
break;
|
|
4924
5491
|
}
|
|
5492
|
+
case "opencode": {
|
|
5493
|
+
const opencodeResult = await parseOpenCodeConfiguration(baseDir);
|
|
5494
|
+
rules = opencodeResult.rules;
|
|
5495
|
+
errors.push(...opencodeResult.errors);
|
|
5496
|
+
ignorePatterns = opencodeResult.ignorePatterns;
|
|
5497
|
+
mcpServers = opencodeResult.mcpServers;
|
|
5498
|
+
break;
|
|
5499
|
+
}
|
|
5500
|
+
case "qwencode": {
|
|
5501
|
+
const qwenResult = await parseQwenConfiguration(baseDir);
|
|
5502
|
+
rules = qwenResult.rules;
|
|
5503
|
+
errors.push(...qwenResult.errors);
|
|
5504
|
+
mcpServers = qwenResult.mcpServers;
|
|
5505
|
+
break;
|
|
5506
|
+
}
|
|
4925
5507
|
default:
|
|
4926
5508
|
errors.push(`Unsupported tool: ${tool}`);
|
|
4927
5509
|
return { success: false, rulesCreated: 0, errors };
|
|
@@ -4934,7 +5516,7 @@ async function importConfiguration(options) {
|
|
|
4934
5516
|
if (rules.length === 0 && !ignorePatterns && !mcpServers) {
|
|
4935
5517
|
return { success: false, rulesCreated: 0, errors };
|
|
4936
5518
|
}
|
|
4937
|
-
const rulesDirPath = (0,
|
|
5519
|
+
const rulesDirPath = (0, import_node_path22.join)(baseDir, rulesDir);
|
|
4938
5520
|
try {
|
|
4939
5521
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
4940
5522
|
await mkdir3(rulesDirPath, { recursive: true });
|
|
@@ -4949,17 +5531,17 @@ async function importConfiguration(options) {
|
|
|
4949
5531
|
const baseFilename = rule.filename;
|
|
4950
5532
|
let targetDir = rulesDirPath;
|
|
4951
5533
|
if (rule.type === "command") {
|
|
4952
|
-
targetDir = (0,
|
|
5534
|
+
targetDir = (0, import_node_path22.join)(rulesDirPath, "commands");
|
|
4953
5535
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
4954
5536
|
await mkdir3(targetDir, { recursive: true });
|
|
4955
5537
|
} else {
|
|
4956
5538
|
if (!useLegacyLocation) {
|
|
4957
|
-
targetDir = (0,
|
|
5539
|
+
targetDir = (0, import_node_path22.join)(rulesDirPath, "rules");
|
|
4958
5540
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
4959
5541
|
await mkdir3(targetDir, { recursive: true });
|
|
4960
5542
|
}
|
|
4961
5543
|
}
|
|
4962
|
-
const filePath = (0,
|
|
5544
|
+
const filePath = (0, import_node_path22.join)(targetDir, `${baseFilename}.md`);
|
|
4963
5545
|
const content = generateRuleFileContent(rule);
|
|
4964
5546
|
await writeFileContent(filePath, content);
|
|
4965
5547
|
rulesCreated++;
|
|
@@ -4974,7 +5556,7 @@ async function importConfiguration(options) {
|
|
|
4974
5556
|
let ignoreFileCreated = false;
|
|
4975
5557
|
if (ignorePatterns && ignorePatterns.length > 0) {
|
|
4976
5558
|
try {
|
|
4977
|
-
const rulesyncignorePath = (0,
|
|
5559
|
+
const rulesyncignorePath = (0, import_node_path22.join)(baseDir, ".rulesyncignore");
|
|
4978
5560
|
const ignoreContent = `${ignorePatterns.join("\n")}
|
|
4979
5561
|
`;
|
|
4980
5562
|
await writeFileContent(rulesyncignorePath, ignoreContent);
|
|
@@ -4990,7 +5572,7 @@ async function importConfiguration(options) {
|
|
|
4990
5572
|
let mcpFileCreated = false;
|
|
4991
5573
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
4992
5574
|
try {
|
|
4993
|
-
const mcpPath = (0,
|
|
5575
|
+
const mcpPath = (0, import_node_path22.join)(baseDir, rulesDir, ".mcp.json");
|
|
4994
5576
|
const mcpContent = `${JSON.stringify({ mcpServers }, null, 2)}
|
|
4995
5577
|
`;
|
|
4996
5578
|
await writeFileContent(mcpPath, mcpContent);
|
|
@@ -5025,9 +5607,11 @@ function generateRuleFileContent(rule) {
|
|
|
5025
5607
|
}
|
|
5026
5608
|
|
|
5027
5609
|
// src/cli/commands/import.ts
|
|
5610
|
+
init_logger();
|
|
5028
5611
|
async function importCommand(options = {}) {
|
|
5029
5612
|
logger.setVerbose(options.verbose || false);
|
|
5030
5613
|
const tools = [];
|
|
5614
|
+
if (options.amazonqcli) tools.push("amazonqcli");
|
|
5031
5615
|
if (options.augmentcode) tools.push("augmentcode");
|
|
5032
5616
|
if (options["augmentcode-legacy"]) tools.push("augmentcode-legacy");
|
|
5033
5617
|
if (options.claudecode) tools.push("claudecode");
|
|
@@ -5036,9 +5620,11 @@ async function importCommand(options = {}) {
|
|
|
5036
5620
|
if (options.cline) tools.push("cline");
|
|
5037
5621
|
if (options.roo) tools.push("roo");
|
|
5038
5622
|
if (options.geminicli) tools.push("geminicli");
|
|
5623
|
+
if (options.qwencode) tools.push("qwencode");
|
|
5624
|
+
if (options.opencode) tools.push("opencode");
|
|
5039
5625
|
if (tools.length === 0) {
|
|
5040
5626
|
logger.error(
|
|
5041
|
-
"\u274C Please specify one tool to import from (--augmentcode, --augmentcode-legacy, --claudecode, --cursor, --copilot, --cline, --roo, --geminicli)"
|
|
5627
|
+
"\u274C Please specify one tool to import from (--amazonqcli, --augmentcode, --augmentcode-legacy, --claudecode, --cursor, --copilot, --cline, --roo, --geminicli, --qwencode, --opencode)"
|
|
5042
5628
|
);
|
|
5043
5629
|
process.exit(1);
|
|
5044
5630
|
}
|
|
@@ -5086,7 +5672,8 @@ async function importCommand(options = {}) {
|
|
|
5086
5672
|
}
|
|
5087
5673
|
|
|
5088
5674
|
// src/cli/commands/init.ts
|
|
5089
|
-
var
|
|
5675
|
+
var import_node_path23 = require("path");
|
|
5676
|
+
init_logger();
|
|
5090
5677
|
async function initCommand(options = {}) {
|
|
5091
5678
|
const configResult = await loadConfig();
|
|
5092
5679
|
const config = configResult.config;
|
|
@@ -5094,7 +5681,7 @@ async function initCommand(options = {}) {
|
|
|
5094
5681
|
logger.log("Initializing rulesync...");
|
|
5095
5682
|
await ensureDir(aiRulesDir);
|
|
5096
5683
|
const useLegacy = options.legacy ?? config.legacy ?? false;
|
|
5097
|
-
const rulesDir = useLegacy ? aiRulesDir : (0,
|
|
5684
|
+
const rulesDir = useLegacy ? aiRulesDir : (0, import_node_path23.join)(aiRulesDir, "rules");
|
|
5098
5685
|
if (!useLegacy) {
|
|
5099
5686
|
await ensureDir(rulesDir);
|
|
5100
5687
|
}
|
|
@@ -5140,7 +5727,7 @@ globs: ["**/*"]
|
|
|
5140
5727
|
- Follow single responsibility principle
|
|
5141
5728
|
`
|
|
5142
5729
|
};
|
|
5143
|
-
const filepath = (0,
|
|
5730
|
+
const filepath = (0, import_node_path23.join)(rulesDir, sampleFile.filename);
|
|
5144
5731
|
if (!await fileExists(filepath)) {
|
|
5145
5732
|
await writeFileContent(filepath, sampleFile.content);
|
|
5146
5733
|
logger.success(`Created ${filepath}`);
|
|
@@ -5150,6 +5737,7 @@ globs: ["**/*"]
|
|
|
5150
5737
|
}
|
|
5151
5738
|
|
|
5152
5739
|
// src/cli/commands/status.ts
|
|
5740
|
+
init_logger();
|
|
5153
5741
|
async function statusCommand() {
|
|
5154
5742
|
const config = getDefaultConfig();
|
|
5155
5743
|
logger.log("rulesync Status");
|
|
@@ -5202,6 +5790,7 @@ async function statusCommand() {
|
|
|
5202
5790
|
}
|
|
5203
5791
|
|
|
5204
5792
|
// src/cli/commands/validate.ts
|
|
5793
|
+
init_logger();
|
|
5205
5794
|
async function validateCommand() {
|
|
5206
5795
|
const config = getDefaultConfig();
|
|
5207
5796
|
logger.log("Validating rulesync configuration...");
|
|
@@ -5244,6 +5833,7 @@ Validation failed with ${validation.errors.length} error(s)`);
|
|
|
5244
5833
|
|
|
5245
5834
|
// src/cli/commands/watch.ts
|
|
5246
5835
|
var import_chokidar = require("chokidar");
|
|
5836
|
+
init_logger();
|
|
5247
5837
|
async function watchCommand() {
|
|
5248
5838
|
const config = getDefaultConfig();
|
|
5249
5839
|
logger.log("\u{1F440} Watching for changes in .rulesync directory...");
|
|
@@ -5284,37 +5874,41 @@ async function watchCommand() {
|
|
|
5284
5874
|
|
|
5285
5875
|
// src/cli/index.ts
|
|
5286
5876
|
var program = new import_commander.Command();
|
|
5287
|
-
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.
|
|
5877
|
+
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.65.0");
|
|
5288
5878
|
program.command("init").description("Initialize rulesync in current directory").option("--legacy", "Use legacy file location (.rulesync/*.md instead of .rulesync/rules/*.md)").action(initCommand);
|
|
5289
5879
|
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);
|
|
5290
5880
|
program.command("gitignore").description("Add generated files to .gitignore").action(gitignoreCommand);
|
|
5291
|
-
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);
|
|
5292
|
-
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(
|
|
5881
|
+
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("--qwencode", "Import from Qwen Code (QWEN.md)").option("--opencode", "Import from OpenCode (AGENTS.md)").option("-v, --verbose", "Verbose output").option("--legacy", "Use legacy file location (.rulesync/*.md instead of .rulesync/rules/*.md)").action(importCommand);
|
|
5882
|
+
program.command("generate").description("Generate configuration files for AI tools").option("--all", "Generate for all supported 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("--qwencode", "Generate only for Qwen Code").option("--kiro", "Generate only for Kiro IDE").option("--opencode", "Generate only for OpenCode").option("--windsurf", "Generate only for Windsurf").option("--delete", "Delete all existing files in output directories before generating").option(
|
|
5293
5883
|
"-b, --base-dir <paths>",
|
|
5294
5884
|
"Base directories to generate files (comma-separated for multiple paths)"
|
|
5295
5885
|
).option("-v, --verbose", "Verbose output").option("-c, --config <path>", "Path to configuration file").option("--no-config", "Disable configuration file loading").action(async (options) => {
|
|
5296
5886
|
const tools = [];
|
|
5297
|
-
if (options.
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5887
|
+
if (options.all) {
|
|
5888
|
+
tools.push(...ALL_TOOL_TARGETS);
|
|
5889
|
+
} else {
|
|
5890
|
+
if (options.augmentcode) tools.push("augmentcode");
|
|
5891
|
+
if (options["augmentcode-legacy"]) tools.push("augmentcode-legacy");
|
|
5892
|
+
if (options.copilot) tools.push("copilot");
|
|
5893
|
+
if (options.cursor) tools.push("cursor");
|
|
5894
|
+
if (options.cline) tools.push("cline");
|
|
5895
|
+
if (options.codexcli) tools.push("codexcli");
|
|
5896
|
+
if (options.claudecode) tools.push("claudecode");
|
|
5897
|
+
if (options.roo) tools.push("roo");
|
|
5898
|
+
if (options.geminicli) tools.push("geminicli");
|
|
5899
|
+
if (options.junie) tools.push("junie");
|
|
5900
|
+
if (options.qwencode) tools.push("qwencode");
|
|
5901
|
+
if (options.kiro) tools.push("kiro");
|
|
5902
|
+
if (options.opencode) tools.push("opencode");
|
|
5903
|
+
if (options.windsurf) tools.push("windsurf");
|
|
5904
|
+
}
|
|
5309
5905
|
const generateOptions = {
|
|
5310
5906
|
verbose: options.verbose,
|
|
5907
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
5311
5908
|
delete: options.delete,
|
|
5312
5909
|
config: options.config,
|
|
5313
5910
|
noConfig: options.noConfig
|
|
5314
5911
|
};
|
|
5315
|
-
if (tools.length > 0) {
|
|
5316
|
-
generateOptions.tools = tools;
|
|
5317
|
-
}
|
|
5318
5912
|
if (options.baseDir) {
|
|
5319
5913
|
generateOptions.baseDirs = options.baseDir.split(",").map((dir) => dir.trim()).filter((dir) => dir.length > 0);
|
|
5320
5914
|
}
|