rulesync 0.62.0 → 0.64.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 +15 -3
- package/dist/amazonqcli-WVGYACHI.js +9 -0
- package/dist/{augmentcode-HIZIQG2W.js → augmentcode-DTHPPXWO.js} +2 -2
- package/dist/{chunk-M7NL7G7A.js → chunk-4NAQ5HL4.js} +1 -1
- package/dist/{chunk-GQTMTBX4.js → chunk-6LSN7HSJ.js} +76 -4
- package/dist/chunk-DMTCLQ4T.js +17 -0
- package/dist/{chunk-YTU3SCQO.js → chunk-E2J3UBBK.js} +9 -3
- package/dist/{chunk-LXTA7DBA.js → chunk-EID75W45.js} +1 -1
- package/dist/{chunk-U4PLVMCG.js → chunk-FVPZQEWP.js} +1 -1
- package/dist/{chunk-NETSYSMD.js → chunk-HHJIL3YZ.js} +1 -1
- package/dist/{chunk-UEAYL4NT.js → chunk-JX55DU6Y.js} +1 -1
- package/dist/{chunk-KUGTKMNW.js → chunk-KKWJVA56.js} +5 -2
- package/dist/chunk-LURFNGH4.js +17 -0
- package/dist/{chunk-AUUSMVCT.js → chunk-LYVES5YR.js} +2 -0
- package/dist/{chunk-4PSTOKKD.js → chunk-TBXG53FV.js} +1 -1
- package/dist/{chunk-2CW2KFB3.js → chunk-TQOL7OKY.js} +1 -1
- package/dist/chunk-YPJW7Z5M.js +210 -0
- package/dist/{claudecode-YTEFACCT.js → claudecode-SSYLLUXX.js} +3 -3
- package/dist/{cline-CKNUDEA3.js → cline-5EUGKNZ6.js} +3 -3
- package/dist/{codexcli-7SDGYI7D.js → codexcli-IGM2ADYK.js} +3 -3
- package/dist/{copilot-MOR3HHJX.js → copilot-HSQO7ZCJ.js} +2 -2
- package/dist/{cursor-YJGH7W24.js → cursor-ZB3XNGBK.js} +3 -3
- package/dist/{geminicli-E7KZTZ2G.js → geminicli-FNRKH5GX.js} +3 -3
- package/dist/index.cjs +1144 -694
- package/dist/index.js +815 -609
- package/dist/{junie-5LEQU4BO.js → junie-3YGOSOGF.js} +3 -3
- package/dist/{kiro-YDHXY2MA.js → kiro-B6WZNLY4.js} +2 -2
- package/dist/opencode-SZETJ62M.js +17 -0
- package/dist/{roo-L3QTTIPO.js → roo-KLTWVAKE.js} +3 -2
- package/dist/{windsurf-4P6HEUBV.js → windsurf-IZEKUAID.js} +3 -3
- package/package.json +2 -1
- package/dist/chunk-MDYDKNXQ.js +0 -61
- package/dist/chunk-PCATT4UZ.js +0 -78
package/README.md
CHANGED
|
@@ -46,11 +46,15 @@ If you already have AI tool configurations:
|
|
|
46
46
|
npx rulesync import --claudecode # From CLAUDE.md
|
|
47
47
|
npx rulesync import --cursor # From .cursorrules
|
|
48
48
|
npx rulesync import --copilot # From .github/copilot-instructions.md
|
|
49
|
+
npx rulesync import --amazonqcli # From .amazonq/rules/*.md
|
|
50
|
+
npx rulesync import --opencode # From AGENTS.md
|
|
49
51
|
|
|
50
52
|
# Import to legacy structure (for existing projects)
|
|
51
53
|
npx rulesync import --claudecode --legacy
|
|
52
54
|
npx rulesync import --cursor --legacy
|
|
53
55
|
npx rulesync import --copilot --legacy
|
|
56
|
+
npx rulesync import --amazonqcli --legacy
|
|
57
|
+
npx rulesync import --opencode --legacy
|
|
54
58
|
|
|
55
59
|
# Generate unified configurations
|
|
56
60
|
npx rulesync generate
|
|
@@ -58,13 +62,15 @@ npx rulesync generate
|
|
|
58
62
|
|
|
59
63
|
## Supported Tools
|
|
60
64
|
|
|
61
|
-
rulesync supports both **generation** and **import** for
|
|
65
|
+
rulesync supports both **generation** and **import** for **12 AI development tools**:
|
|
62
66
|
|
|
63
67
|
- **GitHub Copilot Custom Instructions** (`.github/copilot-instructions.md` + `.github/instructions/*.instructions.md`)
|
|
64
68
|
- **Cursor Project Rules** (`.cursor/rules/*.mdc` + `.cursorrules`)
|
|
65
69
|
- **Cline Rules** (`.clinerules/*.md` + `.cline/instructions.md`)
|
|
66
70
|
- **Claude Code Memory** (`./CLAUDE.md` + `.claude/memories/*.md` + **Custom Slash Commands** `.claude/commands/*.md`)
|
|
67
|
-
- **
|
|
71
|
+
- **Amazon Q Developer CLI** (`.amazonq/rules/*.md` + `.amazonq/mcp.json` + **Built-in Slash Commands** support + **Context Management**)
|
|
72
|
+
- **OpenCode** (`AGENTS.md` + `opencode.json` + **🔐 Permission-Based Security** instead of traditional ignore files)
|
|
73
|
+
- **OpenAI Codex CLI** (`AGENTS.md` + **File Splitting with XML References** `.codex/memories/*.md` + `.codex/mcp-config.json` + `.codexignore`)
|
|
68
74
|
- **AugmentCode Rules** (`.augment/rules/*.md`)
|
|
69
75
|
- **Roo Code Rules** (`.roo/rules/*.md` + `.roo/instructions.md`)
|
|
70
76
|
- **Gemini CLI** (`GEMINI.md` + `.gemini/memories/*.md` + **Custom Slash Commands** `.gemini/commands/*.md`)
|
|
@@ -86,6 +92,8 @@ Enable hybrid development workflows combining multiple AI tools:
|
|
|
86
92
|
- Cursor for refactoring
|
|
87
93
|
- Claude Code for architecture design
|
|
88
94
|
- Cline for debugging assistance
|
|
95
|
+
- **Amazon Q Developer CLI** for comprehensive chat-based development with built-in commands and MCP integration
|
|
96
|
+
- **OpenCode** for secure terminal-based development with granular permission controls
|
|
89
97
|
- Windsurf for comprehensive AI-assisted editing
|
|
90
98
|
|
|
91
99
|
### 🔓 **No Vendor Lock-in**
|
|
@@ -114,9 +122,11 @@ npx rulesync add typescript-rules --legacy
|
|
|
114
122
|
|
|
115
123
|
# Import existing configurations (to .rulesync/rules/ by default)
|
|
116
124
|
npx rulesync import --cursor
|
|
125
|
+
npx rulesync import --amazonqcli
|
|
117
126
|
|
|
118
127
|
# Import to legacy location (for existing projects)
|
|
119
128
|
npx rulesync import --cursor --legacy
|
|
129
|
+
npx rulesync import --amazonqcli --legacy
|
|
120
130
|
|
|
121
131
|
# Validate rules
|
|
122
132
|
npx rulesync validate
|
|
@@ -145,7 +155,9 @@ npx rulesync gitignore
|
|
|
145
155
|
- **[Cursor](./docs/tools/cursor.md)** - Rule types and MDC format
|
|
146
156
|
- **[GitHub Copilot](./docs/tools/copilot.md)** - Custom instructions
|
|
147
157
|
- **[Cline](./docs/tools/cline.md)** - Plain Markdown rules
|
|
148
|
-
- **[
|
|
158
|
+
- **[Amazon Q Developer CLI](./docs/tools/amazonqcli.md)** - Rules, MCP, and built-in commands
|
|
159
|
+
- **[OpenCode](./docs/tools/opencode.md)** - Permission-based configuration and MCP integration
|
|
160
|
+
- **[OpenAI Codex CLI](./docs/tools/codexcli.md)** - Advanced file splitting with XML document references and memory files
|
|
149
161
|
- **[Gemini CLI](./docs/tools/geminicli.md)** - Memory and commands
|
|
150
162
|
- **[Windsurf](./docs/tools/windsurf.md)** - Rules and Cascade AI
|
|
151
163
|
- **[JetBrains Junie](./docs/tools/junie.md)** - Guidelines and IDE integration
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateAugmentcodeMcp,
|
|
3
3
|
generateAugmentcodeMcpConfiguration
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-E2J3UBBK.js";
|
|
5
|
+
import "./chunk-LYVES5YR.js";
|
|
6
6
|
export {
|
|
7
7
|
generateAugmentcodeMcp,
|
|
8
8
|
generateAugmentcodeMcpConfiguration
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shouldIncludeServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LYVES5YR.js";
|
|
4
|
+
|
|
5
|
+
// src/constants/schemas.ts
|
|
6
|
+
var SCHEMA_URLS = {
|
|
7
|
+
OPENCODE: "https://opencode.ai/config.json"
|
|
8
|
+
};
|
|
4
9
|
|
|
5
10
|
// src/generators/mcp/shared-factory.ts
|
|
6
11
|
function generateMcpConfig(config, toolConfig) {
|
|
@@ -35,7 +40,8 @@ var serverTransforms = {
|
|
|
35
40
|
if (server.command) {
|
|
36
41
|
result.command = server.command;
|
|
37
42
|
if (server.args) result.args = server.args;
|
|
38
|
-
}
|
|
43
|
+
}
|
|
44
|
+
if (server.url || server.httpUrl) {
|
|
39
45
|
const url = server.httpUrl || server.url;
|
|
40
46
|
if (url) result.url = url;
|
|
41
47
|
}
|
|
@@ -44,6 +50,25 @@ var serverTransforms = {
|
|
|
44
50
|
}
|
|
45
51
|
return result;
|
|
46
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
|
+
},
|
|
47
72
|
/**
|
|
48
73
|
* Extended server transformation (includes disabled, alwaysAllow, etc.)
|
|
49
74
|
*/
|
|
@@ -95,6 +120,12 @@ var configWrappers = {
|
|
|
95
120
|
})
|
|
96
121
|
};
|
|
97
122
|
var MCP_GENERATOR_REGISTRY = {
|
|
123
|
+
roo: {
|
|
124
|
+
target: "roo",
|
|
125
|
+
configPaths: [".roo/mcp.json"],
|
|
126
|
+
serverTransform: serverTransforms.roo,
|
|
127
|
+
configWrapper: configWrappers.mcpServers
|
|
128
|
+
},
|
|
98
129
|
claudecode: {
|
|
99
130
|
target: "claudecode",
|
|
100
131
|
configPaths: [".mcp.json"],
|
|
@@ -221,6 +252,48 @@ var MCP_GENERATOR_REGISTRY = {
|
|
|
221
252
|
configPaths: [".cline/mcp.json"],
|
|
222
253
|
serverTransform: serverTransforms.extended,
|
|
223
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
|
+
})
|
|
224
297
|
}
|
|
225
298
|
};
|
|
226
299
|
function generateMcpFromRegistry(tool, config) {
|
|
@@ -250,7 +323,7 @@ function generateMcpConfigurationFilesFromRegistry(tool, mcpServers, baseDir = "
|
|
|
250
323
|
if (tool === "junie") {
|
|
251
324
|
return generateJunieMcpConfigurationFiles(mcpServers, baseDir);
|
|
252
325
|
}
|
|
253
|
-
const customTools = ["copilot", "augmentcode", "
|
|
326
|
+
const customTools = ["copilot", "augmentcode", "codexcli", "kiro"];
|
|
254
327
|
if (customTools.includes(tool)) {
|
|
255
328
|
throw new Error(
|
|
256
329
|
`Tool ${tool} uses custom configuration logic - use its specific generator function instead`
|
|
@@ -299,7 +372,6 @@ function generateJunieMcpConfigurationFiles(mcpServers, baseDir = "") {
|
|
|
299
372
|
export {
|
|
300
373
|
generateMcpConfig,
|
|
301
374
|
generateMcpConfigurationFiles,
|
|
302
|
-
configWrappers,
|
|
303
375
|
generateMcpFromRegistry,
|
|
304
376
|
cursorMcpGenerator,
|
|
305
377
|
clineMcpGenerator,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generateMcpConfigurationFilesFromRegistry,
|
|
3
|
+
generateMcpFromRegistry
|
|
4
|
+
} from "./chunk-6LSN7HSJ.js";
|
|
5
|
+
|
|
6
|
+
// src/generators/mcp/geminicli.ts
|
|
7
|
+
function generateGeminiCliMcp(config) {
|
|
8
|
+
return generateMcpFromRegistry("geminicli", config);
|
|
9
|
+
}
|
|
10
|
+
function generateGeminiCliMcpConfiguration(mcpServers, baseDir = "") {
|
|
11
|
+
return generateMcpConfigurationFilesFromRegistry("geminicli", mcpServers, baseDir);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
generateGeminiCliMcp,
|
|
16
|
+
generateGeminiCliMcpConfiguration
|
|
17
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shouldIncludeServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LYVES5YR.js";
|
|
4
4
|
|
|
5
5
|
// src/generators/mcp/augmentcode.ts
|
|
6
6
|
function generateAugmentcodeMcp(config) {
|
|
@@ -16,7 +16,10 @@ function generateAugmentcodeMcp(config) {
|
|
|
16
16
|
name: serverName
|
|
17
17
|
};
|
|
18
18
|
if (server.command) {
|
|
19
|
-
|
|
19
|
+
const command = Array.isArray(server.command) ? server.command[0] : server.command;
|
|
20
|
+
if (command) {
|
|
21
|
+
augmentServer.command = command;
|
|
22
|
+
}
|
|
20
23
|
if (server.args) {
|
|
21
24
|
augmentServer.args = server.args;
|
|
22
25
|
}
|
|
@@ -64,7 +67,10 @@ function generateAugmentcodeMcpConfiguration(mcpServers, baseDir = "") {
|
|
|
64
67
|
const { targets: _, ...serverConfig } = server;
|
|
65
68
|
const augmentServer = {};
|
|
66
69
|
if (serverConfig.command) {
|
|
67
|
-
|
|
70
|
+
const command = Array.isArray(serverConfig.command) ? serverConfig.command[0] : serverConfig.command;
|
|
71
|
+
if (command) {
|
|
72
|
+
augmentServer.command = command;
|
|
73
|
+
}
|
|
68
74
|
if (serverConfig.args) {
|
|
69
75
|
augmentServer.args = serverConfig.args;
|
|
70
76
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shouldIncludeServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LYVES5YR.js";
|
|
4
4
|
|
|
5
5
|
// src/generators/mcp/copilot.ts
|
|
6
6
|
function generateCopilotMcp(config, target) {
|
|
@@ -11,7 +11,10 @@ function generateCopilotMcp(config, target) {
|
|
|
11
11
|
if (!shouldIncludeServer(server, "copilot")) continue;
|
|
12
12
|
const copilotServer = {};
|
|
13
13
|
if (server.command) {
|
|
14
|
-
|
|
14
|
+
const command = Array.isArray(server.command) ? server.command[0] : server.command;
|
|
15
|
+
if (command) {
|
|
16
|
+
copilotServer.command = command;
|
|
17
|
+
}
|
|
15
18
|
if (server.args) copilotServer.args = server.args;
|
|
16
19
|
} else if (server.url || server.httpUrl) {
|
|
17
20
|
const url = server.httpUrl || server.url;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generateMcpConfigurationFilesFromRegistry,
|
|
3
|
+
generateMcpFromRegistry
|
|
4
|
+
} from "./chunk-6LSN7HSJ.js";
|
|
5
|
+
|
|
6
|
+
// src/generators/mcp/roo.ts
|
|
7
|
+
function generateRooMcp(config) {
|
|
8
|
+
return generateMcpFromRegistry("roo", config);
|
|
9
|
+
}
|
|
10
|
+
function generateRooMcpConfiguration(mcpServers, baseDir = "") {
|
|
11
|
+
return generateMcpConfigurationFilesFromRegistry("roo", mcpServers, baseDir);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
generateRooMcp,
|
|
16
|
+
generateRooMcpConfiguration
|
|
17
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/types/tool-targets.ts
|
|
2
2
|
import { z } from "zod/mini";
|
|
3
3
|
var ALL_TOOL_TARGETS = [
|
|
4
|
+
"amazonqcli",
|
|
4
5
|
"augmentcode",
|
|
5
6
|
"augmentcode-legacy",
|
|
6
7
|
"copilot",
|
|
@@ -8,6 +9,7 @@ var ALL_TOOL_TARGETS = [
|
|
|
8
9
|
"cline",
|
|
9
10
|
"claudecode",
|
|
10
11
|
"codexcli",
|
|
12
|
+
"opencode",
|
|
11
13
|
"roo",
|
|
12
14
|
"geminicli",
|
|
13
15
|
"kiro",
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import {
|
|
2
|
+
shouldIncludeServer
|
|
3
|
+
} from "./chunk-LYVES5YR.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,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateClaudeMcp,
|
|
3
3
|
generateClaudeMcpConfiguration
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-FVPZQEWP.js";
|
|
5
|
+
import "./chunk-6LSN7HSJ.js";
|
|
6
|
+
import "./chunk-LYVES5YR.js";
|
|
7
7
|
export {
|
|
8
8
|
generateClaudeMcp,
|
|
9
9
|
generateClaudeMcpConfiguration
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateClineMcp,
|
|
3
3
|
generateClineMcpConfiguration
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-JX55DU6Y.js";
|
|
5
|
+
import "./chunk-6LSN7HSJ.js";
|
|
6
|
+
import "./chunk-LYVES5YR.js";
|
|
7
7
|
export {
|
|
8
8
|
generateClineMcp,
|
|
9
9
|
generateClineMcpConfiguration
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateCodexMcp,
|
|
3
3
|
generateCodexMcpConfiguration
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-TQOL7OKY.js";
|
|
5
|
+
import "./chunk-6LSN7HSJ.js";
|
|
6
|
+
import "./chunk-LYVES5YR.js";
|
|
7
7
|
export {
|
|
8
8
|
generateCodexMcp,
|
|
9
9
|
generateCodexMcpConfiguration
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateCursorMcp,
|
|
3
3
|
generateCursorMcpConfiguration
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-TBXG53FV.js";
|
|
5
|
+
import "./chunk-6LSN7HSJ.js";
|
|
6
|
+
import "./chunk-LYVES5YR.js";
|
|
7
7
|
export {
|
|
8
8
|
generateCursorMcp,
|
|
9
9
|
generateCursorMcpConfiguration
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateGeminiCliMcp,
|
|
3
3
|
generateGeminiCliMcpConfiguration
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-DMTCLQ4T.js";
|
|
5
|
+
import "./chunk-6LSN7HSJ.js";
|
|
6
|
+
import "./chunk-LYVES5YR.js";
|
|
7
7
|
export {
|
|
8
8
|
generateGeminiCliMcp,
|
|
9
9
|
generateGeminiCliMcpConfiguration
|