rulesync 0.53.0 → 0.54.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.ja.md +186 -23
- package/README.md +101 -25
- package/dist/{augmentcode-ICLQ2NEZ.js → augmentcode-MJYD2Y4S.js} +2 -2
- package/dist/{chunk-TTHBLXOB.js → chunk-3PHMFVXP.js} +1 -1
- package/dist/{chunk-FFW6TGCM.js → chunk-BEPSWIZC.js} +1 -1
- package/dist/chunk-D7XQ4OHK.js +145 -0
- package/dist/{chunk-OPZOVKIL.js → chunk-ORNO5MOO.js} +1 -1
- package/dist/{chunk-Y2XH4E5R.js → chunk-OXKDEZJK.js} +1 -1
- package/dist/{chunk-FNL2KPM3.js → chunk-OY6BYYIX.js} +1 -1
- package/dist/{chunk-YPIFCGAP.js → chunk-PPAQWVXX.js} +1 -1
- package/dist/{chunk-QUJMXHNR.js → chunk-QVPD6ENS.js} +1 -1
- package/dist/{chunk-Y26DXTAT.js → chunk-TJKD6LEW.js} +1 -1
- package/dist/{chunk-HMMTSS5E.js → chunk-UHANRG2O.js} +1 -1
- package/dist/{chunk-IXCMY24P.js → chunk-UZCJNUXO.js} +1 -1
- package/dist/{chunk-USKQYIZ2.js → chunk-VI6SBYFB.js} +1 -0
- package/dist/{claudecode-4XWK2WAY.js → claudecode-CKGUHLRR.js} +3 -3
- package/dist/{cline-MNXOHP77.js → cline-Z5C656VR.js} +3 -3
- package/dist/codexcli-VFUJKSIJ.js +10 -0
- package/dist/{copilot-ARYIWVJ7.js → copilot-4WQS5TA7.js} +2 -2
- package/dist/{cursor-FCS74IAH.js → cursor-HOB2F2V2.js} +2 -2
- package/dist/{geminicli-VOPV6DXZ.js → geminicli-XTMQTIU2.js} +2 -2
- package/dist/index.cjs +267 -21
- package/dist/index.js +213 -33
- package/dist/{junie-A2Y2WZI4.js → junie-AN6CR7DD.js} +2 -2
- package/dist/{kiro-MHIK4UBV.js → kiro-PTUZOHQ2.js} +2 -2
- package/dist/{roo-VG4IUNTE.js → roo-WOMS36KU.js} +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ var init_tool_targets = __esm({
|
|
|
43
43
|
"cursor",
|
|
44
44
|
"cline",
|
|
45
45
|
"claudecode",
|
|
46
|
+
"codexcli",
|
|
46
47
|
"roo",
|
|
47
48
|
"geminicli",
|
|
48
49
|
"kiro",
|
|
@@ -241,6 +242,73 @@ var init_cline = __esm({
|
|
|
241
242
|
}
|
|
242
243
|
});
|
|
243
244
|
|
|
245
|
+
// src/generators/mcp/codexcli.ts
|
|
246
|
+
function generateCodexMcp(config) {
|
|
247
|
+
return generateMcpConfig(config, {
|
|
248
|
+
target: "codexcli",
|
|
249
|
+
configPaths: [".codex/mcp-config.json"],
|
|
250
|
+
serverTransform: (server) => {
|
|
251
|
+
const codexServer = {};
|
|
252
|
+
if (server.command) {
|
|
253
|
+
codexServer.command = server.command;
|
|
254
|
+
if (server.args) codexServer.args = server.args;
|
|
255
|
+
codexServer.transport = server.transport || "stdio";
|
|
256
|
+
} else if (server.url || server.httpUrl) {
|
|
257
|
+
const url = server.httpUrl || server.url;
|
|
258
|
+
if (url) {
|
|
259
|
+
codexServer.url = url;
|
|
260
|
+
}
|
|
261
|
+
if (server.httpUrl) {
|
|
262
|
+
codexServer.transport = "http";
|
|
263
|
+
} else if (server.transport === "sse") {
|
|
264
|
+
codexServer.transport = "sse";
|
|
265
|
+
} else if (server.transport === "http") {
|
|
266
|
+
codexServer.transport = "http";
|
|
267
|
+
} else {
|
|
268
|
+
codexServer.transport = "stdio";
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
codexServer.transport = "stdio";
|
|
272
|
+
}
|
|
273
|
+
if (server.env) {
|
|
274
|
+
codexServer.env = { ...server.env };
|
|
275
|
+
if (!codexServer.env.CODEX_DEFAULT_MODEL) {
|
|
276
|
+
codexServer.env.CODEX_DEFAULT_MODEL = "gpt-4o-mini";
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (server.cwd) {
|
|
280
|
+
codexServer.cwd = server.cwd;
|
|
281
|
+
codexServer.workingDirectory = server.cwd;
|
|
282
|
+
}
|
|
283
|
+
if (server.timeout) {
|
|
284
|
+
codexServer.timeout = server.timeout;
|
|
285
|
+
}
|
|
286
|
+
if (server.headers) {
|
|
287
|
+
codexServer.headers = server.headers;
|
|
288
|
+
}
|
|
289
|
+
return codexServer;
|
|
290
|
+
},
|
|
291
|
+
configWrapper: (servers) => ({
|
|
292
|
+
// Configuration format for MCP wrapper servers that expose Codex CLI functionality
|
|
293
|
+
servers,
|
|
294
|
+
_comment: "Configuration for MCP wrapper servers like openai-codex-mcp that integrate with Codex CLI",
|
|
295
|
+
_usage: "This file is intended for use with third-party MCP servers that wrap Codex CLI functionality",
|
|
296
|
+
_examples: {
|
|
297
|
+
python_server: "python -m mcp_server or uvicorn codex_server:app",
|
|
298
|
+
nodejs_server: "node dist/server.js or npm start",
|
|
299
|
+
docker_server: "docker run -i --rm custom/codex-mcp:latest"
|
|
300
|
+
},
|
|
301
|
+
_security_note: "Store API keys in environment variables, not in this configuration file"
|
|
302
|
+
})
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
var init_codexcli = __esm({
|
|
306
|
+
"src/generators/mcp/codexcli.ts"() {
|
|
307
|
+
"use strict";
|
|
308
|
+
init_shared_factory();
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
|
|
244
312
|
// src/generators/mcp/copilot.ts
|
|
245
313
|
function generateCopilotMcp(config, target) {
|
|
246
314
|
const servers = {};
|
|
@@ -558,6 +626,7 @@ function getDefaultConfig() {
|
|
|
558
626
|
cursor: ".cursor/rules",
|
|
559
627
|
cline: ".clinerules",
|
|
560
628
|
claudecode: ".",
|
|
629
|
+
codexcli: ".",
|
|
561
630
|
roo: ".roo/rules",
|
|
562
631
|
geminicli: ".gemini/memories",
|
|
563
632
|
kiro: ".kiro/steering",
|
|
@@ -646,6 +715,7 @@ var OutputPathsSchema = import_mini4.z.object({
|
|
|
646
715
|
cursor: import_mini4.z.optional(import_mini4.z.string()),
|
|
647
716
|
cline: import_mini4.z.optional(import_mini4.z.string()),
|
|
648
717
|
claudecode: import_mini4.z.optional(import_mini4.z.string()),
|
|
718
|
+
codexcli: import_mini4.z.optional(import_mini4.z.string()),
|
|
649
719
|
roo: import_mini4.z.optional(import_mini4.z.string()),
|
|
650
720
|
geminicli: import_mini4.z.optional(import_mini4.z.string()),
|
|
651
721
|
kiro: import_mini4.z.optional(import_mini4.z.string()),
|
|
@@ -709,7 +779,8 @@ var McpServerBaseSchema = import_mini5.z.object({
|
|
|
709
779
|
alwaysAllow: import_mini5.z.optional(import_mini5.z.array(import_mini5.z.string())),
|
|
710
780
|
tools: import_mini5.z.optional(import_mini5.z.array(import_mini5.z.string())),
|
|
711
781
|
kiroAutoApprove: import_mini5.z.optional(import_mini5.z.array(import_mini5.z.string())),
|
|
712
|
-
kiroAutoBlock: import_mini5.z.optional(import_mini5.z.array(import_mini5.z.string()))
|
|
782
|
+
kiroAutoBlock: import_mini5.z.optional(import_mini5.z.array(import_mini5.z.string())),
|
|
783
|
+
headers: import_mini5.z.optional(import_mini5.z.record(import_mini5.z.string(), import_mini5.z.string()))
|
|
713
784
|
});
|
|
714
785
|
var RulesyncMcpServerSchema = import_mini5.z.extend(McpServerBaseSchema, {
|
|
715
786
|
targets: import_mini5.z.optional(RulesyncTargetsSchema)
|
|
@@ -1672,6 +1743,135 @@ var ignoreConfigs = {
|
|
|
1672
1743
|
}
|
|
1673
1744
|
return augmentPatterns;
|
|
1674
1745
|
}
|
|
1746
|
+
},
|
|
1747
|
+
codexcli: {
|
|
1748
|
+
tool: "codexcli",
|
|
1749
|
+
filename: ".codexignore",
|
|
1750
|
+
header: [
|
|
1751
|
+
"# Generated by rulesync - OpenAI Codex CLI ignore file",
|
|
1752
|
+
"# This file controls which files are excluded from Codex CLI's AI context",
|
|
1753
|
+
"# Note: .codexignore is a community-requested feature (GitHub Issue #205)",
|
|
1754
|
+
"# Currently using proposed syntax based on .gitignore patterns"
|
|
1755
|
+
],
|
|
1756
|
+
corePatterns: [
|
|
1757
|
+
"# \u2500\u2500\u2500\u2500\u2500 Security & Credentials (Critical) \u2500\u2500\u2500\u2500\u2500",
|
|
1758
|
+
"# Environment files",
|
|
1759
|
+
".env",
|
|
1760
|
+
".env.*",
|
|
1761
|
+
"!.env.example",
|
|
1762
|
+
"",
|
|
1763
|
+
"# Private keys and certificates",
|
|
1764
|
+
"*.key",
|
|
1765
|
+
"*.pem",
|
|
1766
|
+
"*.p12",
|
|
1767
|
+
"*.pfx",
|
|
1768
|
+
"*.der",
|
|
1769
|
+
"*.crt",
|
|
1770
|
+
"",
|
|
1771
|
+
"# SSH keys",
|
|
1772
|
+
"id_rsa*",
|
|
1773
|
+
"id_dsa*",
|
|
1774
|
+
"*.ppk",
|
|
1775
|
+
"",
|
|
1776
|
+
"# API keys and secrets",
|
|
1777
|
+
"api-keys.json",
|
|
1778
|
+
"credentials.json",
|
|
1779
|
+
"secrets.json",
|
|
1780
|
+
"**/apikeys/",
|
|
1781
|
+
"**/*_token*",
|
|
1782
|
+
"**/*_secret*",
|
|
1783
|
+
"**/*api_key*",
|
|
1784
|
+
"",
|
|
1785
|
+
"# Cloud provider credentials",
|
|
1786
|
+
"aws-credentials.json",
|
|
1787
|
+
"gcp-service-account*.json",
|
|
1788
|
+
"azure-credentials.json",
|
|
1789
|
+
".aws/",
|
|
1790
|
+
"",
|
|
1791
|
+
"# \u2500\u2500\u2500\u2500\u2500 Database & Infrastructure Secrets \u2500\u2500\u2500\u2500\u2500",
|
|
1792
|
+
"# Database configuration",
|
|
1793
|
+
"*.db",
|
|
1794
|
+
"*.sqlite",
|
|
1795
|
+
"*.sqlite3",
|
|
1796
|
+
"database.yml",
|
|
1797
|
+
"**/database/config.*",
|
|
1798
|
+
"",
|
|
1799
|
+
"# Infrastructure as Code secrets",
|
|
1800
|
+
"*.tfstate",
|
|
1801
|
+
"*.tfstate.*",
|
|
1802
|
+
"terraform.tfvars",
|
|
1803
|
+
"secrets.auto.tfvars",
|
|
1804
|
+
".terraform/",
|
|
1805
|
+
"",
|
|
1806
|
+
"# Kubernetes secrets",
|
|
1807
|
+
"**/k8s/**/secret*.yaml",
|
|
1808
|
+
"**/kubernetes/**/secret*.yaml",
|
|
1809
|
+
"",
|
|
1810
|
+
"# \u2500\u2500\u2500\u2500\u2500 Business Sensitive Data \u2500\u2500\u2500\u2500\u2500",
|
|
1811
|
+
"# Sensitive directories",
|
|
1812
|
+
"secrets/",
|
|
1813
|
+
"private/",
|
|
1814
|
+
"confidential/",
|
|
1815
|
+
"internal-docs/",
|
|
1816
|
+
"company-secrets/",
|
|
1817
|
+
"",
|
|
1818
|
+
"# Customer and personal data",
|
|
1819
|
+
"customer-data/",
|
|
1820
|
+
"pii/",
|
|
1821
|
+
"personal-data/",
|
|
1822
|
+
"**/*customer*.csv",
|
|
1823
|
+
"**/*personal*.json",
|
|
1824
|
+
"",
|
|
1825
|
+
"# \u2500\u2500\u2500\u2500\u2500 Build Artifacts & Large Files \u2500\u2500\u2500\u2500\u2500",
|
|
1826
|
+
"# Build outputs (may contain embedded secrets)",
|
|
1827
|
+
"dist/",
|
|
1828
|
+
"build/",
|
|
1829
|
+
"out/",
|
|
1830
|
+
".next/",
|
|
1831
|
+
".nuxt/",
|
|
1832
|
+
"",
|
|
1833
|
+
"# Large files that slow down AI processing",
|
|
1834
|
+
"*.zip",
|
|
1835
|
+
"*.tar.gz",
|
|
1836
|
+
"*.rar",
|
|
1837
|
+
"**/*.{mp4,avi,mov,mkv}",
|
|
1838
|
+
"**/*.{pdf,doc,docx}",
|
|
1839
|
+
"",
|
|
1840
|
+
"# Data files",
|
|
1841
|
+
"*.csv",
|
|
1842
|
+
"*.tsv",
|
|
1843
|
+
"*.xlsx",
|
|
1844
|
+
"data/",
|
|
1845
|
+
"datasets/",
|
|
1846
|
+
"",
|
|
1847
|
+
"# \u2500\u2500\u2500\u2500\u2500 Development Environment \u2500\u2500\u2500\u2500\u2500",
|
|
1848
|
+
"# Personal IDE settings",
|
|
1849
|
+
".vscode/settings.json",
|
|
1850
|
+
".idea/workspace.xml",
|
|
1851
|
+
"",
|
|
1852
|
+
"# Temporary files",
|
|
1853
|
+
"*.swp",
|
|
1854
|
+
"*.swo",
|
|
1855
|
+
"*~",
|
|
1856
|
+
"*.tmp",
|
|
1857
|
+
"",
|
|
1858
|
+
"# Test data with sensitive content",
|
|
1859
|
+
"test-data/sensitive/",
|
|
1860
|
+
"tests/fixtures/real-data/**",
|
|
1861
|
+
"",
|
|
1862
|
+
"# \u2500\u2500\u2500\u2500\u2500 Logs & Runtime Data \u2500\u2500\u2500\u2500\u2500",
|
|
1863
|
+
"*.log",
|
|
1864
|
+
"logs/",
|
|
1865
|
+
".cache/",
|
|
1866
|
+
"",
|
|
1867
|
+
"# \u2500\u2500\u2500\u2500\u2500 Re-include Important Files \u2500\u2500\u2500\u2500\u2500",
|
|
1868
|
+
"# Allow configuration examples and documentation",
|
|
1869
|
+
"!secrets/README.md",
|
|
1870
|
+
"!config/*.example.*",
|
|
1871
|
+
"!docs/**/*.md"
|
|
1872
|
+
],
|
|
1873
|
+
includeCommonPatterns: false,
|
|
1874
|
+
projectPatternsHeader: "# \u2500\u2500\u2500\u2500\u2500 Project-specific patterns from rulesync rules \u2500\u2500\u2500\u2500\u2500"
|
|
1675
1875
|
}
|
|
1676
1876
|
};
|
|
1677
1877
|
|
|
@@ -2016,6 +2216,37 @@ async function generateClineConfig(rules, config, baseDir) {
|
|
|
2016
2216
|
);
|
|
2017
2217
|
}
|
|
2018
2218
|
|
|
2219
|
+
// src/generators/rules/codexcli.ts
|
|
2220
|
+
async function generateCodexConfig(rules, config, baseDir) {
|
|
2221
|
+
const generatorConfig = {
|
|
2222
|
+
tool: "codexcli",
|
|
2223
|
+
fileExtension: ".md",
|
|
2224
|
+
ignoreFileName: ".codexignore",
|
|
2225
|
+
generateContent: generateCodexInstructionsMarkdown,
|
|
2226
|
+
pathResolver: (rule, outputDir) => {
|
|
2227
|
+
if (rule.frontmatter.root === true) {
|
|
2228
|
+
return `${outputDir}/codex.md`;
|
|
2229
|
+
}
|
|
2230
|
+
return `${outputDir}/${rule.filename}.md`;
|
|
2231
|
+
}
|
|
2232
|
+
};
|
|
2233
|
+
return generateRulesConfig(rules, config, generatorConfig, baseDir);
|
|
2234
|
+
}
|
|
2235
|
+
function generateCodexInstructionsMarkdown(rule) {
|
|
2236
|
+
const lines = [];
|
|
2237
|
+
if (rule.frontmatter.root === false && rule.frontmatter.description && rule.frontmatter.description !== "Main instructions" && !rule.frontmatter.description.includes("Project-level Codex CLI instructions")) {
|
|
2238
|
+
lines.push(`<!-- ${rule.frontmatter.description} -->`);
|
|
2239
|
+
if (rule.content.trim()) {
|
|
2240
|
+
lines.push("");
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
const content = rule.content.trim();
|
|
2244
|
+
if (content) {
|
|
2245
|
+
lines.push(content);
|
|
2246
|
+
}
|
|
2247
|
+
return lines.join("\n");
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2019
2250
|
// src/generators/rules/copilot.ts
|
|
2020
2251
|
var import_node_path8 = require("path");
|
|
2021
2252
|
async function generateCopilotConfig(rules, config, baseDir) {
|
|
@@ -2280,6 +2511,8 @@ async function generateForTool(tool, rules, config, baseDir) {
|
|
|
2280
2511
|
return generateClineConfig(rules, config, baseDir);
|
|
2281
2512
|
case "claudecode":
|
|
2282
2513
|
return await generateClaudecodeConfig(rules, config, baseDir);
|
|
2514
|
+
case "codexcli":
|
|
2515
|
+
return generateCodexConfig(rules, config, baseDir);
|
|
2283
2516
|
case "roo":
|
|
2284
2517
|
return generateRooConfig(rules, config, baseDir);
|
|
2285
2518
|
case "geminicli":
|
|
@@ -2410,6 +2643,7 @@ var path4 = __toESM(require("path"), 1);
|
|
|
2410
2643
|
init_augmentcode();
|
|
2411
2644
|
init_claudecode();
|
|
2412
2645
|
init_cline();
|
|
2646
|
+
init_codexcli();
|
|
2413
2647
|
init_copilot();
|
|
2414
2648
|
init_cursor();
|
|
2415
2649
|
init_geminicli();
|
|
@@ -2483,6 +2717,11 @@ async function generateMcpConfigs(projectRoot, baseDir, targetTools) {
|
|
|
2483
2717
|
path: path4.join(targetRoot, ".cline", "mcp.json"),
|
|
2484
2718
|
generate: () => generateClineMcp(config)
|
|
2485
2719
|
},
|
|
2720
|
+
{
|
|
2721
|
+
tool: "codexcli-project",
|
|
2722
|
+
path: path4.join(targetRoot, ".codex", "mcp-config.json"),
|
|
2723
|
+
generate: () => generateCodexMcp(config)
|
|
2724
|
+
},
|
|
2486
2725
|
{
|
|
2487
2726
|
tool: "gemini-project",
|
|
2488
2727
|
path: path4.join(targetRoot, ".gemini", "settings.json"),
|
|
@@ -2518,7 +2757,7 @@ async function generateMcpConfigs(projectRoot, baseDir, targetTools) {
|
|
|
2518
2757
|
try {
|
|
2519
2758
|
const content = generator.generate();
|
|
2520
2759
|
const parsed = JSON.parse(content);
|
|
2521
|
-
if (generator.tool.includes("augmentcode") || generator.tool.includes("claude") || generator.tool.includes("cline") || generator.tool.includes("cursor") || generator.tool.includes("gemini") || generator.tool.includes("junie") || generator.tool.includes("kiro") || generator.tool.includes("roo")) {
|
|
2760
|
+
if (generator.tool.includes("augmentcode") || generator.tool.includes("claude") || generator.tool.includes("cline") || generator.tool.includes("codexcli") || generator.tool.includes("cursor") || generator.tool.includes("gemini") || generator.tool.includes("junie") || generator.tool.includes("kiro") || generator.tool.includes("roo")) {
|
|
2522
2761
|
if (!parsed.mcpServers || Object.keys(parsed.mcpServers).length === 0) {
|
|
2523
2762
|
results.push({
|
|
2524
2763
|
tool: generator.tool,
|
|
@@ -2743,6 +2982,8 @@ var gitignoreCommand = async () => {
|
|
|
2743
2982
|
"**/.clineignore",
|
|
2744
2983
|
"**/CLAUDE.md",
|
|
2745
2984
|
"**/.claude/memories/",
|
|
2985
|
+
"**/codex.md",
|
|
2986
|
+
"**/.codexignore",
|
|
2746
2987
|
"**/.roo/rules/",
|
|
2747
2988
|
"**/.rooignore",
|
|
2748
2989
|
"**/.copilotignore",
|
|
@@ -2761,6 +3002,7 @@ var gitignoreCommand = async () => {
|
|
|
2761
3002
|
"**/.cursor/mcp.json",
|
|
2762
3003
|
"**/.cline/mcp.json",
|
|
2763
3004
|
"**/.vscode/mcp.json",
|
|
3005
|
+
"**/.codex/mcp-config.json",
|
|
2764
3006
|
"**/.gemini/settings.json",
|
|
2765
3007
|
"**/.roo/mcp.json"
|
|
2766
3008
|
];
|
|
@@ -2793,7 +3035,7 @@ ${linesToAdd.join("\n")}
|
|
|
2793
3035
|
};
|
|
2794
3036
|
|
|
2795
3037
|
// src/core/importer.ts
|
|
2796
|
-
var
|
|
3038
|
+
var import_node_path20 = require("path");
|
|
2797
3039
|
var import_gray_matter5 = __toESM(require("gray-matter"), 1);
|
|
2798
3040
|
|
|
2799
3041
|
// src/parsers/augmentcode.ts
|
|
@@ -3218,6 +3460,9 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
|
|
|
3218
3460
|
});
|
|
3219
3461
|
}
|
|
3220
3462
|
|
|
3463
|
+
// src/parsers/codexcli.ts
|
|
3464
|
+
var import_node_path17 = require("path");
|
|
3465
|
+
|
|
3221
3466
|
// src/parsers/copilot.ts
|
|
3222
3467
|
async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
3223
3468
|
return parseConfigurationFiles(baseDir, {
|
|
@@ -3239,7 +3484,7 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
|
|
|
3239
3484
|
}
|
|
3240
3485
|
|
|
3241
3486
|
// src/parsers/cursor.ts
|
|
3242
|
-
var
|
|
3487
|
+
var import_node_path18 = require("path");
|
|
3243
3488
|
var import_gray_matter4 = __toESM(require("gray-matter"), 1);
|
|
3244
3489
|
var import_js_yaml = require("js-yaml");
|
|
3245
3490
|
var import_mini7 = require("zod/mini");
|
|
@@ -3364,7 +3609,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
3364
3609
|
const rules = [];
|
|
3365
3610
|
let ignorePatterns;
|
|
3366
3611
|
let mcpServers;
|
|
3367
|
-
const cursorFilePath = (0,
|
|
3612
|
+
const cursorFilePath = (0, import_node_path18.join)(baseDir, ".cursorrules");
|
|
3368
3613
|
if (await fileExists(cursorFilePath)) {
|
|
3369
3614
|
try {
|
|
3370
3615
|
const rawContent = await readFileContent(cursorFilePath);
|
|
@@ -3385,20 +3630,20 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
3385
3630
|
errors.push(`Failed to parse .cursorrules file: ${errorMessage}`);
|
|
3386
3631
|
}
|
|
3387
3632
|
}
|
|
3388
|
-
const cursorRulesDir = (0,
|
|
3633
|
+
const cursorRulesDir = (0, import_node_path18.join)(baseDir, ".cursor", "rules");
|
|
3389
3634
|
if (await fileExists(cursorRulesDir)) {
|
|
3390
3635
|
try {
|
|
3391
3636
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
3392
3637
|
const files = await readdir2(cursorRulesDir);
|
|
3393
3638
|
for (const file of files) {
|
|
3394
3639
|
if (file.endsWith(".mdc")) {
|
|
3395
|
-
const filePath = (0,
|
|
3640
|
+
const filePath = (0, import_node_path18.join)(cursorRulesDir, file);
|
|
3396
3641
|
try {
|
|
3397
3642
|
const rawContent = await readFileContent(filePath);
|
|
3398
3643
|
const parsed = (0, import_gray_matter4.default)(rawContent, customMatterOptions);
|
|
3399
3644
|
const content = parsed.content.trim();
|
|
3400
3645
|
if (content) {
|
|
3401
|
-
const filename = (0,
|
|
3646
|
+
const filename = (0, import_node_path18.basename)(file, ".mdc");
|
|
3402
3647
|
const frontmatter = convertCursorMdcFrontmatter(parsed.data, filename);
|
|
3403
3648
|
rules.push({
|
|
3404
3649
|
frontmatter,
|
|
@@ -3421,7 +3666,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
3421
3666
|
if (rules.length === 0) {
|
|
3422
3667
|
errors.push("No Cursor configuration files found (.cursorrules or .cursor/rules/*.mdc)");
|
|
3423
3668
|
}
|
|
3424
|
-
const cursorIgnorePath = (0,
|
|
3669
|
+
const cursorIgnorePath = (0, import_node_path18.join)(baseDir, ".cursorignore");
|
|
3425
3670
|
if (await fileExists(cursorIgnorePath)) {
|
|
3426
3671
|
try {
|
|
3427
3672
|
const content = await readFileContent(cursorIgnorePath);
|
|
@@ -3434,7 +3679,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
|
|
|
3434
3679
|
errors.push(`Failed to parse .cursorignore: ${errorMessage}`);
|
|
3435
3680
|
}
|
|
3436
3681
|
}
|
|
3437
|
-
const cursorMcpPath = (0,
|
|
3682
|
+
const cursorMcpPath = (0, import_node_path18.join)(baseDir, ".cursor", "mcp.json");
|
|
3438
3683
|
if (await fileExists(cursorMcpPath)) {
|
|
3439
3684
|
try {
|
|
3440
3685
|
const content = await readFileContent(cursorMcpPath);
|
|
@@ -3483,11 +3728,11 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
|
|
|
3483
3728
|
}
|
|
3484
3729
|
|
|
3485
3730
|
// src/parsers/junie.ts
|
|
3486
|
-
var
|
|
3731
|
+
var import_node_path19 = require("path");
|
|
3487
3732
|
async function parseJunieConfiguration(baseDir = process.cwd()) {
|
|
3488
3733
|
const errors = [];
|
|
3489
3734
|
const rules = [];
|
|
3490
|
-
const guidelinesPath = (0,
|
|
3735
|
+
const guidelinesPath = (0, import_node_path19.join)(baseDir, ".junie", "guidelines.md");
|
|
3491
3736
|
if (!await fileExists(guidelinesPath)) {
|
|
3492
3737
|
errors.push(".junie/guidelines.md file not found");
|
|
3493
3738
|
return { rules, errors };
|
|
@@ -3622,7 +3867,7 @@ async function importConfiguration(options) {
|
|
|
3622
3867
|
if (rules.length === 0 && !ignorePatterns && !mcpServers) {
|
|
3623
3868
|
return { success: false, rulesCreated: 0, errors };
|
|
3624
3869
|
}
|
|
3625
|
-
const rulesDirPath = (0,
|
|
3870
|
+
const rulesDirPath = (0, import_node_path20.join)(baseDir, rulesDir);
|
|
3626
3871
|
try {
|
|
3627
3872
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
3628
3873
|
await mkdir3(rulesDirPath, { recursive: true });
|
|
@@ -3636,7 +3881,7 @@ async function importConfiguration(options) {
|
|
|
3636
3881
|
try {
|
|
3637
3882
|
const baseFilename = rule.filename;
|
|
3638
3883
|
const filename = await generateUniqueFilename(rulesDirPath, baseFilename);
|
|
3639
|
-
const filePath = (0,
|
|
3884
|
+
const filePath = (0, import_node_path20.join)(rulesDirPath, `${filename}.md`);
|
|
3640
3885
|
const content = generateRuleFileContent(rule);
|
|
3641
3886
|
await writeFileContent(filePath, content);
|
|
3642
3887
|
rulesCreated++;
|
|
@@ -3651,7 +3896,7 @@ async function importConfiguration(options) {
|
|
|
3651
3896
|
let ignoreFileCreated = false;
|
|
3652
3897
|
if (ignorePatterns && ignorePatterns.length > 0) {
|
|
3653
3898
|
try {
|
|
3654
|
-
const rulesyncignorePath = (0,
|
|
3899
|
+
const rulesyncignorePath = (0, import_node_path20.join)(baseDir, ".rulesyncignore");
|
|
3655
3900
|
const ignoreContent = `${ignorePatterns.join("\n")}
|
|
3656
3901
|
`;
|
|
3657
3902
|
await writeFileContent(rulesyncignorePath, ignoreContent);
|
|
@@ -3667,7 +3912,7 @@ async function importConfiguration(options) {
|
|
|
3667
3912
|
let mcpFileCreated = false;
|
|
3668
3913
|
if (mcpServers && Object.keys(mcpServers).length > 0) {
|
|
3669
3914
|
try {
|
|
3670
|
-
const mcpPath = (0,
|
|
3915
|
+
const mcpPath = (0, import_node_path20.join)(baseDir, rulesDir, ".mcp.json");
|
|
3671
3916
|
const mcpContent = `${JSON.stringify({ mcpServers }, null, 2)}
|
|
3672
3917
|
`;
|
|
3673
3918
|
await writeFileContent(mcpPath, mcpContent);
|
|
@@ -3695,7 +3940,7 @@ function generateRuleFileContent(rule) {
|
|
|
3695
3940
|
async function generateUniqueFilename(rulesDir, baseFilename) {
|
|
3696
3941
|
let filename = baseFilename;
|
|
3697
3942
|
let counter = 1;
|
|
3698
|
-
while (await fileExists((0,
|
|
3943
|
+
while (await fileExists((0, import_node_path20.join)(rulesDir, `${filename}.md`))) {
|
|
3699
3944
|
filename = `${baseFilename}-${counter}`;
|
|
3700
3945
|
counter++;
|
|
3701
3946
|
}
|
|
@@ -3762,7 +4007,7 @@ async function importCommand(options = {}) {
|
|
|
3762
4007
|
}
|
|
3763
4008
|
|
|
3764
4009
|
// src/cli/commands/init.ts
|
|
3765
|
-
var
|
|
4010
|
+
var import_node_path21 = require("path");
|
|
3766
4011
|
async function initCommand() {
|
|
3767
4012
|
const aiRulesDir = ".rulesync";
|
|
3768
4013
|
console.log("Initializing rulesync...");
|
|
@@ -3809,7 +4054,7 @@ globs: ["**/*"]
|
|
|
3809
4054
|
- Follow single responsibility principle
|
|
3810
4055
|
`
|
|
3811
4056
|
};
|
|
3812
|
-
const filepath = (0,
|
|
4057
|
+
const filepath = (0, import_node_path21.join)(aiRulesDir, sampleFile.filename);
|
|
3813
4058
|
if (!await fileExists(filepath)) {
|
|
3814
4059
|
await writeFileContent(filepath, sampleFile.content);
|
|
3815
4060
|
console.log(`Created ${filepath}`);
|
|
@@ -3953,12 +4198,12 @@ async function watchCommand() {
|
|
|
3953
4198
|
|
|
3954
4199
|
// src/cli/index.ts
|
|
3955
4200
|
var program = new import_commander.Command();
|
|
3956
|
-
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.
|
|
4201
|
+
program.name("rulesync").description("Unified AI rules management CLI tool").version("0.54.0");
|
|
3957
4202
|
program.command("init").description("Initialize rulesync in current directory").action(initCommand);
|
|
3958
4203
|
program.command("add <filename>").description("Add a new rule file").action(addCommand);
|
|
3959
4204
|
program.command("gitignore").description("Add generated files to .gitignore").action(gitignoreCommand);
|
|
3960
4205
|
program.command("import").description("Import configurations from AI tools to rulesync format").option("--augmentcode", "Import from AugmentCode (.augment/rules/)").option("--augmentcode-legacy", "Import from AugmentCode legacy format (.augment-guidelines)").option("--claudecode", "Import from Claude Code (CLAUDE.md)").option("--cursor", "Import from Cursor (.cursorrules)").option("--copilot", "Import from GitHub Copilot (.github/copilot-instructions.md)").option("--cline", "Import from Cline (.cline/instructions.md)").option("--roo", "Import from Roo Code (.roo/instructions.md)").option("--geminicli", "Import from Gemini CLI (GEMINI.md)").option("--junie", "Import from JetBrains Junie (.junie/guidelines.md)").option("-v, --verbose", "Verbose output").action(importCommand);
|
|
3961
|
-
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("--claudecode", "Generate only for Claude Code").option("--roo", "Generate only for Roo Code").option("--geminicli", "Generate only for Gemini CLI").option("--junie", "Generate only for JetBrains Junie").option("--kiro", "Generate only for Kiro IDE").option("--delete", "Delete all existing files in output directories before generating").option(
|
|
4206
|
+
program.command("generate").description("Generate configuration files for AI tools").option("--augmentcode", "Generate only for AugmentCode").option("--augmentcode-legacy", "Generate only for AugmentCode legacy format").option("--copilot", "Generate only for GitHub Copilot").option("--cursor", "Generate only for Cursor").option("--cline", "Generate only for Cline").option("--codexcli", "Generate only for OpenAI Codex CLI").option("--claudecode", "Generate only for Claude Code").option("--roo", "Generate only for Roo Code").option("--geminicli", "Generate only for Gemini CLI").option("--junie", "Generate only for JetBrains Junie").option("--kiro", "Generate only for Kiro IDE").option("--delete", "Delete all existing files in output directories before generating").option(
|
|
3962
4207
|
"-b, --base-dir <paths>",
|
|
3963
4208
|
"Base directories to generate files (comma-separated for multiple paths)"
|
|
3964
4209
|
).option("-v, --verbose", "Verbose output").option("-c, --config <path>", "Path to configuration file").option("--no-config", "Disable configuration file loading").action(async (options) => {
|
|
@@ -3968,6 +4213,7 @@ program.command("generate").description("Generate configuration files for AI too
|
|
|
3968
4213
|
if (options.copilot) tools.push("copilot");
|
|
3969
4214
|
if (options.cursor) tools.push("cursor");
|
|
3970
4215
|
if (options.cline) tools.push("cline");
|
|
4216
|
+
if (options.codexcli) tools.push("codexcli");
|
|
3971
4217
|
if (options.claudecode) tools.push("claudecode");
|
|
3972
4218
|
if (options.roo) tools.push("roo");
|
|
3973
4219
|
if (options.geminicli) tools.push("geminicli");
|