rulesync 3.11.3 → 3.12.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.
Files changed (4) hide show
  1. package/README.md +38 -3
  2. package/dist/index.cjs +326 -148
  3. package/dist/index.js +316 -138
  4. package/package.json +11 -10
package/dist/index.js CHANGED
@@ -1628,6 +1628,7 @@ var Config = class {
1628
1628
  global;
1629
1629
  simulatedCommands;
1630
1630
  simulatedSubagents;
1631
+ modularMcp;
1631
1632
  constructor({
1632
1633
  baseDirs,
1633
1634
  targets,
@@ -1637,6 +1638,7 @@ var Config = class {
1637
1638
  global,
1638
1639
  simulatedCommands,
1639
1640
  simulatedSubagents,
1641
+ modularMcp,
1640
1642
  experimentalGlobal,
1641
1643
  experimentalSimulateCommands,
1642
1644
  experimentalSimulateSubagents
@@ -1649,6 +1651,7 @@ var Config = class {
1649
1651
  this.global = global ?? experimentalGlobal ?? false;
1650
1652
  this.simulatedCommands = simulatedCommands ?? experimentalSimulateCommands ?? false;
1651
1653
  this.simulatedSubagents = simulatedSubagents ?? experimentalSimulateSubagents ?? false;
1654
+ this.modularMcp = modularMcp ?? false;
1652
1655
  }
1653
1656
  getBaseDirs() {
1654
1657
  return this.baseDirs;
@@ -1680,6 +1683,9 @@ var Config = class {
1680
1683
  getSimulatedSubagents() {
1681
1684
  return this.simulatedSubagents;
1682
1685
  }
1686
+ getModularMcp() {
1687
+ return this.modularMcp;
1688
+ }
1683
1689
  // Deprecated getters for backward compatibility
1684
1690
  /** @deprecated Use getGlobal() instead */
1685
1691
  getExperimentalGlobal() {
@@ -1706,6 +1712,7 @@ var defaults = {
1706
1712
  global: false,
1707
1713
  simulatedCommands: false,
1708
1714
  simulatedSubagents: false,
1715
+ modularMcp: false,
1709
1716
  experimentalGlobal: false,
1710
1717
  experimentalSimulateCommands: false,
1711
1718
  experimentalSimulateSubagents: false
@@ -1721,6 +1728,7 @@ var ConfigResolver = class {
1721
1728
  global,
1722
1729
  simulatedCommands,
1723
1730
  simulatedSubagents,
1731
+ modularMcp,
1724
1732
  experimentalGlobal,
1725
1733
  experimentalSimulateCommands,
1726
1734
  experimentalSimulateSubagents
@@ -1749,7 +1757,8 @@ var ConfigResolver = class {
1749
1757
  }),
1750
1758
  global: resolvedGlobal2,
1751
1759
  simulatedCommands: resolvedSimulatedCommands2,
1752
- simulatedSubagents: resolvedSimulatedSubagents2
1760
+ simulatedSubagents: resolvedSimulatedSubagents2,
1761
+ modularMcp: modularMcp ?? defaults.modularMcp
1753
1762
  });
1754
1763
  }
1755
1764
  const loadOptions = {
@@ -1790,7 +1799,8 @@ var ConfigResolver = class {
1790
1799
  }),
1791
1800
  global: resolvedGlobal,
1792
1801
  simulatedCommands: resolvedSimulatedCommands,
1793
- simulatedSubagents: resolvedSimulatedSubagents
1802
+ simulatedSubagents: resolvedSimulatedSubagents,
1803
+ modularMcp: modularMcp ?? configByFile.modularMcp ?? defaults.modularMcp
1794
1804
  };
1795
1805
  return new Config(configParams);
1796
1806
  }
@@ -2658,6 +2668,7 @@ import { join as join25 } from "path";
2658
2668
 
2659
2669
  // src/mcp/rulesync-mcp.ts
2660
2670
  import { join as join24 } from "path";
2671
+ import { omit } from "es-toolkit/object";
2661
2672
  import { z as z11 } from "zod/mini";
2662
2673
  var McpTransportTypeSchema = z11.enum(["stdio", "sse", "http"]);
2663
2674
  var McpServerBaseSchema = z11.object({
@@ -2679,7 +2690,12 @@ var McpServerBaseSchema = z11.object({
2679
2690
  kiroAutoBlock: z11.optional(z11.array(z11.string())),
2680
2691
  headers: z11.optional(z11.record(z11.string(), z11.string()))
2681
2692
  });
2693
+ var ModularMcpServerSchema = z11.extend(McpServerBaseSchema, {
2694
+ description: z11.string().check(z11.minLength(1))
2695
+ });
2696
+ var ModularMcpServersSchema = z11.record(z11.string(), ModularMcpServerSchema);
2682
2697
  var RulesyncMcpServersSchema = z11.extend(McpServerBaseSchema, {
2698
+ description: z11.optional(z11.string()),
2683
2699
  targets: z11.optional(RulesyncTargetsSchema)
2684
2700
  });
2685
2701
  var RulesyncMcpConfigSchema = z11.object({
@@ -2687,9 +2703,11 @@ var RulesyncMcpConfigSchema = z11.object({
2687
2703
  });
2688
2704
  var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2689
2705
  json;
2690
- constructor({ ...rest }) {
2706
+ modularMcp;
2707
+ constructor({ modularMcp = false, ...rest }) {
2691
2708
  super({ ...rest });
2692
2709
  this.json = JSON.parse(this.fileContent);
2710
+ this.modularMcp = modularMcp;
2693
2711
  if (rest.validate) {
2694
2712
  const result = this.validate();
2695
2713
  if (!result.success) {
@@ -2710,9 +2728,23 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2710
2728
  };
2711
2729
  }
2712
2730
  validate() {
2731
+ if (this.modularMcp) {
2732
+ const result = ModularMcpServersSchema.safeParse(this.json.mcpServers);
2733
+ if (!result.success) {
2734
+ return {
2735
+ success: false,
2736
+ error: new Error(
2737
+ `Invalid MCP server configuration for modular-mcp: ${result.error.message}`
2738
+ )
2739
+ };
2740
+ }
2741
+ }
2713
2742
  return { success: true, error: null };
2714
2743
  }
2715
- static async fromFile({ validate = true }) {
2744
+ static async fromFile({
2745
+ validate = true,
2746
+ modularMcp = false
2747
+ }) {
2716
2748
  const paths = this.getSettablePaths();
2717
2749
  const recommendedPath = join24(
2718
2750
  paths.recommended.relativeDirPath,
@@ -2726,7 +2758,8 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2726
2758
  relativeDirPath: paths.recommended.relativeDirPath,
2727
2759
  relativeFilePath: paths.recommended.relativeFilePath,
2728
2760
  fileContent: fileContent2,
2729
- validate
2761
+ validate,
2762
+ modularMcp
2730
2763
  });
2731
2764
  }
2732
2765
  if (await fileExists(legacyPath)) {
@@ -2739,7 +2772,8 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2739
2772
  relativeDirPath: paths.legacy.relativeDirPath,
2740
2773
  relativeFilePath: paths.legacy.relativeFilePath,
2741
2774
  fileContent: fileContent2,
2742
- validate
2775
+ validate,
2776
+ modularMcp
2743
2777
  });
2744
2778
  }
2745
2779
  const fileContent = await readFileContent(recommendedPath);
@@ -2748,11 +2782,30 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2748
2782
  relativeDirPath: paths.recommended.relativeDirPath,
2749
2783
  relativeFilePath: paths.recommended.relativeFilePath,
2750
2784
  fileContent,
2751
- validate
2785
+ validate,
2786
+ modularMcp
2752
2787
  });
2753
2788
  }
2754
- getJson() {
2755
- return this.json;
2789
+ getJson({ modularMcp = false } = {}) {
2790
+ if (modularMcp) {
2791
+ return this.json;
2792
+ }
2793
+ if (!this.json || typeof this.json !== "object") {
2794
+ return this.json;
2795
+ }
2796
+ if (!this.json.mcpServers || typeof this.json.mcpServers !== "object") {
2797
+ return this.json;
2798
+ }
2799
+ const mcpServersWithoutDescription = Object.fromEntries(
2800
+ Object.entries(this.json.mcpServers).map(([serverName, serverConfig]) => [
2801
+ serverName,
2802
+ omit(serverConfig, ["description"])
2803
+ ])
2804
+ );
2805
+ return {
2806
+ ...this.json,
2807
+ mcpServers: mcpServersWithoutDescription
2808
+ };
2756
2809
  }
2757
2810
  };
2758
2811
 
@@ -2852,7 +2905,97 @@ var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
2852
2905
  };
2853
2906
 
2854
2907
  // src/mcp/claudecode-mcp.ts
2908
+ import { join as join27 } from "path";
2909
+
2910
+ // src/mcp/modular-mcp.ts
2855
2911
  import { join as join26 } from "path";
2912
+ var ModularMcp = class _ModularMcp extends AiFile {
2913
+ json;
2914
+ constructor(params) {
2915
+ super(params);
2916
+ this.json = JSON.parse(this.fileContent || "{}");
2917
+ }
2918
+ getJson() {
2919
+ return this.json;
2920
+ }
2921
+ static getSettablePaths(params = {
2922
+ global: false,
2923
+ relativeDirPath: void 0
2924
+ }) {
2925
+ const relativeFilePath = "modular-mcp.json";
2926
+ if (!params.global) {
2927
+ return {
2928
+ relativeDirPath: ".",
2929
+ relativeFilePath
2930
+ };
2931
+ }
2932
+ return {
2933
+ relativeDirPath: params.relativeDirPath,
2934
+ relativeFilePath
2935
+ };
2936
+ }
2937
+ static getMcpServers({
2938
+ baseDir,
2939
+ global,
2940
+ relativeDirPath
2941
+ } = {
2942
+ baseDir: ".",
2943
+ global: false,
2944
+ relativeDirPath: void 0
2945
+ }) {
2946
+ const paths = this.getSettablePaths(
2947
+ global ? { global: true, relativeDirPath } : { global: false, relativeDirPath: void 0 }
2948
+ );
2949
+ if (!global) {
2950
+ return {
2951
+ "modular-mcp": {
2952
+ type: "stdio",
2953
+ command: "npx",
2954
+ args: ["-y", "@kimuson/modular-mcp", paths.relativeFilePath],
2955
+ env: {}
2956
+ }
2957
+ };
2958
+ }
2959
+ return {
2960
+ "modular-mcp": {
2961
+ type: "stdio",
2962
+ command: "npx",
2963
+ args: [
2964
+ "-y",
2965
+ "@kimuson/modular-mcp",
2966
+ join26(baseDir, paths.relativeDirPath, paths.relativeFilePath)
2967
+ ],
2968
+ env: {}
2969
+ }
2970
+ };
2971
+ }
2972
+ static fromRulesyncMcp({
2973
+ baseDir = ".",
2974
+ rulesyncMcp,
2975
+ validate = true,
2976
+ global = false,
2977
+ relativeDirPath
2978
+ }) {
2979
+ const paths = this.getSettablePaths(
2980
+ global && relativeDirPath ? { global: true, relativeDirPath } : { global: false, relativeDirPath: void 0 }
2981
+ );
2982
+ const modularMcpJson = {
2983
+ mcpServers: rulesyncMcp.getJson({ modularMcp: true }).mcpServers
2984
+ };
2985
+ return new _ModularMcp({
2986
+ baseDir,
2987
+ relativeDirPath: paths.relativeDirPath,
2988
+ relativeFilePath: paths.relativeFilePath,
2989
+ fileContent: JSON.stringify(modularMcpJson, null, 2),
2990
+ validate
2991
+ });
2992
+ }
2993
+ validate() {
2994
+ return { success: true, error: null };
2995
+ }
2996
+ };
2997
+
2998
+ // src/mcp/claudecode-mcp.ts
2856
2999
  var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2857
3000
  json;
2858
3001
  constructor(params) {
@@ -2881,7 +3024,7 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2881
3024
  }) {
2882
3025
  const paths = this.getSettablePaths({ global });
2883
3026
  const fileContent = await readOrInitializeFileContent(
2884
- join26(baseDir, paths.relativeDirPath, paths.relativeFilePath),
3027
+ join27(baseDir, paths.relativeDirPath, paths.relativeFilePath),
2885
3028
  JSON.stringify({ mcpServers: {} }, null, 2)
2886
3029
  );
2887
3030
  const json = JSON.parse(fileContent);
@@ -2898,20 +3041,28 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2898
3041
  baseDir = ".",
2899
3042
  rulesyncMcp,
2900
3043
  validate = true,
2901
- global = false
3044
+ global = false,
3045
+ modularMcp = false
2902
3046
  }) {
2903
3047
  const paths = this.getSettablePaths({ global });
2904
3048
  const fileContent = await readOrInitializeFileContent(
2905
- join26(baseDir, paths.relativeDirPath, paths.relativeFilePath),
3049
+ join27(baseDir, paths.relativeDirPath, paths.relativeFilePath),
2906
3050
  JSON.stringify({ mcpServers: {} }, null, 2)
2907
3051
  );
2908
3052
  const json = JSON.parse(fileContent);
2909
- const newJson = { ...json, mcpServers: rulesyncMcp.getJson().mcpServers };
3053
+ const mcpJson = modularMcp ? {
3054
+ ...json,
3055
+ mcpServers: global ? ModularMcp.getMcpServers({
3056
+ baseDir,
3057
+ global: true,
3058
+ relativeDirPath: this.getSettablePaths({ global: true }).relativeDirPath
3059
+ }) : ModularMcp.getMcpServers({ baseDir, global: false })
3060
+ } : { ...json, mcpServers: rulesyncMcp.getJson({ modularMcp: false }).mcpServers };
2910
3061
  return new _ClaudecodeMcp({
2911
3062
  baseDir,
2912
3063
  relativeDirPath: paths.relativeDirPath,
2913
3064
  relativeFilePath: paths.relativeFilePath,
2914
- fileContent: JSON.stringify(newJson, null, 2),
3065
+ fileContent: JSON.stringify(mcpJson, null, 2),
2915
3066
  validate
2916
3067
  });
2917
3068
  }
@@ -2926,7 +3077,7 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2926
3077
  };
