rulesync 0.67.0 → 0.69.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.
@@ -1,392 +0,0 @@
1
- import {
2
- shouldIncludeServer
3
- } from "./chunk-CS7AV6JT.js";
4
-
5
- // src/constants/schemas.ts
6
- var SCHEMA_URLS = {
7
- OPENCODE: "https://opencode.ai/config.json"
8
- };
9
-
10
- // src/generators/mcp/shared-factory.ts
11
- function generateMcpConfig(config, toolConfig) {
12
- const servers = {};
13
- for (const [serverName, server] of Object.entries(config.mcpServers)) {
14
- if (!shouldIncludeServer(server, toolConfig.target)) continue;
15
- servers[serverName] = toolConfig.serverTransform(server, serverName);
16
- }
17
- const finalConfig = toolConfig.configWrapper(servers);
18
- return JSON.stringify(finalConfig, null, 2);
19
- }
20
- function generateMcpConfigurationFiles(mcpServers, toolConfig, baseDir = "") {
21
- const configs = [];
22
- const rulesyncConfig = { mcpServers };
23
- for (const configPath of toolConfig.configPaths) {
24
- const filepath = baseDir ? `${baseDir}/${configPath}` : configPath;
25
- const content = generateMcpConfig(rulesyncConfig, toolConfig);
26
- configs.push({
27
- filepath,
28
- content: `${content}
29
- `
30
- });
31
- }
32
- return configs;
33
- }
34
- var serverTransforms = {
35
- /**
36
- * Basic server transformation (command, args, env, url handling)
37
- */
38
- basic: (server) => {
39
- const result = {};
40
- if (server.command) {
41
- result.command = server.command;
42
- if (server.args) result.args = server.args;
43
- }
44
- if (server.url || server.httpUrl) {
45
- const url = server.httpUrl || server.url;
46
- if (url) result.url = url;
47
- }
48
- if (server.env) {
49
- result.env = server.env;
50
- }
51
- return result;
52
- },
53
- /**
54
- * Roo-specific server transformation (preserves httpUrl, transport, type, etc.)
55
- */
56
- roo: (server) => {
57
- const result = serverTransforms.extended(server);
58
- if (server.httpUrl) {
59
- if (!server.url) {
60
- result.httpUrl = server.httpUrl;
61
- delete result.url;
62
- }
63
- }
64
- if (server.transport) {
65
- result.transport = server.transport;
66
- }
67
- if (server.type) {
68
- result.type = server.type;
69
- }
70
- return result;
71
- },
72
- /**
73
- * Extended server transformation (includes disabled, alwaysAllow, etc.)
74
- */
75
- extended: (server) => {
76
- const result = serverTransforms.basic(server);
77
- if (server.disabled !== void 0) {
78
- result.disabled = server.disabled;
79
- }
80
- if (server.alwaysAllow) {
81
- result.alwaysAllow = server.alwaysAllow;
82
- }
83
- if (server.networkTimeout !== void 0) {
84
- result.networkTimeout = server.networkTimeout;
85
- }
86
- if (server.tools) {
87
- result.tools = server.tools;
88
- }
89
- if (server.timeout !== void 0) {
90
- result.timeout = server.timeout;
91
- }
92
- if (server.trust !== void 0) {
93
- result.trust = server.trust;
94
- }
95
- if (server.headers) {
96
- result.headers = server.headers;
97
- }
98
- return result;
99
- },
100
- /**
101
- * Remove rulesync-specific properties from server config
102
- */
103
- cleanRulesyncProps: (server) => {
104
- const { targets: _, transport: _transport, ...cleanServer } = server;
105
- return { ...cleanServer };
106
- }
107
- };
108
- var configWrappers = {
109
- /**
110
- * Standard mcpServers wrapper
111
- */
112
- mcpServers: (servers) => ({
113
- mcpServers: servers
114
- }),
115
- /**
116
- * Servers-only wrapper (for tools that use "servers" instead of "mcpServers")
117
- */
118
- servers: (servers) => ({
119
- servers
120
- })
121
- };
122
- var MCP_GENERATOR_REGISTRY = {
123
- roo: {
124
- target: "roo",
125
- configPaths: [".roo/mcp.json"],
126
- serverTransform: serverTransforms.roo,
127
- configWrapper: configWrappers.mcpServers
128
- },
129
- claudecode: {
130
- target: "claudecode",
131
- configPaths: [".mcp.json"],
132
- serverTransform: (server) => {
133
- const claudeServer = {};
134
- if (server.command) {
135
- claudeServer.command = server.command;
136
- if (server.args) claudeServer.args = server.args;
137
- } else if (server.url || server.httpUrl) {
138
- const url = server.httpUrl || server.url;
139
- if (url) {
140
- claudeServer.url = url;
141
- }
142
- if (server.httpUrl) {
143
- claudeServer.transport = "http";
144
- } else if (server.transport === "sse") {
145
- claudeServer.transport = "sse";
146
- }
147
- }
148
- if (server.env) {
149
- claudeServer.env = server.env;
150
- }
151
- return claudeServer;
152
- },
153
- configWrapper: configWrappers.mcpServers
154
- },
155
- cursor: {
156
- target: "cursor",
157
- configPaths: [".cursor/mcp.json"],
158
- serverTransform: (server) => {
159
- const cursorServer = {};
160
- if (server.command) {
161
- cursorServer.command = server.command;
162
- if (server.args) cursorServer.args = server.args;
163
- } else if (server.url || server.httpUrl) {
164
- const url = server.httpUrl || server.url;
165
- if (url) {
166
- cursorServer.url = url;
167
- }
168
- if (server.httpUrl || server.transport === "http") {
169
- cursorServer.type = "streamable-http";
170
- } else if (server.transport === "sse" || server.type === "sse") {
171
- cursorServer.type = "sse";
172
- }
173
- }
174
- if (server.env) {
175
- cursorServer.env = server.env;
176
- }
177
- if (server.cwd) {
178
- cursorServer.cwd = server.cwd;
179
- }
180
- return cursorServer;
181
- },
182
- configWrapper: configWrappers.mcpServers
183
- },
184
- windsurf: {
185
- target: "windsurf",
186
- configPaths: ["mcp_config.json"],
187
- serverTransform: (server) => {
188
- const windsurfServer = {};
189
- if (server.command) {
190
- windsurfServer.command = server.command;
191
- if (server.args) windsurfServer.args = server.args;
192
- } else if (server.url || server.httpUrl) {
193
- const url = server.httpUrl || server.url;
194
- if (url) {
195
- windsurfServer.serverUrl = url;
196
- }
197
- }
198
- if (server.env) {
199
- windsurfServer.env = server.env;
200
- }
201
- if (server.cwd) {
202
- windsurfServer.cwd = server.cwd;
203
- }
204
- return windsurfServer;
205
- },
206
- configWrapper: configWrappers.mcpServers
207
- },
208
- junie: {
209
- target: "junie",
210
- configPaths: [".junie/mcp/mcp.json"],
211
- serverTransform: (server, serverName) => {
212
- const junieServer = {
213
- name: serverName
214
- };
215
- if (server.command) {
216
- junieServer.command = server.command;
217
- if (server.args) junieServer.args = server.args;
218
- } else if (server.url || server.httpUrl) {
219
- if (server.httpUrl) {
220
- junieServer.httpUrl = server.httpUrl;
221
- } else if (server.url) {
222
- junieServer.url = server.url;
223
- }
224
- }
225
- if (server.env) {
226
- junieServer.env = server.env;
227
- }
228
- if (server.cwd) {
229
- junieServer.workingDirectory = server.cwd;
230
- }
231
- if (server.timeout !== void 0) {
232
- junieServer.timeout = server.timeout;
233
- }
234
- if (server.trust !== void 0) {
235
- junieServer.trust = server.trust;
236
- }
237
- if (server.transport) {
238
- if (String(server.transport) === "streamable-http") {
239
- junieServer.transport = "http";
240
- } else if (server.transport === "stdio" || server.transport === "http" || server.transport === "sse") {
241
- junieServer.transport = server.transport;
242
- }
243
- } else if (server.command) {
244
- junieServer.transport = "stdio";
245
- }
246
- return junieServer;
247
- },
248
- configWrapper: configWrappers.mcpServers
249
- },
250
- cline: {
251
- target: "cline",
252
- configPaths: [".cline/mcp.json"],
253
- serverTransform: serverTransforms.extended,
254
- configWrapper: configWrappers.mcpServers
255
- },
256
- geminicli: {
257
- target: "geminicli",
258
- configPaths: [".gemini/settings.json"],
259
- serverTransform: (server) => {
260
- const { targets: _, ...serverConfig } = server;
261
- const geminiServer = { ...serverConfig };
262
- if (server.env) {
263
- geminiServer.env = server.env;
264
- }
265
- return geminiServer;
266
- },
267
- configWrapper: configWrappers.mcpServers
268
- },
269
- opencode: {
270
- target: "opencode",
271
- configPaths: ["opencode.json"],
272
- serverTransform: (server) => {
273
- const opencodeServer = {};
274
- if (server.command) {
275
- opencodeServer.type = "local";
276
- opencodeServer.command = Array.isArray(server.command) ? server.command : [server.command];
277
- if (server.args) opencodeServer.args = server.args;
278
- if (server.env) opencodeServer.environment = server.env;
279
- if (server.cwd) opencodeServer.cwd = server.cwd;
280
- } else if (server.url || server.httpUrl) {
281
- opencodeServer.type = "remote";
282
- const url = server.httpUrl || server.url;
283
- if (url) opencodeServer.url = url;
284
- if (server.headers) opencodeServer.headers = server.headers;
285
- }
286
- if (server.disabled !== void 0) {
287
- opencodeServer.enabled = !server.disabled;
288
- } else {
289
- opencodeServer.enabled = true;
290
- }
291
- return opencodeServer;
292
- },
293
- configWrapper: (servers) => ({
294
- $schema: SCHEMA_URLS.OPENCODE,
295
- mcp: servers
296
- })
297
- },
298
- qwencode: {
299
- target: "qwencode",
300
- configPaths: [".qwen/settings.json"],
301
- serverTransform: (server) => {
302
- const { targets: _, ...serverConfig } = server;
303
- const qwenServer = { ...serverConfig };
304
- if (server.env) {
305
- qwenServer.env = server.env;
306
- }
307
- return qwenServer;
308
- },
309
- configWrapper: configWrappers.mcpServers
310
- }
311
- };
312
- function generateMcpFromRegistry(tool, config) {
313
- const generatorConfig = MCP_GENERATOR_REGISTRY[tool];
314
- if (!generatorConfig) {
315
- throw new Error(`No MCP generator configuration found for tool: ${tool}`);
316
- }
317
- return generateMcpConfig(config, generatorConfig);
318
- }
319
- function createMcpGenerator(toolName) {
320
- return {
321
- generateMcp: (config) => {
322
- return generateMcpFromRegistry(toolName, config);
323
- },
324
- generateMcpConfiguration: (mcpServers, baseDir = "") => {
325
- return generateMcpConfigurationFilesFromRegistry(toolName, mcpServers, baseDir);
326
- }
327
- };
328
- }
329
- var cursorMcpGenerator = createMcpGenerator("cursor");
330
- var clineMcpGenerator = createMcpGenerator("cline");
331
- function generateMcpConfigurationFilesFromRegistry(tool, mcpServers, baseDir = "") {
332
- const generatorConfig = MCP_GENERATOR_REGISTRY[tool];
333
- if (!generatorConfig) {
334
- throw new Error(`No MCP generator configuration found for tool: ${tool}`);
335
- }
336
- if (tool === "junie") {
337
- return generateJunieMcpConfigurationFiles(mcpServers, baseDir);
338
- }
339
- const customTools = ["copilot", "augmentcode", "codexcli", "kiro"];
340
- if (customTools.includes(tool)) {
341
- throw new Error(
342
- `Tool ${tool} uses custom configuration logic - use its specific generator function instead`
343
- );
344
- }
345
- return generateMcpConfigurationFiles(mcpServers, generatorConfig, baseDir);
346
- }
347
- function generateJunieMcpConfigurationFiles(mcpServers, baseDir = "") {
348
- const junieMcpPath = ".junie/mcp/mcp.json";
349
- const filepath = baseDir ? `${baseDir}/${junieMcpPath}` : junieMcpPath;
350
- const config = {
351
- mcpServers: {}
352
- };
353
- for (const [serverName, server] of Object.entries(mcpServers)) {
354
- if (!shouldIncludeServer(server, "junie")) {
355
- continue;
356
- }
357
- const { targets: _, transport, cwd, ...serverConfig } = server;
358
- const junieServer = {
359
- ...serverConfig,
360
- name: serverName
361
- };
362
- if (cwd) {
363
- junieServer.workingDirectory = cwd;
364
- }
365
- if (transport) {
366
- if (String(transport) === "streamable-http") {
367
- junieServer.transport = "http";
368
- } else if (transport === "stdio" || transport === "http" || transport === "sse") {
369
- junieServer.transport = transport;
370
- }
371
- } else if (serverConfig.command) {
372
- junieServer.transport = "stdio";
373
- }
374
- config.mcpServers[serverName] = junieServer;
375
- }
376
- return [
377
- {
378
- filepath,
379
- content: `${JSON.stringify(config, null, 2)}
380
- `
381
- }
382
- ];
383
- }
384
-
385
- export {
386
- generateMcpConfig,
387
- generateMcpConfigurationFiles,
388
- generateMcpFromRegistry,
389
- cursorMcpGenerator,
390
- clineMcpGenerator,
391
- generateMcpConfigurationFilesFromRegistry
392
- };
@@ -1,12 +0,0 @@
1
- import {
2
- cursorMcpGenerator
3
- } from "./chunk-V36ICGOY.js";
4
-
5
- // src/generators/mcp/cursor.ts
6
- var generateCursorMcp = cursorMcpGenerator.generateMcp;
7
- var generateCursorMcpConfiguration = cursorMcpGenerator.generateMcpConfiguration;
8
-
9
- export {
10
- generateCursorMcp,
11
- generateCursorMcpConfiguration
12
- };
@@ -1,210 +0,0 @@
1
- import {
2
- shouldIncludeServer
3
- } from "./chunk-CS7AV6JT.js";
4
-
5
- // src/utils/file.ts
6
- import { mkdir, readdir, readFile, rm, stat, writeFile } from "fs/promises";
7
- import { dirname, join, relative, resolve } from "path";
8
-
9
- // src/utils/logger.ts
10
- import { consola } from "consola";
11
- var Logger = class {
12
- _verbose = false;
13
- console = consola.withDefaults({
14
- tag: "rulesync"
15
- });
16
- setVerbose(verbose) {
17
- this._verbose = verbose;
18
- }
19
- get verbose() {
20
- return this._verbose;
21
- }
22
- // Regular log (always shown, regardless of verbose)
23
- log(message, ...args) {
24
- this.console.log(message, ...args);
25
- }
26
- // Info level (shown only in verbose mode)
27
- info(message, ...args) {
28
- if (this._verbose) {
29
- this.console.info(message, ...args);
30
- }
31
- }
32
- // Success (always shown)
33
- success(message, ...args) {
34
- this.console.success(message, ...args);
35
- }
36
- // Warning (always shown)
37
- warn(message, ...args) {
38
- this.console.warn(message, ...args);
39
- }
40
- // Error (always shown)
41
- error(message, ...args) {
42
- this.console.error(message, ...args);
43
- }
44
- // Debug level (shown only in verbose mode)
45
- debug(message, ...args) {
46
- if (this._verbose) {
47
- this.console.debug(message, ...args);
48
- }
49
- }
50
- };
51
- var logger = new Logger();
52
-
53
- // src/utils/file.ts
54
- async function ensureDir(dirPath) {
55
- try {
56
- await stat(dirPath);
57
- } catch {
58
- await mkdir(dirPath, { recursive: true });
59
- }
60
- }
61
- function resolvePath(relativePath, baseDir) {
62
- if (!baseDir) return relativePath;
63
- const resolved = resolve(baseDir, relativePath);
64
- const rel = relative(baseDir, resolved);
65
- if (rel.startsWith("..") || resolve(resolved) !== resolved) {
66
- throw new Error(`Path traversal detected: ${relativePath}`);
67
- }
68
- return resolved;
69
- }
70
- async function readFileContent(filepath) {
71
- return readFile(filepath, "utf-8");
72
- }
73
- async function writeFileContent(filepath, content) {
74
- await ensureDir(dirname(filepath));
75
- await writeFile(filepath, content, "utf-8");
76
- }
77
- async function fileExists(filepath) {
78
- try {
79
- await stat(filepath);
80
- return true;
81
- } catch {
82
- return false;
83
- }
84
- }
85
- async function findFiles(dir, extension = ".md") {
86
- try {
87
- const files = await readdir(dir);
88
- return files.filter((file) => file.endsWith(extension)).map((file) => join(dir, file));
89
- } catch {
90
- return [];
91
- }
92
- }
93
- async function findRuleFiles(aiRulesDir) {
94
- const rulesDir = join(aiRulesDir, "rules");
95
- const newLocationFiles = await findFiles(rulesDir, ".md");
96
- const legacyLocationFiles = await findFiles(aiRulesDir, ".md");
97
- const newLocationBasenames = new Set(
98
- newLocationFiles.map((file) => file.split("/").pop()?.replace(/\.md$/, ""))
99
- );
100
- const filteredLegacyFiles = legacyLocationFiles.filter((file) => {
101
- const basename = file.split("/").pop()?.replace(/\.md$/, "");
102
- return !newLocationBasenames.has(basename);
103
- });
104
- return [...newLocationFiles, ...filteredLegacyFiles];
105
- }
106
- async function removeDirectory(dirPath) {
107
- const dangerousPaths = [".", "/", "~", "src", "node_modules"];
108
- if (dangerousPaths.includes(dirPath) || dirPath === "") {
109
- logger.warn(`Skipping deletion of dangerous path: ${dirPath}`);
110
- return;
111
- }
112
- try {
113
- if (await fileExists(dirPath)) {
114
- await rm(dirPath, { recursive: true, force: true });
115
- }
116
- } catch (error) {
117
- logger.warn(`Failed to remove directory ${dirPath}:`, error);
118
- }
119
- }
120
- async function removeFile(filepath) {
121
- try {
122
- if (await fileExists(filepath)) {
123
- await rm(filepath);
124
- }
125
- } catch (error) {
126
- logger.warn(`Failed to remove file ${filepath}:`, error);
127
- }
128
- }
129
- async function removeClaudeGeneratedFiles() {
130
- const filesToRemove = ["CLAUDE.md", ".claude/memories"];
131
- for (const fileOrDir of filesToRemove) {
132
- if (fileOrDir.endsWith("/memories")) {
133
- await removeDirectory(fileOrDir);
134
- } else {
135
- await removeFile(fileOrDir);
136
- }
137
- }
138
- }
139
-
140
- // src/generators/mcp/amazonqcli.ts
141
- async function generateAmazonqcliMcp(mcpServers, config, baseDir) {
142
- const outputs = [];
143
- const configPaths = [
144
- ".amazonq/mcp.json"
145
- // Workspace configuration
146
- // Note: Global configuration is ~/.aws/amazonq/mcp.json but is user-specific
147
- // According to precautions.md, we should not create user-level files
148
- ];
149
- for (const configPath of configPaths) {
150
- const filepath = resolvePath(configPath, baseDir);
151
- const content = generateAmazonqcliMcpConfig({ mcpServers });
152
- outputs.push({
153
- tool: "amazonqcli",
154
- filepath,
155
- content
156
- });
157
- }
158
- return outputs;
159
- }
160
- function generateAmazonqcliMcpString(config) {
161
- return generateAmazonqcliMcpConfig(config);
162
- }
163
- function generateAmazonqcliMcpConfig(config) {
164
- const servers = {};
165
- for (const [serverName, server] of Object.entries(config.mcpServers)) {
166
- if (!shouldIncludeServer(server, "amazonqcli")) {
167
- continue;
168
- }
169
- const amazonqServer = {};
170
- if (server.command) {
171
- amazonqServer.command = server.command;
172
- if (server.args) {
173
- amazonqServer.args = server.args;
174
- }
175
- }
176
- if (server.env) {
177
- amazonqServer.env = server.env;
178
- }
179
- if (server.timeout !== void 0) {
180
- amazonqServer.timeout = server.timeout;
181
- }
182
- if (server.disabled !== void 0) {
183
- amazonqServer.disabled = server.disabled;
184
- }
185
- if (server.alwaysAllow) {
186
- amazonqServer.autoApprove = server.alwaysAllow;
187
- }
188
- servers[serverName] = amazonqServer;
189
- }
190
- const finalConfig = {
191
- mcpServers: servers
192
- };
193
- return `${JSON.stringify(finalConfig, null, 2)}
194
- `;
195
- }
196
-
197
- export {
198
- logger,
199
- ensureDir,
200
- resolvePath,
201
- readFileContent,
202
- writeFileContent,
203
- fileExists,
204
- findFiles,
205
- findRuleFiles,
206
- removeDirectory,
207
- removeClaudeGeneratedFiles,
208
- generateAmazonqcliMcp,
209
- generateAmazonqcliMcpString
210
- };
@@ -1,17 +0,0 @@
1
- import {
2
- generateMcpConfigurationFilesFromRegistry,
3
- generateMcpFromRegistry
4
- } from "./chunk-V36ICGOY.js";
5
-
6
- // src/generators/mcp/junie.ts
7
- function generateJunieMcp(config) {
8
- return generateMcpFromRegistry("junie", config);
9
- }
10
- function generateJunieMcpConfiguration(mcpServers, baseDir = "") {
11
- return generateMcpConfigurationFilesFromRegistry("junie", mcpServers, baseDir);
12
- }
13
-
14
- export {
15
- generateJunieMcp,
16
- generateJunieMcpConfiguration
17
- };