rulesync 3.2.0 → 3.3.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 CHANGED
@@ -58,7 +58,7 @@ Rulesync supports both **generation** and **import** for All of the major AI cod
58
58
  | Tool | rules | ignore | mcp | commands | subagents |
59
59
  |------------------------|:-----:|:------:|:-----:|:--------:|:---------:|
60
60
  | AGENTS.md | ✅ | | | 🎮 | 🎮 |
61
- | Claude Code | ✅ 🌏 | ✅ | ✅ | ✅ 🌏 | ✅ |
61
+ | Claude Code | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ 🌏 | ✅ |
62
62
  | Codex CLI | ✅ 🌏 | | 🌏 | 🌏 | 🎮 |
63
63
  | Gemini CLI | ✅ 🌏 | ✅ | | ✅ 🌏 | 🎮 |
64
64
  | GitHub Copilot | ✅ | | ✅ | 🎮 | 🎮 |
package/dist/index.cjs CHANGED
@@ -115,6 +115,7 @@ async function readOrInitializeFileContent(filePath, initialContent = "") {
115
115
  return await readFileContent(filePath);
116
116
  } else {
117
117
  await ensureDir((0, import_node_path.dirname)(filePath));
118
+ await writeFileContent(filePath, initialContent);
118
119
  return initialContent;
119
120
  }
120
121
  }