2927
3078
 
2928
3079
  // src/mcp/cline-mcp.ts
2929
- import { join as join27 } from "path";
3080
+ import { join as join28 } from "path";
2930
3081
  var ClineMcp = class _ClineMcp extends ToolMcp {
2931
3082
  json;
2932
3083
  constructor(params) {
@@ -2947,7 +3098,7 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
2947
3098
  validate = true
2948
3099
  }) {
2949
3100
  const fileContent = await readFileContent(
2950
- join27(
3101
+ join28(
2951
3102
  baseDir,
2952
3103
  this.getSettablePaths().relativeDirPath,
2953
3104
  this.getSettablePaths().relativeFilePath
@@ -2983,7 +3134,7 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
2983
3134
  };
2984
3135
 
2985
3136
  // src/mcp/codexcli-mcp.ts
2986
- import { join as join28 } from "path";
3137
+ import { join as join29 } from "path";
2987
3138
  import * as smolToml from "smol-toml";
2988
3139
  var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
2989
3140
  toml;
@@ -3019,7 +3170,7 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
3019
3170
  }) {
3020
3171
  const paths = this.getSettablePaths({ global });
3021
3172
  const fileContent = await readFileContent(
3022
- join28(baseDir, paths.relativeDirPath, paths.relativeFilePath)
3173
+ join29(baseDir, paths.relativeDirPath, paths.relativeFilePath)
3023
3174
  );
3024
3175
  return new _CodexcliMcp({
3025
3176
  baseDir,
@@ -3036,13 +3187,13 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
3036
3187
  global = false
3037
3188
  }) {
3038
3189
  const paths = this.getSettablePaths({ global });
3039
- const configTomlFilePath = join28(baseDir, paths.relativeDirPath, paths.relativeFilePath);
3190
+ const configTomlFilePath = join29(baseDir, paths.relativeDirPath, paths.relativeFilePath);
3040
3191
  const configTomlFileContent = await readOrInitializeFileContent(
3041
3192
  configTomlFilePath,
3042
3193
  smolToml.stringify({})
3043
3194
  );
3044
3195
  const configToml = smolToml.parse(configTomlFileContent);
3045
- const mcpServers = rulesyncMcp.getJson().mcpServers;
3196
+ const mcpServers = rulesyncMcp.getJson({ modularMcp: false }).mcpServers;
3046
3197
  const filteredMcpServers = this.removeEmptyEntries(mcpServers);
3047
3198
  configToml["mcp_servers"] = filteredMcpServers;
3048
3199
  return new _CodexcliMcp({
@@ -3077,7 +3228,7 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
3077
3228
  };
3078
3229
 
3079
3230
  // src/mcp/copilot-mcp.ts
3080
- import { join as join29 } from "path";
3231
+ import { join as join30 } from "path";
3081
3232
  var CopilotMcp = class _CopilotMcp extends ToolMcp {
3082
3233
  json;
3083
3234
  constructor(params) {
@@ -3098,7 +3249,7 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
3098
3249
  validate = true
3099
3250
  }) {
3100
3251
  const fileContent = await readFileContent(
3101
- join29(
3252
+ join30(
3102
3253
  baseDir,
3103
3254
  this.getSettablePaths().relativeDirPath,
3104
3255
  this.getSettablePaths().relativeFilePath
@@ -3134,7 +3285,7 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
3134
3285
  };
3135
3286
 
3136
3287
  // src/mcp/cursor-mcp.ts
3137
- import { join as join30 } from "path";
3288
+ import { join as join31 } from "path";
3138
3289
  var CursorMcp = class _CursorMcp extends ToolMcp {
3139
3290
  json;
3140
3291
  constructor(params) {
@@ -3155,7 +3306,7 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
3155
3306
  validate = true
3156
3307
  }) {
3157
3308
  const fileContent = await readFileContent(
3158
- join30(
3309
+ join31(
3159
3310
  baseDir,
3160
3311
  this.getSettablePaths().relativeDirPath,
3161
3312
  this.getSettablePaths().relativeFilePath
@@ -3174,7 +3325,7 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
3174
3325
  rulesyncMcp,
3175
3326
  validate = true
3176
3327
  }) {
3177
- const json = rulesyncMcp.getJson();
3328
+ const json = rulesyncMcp.getJson({ modularMcp: false });
3178
3329
  const cursorConfig = {
3179
3330
  mcpServers: json.mcpServers || {}
3180
3331
  };
@@ -3202,7 +3353,7 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
3202
3353
  };
3203
3354
 
3204
3355
  // src/mcp/geminicli-mcp.ts
3205
- import { join as join31 } from "path";
3356
+ import { join as join32 } from "path";
3206
3357
  var GeminiCliMcp = class _GeminiCliMcp extends ToolMcp {
3207
3358
  json;
3208
3359
  constructor(params) {
@@ -3231,7 +3382,7 @@ var GeminiCliMcp = class _GeminiCliMcp extends ToolMcp {
3231
3382
  }) {
3232
3383
  const paths = this.getSettablePaths({ global });
3233
3384
  const fileContent = await readOrInitializeFileContent(
3234
- join31(baseDir, paths.relativeDirPath, paths.relativeFilePath),
3385
+ join32(baseDir, paths.relativeDirPath, paths.relativeFilePath),
3235
3386
  JSON.stringify({ mcpServers: {} }, null, 2)
3236
3387
  );
3237
3388
  const json = JSON.parse(fileContent);
@@ -3252,11 +3403,11 @@ var GeminiCliMcp = class _GeminiCliMcp extends ToolMcp {
3252
3403
  }) {
3253
3404
  const paths = this.getSettablePaths({ global });
3254
3405
  const fileContent = await readOrInitializeFileContent(
3255
- join31(baseDir, paths.relativeDirPath, paths.relativeFilePath),
3406
+ join32(baseDir, paths.relativeDirPath, paths.relativeFilePath),
3256
3407
  JSON.stringify({ mcpServers: {} }, null, 2)
3257
3408
  );
3258
3409
  const json = JSON.parse(fileContent);
3259
- const newJson = { ...json, mcpServers: rulesyncMcp.getJson().mcpServers };
3410
+ const newJson = { ...json, mcpServers: rulesyncMcp.getJson({ modularMcp: false }).mcpServers };
3260
3411
  return new _GeminiCliMcp({
3261
3412
  baseDir,
3262
3413
  relativeDirPath: paths.relativeDirPath,
@@ -3276,7 +3427,7 @@ var GeminiCliMcp = class _GeminiCliMcp extends ToolMcp {
3276
3427
  };
3277
3428
 
3278
3429
  // src/mcp/roo-mcp.ts
3279
- import { join as join32 } from "path";
3430
+ import { join as join33 } from "path";
3280
3431
  var RooMcp = class _RooMcp extends ToolMcp {
3281
3432
  json;
3282
3433
  constructor(params) {
@@ -3297,7 +3448,7 @@ var RooMcp = class _RooMcp extends ToolMcp {
3297
3448
  validate = true
3298
3449
  }) {
3299
3450
  const fileContent = await readFileContent(
3300
- join32(
3451
+ join33(
3301
3452
  baseDir,
3302
3453
  this.getSettablePaths().relativeDirPath,
3303
3454
  this.getSettablePaths().relativeFilePath
@@ -3348,13 +3499,16 @@ var McpProcessorToolTargetSchema = z12.enum(
3348
3499
  mcpProcessorToolTargets.concat("codexcli")
3349
3500
  );
3350
3501
  var mcpProcessorToolTargetsGlobal = ["claudecode", "codexcli", "geminicli"];
3502
+ var mcpProcessorToolTargetsModular = ["claudecode"];
3351
3503
  var McpProcessor = class extends FeatureProcessor {
3352
3504
  toolTarget;
3353
3505
  global;
3506
+ modularMcp;
3354
3507
  constructor({
3355
3508
  baseDir = ".",
3356
3509
  toolTarget,
3357
- global = false
3510
+ global = false,
3511
+ modularMcp = false
3358
3512
  }) {
3359
3513
  super({ baseDir });
3360
3514
  const result = McpProcessorToolTargetSchema.safeParse(toolTarget);
@@ -3365,6 +3519,7 @@ var McpProcessor = class extends FeatureProcessor {
3365
3519
  }
3366
3520
  this.toolTarget = result.data;
3367
3521
  this.global = global;
3522
+ this.modularMcp = modularMcp;
3368
3523
  }
3369
3524
  /**
3370
3525
  * Implementation of abstract method from FeatureProcessor
@@ -3372,9 +3527,9 @@ var McpProcessor = class extends FeatureProcessor {
3372
3527
  */
3373
3528
  async loadRulesyncFiles() {
3374
3529
  try {
3375
- return [await RulesyncMcp.fromFile({})];
3530
+ return [await RulesyncMcp.fromFile({ modularMcp: this.modularMcp })];
3376
3531
  } catch (error) {
3377
- logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
3532
+ logger.debug(`Failed to load MCP files for tool target: ${this.toolTarget}`, error);
3378
3533
  return [];
3379
3534
  }
3380
3535
  }
@@ -3468,7 +3623,7 @@ var McpProcessor = class extends FeatureProcessor {
3468
3623
  logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
3469
3624
  return toolMcps;
3470
3625
  } catch (error) {
3471
- logger.debug(`No MCP files found for tool target: ${this.toolTarget}`, error);
3626
+ logger.debug(`Failed to load MCP files for tool target: ${this.toolTarget}`, error);
3472
3627
  return [];
3473
3628
  }
3474
3629
  }
@@ -3492,10 +3647,11 @@ var McpProcessor = class extends FeatureProcessor {
3492
3647
  rulesyncMcp: rulesyncMcp2
3493
3648
  });
3494
3649
  case "claudecode":
3495
- return ClaudecodeMcp.fromRulesyncMcp({
3650
+ return await ClaudecodeMcp.fromRulesyncMcp({
3496
3651
  baseDir: this.baseDir,
3497
3652
  rulesyncMcp: rulesyncMcp2,
3498
- global: this.global
3653
+ global: this.global,
3654
+ modularMcp: this.modularMcp
3499
3655
  });
3500
3656
  case "cline":
3501
3657
  return ClineMcp.fromRulesyncMcp({
@@ -3534,7 +3690,18 @@ var McpProcessor = class extends FeatureProcessor {
3534
3690
  }
3535
3691
  })
3536
3692
  );
3537
- return toolMcps;
3693
+ const toolFiles = toolMcps;
3694
+ if (this.modularMcp && mcpProcessorToolTargetsModular.includes(this.toolTarget)) {
3695
+ const relativeDirPath = this.toolTarget === "claudecode" ? ClaudecodeMcp.getSettablePaths({ global: this.global }).relativeDirPath : void 0;
3696
+ toolFiles.push(
3697
+ ModularMcp.fromRulesyncMcp({
3698
+ baseDir: this.baseDir,
3699
+ rulesyncMcp,
3700
+ ...this.global && relativeDirPath ? { global: true, relativeDirPath } : { global: false }
3701
+ })
3702
+ );
3703
+ }
3704
+ return toolFiles;
3538
3705
  }
3539
3706
  /**
3540
3707
  * Implementation of abstract method from FeatureProcessor
@@ -3560,12 +3727,12 @@ var McpProcessor = class extends FeatureProcessor {
3560
3727
  };
3561
3728
 
3562
3729
  // src/rules/rules-processor.ts
3563
- import { basename as basename17, join as join56 } from "path";
3730
+ import { basename as basename17, join as join57 } from "path";
3564
3731
  import { XMLBuilder } from "fast-xml-parser";
3565
3732
  import { z as z21 } from "zod/mini";
3566
3733
 
3567
3734
  // src/subagents/simulated-subagent.ts
3568
- import { basename as basename12, join as join33 } from "path";
3735
+ import { basename as basename12, join as join34 } from "path";
3569
3736
  import { z as z13 } from "zod/mini";
3570
3737
 
3571
3738
  // src/subagents/tool-subagent.ts
@@ -3613,7 +3780,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3613
3780
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
3614
3781
  if (!result.success) {
3615
3782
  throw new Error(
3616
- `Invalid frontmatter in ${join33(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
3783
+ `Invalid frontmatter in ${join34(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
3617
3784
  );
3618
3785
  }
3619
3786
  }
@@ -3664,7 +3831,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3664
3831
  return {
3665
3832
  success: false,
3666
3833
  error: new Error(
3667
- `Invalid frontmatter in ${join33(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
3834
+ `Invalid frontmatter in ${join34(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
3668
3835
  )
3669
3836
  };
3670
3837
  }
@@ -3674,7 +3841,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3674
3841
  relativeFilePath,
3675
3842
  validate = true
3676
3843
  }) {
3677
- const filePath = join33(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
3844
+ const filePath = join34(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
3678
3845
  const fileContent = await readFileContent(filePath);
3679
3846
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3680
3847
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -3831,15 +3998,15 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
3831
3998
  };
3832
3999
 
3833
4000
  // src/subagents/subagents-processor.ts
3834
- import { basename as basename14, join as join36 } from "path";
4001
+ import { basename as basename14, join as join37 } from "path";
3835
4002
  import { z as z16 } from "zod/mini";
3836
4003
 
3837
4004
  // src/subagents/claudecode-subagent.ts
3838
- import { join as join35 } from "path";
4005
+ import { join as join36 } from "path";
3839
4006
  import { z as z15 } from "zod/mini";
3840
4007
 
3841
4008
  // src/subagents/rulesync-subagent.ts
3842
- import { basename as basename13, join as join34 } from "path";
4009
+ import { basename as basename13, join as join35 } from "path";
3843
4010
  import { z as z14 } from "zod/mini";
3844
4011
  var RulesyncSubagentModelSchema = z14.enum(["opus", "sonnet", "haiku", "inherit"]);
3845
4012
  var RulesyncSubagentFrontmatterSchema = z14.object({
@@ -3860,7 +4027,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
3860
4027
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
3861
4028
  if (!result.success) {
3862
4029
  throw new Error(
3863
- `Invalid frontmatter in ${join34(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
4030
+ `Invalid frontmatter in ${join35(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
3864
4031
  );
3865
4032
  }
3866
4033
  }
@@ -3892,7 +4059,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
3892
4059
  return {
3893
4060
  success: false,
3894
4061
  error: new Error(
3895
- `Invalid frontmatter in ${join34(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
4062
+ `Invalid frontmatter in ${join35(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
3896
4063
  )
3897
4064
  };
3898
4065
  }
@@ -3900,7 +4067,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
3900
4067
  static async fromFile({
3901
4068
  relativeFilePath
3902
4069
  }) {
3903
- const fileContent = await readFileContent(join34(".rulesync/subagents", relativeFilePath));
4070
+ const fileContent = await readFileContent(join35(".rulesync/subagents", relativeFilePath));
3904
4071
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3905
4072
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
3906
4073
  if (!result.success) {
@@ -3932,7 +4099,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
3932
4099
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
3933
4100
  if (!result.success) {
3934
4101
  throw new Error(
3935
- `Invalid frontmatter in ${join35(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
4102
+ `Invalid frontmatter in ${join36(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
3936
4103
  );
3937
4104
  }
3938
4105
  }
@@ -3944,7 +4111,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
3944
4111
  }
3945
4112
  static getSettablePaths(_options = {}) {
3946
4113
  return {
3947
- relativeDirPath: join35(".claude", "agents")
4114
+ relativeDirPath: join36(".claude", "agents")
3948
4115
  };
3949
4116
  }
3950
4117
  getFrontmatter() {
@@ -4012,7 +4179,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4012
4179
  return {
4013
4180
  success: false,
4014
4181
  error: new Error(
4015
- `Invalid frontmatter in ${join35(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
4182
+ `Invalid frontmatter in ${join36(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
4016
4183
  )
4017
4184
  };
4018
4185
  }
@@ -4030,7 +4197,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4030
4197
  global = false
4031
4198
  }) {
4032
4199
  const paths = this.getSettablePaths({ global });
4033
- const filePath = join35(baseDir, paths.relativeDirPath, relativeFilePath);
4200
+ const filePath = join36(baseDir, paths.relativeDirPath, relativeFilePath);
4034
4201
  const fileContent = await readFileContent(filePath);
4035
4202
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4036
4203
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -4184,7 +4351,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
4184
4351
  * Load and parse rulesync subagent files from .rulesync/subagents/ directory
4185
4352
  */
4186
4353
  async loadRulesyncFiles() {
4187
- const subagentsDir = join36(RulesyncSubagent.getSettablePaths().relativeDirPath);
4354
+ const subagentsDir = join37(RulesyncSubagent.getSettablePaths().relativeDirPath);
4188
4355
  const dirExists = await directoryExists(subagentsDir);
4189
4356
  if (!dirExists) {
4190
4357
  logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
@@ -4199,7 +4366,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
4199
4366
  logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
4200
4367
  const rulesyncSubagents = [];
4201
4368
  for (const mdFile of mdFiles) {
4202
- const filepath = join36(subagentsDir, mdFile);
4369
+ const filepath = join37(subagentsDir, mdFile);
4203
4370
  try {
4204
4371
  const rulesyncSubagent = await RulesyncSubagent.fromFile({
4205
4372
  relativeFilePath: mdFile,
@@ -4318,7 +4485,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
4318
4485
  relativeDirPath,
4319
4486
  fromFile
4320
4487
  }) {
4321
- const paths = await findFilesByGlobs(join36(this.baseDir, relativeDirPath, "*.md"));
4488
+ const paths = await findFilesByGlobs(join37(this.baseDir, relativeDirPath, "*.md"));
4322
4489
  const subagents = (await Promise.allSettled(paths.map((path2) => fromFile(basename14(path2))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
4323
4490
  logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
4324
4491
  return subagents;
@@ -4346,13 +4513,13 @@ var SubagentsProcessor = class extends FeatureProcessor {
4346
4513
  };
4347
4514
 
4348
4515
  // src/rules/agentsmd-rule.ts
4349
- import { join as join39 } from "path";
4516
+ import { join as join40 } from "path";
4350
4517
 
4351
4518
  // src/rules/tool-rule.ts
4352
- import { join as join38 } from "path";
4519
+ import { join as join39 } from "path";
4353
4520
 
4354
4521
  // src/rules/rulesync-rule.ts
4355
- import { basename as basename15, join as join37 } from "path";
4522
+ import { basename as basename15, join as join38 } from "path";
4356
4523
  import { z as z17 } from "zod/mini";
4357
4524
  var RulesyncRuleFrontmatterSchema = z17.object({
4358
4525
  root: z17.optional(z17.optional(z17.boolean())),
@@ -4381,7 +4548,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4381
4548
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
4382
4549
  if (!result.success) {
4383
4550
  throw new Error(
4384
- `Invalid frontmatter in ${join37(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
4551
+ `Invalid frontmatter in ${join38(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
4385
4552
  );
4386
4553
  }
4387
4554
  }
@@ -4416,7 +4583,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4416
4583
  return {
4417
4584
  success: false,
4418
4585
  error: new Error(
4419
- `Invalid frontmatter in ${join37(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
4586
+ `Invalid frontmatter in ${join38(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
4420
4587
  )
4421
4588
  };
4422
4589
  }
@@ -4425,8 +4592,8 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4425
4592
  relativeFilePath,
4426
4593
  validate = true
4427
4594
  }) {
4428
- const legacyPath = join37(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
4429
- const recommendedPath = join37(
4595
+ const legacyPath = join38(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
4596
+ const recommendedPath = join38(
4430
4597
  this.getSettablePaths().recommended.relativeDirPath,
4431
4598
  relativeFilePath
4432
4599
  );
@@ -4459,7 +4626,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4459
4626
  relativeFilePath,
4460
4627
  validate = true
4461
4628
  }) {
4462
- const filePath = join37(this.getSettablePaths().recommended.relativeDirPath, relativeFilePath);
4629
+ const filePath = join38(this.getSettablePaths().recommended.relativeDirPath, relativeFilePath);
4463
4630
  const fileContent = await readFileContent(filePath);
4464
4631
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4465
4632
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
@@ -4560,7 +4727,7 @@ var ToolRule = class extends ToolFile {
4560
4727
  });
4561
4728
  const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
4562
4729
  if (!rulesyncFrontmatter.root && rulesyncFrontmatter.agentsmd?.subprojectPath) {
4563
- params.relativeDirPath = join38(rulesyncFrontmatter.agentsmd.subprojectPath);
4730
+ params.relativeDirPath = join39(rulesyncFrontmatter.agentsmd.subprojectPath);
4564
4731
  params.relativeFilePath = "AGENTS.md";
4565
4732
  }
4566
4733
  return params;
@@ -4636,8 +4803,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
4636
4803
  validate = true
4637
4804
  }) {
4638
4805
  const isRoot = relativeFilePath === "AGENTS.md";
4639
- const relativePath = isRoot ? "AGENTS.md" : join39(".agents/memories", relativeFilePath);
4640
- const fileContent = await readFileContent(join39(baseDir, relativePath));
4806
+ const relativePath = isRoot ? "AGENTS.md" : join40(".agents/memories", relativeFilePath);
4807
+ const fileContent = await readFileContent(join40(baseDir, relativePath));
4641
4808
  return new _AgentsMdRule({
4642
4809
  baseDir,
4643
4810
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -4677,7 +4844,7 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
4677
4844
  };
4678
4845
 
4679
4846
  // src/rules/amazonqcli-rule.ts
4680
- import { join as join40 } from "path";
4847
+ import { join as join41 } from "path";
4681
4848
  var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4682
4849
  static getSettablePaths() {
4683
4850
  return {
@@ -4692,7 +4859,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4692
4859
  validate = true
4693
4860
  }) {
4694
4861
  const fileContent = await readFileContent(
4695
- join40(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4862
+ join41(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4696
4863
  );
4697
4864
  return new _AmazonQCliRule({
4698
4865
  baseDir,
@@ -4732,7 +4899,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4732
4899
  };
4733
4900
 
4734
4901
  // src/rules/augmentcode-legacy-rule.ts
4735
- import { join as join41 } from "path";
4902
+ import { join as join42 } from "path";
4736
4903
  var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4737
4904
  toRulesyncRule() {
4738
4905
  const rulesyncFrontmatter = {
@@ -4793,8 +4960,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4793
4960
  }) {
4794
4961
  const settablePaths = this.getSettablePaths();
4795
4962
  const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
4796
- const relativePath = isRoot ? settablePaths.root.relativeFilePath : join41(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
4797
- const fileContent = await readFileContent(join41(baseDir, relativePath));
4963
+ const relativePath = isRoot ? settablePaths.root.relativeFilePath : join42(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
4964
+ const fileContent = await readFileContent(join42(baseDir, relativePath));
4798
4965
  return new _AugmentcodeLegacyRule({
4799
4966
  baseDir,
4800
4967
  relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
@@ -4807,7 +4974,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4807
4974
  };
4808
4975
 
4809
4976
  // src/rules/augmentcode-rule.ts
4810
- import { join as join42 } from "path";
4977
+ import { join as join43 } from "path";
4811
4978
  var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
4812
4979
  toRulesyncRule() {
4813
4980
  return this.toRulesyncRuleDefault();
@@ -4839,7 +5006,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
4839
5006
  validate = true
4840
5007
  }) {
4841
5008
  const fileContent = await readFileContent(
4842
- join42(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5009
+ join43(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4843
5010
  );
4844
5011
  const { body: content } = parseFrontmatter(fileContent);
4845
5012
  return new _AugmentcodeRule({
@@ -4862,7 +5029,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
4862
5029
  };
4863
5030
 
4864
5031
  // src/rules/claudecode-rule.ts
4865
- import { join as join43 } from "path";
5032
+ import { join as join44 } from "path";
4866
5033
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4867
5034
  static getSettablePaths({
4868
5035
  global
@@ -4881,7 +5048,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4881
5048
  relativeFilePath: "CLAUDE.md"
4882
5049
  },
4883
5050
  nonRoot: {
4884
- relativeDirPath: join43(".claude", "memories")
5051
+ relativeDirPath: join44(".claude", "memories")
4885
5052
  }
4886
5053
  };
4887
5054
  }
@@ -4896,7 +5063,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4896
5063
  if (isRoot) {
4897
5064
  const relativePath2 = paths.root.relativeFilePath;
4898
5065
  const fileContent2 = await readFileContent(
4899
- join43(baseDir, paths.root.relativeDirPath, relativePath2)
5066
+ join44(baseDir, paths.root.relativeDirPath, relativePath2)
4900
5067
  );
4901
5068
  return new _ClaudecodeRule({
4902
5069
  baseDir,
@@ -4910,8 +5077,8 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4910
5077
  if (!paths.nonRoot) {
4911
5078
  throw new Error("nonRoot path is not set");
4912
5079
  }
4913
- const relativePath = join43(paths.nonRoot.relativeDirPath, relativeFilePath);
4914
- const fileContent = await readFileContent(join43(baseDir, relativePath));
5080
+ const relativePath = join44(paths.nonRoot.relativeDirPath, relativeFilePath);
5081
+ const fileContent = await readFileContent(join44(baseDir, relativePath));
4915
5082
  return new _ClaudecodeRule({
4916
5083
  baseDir,
4917
5084
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -4953,7 +5120,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4953
5120
  };
4954
5121
 
4955
5122
  // src/rules/cline-rule.ts
4956
- import { join as join44 } from "path";
5123
+ import { join as join45 } from "path";
4957
5124
  import { z as z18 } from "zod/mini";
4958
5125
  var ClineRuleFrontmatterSchema = z18.object({
4959
5126
  description: z18.string()
@@ -4998,7 +5165,7 @@ var ClineRule = class _ClineRule extends ToolRule {
4998
5165
  validate = true
4999
5166
  }) {
5000
5167
  const fileContent = await readFileContent(
5001
- join44(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5168
+ join45(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5002
5169
  );
5003
5170
  return new _ClineRule({
5004
5171
  baseDir,
@@ -5011,7 +5178,7 @@ var ClineRule = class _ClineRule extends ToolRule {
5011
5178
  };
5012
5179
 
5013
5180
  // src/rules/codexcli-rule.ts
5014
- import { join as join45 } from "path";
5181
+ import { join as join46 } from "path";
5015
5182
  var CodexcliRule = class _CodexcliRule extends ToolRule {
5016
5183
  static getSettablePaths({
5017
5184
  global
@@ -5045,7 +5212,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
5045
5212
  if (isRoot) {
5046
5213
  const relativePath2 = paths.root.relativeFilePath;
5047
5214
  const fileContent2 = await readFileContent(
5048
- join45(baseDir, paths.root.relativeDirPath, relativePath2)
5215
+ join46(baseDir, paths.root.relativeDirPath, relativePath2)
5049
5216
  );
5050
5217
  return new _CodexcliRule({
5051
5218
  baseDir,
@@ -5059,8 +5226,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
5059
5226
  if (!paths.nonRoot) {
5060
5227
  throw new Error("nonRoot path is not set");
5061
5228
  }
5062
- const relativePath = join45(paths.nonRoot.relativeDirPath, relativeFilePath);
5063
- const fileContent = await readFileContent(join45(baseDir, relativePath));
5229
+ const relativePath = join46(paths.nonRoot.relativeDirPath, relativeFilePath);
5230
+ const fileContent = await readFileContent(join46(baseDir, relativePath));
5064
5231
  return new _CodexcliRule({
5065
5232
  baseDir,
5066
5233
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -5102,7 +5269,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
5102
5269
  };
5103
5270
 
5104
5271
  // src/rules/copilot-rule.ts
5105
- import { join as join46 } from "path";
5272
+ import { join as join47 } from "path";
5106
5273
  import { z as z19 } from "zod/mini";
5107
5274
  var CopilotRuleFrontmatterSchema = z19.object({
5108
5275
  description: z19.optional(z19.string()),
@@ -5127,7 +5294,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5127
5294
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
5128
5295
  if (!result.success) {
5129
5296
  throw new Error(
5130
- `Invalid frontmatter in ${join46(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
5297
+ `Invalid frontmatter in ${join47(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
5131
5298
  );
5132
5299
  }
5133
5300
  }
@@ -5199,11 +5366,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5199
5366
  validate = true
5200
5367
  }) {
5201
5368
  const isRoot = relativeFilePath === "copilot-instructions.md";
5202
- const relativePath = isRoot ? join46(
5369
+ const relativePath = isRoot ? join47(
5203
5370
  this.getSettablePaths().root.relativeDirPath,
5204
5371
  this.getSettablePaths().root.relativeFilePath
5205
- ) : join46(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
5206
- const fileContent = await readFileContent(join46(baseDir, relativePath));
5372
+ ) : join47(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
5373
+ const fileContent = await readFileContent(join47(baseDir, relativePath));
5207
5374
  if (isRoot) {
5208
5375
  return new _CopilotRule({
5209
5376
  baseDir,
@@ -5222,7 +5389,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5222
5389
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
5223
5390
  if (!result.success) {
5224
5391
  throw new Error(
5225
- `Invalid frontmatter in ${join46(baseDir, relativeFilePath)}: ${result.error.message}`
5392
+ `Invalid frontmatter in ${join47(baseDir, relativeFilePath)}: ${result.error.message}`
5226
5393
  );
5227
5394
  }
5228
5395
  return new _CopilotRule({
@@ -5246,7 +5413,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5246
5413
  return {
5247
5414
  success: false,
5248
5415
  error: new Error(
5249
- `Invalid frontmatter in ${join46(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
5416
+ `Invalid frontmatter in ${join47(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
5250
5417
  )
5251
5418
  };
5252
5419
  }
@@ -5266,7 +5433,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5266
5433
  };
5267
5434
 
5268
5435
  // src/rules/cursor-rule.ts
5269
- import { basename as basename16, join as join47 } from "path";
5436
+ import { basename as basename16, join as join48 } from "path";
5270
5437
  import { z as z20 } from "zod/mini";
5271
5438
  var CursorRuleFrontmatterSchema = z20.object({
5272
5439
  description: z20.optional(z20.string()),
@@ -5288,7 +5455,7 @@ var CursorRule = class _CursorRule extends ToolRule {
5288
5455
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
5289
5456
  if (!result.success) {
5290
5457
  throw new Error(
5291
- `Invalid frontmatter in ${join47(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
5458
+ `Invalid frontmatter in ${join48(rest.relativeDirPath, rest.relativeFilePath)}: ${result.error.message}`
5292
5459
  );
5293
5460
  }
5294
5461
  }
@@ -5405,13 +5572,13 @@ var CursorRule = class _CursorRule extends ToolRule {
5405
5572
  validate = true
5406
5573
  }) {
5407
5574
  const fileContent = await readFileContent(
5408
- join47(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5575
+ join48(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5409
5576
  );
5410
5577
  const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
5411
5578
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
5412
5579
  if (!result.success) {
5413
5580
  throw new Error(
5414
- `Invalid frontmatter in ${join47(baseDir, relativeFilePath)}: ${result.error.message}`
5581
+ `Invalid frontmatter in ${join48(baseDir, relativeFilePath)}: ${result.error.message}`
5415
5582
  );
5416
5583
  }
5417
5584
  return new _CursorRule({
@@ -5434,7 +5601,7 @@ var CursorRule = class _CursorRule extends ToolRule {
5434
5601
  return {
5435
5602
  success: false,
5436
5603
  error: new Error(
5437
- `Invalid frontmatter in ${join47(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
5604
+ `Invalid frontmatter in ${join48(this.relativeDirPath, this.relativeFilePath)}: ${result.error.message}`
5438
5605
  )
5439
5606
  };
5440
5607
  }
@@ -5454,7 +5621,7 @@ var CursorRule = class _CursorRule extends ToolRule {
5454
5621
  };
5455
5622
 
5456
5623
  // src/rules/geminicli-rule.ts
5457
- import { join as join48 } from "path";
5624
+ import { join as join49 } from "path";
5458
5625
  var GeminiCliRule = class _GeminiCliRule extends ToolRule {
5459
5626
  static getSettablePaths({
5460
5627
  global
@@ -5488,7 +5655,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
5488
5655
  if (isRoot) {
5489
5656
  const relativePath2 = paths.root.relativeFilePath;
5490
5657
  const fileContent2 = await readFileContent(
5491
- join48(baseDir, paths.root.relativeDirPath, relativePath2)
5658
+ join49(baseDir, paths.root.relativeDirPath, relativePath2)
5492
5659
  );
5493
5660
  return new _GeminiCliRule({
5494
5661
  baseDir,
@@ -5502,8 +5669,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
5502
5669
  if (!paths.nonRoot) {
5503
5670
  throw new Error("nonRoot path is not set");
5504
5671
  }
5505
- const relativePath = join48(paths.nonRoot.relativeDirPath, relativeFilePath);
5506
- const fileContent = await readFileContent(join48(baseDir, relativePath));
5672
+ const relativePath = join49(paths.nonRoot.relativeDirPath, relativeFilePath);
5673
+ const fileContent = await readFileContent(join49(baseDir, relativePath));
5507
5674
  return new _GeminiCliRule({
5508
5675
  baseDir,
5509
5676
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -5545,7 +5712,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
5545
5712
  };
5546
5713
 
5547
5714
  // src/rules/junie-rule.ts
5548
- import { join as join49 } from "path";
5715
+ import { join as join50 } from "path";
5549
5716
  var JunieRule = class _JunieRule extends ToolRule {
5550
5717
  static getSettablePaths() {
5551
5718
  return {
@@ -5564,8 +5731,8 @@ var JunieRule = class _JunieRule extends ToolRule {
5564
5731
  validate = true
5565
5732
  }) {
5566
5733
  const isRoot = relativeFilePath === "guidelines.md";
5567
- const relativePath = isRoot ? "guidelines.md" : join49(".junie/memories", relativeFilePath);
5568
- const fileContent = await readFileContent(join49(baseDir, relativePath));
5734
+ const relativePath = isRoot ? "guidelines.md" : join50(".junie/memories", relativeFilePath);
5735
+ const fileContent = await readFileContent(join50(baseDir, relativePath));
5569
5736
  return new _JunieRule({
5570
5737
  baseDir,
5571
5738
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5605,7 +5772,7 @@ var JunieRule = class _JunieRule extends ToolRule {
5605
5772
  };
5606
5773
 
5607
5774
  // src/rules/kiro-rule.ts
5608
- import { join as join50 } from "path";
5775
+ import { join as join51 } from "path";
5609
5776
  var KiroRule = class _KiroRule extends ToolRule {
5610
5777
  static getSettablePaths() {
5611
5778
  return {
@@ -5620,7 +5787,7 @@ var KiroRule = class _KiroRule extends ToolRule {
5620
5787
  validate = true
5621
5788
  }) {
5622
5789
  const fileContent = await readFileContent(
5623
- join50(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5790
+ join51(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5624
5791
  );
5625
5792
  return new _KiroRule({
5626
5793
  baseDir,
@@ -5660,7 +5827,7 @@ var KiroRule = class _KiroRule extends ToolRule {
5660
5827
  };
5661
5828
 
5662
5829
  // src/rules/opencode-rule.ts
5663
- import { join as join51 } from "path";
5830
+ import { join as join52 } from "path";
5664
5831
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5665
5832
  static getSettablePaths() {
5666
5833
  return {
@@ -5679,8 +5846,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5679
5846
  validate = true
5680
5847
  }) {
5681
5848
  const isRoot = relativeFilePath === "AGENTS.md";
5682
- const relativePath = isRoot ? "AGENTS.md" : join51(".opencode/memories", relativeFilePath);
5683
- const fileContent = await readFileContent(join51(baseDir, relativePath));
5849
+ const relativePath = isRoot ? "AGENTS.md" : join52(".opencode/memories", relativeFilePath);
5850
+ const fileContent = await readFileContent(join52(baseDir, relativePath));
5684
5851
  return new _OpenCodeRule({
5685
5852
  baseDir,
5686
5853
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5720,7 +5887,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5720
5887
  };
5721
5888
 
5722
5889
  // src/rules/qwencode-rule.ts
5723
- import { join as join52 } from "path";
5890
+ import { join as join53 } from "path";
5724
5891
  var QwencodeRule = class _QwencodeRule extends ToolRule {
5725
5892
  static getSettablePaths() {
5726
5893
  return {
@@ -5739,8 +5906,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
5739
5906
  validate = true
5740
5907
  }) {
5741
5908
  const isRoot = relativeFilePath === "QWEN.md";
5742
- const relativePath = isRoot ? "QWEN.md" : join52(".qwen/memories", relativeFilePath);
5743
- const fileContent = await readFileContent(join52(baseDir, relativePath));
5909
+ const relativePath = isRoot ? "QWEN.md" : join53(".qwen/memories", relativeFilePath);
5910
+ const fileContent = await readFileContent(join53(baseDir, relativePath));
5744
5911
  return new _QwencodeRule({
5745
5912
  baseDir,
5746
5913
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5777,7 +5944,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
5777
5944
  };
5778
5945
 
5779
5946
  // src/rules/roo-rule.ts
5780
- import { join as join53 } from "path";
5947
+ import { join as join54 } from "path";
5781
5948
  var RooRule = class _RooRule extends ToolRule {
5782
5949
  static getSettablePaths() {
5783
5950
  return {
@@ -5792,7 +5959,7 @@ var RooRule = class _RooRule extends ToolRule {
5792
5959
  validate = true
5793
5960
  }) {
5794
5961
  const fileContent = await readFileContent(
5795
- join53(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5962
+ join54(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5796
5963
  );
5797
5964
  return new _RooRule({
5798
5965
  baseDir,
@@ -5847,7 +6014,7 @@ var RooRule = class _RooRule extends ToolRule {
5847
6014
  };
5848
6015
 
5849
6016
  // src/rules/warp-rule.ts
5850
- import { join as join54 } from "path";
6017
+ import { join as join55 } from "path";
5851
6018
  var WarpRule = class _WarpRule extends ToolRule {
5852
6019
  constructor({ fileContent, root, ...rest }) {
5853
6020
  super({
@@ -5873,8 +6040,8 @@ var WarpRule = class _WarpRule extends ToolRule {
5873
6040
  validate = true
5874
6041
  }) {
5875
6042
  const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
5876
- const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join54(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
5877
- const fileContent = await readFileContent(join54(baseDir, relativePath));
6043
+ const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join55(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
6044
+ const fileContent = await readFileContent(join55(baseDir, relativePath));
5878
6045
  return new _WarpRule({
5879
6046
  baseDir,
5880
6047
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
@@ -5914,7 +6081,7 @@ var WarpRule = class _WarpRule extends ToolRule {
5914
6081
  };
5915
6082
 
5916
6083
  // src/rules/windsurf-rule.ts
5917
- import { join as join55 } from "path";
6084
+ import { join as join56 } from "path";
5918
6085
  var WindsurfRule = class _WindsurfRule extends ToolRule {
5919
6086
  static getSettablePaths() {
5920
6087
  return {
@@ -5929,7 +6096,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
5929
6096
  validate = true
5930
6097
  }) {
5931
6098
  const fileContent = await readFileContent(
5932
- join55(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
6099
+ join56(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5933
6100
  );
5934
6101
  return new _WindsurfRule({
5935
6102
  baseDir,
@@ -6329,7 +6496,7 @@ var RulesProcessor = class extends FeatureProcessor {
6329
6496
  * Load and parse rulesync rule files from .rulesync/rules/ directory
6330
6497
  */
6331
6498
  async loadRulesyncFiles() {
6332
- const files = await findFilesByGlobs(join56(".rulesync/rules", "*.md"));
6499
+ const files = await findFilesByGlobs(join57(".rulesync/rules", "*.md"));
6333
6500
  logger.debug(`Found ${files.length} rulesync files`);
6334
6501
  const rulesyncRules = await Promise.all(
6335
6502
  files.map((file) => RulesyncRule.fromFile({ relativeFilePath: basename17(file) }))
@@ -6350,7 +6517,7 @@ var RulesProcessor = class extends FeatureProcessor {
6350
6517
  return rulesyncRules;
6351
6518
  }
6352
6519
  async loadRulesyncFilesLegacy() {
6353
- const legacyFiles = await findFilesByGlobs(join56(".rulesync", "*.md"));
6520
+ const legacyFiles = await findFilesByGlobs(join57(".rulesync", "*.md"));
6354
6521
  logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
6355
6522
  return Promise.all(
6356
6523
  legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: basename17(file) }))
@@ -6417,7 +6584,7 @@ var RulesProcessor = class extends FeatureProcessor {
6417
6584
  return [];
6418
6585
  }
6419
6586
  const rootFilePaths = await findFilesByGlobs(
6420
- join56(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
6587
+ join57(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
6421
6588
  );
6422
6589
  return await Promise.all(
6423
6590
  rootFilePaths.map(
@@ -6435,7 +6602,7 @@ var RulesProcessor = class extends FeatureProcessor {
6435
6602
  return [];
6436
6603
  }
6437
6604
  const nonRootFilePaths = await findFilesByGlobs(
6438
- join56(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
6605
+ join57(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
6439
6606
  );
6440
6607
  return await Promise.all(
6441
6608
  nonRootFilePaths.map(
@@ -6811,14 +6978,14 @@ s/<command> [arguments]
6811
6978
  This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
6812
6979
  The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
6813
6980
 
6814
- When users call a custom slash command, you have to look for the markdown file, \`${join56(commands.relativeDirPath, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
6981
+ When users call a custom slash command, you have to look for the markdown file, \`${join57(commands.relativeDirPath, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
6815
6982
  const subagentsSection = subagents ? `## Simulated Subagents
6816
6983
 
6817
6984
  Simulated subagents are specialized AI assistants that can be invoked to handle specific types of tasks. In this case, it can be appear something like custom slash commands simply. Simulated subagents can be called by custom slash commands.
6818
6985
 
6819
- When users call a simulated subagent, it will look for the corresponding markdown file, \`${join56(subagents.relativeDirPath, "{subagent}.md")}\`, and execute its contents as the block of operations.
6986
+ When users call a simulated subagent, it will look for the corresponding markdown file, \`${join57(subagents.relativeDirPath, "{subagent}.md")}\`, and execute its contents as the block of operations.
6820
6987
 
6821
- For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join56(subagents.relativeDirPath, "planner.md")}\`, and execute its contents as the block of operations.` : "";
6988
+ For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join57(subagents.relativeDirPath, "planner.md")}\`, and execute its contents as the block of operations.` : "";
6822
6989
  const result = [
6823
6990
  overview,
6824
6991
  ...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
@@ -6939,13 +7106,17 @@ async function generateMcp(config) {
6939
7106
  }
6940
7107
  let totalMcpOutputs = 0;
6941
7108
  logger.info("Generating MCP files...");
7109
+ if (config.getModularMcp()) {
7110
+ logger.info("\u2139\uFE0F Modular MCP support is experimental.");
7111
+ }
6942
7112
  const toolTargets = config.getGlobal() ? intersection(config.getTargets(), McpProcessor.getToolTargetsGlobal()) : intersection(config.getTargets(), McpProcessor.getToolTargets());
6943
7113
  for (const baseDir of config.getBaseDirs()) {
6944
7114
  for (const toolTarget of toolTargets) {
6945
7115
  const processor = new McpProcessor({
6946
7116
  baseDir,
6947
7117
  toolTarget,
6948
- global: config.getGlobal()
7118
+ global: config.getGlobal(),
7119
+ modularMcp: config.getModularMcp()
6949
7120
  });
6950
7121
  if (config.getDelete()) {
6951
7122
  const oldToolFiles = await processor.loadToolFilesToDelete();
@@ -7028,9 +7199,9 @@ async function generateSubagents(config) {
7028
7199
  }
7029
7200
 
7030
7201
  // src/cli/commands/gitignore.ts
7031
- import { join as join57 } from "path";
7202
+ import { join as join58 } from "path";
7032
7203
  var gitignoreCommand = async () => {
7033
- const gitignorePath = join57(process.cwd(), ".gitignore");
7204
+ const gitignorePath = join58(process.cwd(), ".gitignore");
7034
7205
  const rulesFilesToIgnore = [
7035
7206
  "# Generated by rulesync - AI tool configuration files",
7036
7207
  // AGENTS.md
@@ -7090,7 +7261,9 @@ var gitignoreCommand = async () => {
7090
7261
  "**/.roo/subagents/",
7091
7262
  // Warp
7092
7263
  "**/.warp/",
7093
- "**/WARP.md"
7264
+ "**/WARP.md",
7265
+ // Others
7266
+ "**/modular-mcp.json"
7094
7267
  ];
7095
7268
  let gitignoreContent = "";
7096
7269
  if (await fileExists(gitignorePath)) {
@@ -7269,7 +7442,7 @@ async function importSubagents(config, tool) {
7269
7442
  }
7270
7443
 
7271
7444
  // src/cli/commands/init.ts
7272
- import { join as join58 } from "path";
7445
+ import { join as join59 } from "path";
7273
7446
  async function initCommand() {
7274
7447
  logger.info("Initializing rulesync...");
7275
7448
  await ensureDir(".rulesync");
@@ -7296,7 +7469,8 @@ async function createConfigFile() {
7296
7469
  verbose: false,
7297
7470
  global: false,
7298
7471
  simulatedCommands: false,
7299
- simulatedSubagents: false
7472
+ simulatedSubagents: false,
7473
+ modularMcp: false
7300
7474
  },
7301
7475
  null,
7302
7476
  2
@@ -7429,14 +7603,14 @@ Attention, again, you are just the planner, so though you can read any files and
7429
7603
  await ensureDir(commandPaths.relativeDirPath);
7430
7604
  await ensureDir(subagentPaths.relativeDirPath);
7431
7605
  await ensureDir(ignorePaths.relativeDirPath);
7432
- const ruleFilepath = join58(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
7606
+ const ruleFilepath = join59(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
7433
7607
  if (!await fileExists(ruleFilepath)) {
7434
7608
  await writeFileContent(ruleFilepath, sampleRuleFile.content);
7435
7609
  logger.success(`Created ${ruleFilepath}`);
7436
7610
  } else {
7437
7611
  logger.info(`Skipped ${ruleFilepath} (already exists)`);
7438
7612
  }
7439
- const mcpFilepath = join58(
7613
+ const mcpFilepath = join59(
7440
7614
  mcpPaths.recommended.relativeDirPath,
7441
7615
  mcpPaths.recommended.relativeFilePath
7442
7616
  );
@@ -7446,21 +7620,21 @@ Attention, again, you are just the planner, so though you can read any files and
7446
7620
  } else {
7447
7621
  logger.info(`Skipped ${mcpFilepath} (already exists)`);
7448
7622
  }
7449
- const commandFilepath = join58(commandPaths.relativeDirPath, sampleCommandFile.filename);
7623
+ const commandFilepath = join59(commandPaths.relativeDirPath, sampleCommandFile.filename);
7450
7624
  if (!await fileExists(commandFilepath)) {
7451
7625
  await writeFileContent(commandFilepath, sampleCommandFile.content);
7452
7626
  logger.success(`Created ${commandFilepath}`);
7453
7627
  } else {
7454
7628
  logger.info(`Skipped ${commandFilepath} (already exists)`);
7455
7629
  }
7456
- const subagentFilepath = join58(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
7630
+ const subagentFilepath = join59(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
7457
7631
  if (!await fileExists(subagentFilepath)) {
7458
7632
  await writeFileContent(subagentFilepath, sampleSubagentFile.content);
7459
7633
  logger.success(`Created ${subagentFilepath}`);
7460
7634
  } else {
7461
7635
  logger.info(`Skipped ${subagentFilepath} (already exists)`);
7462
7636
  }
7463
- const ignoreFilepath = join58(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
7637
+ const ignoreFilepath = join59(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
7464
7638
  if (!await fileExists(ignoreFilepath)) {
7465
7639
  await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
7466
7640
  logger.success(`Created ${ignoreFilepath}`);
@@ -7470,7 +7644,7 @@ Attention, again, you are just the planner, so though you can read any files and
7470
7644
  }
7471
7645
 
7472
7646
  // src/cli/index.ts
7473
- var getVersion = () => "3.11.3";
7647
+ var getVersion = () => "3.12.0";
7474
7648
  var main = async () => {
7475
7649
  const program = new Command();
7476
7650
  const version = getVersion();
@@ -7542,6 +7716,9 @@ var main = async () => {
7542
7716
  ).option(
7543
7717
  "--experimental-simulate-subagents",
7544
7718
  "Generate simulated subagents (deprecated: use --simulated-subagents instead)"
7719
+ ).option(
7720
+ "--modular-mcp",
7721
+ "Generate modular-mcp configuration for context compression (experimental)"
7545
7722
  ).action(async (options) => {
7546
7723
  try {
7547
7724
  await generateCommand({
@@ -7554,6 +7731,7 @@ var main = async () => {
7554
7731
  global: options.global,
7555
7732
  simulatedCommands: options.simulatedCommands,
7556
7733
  simulatedSubagents: options.simulatedSubagents,
7734
+ modularMcp: options.modularMcp,
7557
7735
  experimentalGlobal: options.experimentalGlobal,
7558
7736
  experimentalSimulateCommands: options.experimentalSimulateCommands,
7559
7737
  experimentalSimulateSubagents: options.experimentalSimulateSubagents