rulesync 3.22.0 → 3.23.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
@@ -460,6 +460,25 @@ When enabling modular-mcp, each MCP server must have a `description` field. Exam
460
460
  }
461
461
  ```
462
462
 
463
+ You can also configure `exposed` to exclude specific MCP servers from modular-mcp. It is optional and default to `false`. If you specify `exposed: true`, the MCP server is always loaded in the initial context.
464
+
465
+ ```diff
466
+ // .rulesync/mcp.json
467
+ {
468
+ "mcpServers": {
469
+ "context7": {
470
+ + "exposed": true,
471
+ "type": "stdio",
472
+ "command": "npx",
473
+ "args": [
474
+ "-y",
475
+ "@upstash/context7-mcp"
476
+ ],
477
+ "env": {}
478
+ }
479
+ }
480
+ ```
481
+
463
482
  To demonstrate the effect of modular-mcp, please see the following example:
464
483
 
465
484
  <details>
package/dist/index.cjs CHANGED
@@ -46,10 +46,7 @@ function isZodErrorLike(error) {
46
46
  }
47
47
  function formatError(error) {
48
48
  if (error instanceof import_zod.ZodError || isZodErrorLike(error)) {
49
- return error.issues.map((issue) => {
50
- const path2 = issue.path.length > 0 ? `${issue.path.join(".")}: ` : "";
51
- return `${path2}${issue.message}`;
52
- }).join("; ");
49
+ return `Zod raw error: ${JSON.stringify(error.issues)}`;
53
50
  }
54
51
  if (error instanceof Error) {
55
52
  return `${error.name}: ${error.message}`;
@@ -112,10 +109,10 @@ var import_node_path2 = require("path");
112
109
  var import_jsonc_parser = require("jsonc-parser");
113
110
 
114
111
  // src/utils/file.ts
112
+ var import_node_fs = require("fs");
115
113
  var import_promises = require("fs/promises");
116
114
  var import_node_os = __toESM(require("os"), 1);
117
115
  var import_node_path = require("path");
118
- var import_fast_glob = __toESM(require("fast-glob"), 1);
119
116
  async function ensureDir(dirPath) {
120
117
  try {
121
118
  await (0, import_promises.stat)(dirPath);
@@ -190,7 +187,7 @@ async function listDirectoryFiles(dir) {
190
187
  }
191
188
  }
192
189
  async function findFilesByGlobs(globs) {
193
- return await (0, import_fast_glob.default)(globs);
190
+ return (0, import_node_fs.globSync)(globs);
194
191
  }
195
192
  async function removeFile(filepath) {
196
193
  logger.debug(`Removing file: ${filepath}`);
@@ -2743,14 +2740,18 @@ var McpServerBaseSchema = import_mini12.z.object({
2743
2740
  kiroAutoBlock: import_mini12.z.optional(import_mini12.z.array(import_mini12.z.string())),
2744
2741
  headers: import_mini12.z.optional(import_mini12.z.record(import_mini12.z.string(), import_mini12.z.string()))
2745
2742
  });
2746
- var ModularMcpServerSchema = import_mini12.z.extend(McpServerBaseSchema, {
2747
- description: import_mini12.z.string().check(import_mini12.z.minLength(1))
2748
- });
2749
- var ModularMcpServersSchema = import_mini12.z.record(import_mini12.z.string(), ModularMcpServerSchema);
2750
- var RulesyncMcpServersSchema = import_mini12.z.extend(McpServerBaseSchema, {
2751
- description: import_mini12.z.optional(import_mini12.z.string()),
2752
- targets: import_mini12.z.optional(RulesyncTargetsSchema)
2753
- });
2743
+ var RulesyncMcpServersSchema = import_mini12.z.union([
2744
+ import_mini12.z.extend(McpServerBaseSchema, {
2745
+ targets: import_mini12.z.optional(RulesyncTargetsSchema),
2746
+ description: import_mini12.z.optional(import_mini12.z.string()),
2747
+ exposed: import_mini12.z.optional(import_mini12.z.literal(false))
2748
+ }),
2749
+ import_mini12.z.extend(McpServerBaseSchema, {
2750
+ targets: import_mini12.z.optional(RulesyncTargetsSchema),
2751
+ description: import_mini12.z.undefined(),
2752
+ exposed: import_mini12.z.literal(true)
2753
+ })
2754
+ ]);
2754
2755
  var RulesyncMcpConfigSchema = import_mini12.z.object({
2755
2756
  mcpServers: import_mini12.z.record(import_mini12.z.string(), RulesyncMcpServersSchema)
2756
2757
  });
@@ -2781,17 +2782,6 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2781
2782
  };
2782
2783
  }
2783
2784
  validate() {
2784
- if (this.modularMcp) {
2785
- const result = ModularMcpServersSchema.safeParse(this.json.mcpServers);
2786
- if (!result.success) {
2787
- return {
2788
- success: false,
2789
- error: new Error(
2790
- `Invalid MCP server configuration for modular-mcp: ${formatError(result.error)}`
2791
- )
2792
- };
2793
- }
2794
- }
2795
2785
  return { success: true, error: null };
2796
2786
  }
2797
2787
  static async fromFile({
@@ -2841,20 +2831,40 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2841
2831
  modularMcp
2842
2832
  });
2843
2833
  }
2844
- getJson({ modularMcp = false } = {}) {
2845
- if (modularMcp) {
2846
- return this.json;
2834
+ getExposedServers() {
2835
+ if (!this.json || typeof this.json !== "object") {
2836
+ return {};
2837
+ }
2838
+ if (!this.json.mcpServers || typeof this.json.mcpServers !== "object") {
2839
+ return {};
2847
2840
  }
2841
+ return Object.fromEntries(
2842
+ Object.entries(this.json.mcpServers).filter(([, serverConfig]) => serverConfig.exposed === true).map(([serverName, serverConfig]) => [
2843
+ serverName,
2844
+ (0, import_object.omit)(serverConfig, ["description", "exposed"])
2845
+ ])
2846
+ );
2847
+ }
2848
+ getJson({ modularMcp = false } = {}) {
2848
2849
  if (!this.json || typeof this.json !== "object") {
2849
2850
  return this.json;
2850
2851
  }
2851
2852
  if (!this.json.mcpServers || typeof this.json.mcpServers !== "object") {
2852
2853
  return this.json;
2853
2854
  }
2855
+ if (modularMcp) {
2856
+ const mcpServersForModularMcp = Object.fromEntries(
2857
+ Object.entries(this.json.mcpServers).filter(([, serverConfig]) => !serverConfig.exposed).map(([serverName, serverConfig]) => [serverName, (0, import_object.omit)(serverConfig, ["exposed"])])
2858
+ );
2859
+ return {
2860
+ ...this.json,
2861
+ mcpServers: mcpServersForModularMcp
2862
+ };
2863
+ }
2854
2864
  const mcpServersWithoutDescription = Object.fromEntries(
2855
2865
  Object.entries(this.json.mcpServers).map(([serverName, serverConfig]) => [
2856
2866
  serverName,
2857
- (0, import_object.omit)(serverConfig, ["description"])
2867
+ (0, import_object.omit)(serverConfig, ["description", "exposed"])
2858
2868
  ])
2859
2869
  );
2860
2870
  return {
@@ -3107,11 +3117,15 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
3107
3117
  const json = JSON.parse(fileContent);
3108
3118
  const mcpJson = modularMcp ? {
3109
3119
  ...json,
3110
- mcpServers: global ? ModularMcp.getMcpServers({
3111
- baseDir,
3112
- global: true,
3113
- relativeDirPath: this.getSettablePaths({ global: true }).relativeDirPath
3114
- }) : ModularMcp.getMcpServers({ baseDir, global: false })
3120
+ mcpServers: {
3121
+ ...global ? ModularMcp.getMcpServers({
3122
+ baseDir,
3123
+ global: true,
3124
+ relativeDirPath: this.getSettablePaths({ global: true }).relativeDirPath
3125
+ }) : ModularMcp.getMcpServers({ baseDir, global: false }),
3126
+ // Merge exposed servers
3127
+ ...rulesyncMcp.getExposedServers()
3128
+ }
3115
3129
  } : { ...json, mcpServers: rulesyncMcp.getJson({ modularMcp: false }).mcpServers };
3116
3130
  return new _ClaudecodeMcp({
3117
3131
  baseDir,
@@ -8515,7 +8529,7 @@ async function mcpCommand({ version }) {
8515
8529
  }
8516
8530
 
8517
8531
  // src/cli/index.ts
8518
- var getVersion = () => "3.22.0";
8532
+ var getVersion = () => "3.23.0";
8519
8533
  var main = async () => {
8520
8534
  const program = new import_commander.Command();
8521
8535
  const version = getVersion();
package/dist/index.js CHANGED
@@ -23,10 +23,7 @@ function isZodErrorLike(error) {
23
23
  }
24
24
  function formatError(error) {
25
25
  if (error instanceof ZodError || isZodErrorLike(error)) {
26
- return error.issues.map((issue) => {
27
- const path2 = issue.path.length > 0 ? `${issue.path.join(".")}: ` : "";
28
- return `${path2}${issue.message}`;
29
- }).join("; ");
26
+ return `Zod raw error: ${JSON.stringify(error.issues)}`;
30
27
  }
31
28
  if (error instanceof Error) {
32
29
  return `${error.name}: ${error.message}`;
@@ -89,10 +86,10 @@ import { resolve as resolve2 } from "path";
89
86
  import { parse as parseJsonc } from "jsonc-parser";
90
87
 
91
88
  // src/utils/file.ts
89
+ import { globSync } from "fs";
92
90
  import { mkdir, readdir, readFile, rm, stat, writeFile } from "fs/promises";
93
91
  import os from "os";
94
92
  import { basename, dirname, join, relative, resolve } from "path";
95
- import fg from "fast-glob";
96
93
  async function ensureDir(dirPath) {
97
94
  try {
98
95
  await stat(dirPath);
@@ -167,7 +164,7 @@ async function listDirectoryFiles(dir) {
167
164
  }
168
165
  }
169
166
  async function findFilesByGlobs(globs) {
170
- return await fg(globs);
167
+ return globSync(globs);
171
168
  }
172
169
  async function removeFile(filepath) {
173
170
  logger.debug(`Removing file: ${filepath}`);
@@ -2720,14 +2717,18 @@ var McpServerBaseSchema = z12.object({
2720
2717
  kiroAutoBlock: z12.optional(z12.array(z12.string())),
2721
2718
  headers: z12.optional(z12.record(z12.string(), z12.string()))
2722
2719
  });
2723
- var ModularMcpServerSchema = z12.extend(McpServerBaseSchema, {
2724
- description: z12.string().check(z12.minLength(1))
2725
- });
2726
- var ModularMcpServersSchema = z12.record(z12.string(), ModularMcpServerSchema);
2727
- var RulesyncMcpServersSchema = z12.extend(McpServerBaseSchema, {
2728
- description: z12.optional(z12.string()),
2729
- targets: z12.optional(RulesyncTargetsSchema)
2730
- });
2720
+ var RulesyncMcpServersSchema = z12.union([
2721
+ z12.extend(McpServerBaseSchema, {
2722
+ targets: z12.optional(RulesyncTargetsSchema),
2723
+ description: z12.optional(z12.string()),
2724
+ exposed: z12.optional(z12.literal(false))
2725
+ }),
2726
+ z12.extend(McpServerBaseSchema, {
2727
+ targets: z12.optional(RulesyncTargetsSchema),
2728
+ description: z12.undefined(),
2729
+ exposed: z12.literal(true)
2730
+ })
2731
+ ]);
2731
2732
  var RulesyncMcpConfigSchema = z12.object({
2732
2733
  mcpServers: z12.record(z12.string(), RulesyncMcpServersSchema)
2733
2734
  });
@@ -2758,17 +2759,6 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2758
2759
  };
2759
2760
  }
2760
2761
  validate() {
2761
- if (this.modularMcp) {
2762
- const result = ModularMcpServersSchema.safeParse(this.json.mcpServers);
2763
- if (!result.success) {
2764
- return {
2765
- success: false,
2766
- error: new Error(
2767
- `Invalid MCP server configuration for modular-mcp: ${formatError(result.error)}`
2768
- )
2769
- };
2770
- }
2771
- }
2772
2762
  return { success: true, error: null };
2773
2763
  }
2774
2764
  static async fromFile({
@@ -2818,20 +2808,40 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2818
2808
  modularMcp
2819
2809
  });
2820
2810
  }
2821
- getJson({ modularMcp = false } = {}) {
2822
- if (modularMcp) {
2823
- return this.json;
2811
+ getExposedServers() {
2812
+ if (!this.json || typeof this.json !== "object") {
2813
+ return {};
2814
+ }
2815
+ if (!this.json.mcpServers || typeof this.json.mcpServers !== "object") {
2816
+ return {};
2824
2817
  }
2818
+ return Object.fromEntries(
2819
+ Object.entries(this.json.mcpServers).filter(([, serverConfig]) => serverConfig.exposed === true).map(([serverName, serverConfig]) => [
2820
+ serverName,
2821
+ omit(serverConfig, ["description", "exposed"])
2822
+ ])
2823
+ );
2824
+ }
2825
+ getJson({ modularMcp = false } = {}) {
2825
2826
  if (!this.json || typeof this.json !== "object") {
2826
2827
  return this.json;
2827
2828
  }
2828
2829
  if (!this.json.mcpServers || typeof this.json.mcpServers !== "object") {
2829
2830
  return this.json;
2830
2831
  }
2832
+ if (modularMcp) {
2833
+ const mcpServersForModularMcp = Object.fromEntries(
2834
+ Object.entries(this.json.mcpServers).filter(([, serverConfig]) => !serverConfig.exposed).map(([serverName, serverConfig]) => [serverName, omit(serverConfig, ["exposed"])])
2835
+ );
2836
+ return {
2837
+ ...this.json,
2838
+ mcpServers: mcpServersForModularMcp
2839
+ };
2840
+ }
2831
2841
  const mcpServersWithoutDescription = Object.fromEntries(
2832
2842
  Object.entries(this.json.mcpServers).map(([serverName, serverConfig]) => [
2833
2843
  serverName,
2834
- omit(serverConfig, ["description"])
2844
+ omit(serverConfig, ["description", "exposed"])
2835
2845
  ])
2836
2846
  );
2837
2847
  return {
@@ -3084,11 +3094,15 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
3084
3094
  const json = JSON.parse(fileContent);
3085
3095
  const mcpJson = modularMcp ? {
3086
3096
  ...json,
3087
- mcpServers: global ? ModularMcp.getMcpServers({
3088
- baseDir,
3089
- global: true,
3090
- relativeDirPath: this.getSettablePaths({ global: true }).relativeDirPath
3091
- }) : ModularMcp.getMcpServers({ baseDir, global: false })
3097
+ mcpServers: {
3098
+ ...global ? ModularMcp.getMcpServers({
3099
+ baseDir,
3100
+ global: true,
3101
+ relativeDirPath: this.getSettablePaths({ global: true }).relativeDirPath
3102
+ }) : ModularMcp.getMcpServers({ baseDir, global: false }),
3103
+ // Merge exposed servers
3104
+ ...rulesyncMcp.getExposedServers()
3105
+ }
3092
3106
  } : { ...json, mcpServers: rulesyncMcp.getJson({ modularMcp: false }).mcpServers };
3093
3107
  return new _ClaudecodeMcp({
3094
3108
  baseDir,
@@ -8492,7 +8506,7 @@ async function mcpCommand({ version }) {
8492
8506
  }
8493
8507
 
8494
8508
  // src/cli/index.ts
8495
- var getVersion = () => "3.22.0";
8509
+ var getVersion = () => "3.23.0";
8496
8510
  var main = async () => {
8497
8511
  const program = new Command();
8498
8512
  const version = getVersion();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulesync",
3
- "version": "3.22.0",
3
+ "version": "3.23.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",
@@ -42,7 +42,6 @@
42
42
  "commander": "14.0.2",
43
43
  "consola": "3.4.2",
44
44
  "es-toolkit": "1.41.0",
45
- "fast-glob": "3.3.3",
46
45
  "fast-xml-parser": "5.3.2",
47
46
  "fastmcp": "3.23.0",
48
47
  "gray-matter": "4.0.3",