@@ -2594,12 +2595,17 @@ var ToolMcp = class extends ToolFile {
2594
2595
  static getSettablePaths() {
2595
2596
  throw new Error("Please implement this method in the subclass.");
2596
2597
  }
2597
- toRulesyncMcpDefault() {
2598
+ static getToolTargetsGlobal() {
2599
+ throw new Error("Please implement this method in the subclass.");
2600
+ }
2601
+ toRulesyncMcpDefault({
2602
+ fileContent = void 0
2603
+ } = {}) {
2598
2604
  return new RulesyncMcp({
2599
2605
  baseDir: this.baseDir,
2600
2606
  relativeDirPath: ".rulesync",
2601
2607
  relativeFilePath: ".mcp.json",
2602
- fileContent: this.fileContent
2608
+ fileContent: fileContent ?? this.fileContent
2603
2609
  });
2604
2610
  }
2605
2611
  static async fromFile(_params) {
@@ -2672,7 +2678,7 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2672
2678
  json;
2673
2679
  constructor(params) {
2674
2680
  super(params);
2675
- this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
2681
+ this.json = JSON.parse(this.fileContent || "{}");
2676
2682
  }
2677
2683
  getJson() {
2678
2684
  return this.json;
@@ -2683,40 +2689,57 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2683
2689
  relativeFilePath: ".mcp.json"
2684
2690
  };
2685
2691
  }
2692
+ static getSettablePathsGlobal() {
2693
+ return {
2694
+ relativeDirPath: ".claude",
2695
+ relativeFilePath: ".claude.json"
2696
+ };
2697
+ }
2686
2698
  static async fromFile({
2687
2699
  baseDir = ".",
2688
- validate = true
2700
+ validate = true,
2701
+ global = false
2689
2702
  }) {
2690
- const fileContent = await readFileContent(
2691
- (0, import_node_path27.join)(
2692
- baseDir,
2693
- this.getSettablePaths().relativeDirPath,
2694
- this.getSettablePaths().relativeFilePath
2695
- )
2703
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
2704
+ const fileContent = await readOrInitializeFileContent(
2705
+ (0, import_node_path27.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath),
2706
+ JSON.stringify({ mcpServers: {} }, null, 2)
2696
2707
  );
2708
+ const json = JSON.parse(fileContent);
2709
+ const newJson = { ...json, mcpServers: json.mcpServers ?? {} };
2697
2710
  return new _ClaudecodeMcp({
2698
2711
  baseDir,
2699
- relativeDirPath: this.getSettablePaths().relativeDirPath,
2700
- relativeFilePath: this.getSettablePaths().relativeFilePath,
2701
- fileContent,
2712
+ relativeDirPath: paths.relativeDirPath,
2713
+ relativeFilePath: paths.relativeFilePath,
2714
+ fileContent: JSON.stringify(newJson, null, 2),
2702
2715
  validate
2703
2716
  });
2704
2717
  }
2705
- static fromRulesyncMcp({
2718
+ static async fromRulesyncMcp({
2706
2719
  baseDir = ".",
2707
2720
  rulesyncMcp,
2708
- validate = true
2721
+ validate = true,
2722
+ global = false
2709
2723
  }) {
2724
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
2725
+ const fileContent = await readOrInitializeFileContent(
2726
+ (0, import_node_path27.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath),
2727
+ JSON.stringify({ mcpServers: {} }, null, 2)
2728
+ );
2729
+ const json = JSON.parse(fileContent);
2730
+ const newJson = { ...json, mcpServers: rulesyncMcp.getJson().mcpServers };
2710
2731
  return new _ClaudecodeMcp({
2711
2732
  baseDir,
2712
- relativeDirPath: this.getSettablePaths().relativeDirPath,
2713
- relativeFilePath: this.getSettablePaths().relativeFilePath,
2714
- fileContent: rulesyncMcp.getFileContent(),
2733
+ relativeDirPath: paths.relativeDirPath,
2734
+ relativeFilePath: paths.relativeFilePath,
2735
+ fileContent: JSON.stringify(newJson, null, 2),
2715
2736
  validate
2716
2737
  });
2717
2738
  }
2718
2739
  toRulesyncMcp() {
2719
- return this.toRulesyncMcpDefault();
2740
+ return this.toRulesyncMcpDefault({
2741
+ fileContent: JSON.stringify({ mcpServers: this.json.mcpServers }, null, 2)
2742
+ });
2720
2743
  }
2721
2744
  validate() {
2722
2745
  return { success: true, error: null };
@@ -2780,7 +2803,7 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
2780
2803
  }
2781
2804
  };
2782
2805
 
2783
- // src/mcp/codex-mcp.ts
2806
+ // src/mcp/codexcli-mcp.ts
2784
2807
  var import_node_path29 = require("path");
2785
2808
  var smolToml = __toESM(require("smol-toml"), 1);
2786
2809
  var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
@@ -2856,7 +2879,7 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
2856
2879
  baseDir: this.baseDir,
2857
2880
  relativeDirPath: ".rulesync",
2858
2881
  relativeFilePath: ".mcp.json",
2859
- fileContent: JSON.stringify({ mcpServers: this.toml.mcp_servers ?? {} })
2882
+ fileContent: JSON.stringify({ mcpServers: this.toml.mcp_servers ?? {} }, null, 2)
2860
2883
  });
2861
2884
  }
2862
2885
  validate() {
@@ -3070,7 +3093,7 @@ var McpProcessorToolTargetSchema = import_mini11.z.enum(
3070
3093
  // codexcli is not in the list of tool targets but we add it here because it is a valid tool target for global mode generation
3071
3094
  mcpProcessorToolTargets.concat("codexcli")
3072
3095
  );
3073
- var mcpProcessorToolTargetsGlobal = ["codexcli"];
3096
+ var mcpProcessorToolTargetsGlobal = ["claudecode", "codexcli"];
3074
3097
  var McpProcessor = class extends FeatureProcessor {
3075
3098
  toolTarget;
3076
3099
  global;
@@ -3096,6 +3119,11 @@ var McpProcessor = class extends FeatureProcessor {
3096
3119
  }
3097
3120
  }
3098
3121
  async loadToolFilesToDelete() {
3122
+ if (this.global) {
3123
+ return (await this.loadToolFiles()).filter(
3124
+ (toolFile) => !(toolFile instanceof ClaudecodeMcp)
3125
+ );
3126
+ }
3099
3127
  return this.loadToolFiles();
3100
3128
  }
3101
3129
  /**
@@ -3118,7 +3146,8 @@ var McpProcessor = class extends FeatureProcessor {
3118
3146
  return [
3119
3147
  await ClaudecodeMcp.fromFile({
3120
3148
  baseDir: this.baseDir,
3121
- validate: true
3149
+ validate: true,
3150
+ global: this.global
3122
3151
  })
3123
3152
  ];
3124
3153
  }
@@ -3196,7 +3225,8 @@ var McpProcessor = class extends FeatureProcessor {
3196
3225
  case "claudecode":
3197
3226
  return ClaudecodeMcp.fromRulesyncMcp({
3198
3227
  baseDir: this.baseDir,
3199
- rulesyncMcp: rulesyncMcp2
3228
+ rulesyncMcp: rulesyncMcp2,
3229
+ global: this.global
3200
3230
  });
3201
3231
  case "cline":
3202
3232
  return ClineMcp.fromRulesyncMcp({
@@ -6948,7 +6978,7 @@ globs: ["**/*"]
6948
6978
  }
6949
6979
 
6950
6980
  // src/cli/index.ts
6951
- var getVersion = () => "3.2.0";
6981
+ var getVersion = () => "3.3.0";
6952
6982
  var main = async () => {
6953
6983
  const program = new import_commander.Command();
6954
6984
  const version = getVersion();
package/dist/index.js CHANGED
@@ -92,6 +92,7 @@ async function readOrInitializeFileContent(filePath, initialContent = "") {
92
92
  return await readFileContent(filePath);
93
93
  } else {
94
94
  await ensureDir(dirname(filePath));
95
+ await writeFileContent(filePath, initialContent);
95
96
  return initialContent;
96
97
  }
97
98
  }
@@ -2571,12 +2572,17 @@ var ToolMcp = class extends ToolFile {
2571
2572
  static getSettablePaths() {
2572
2573
  throw new Error("Please implement this method in the subclass.");
2573
2574
  }
2574
- toRulesyncMcpDefault() {
2575
+ static getToolTargetsGlobal() {
2576
+ throw new Error("Please implement this method in the subclass.");
2577
+ }
2578
+ toRulesyncMcpDefault({
2579
+ fileContent = void 0
2580
+ } = {}) {
2575
2581
  return new RulesyncMcp({
2576
2582
  baseDir: this.baseDir,
2577
2583
  relativeDirPath: ".rulesync",
2578
2584
  relativeFilePath: ".mcp.json",
2579
- fileContent: this.fileContent
2585
+ fileContent: fileContent ?? this.fileContent
2580
2586
  });
2581
2587
  }
2582
2588
  static async fromFile(_params) {
@@ -2649,7 +2655,7 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2649
2655
  json;
2650
2656
  constructor(params) {
2651
2657
  super(params);
2652
- this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
2658
+ this.json = JSON.parse(this.fileContent || "{}");
2653
2659
  }
2654
2660
  getJson() {
2655
2661
  return this.json;
@@ -2660,40 +2666,57 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2660
2666
  relativeFilePath: ".mcp.json"
2661
2667
  };
2662
2668
  }
2669
+ static getSettablePathsGlobal() {
2670
+ return {
2671
+ relativeDirPath: ".claude",
2672
+ relativeFilePath: ".claude.json"
2673
+ };
2674
+ }
2663
2675
  static async fromFile({
2664
2676
  baseDir = ".",
2665
- validate = true
2677
+ validate = true,
2678
+ global = false
2666
2679
  }) {
2667
- const fileContent = await readFileContent(
2668
- join26(
2669
- baseDir,
2670
- this.getSettablePaths().relativeDirPath,
2671
- this.getSettablePaths().relativeFilePath
2672
- )
2680
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
2681
+ const fileContent = await readOrInitializeFileContent(
2682
+ join26(baseDir, paths.relativeDirPath, paths.relativeFilePath),
2683
+ JSON.stringify({ mcpServers: {} }, null, 2)
2673
2684
  );
2685
+ const json = JSON.parse(fileContent);
2686
+ const newJson = { ...json, mcpServers: json.mcpServers ?? {} };
2674
2687
  return new _ClaudecodeMcp({
2675
2688
  baseDir,
2676
- relativeDirPath: this.getSettablePaths().relativeDirPath,
2677
- relativeFilePath: this.getSettablePaths().relativeFilePath,
2678
- fileContent,
2689
+ relativeDirPath: paths.relativeDirPath,
2690
+ relativeFilePath: paths.relativeFilePath,
2691
+ fileContent: JSON.stringify(newJson, null, 2),
2679
2692
  validate
2680
2693
  });
2681
2694
  }
2682
- static fromRulesyncMcp({
2695
+ static async fromRulesyncMcp({
2683
2696
  baseDir = ".",
2684
2697
  rulesyncMcp,
2685
- validate = true
2698
+ validate = true,
2699
+ global = false
2686
2700
  }) {
2701
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
2702
+ const fileContent = await readOrInitializeFileContent(
2703
+ join26(baseDir, paths.relativeDirPath, paths.relativeFilePath),
2704
+ JSON.stringify({ mcpServers: {} }, null, 2)
2705
+ );
2706
+ const json = JSON.parse(fileContent);
2707
+ const newJson = { ...json, mcpServers: rulesyncMcp.getJson().mcpServers };
2687
2708
  return new _ClaudecodeMcp({
2688
2709
  baseDir,
2689
- relativeDirPath: this.getSettablePaths().relativeDirPath,
2690
- relativeFilePath: this.getSettablePaths().relativeFilePath,
2691
- fileContent: rulesyncMcp.getFileContent(),
2710
+ relativeDirPath: paths.relativeDirPath,
2711
+ relativeFilePath: paths.relativeFilePath,
2712
+ fileContent: JSON.stringify(newJson, null, 2),
2692
2713
  validate
2693
2714
  });
2694
2715
  }
2695
2716
  toRulesyncMcp() {
2696
- return this.toRulesyncMcpDefault();
2717
+ return this.toRulesyncMcpDefault({
2718
+ fileContent: JSON.stringify({ mcpServers: this.json.mcpServers }, null, 2)
2719
+ });
2697
2720
  }
2698
2721
  validate() {
2699
2722
  return { success: true, error: null };
@@ -2757,7 +2780,7 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
2757
2780
  }
2758
2781
  };
2759
2782
 
2760
- // src/mcp/codex-mcp.ts
2783
+ // src/mcp/codexcli-mcp.ts
2761
2784
  import { join as join28 } from "path";
2762
2785
  import * as smolToml from "smol-toml";
2763
2786
  var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
@@ -2833,7 +2856,7 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
2833
2856
  baseDir: this.baseDir,
2834
2857
  relativeDirPath: ".rulesync",
2835
2858
  relativeFilePath: ".mcp.json",
2836
- fileContent: JSON.stringify({ mcpServers: this.toml.mcp_servers ?? {} })
2859
+ fileContent: JSON.stringify({ mcpServers: this.toml.mcp_servers ?? {} }, null, 2)
2837
2860
  });
2838
2861
  }
2839
2862
  validate() {
@@ -3047,7 +3070,7 @@ var McpProcessorToolTargetSchema = z11.enum(
3047
3070
  // codexcli is not in the list of tool targets but we add it here because it is a valid tool target for global mode generation
3048
3071
  mcpProcessorToolTargets.concat("codexcli")
3049
3072
  );
3050
- var mcpProcessorToolTargetsGlobal = ["codexcli"];
3073
+ var mcpProcessorToolTargetsGlobal = ["claudecode", "codexcli"];
3051
3074
  var McpProcessor = class extends FeatureProcessor {
3052
3075
  toolTarget;
3053
3076
  global;
@@ -3073,6 +3096,11 @@ var McpProcessor = class extends FeatureProcessor {
3073
3096
  }
3074
3097
  }
3075
3098
  async loadToolFilesToDelete() {
3099
+ if (this.global) {
3100
+ return (await this.loadToolFiles()).filter(
3101
+ (toolFile) => !(toolFile instanceof ClaudecodeMcp)
3102
+ );
3103
+ }
3076
3104
  return this.loadToolFiles();
3077
3105
  }
3078
3106
  /**
@@ -3095,7 +3123,8 @@ var McpProcessor = class extends FeatureProcessor {
3095
3123
  return [
3096
3124
  await ClaudecodeMcp.fromFile({
3097
3125
  baseDir: this.baseDir,
3098
- validate: true
3126
+ validate: true,
3127
+ global: this.global
3099
3128
  })
3100
3129
  ];
3101
3130
  }
@@ -3173,7 +3202,8 @@ var McpProcessor = class extends FeatureProcessor {
3173
3202
  case "claudecode":
3174
3203
  return ClaudecodeMcp.fromRulesyncMcp({
3175
3204
  baseDir: this.baseDir,
3176
- rulesyncMcp: rulesyncMcp2
3205
+ rulesyncMcp: rulesyncMcp2,
3206
+ global: this.global
3177
3207
  });
3178
3208
  case "cline":
3179
3209
  return ClineMcp.fromRulesyncMcp({
@@ -6925,7 +6955,7 @@ globs: ["**/*"]
6925
6955
  }
6926
6956
 
6927
6957
  // src/cli/index.ts
6928
- var getVersion = () => "3.2.0";
6958
+ var getVersion = () => "3.3.0";
6929
6959
  var main = async () => {
6930
6960
  const program = new Command();
6931
6961
  const version = getVersion();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulesync",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Unified AI rules management CLI tool that generates configuration files for various AI development tools",
5
5
  "keywords": [
6
6
  "ai",