rulesync 3.1.1 → 3.2.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/dist/index.js CHANGED
@@ -87,6 +87,14 @@ async function ensureDir(dirPath) {
87
87
  await mkdir(dirPath, { recursive: true });
88
88
  }
89
89
  }
90
+ async function readOrInitializeFileContent(filePath, initialContent = "") {
91
+ if (await fileExists(filePath)) {
92
+ return await readFileContent(filePath);
93
+ } else {
94
+ await ensureDir(dirname(filePath));
95
+ return initialContent;
96
+ }
97
+ }
90
98
  async function directoryExists(dirPath) {
91
99
  try {
92
100
  const stats = await stat(dirPath);
@@ -2501,11 +2509,11 @@ var McpServerBaseSchema = z10.object({
2501
2509
  kiroAutoBlock: z10.optional(z10.array(z10.string())),
2502
2510
  headers: z10.optional(z10.record(z10.string(), z10.string()))
2503
2511
  });
2504
- var RulesyncMcpServerSchema = z10.extend(McpServerBaseSchema, {
2512
+ var RulesyncMcpServersSchema = z10.extend(McpServerBaseSchema, {
2505
2513
  targets: z10.optional(RulesyncTargetsSchema)
2506
2514
  });
2507
2515
  var RulesyncMcpConfigSchema = z10.object({
2508
- mcpServers: z10.record(z10.string(), RulesyncMcpServerSchema)
2516
+ mcpServers: z10.record(z10.string(), RulesyncMcpServersSchema)
2509
2517
  });
2510
2518
  var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2511
2519
  json;
@@ -2547,14 +2555,12 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2547
2555
 
2548
2556
  // src/mcp/tool-mcp.ts
2549
2557
  var ToolMcp = class extends ToolFile {
2550
- json;
2551
2558
  constructor({ ...rest }) {
2552
2559
  super({
2553
2560
  ...rest,
2554
2561
  validate: true
2555
2562
  // Skip validation during construction
2556
2563
  });
2557
- this.json = JSON.parse(this.fileContent);
2558
2564
  if (rest.validate) {
2559
2565
  const result = this.validate();
2560
2566
  if (!result.success) {
@@ -2562,9 +2568,6 @@ var ToolMcp = class extends ToolFile {
2562
2568
  }
2563
2569
  }
2564
2570
  }
2565
- getJson() {
2566
- return this.json;
2567
- }
2568
2571
  static getSettablePaths() {
2569
2572
  throw new Error("Please implement this method in the subclass.");
2570
2573
  }
@@ -2586,6 +2589,14 @@ var ToolMcp = class extends ToolFile {
2586
2589
 
2587
2590
  // src/mcp/amazonqcli-mcp.ts
2588
2591
  var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
2592
+ json;
2593
+ constructor(params) {
2594
+ super(params);
2595
+ this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
2596
+ }
2597
+ getJson() {
2598
+ return this.json;
2599
+ }
2589
2600
  static getSettablePaths() {
2590
2601
  return {
2591
2602
  relativeDirPath: ".amazonq",
@@ -2635,6 +2646,14 @@ var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
2635
2646
  // src/mcp/claudecode-mcp.ts
2636
2647
  import { join as join26 } from "path";
2637
2648
  var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2649
+ json;
2650
+ constructor(params) {
2651
+ super(params);
2652
+ this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
2653
+ }
2654
+ getJson() {
2655
+ return this.json;
2656
+ }
2638
2657
  static getSettablePaths() {
2639
2658
  return {
2640
2659
  relativeDirPath: ".",
@@ -2684,6 +2703,14 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2684
2703
  // src/mcp/cline-mcp.ts
2685
2704
  import { join as join27 } from "path";
2686
2705
  var ClineMcp = class _ClineMcp extends ToolMcp {
2706
+ json;
2707
+ constructor(params) {
2708
+ super(params);
2709
+ this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
2710
+ }
2711
+ getJson() {
2712
+ return this.json;
2713
+ }
2687
2714
  static getSettablePaths() {
2688
2715
  return {
2689
2716
  relativeDirPath: ".cline",
@@ -2730,9 +2757,111 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
2730
2757
  }
2731
2758
  };
2732
2759
 
2733
- // src/mcp/copilot-mcp.ts
2760
+ // src/mcp/codex-mcp.ts
2734
2761
  import { join as join28 } from "path";
2762
+ import * as smolToml from "smol-toml";
2763
+ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
2764
+ toml;
2765
+ constructor({ ...rest }) {
2766
+ super({
2767
+ ...rest,
2768
+ validate: false
2769
+ });
2770
+ this.toml = smolToml.parse(this.fileContent);
2771
+ if (rest.validate) {
2772
+ const result = this.validate();
2773
+ if (!result.success) {
2774
+ throw result.error;
2775
+ }
2776
+ }
2777
+ }
2778
+ getToml() {
2779
+ return this.toml;
2780
+ }
2781
+ static getSettablePaths() {
2782
+ throw new Error("getSettablePaths is not supported for CodexcliMcp");
2783
+ }
2784
+ static getSettablePathsGlobal() {
2785
+ return {
2786
+ relativeDirPath: ".codex",
2787
+ relativeFilePath: "config.toml"
2788
+ };
2789
+ }
2790
+ static async fromFile({
2791
+ baseDir = ".",
2792
+ validate = true,
2793
+ global = false
2794
+ }) {
2795
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
2796
+ const fileContent = await readFileContent(
2797
+ join28(baseDir, paths.relativeDirPath, paths.relativeFilePath)
2798
+ );
2799
+ return new _CodexcliMcp({
2800
+ baseDir,
2801
+ relativeDirPath: paths.relativeDirPath,
2802
+ relativeFilePath: paths.relativeFilePath,
2803
+ fileContent,
2804
+ validate
2805
+ });
2806
+ }
2807
+ static async fromRulesyncMcp({
2808
+ baseDir = ".",
2809
+ rulesyncMcp,
2810
+ validate = true,
2811
+ global = false
2812
+ }) {
2813
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
2814
+ const configTomlFilePath = join28(baseDir, paths.relativeDirPath, paths.relativeFilePath);
2815
+ const configTomlFileContent = await readOrInitializeFileContent(
2816
+ configTomlFilePath,
2817
+ smolToml.stringify({})
2818
+ );
2819
+ const configToml = smolToml.parse(configTomlFileContent);
2820
+ const mcpServers = rulesyncMcp.getJson().mcpServers;
2821
+ const filteredMcpServers = this.removeEmptyEntries(mcpServers);
2822
+ configToml["mcp_servers"] = filteredMcpServers;
2823
+ return new _CodexcliMcp({
2824
+ baseDir,
2825
+ relativeDirPath: paths.relativeDirPath,
2826
+ relativeFilePath: paths.relativeFilePath,
2827
+ fileContent: smolToml.stringify(configToml),
2828
+ validate
2829
+ });
2830
+ }
2831
+ toRulesyncMcp() {
2832
+ return new RulesyncMcp({
2833
+ baseDir: this.baseDir,
2834
+ relativeDirPath: ".rulesync",
2835
+ relativeFilePath: ".mcp.json",
2836
+ fileContent: JSON.stringify({ mcpServers: this.toml.mcp_servers ?? {} })
2837
+ });
2838
+ }
2839
+ validate() {
2840
+ return { success: true, error: null };
2841
+ }
2842
+ static removeEmptyEntries(obj) {
2843
+ if (!obj) return {};
2844
+ const filtered = {};
2845
+ for (const [key, value] of Object.entries(obj)) {
2846
+ if (value === null) continue;
2847
+ if (typeof value === "object" && Object.keys(value).length === 0) continue;
2848
+ filtered[key] = value;
2849
+ }
2850
+ return filtered;
2851
+ }
2852
+ };
2853
+
2854
+ // src/mcp/copilot-mcp.ts
2855
+ import { join as join29 } from "path";
2735
2856
  var CopilotMcp = class _CopilotMcp extends ToolMcp {
2857
+ json;
2858
+ constructor(params) {
2859
+ super(params);
2860
+ this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
2861
+ }
2862
+ getJson() {
2863
+ return this.json;
2864
+ }
2736
2865
  static getSettablePaths() {
2737
2866
  return {
2738
2867
  relativeDirPath: ".vscode",
@@ -2744,7 +2873,7 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
2744
2873
  validate = true
2745
2874
  }) {
2746
2875
  const fileContent = await readFileContent(
2747
- join28(
2876
+ join29(
2748
2877
  baseDir,
2749
2878
  this.getSettablePaths().relativeDirPath,
2750
2879
  this.getSettablePaths().relativeFilePath
@@ -2780,8 +2909,16 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
2780
2909
  };
2781
2910
 
2782
2911
  // src/mcp/cursor-mcp.ts
2783
- import { join as join29 } from "path";
2912
+ import { join as join30 } from "path";
2784
2913
  var CursorMcp = class _CursorMcp extends ToolMcp {
2914
+ json;
2915
+ constructor(params) {
2916
+ super(params);
2917
+ this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
2918
+ }
2919
+ getJson() {
2920
+ return this.json;
2921
+ }
2785
2922
  static getSettablePaths() {
2786
2923
  return {
2787
2924
  relativeDirPath: ".cursor",
@@ -2793,7 +2930,7 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
2793
2930
  validate = true
2794
2931
  }) {
2795
2932
  const fileContent = await readFileContent(
2796
- join29(
2933
+ join30(
2797
2934
  baseDir,
2798
2935
  this.getSettablePaths().relativeDirPath,
2799
2936
  this.getSettablePaths().relativeFilePath
@@ -2840,8 +2977,16 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
2840
2977
  };
2841
2978
 
2842
2979
  // src/mcp/roo-mcp.ts
2843
- import { join as join30 } from "path";
2980
+ import { join as join31 } from "path";
2844
2981
  var RooMcp = class _RooMcp extends ToolMcp {
2982
+ json;
2983
+ constructor(params) {
2984
+ super(params);
2985
+ this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
2986
+ }
2987
+ getJson() {
2988
+ return this.json;
2989
+ }
2845
2990
  static getSettablePaths() {
2846
2991
  return {
2847
2992
  relativeDirPath: ".roo",
@@ -2853,7 +2998,7 @@ var RooMcp = class _RooMcp extends ToolMcp {
2853
2998
  validate = true
2854
2999
  }) {
2855
3000
  const fileContent = await readFileContent(
2856
- join30(
3001
+ join31(
2857
3002
  baseDir,
2858
3003
  this.getSettablePaths().relativeDirPath,
2859
3004
  this.getSettablePaths().relativeFilePath
@@ -2898,15 +3043,22 @@ var mcpProcessorToolTargets = [
2898
3043
  "cursor",
2899
3044
  "roo"
2900
3045
  ];
2901
- var McpProcessorToolTargetSchema = z11.enum(mcpProcessorToolTargets);
3046
+ var McpProcessorToolTargetSchema = z11.enum(
3047
+ // 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
+ mcpProcessorToolTargets.concat("codexcli")
3049
+ );
3050
+ var mcpProcessorToolTargetsGlobal = ["codexcli"];
2902
3051
  var McpProcessor = class extends FeatureProcessor {
2903
3052
  toolTarget;
3053
+ global;
2904
3054
  constructor({
2905
3055
  baseDir = ".",
2906
- toolTarget
3056
+ toolTarget,
3057
+ global = false
2907
3058
  }) {
2908
3059
  super({ baseDir });
2909
3060
  this.toolTarget = McpProcessorToolTargetSchema.parse(toolTarget);
3061
+ this.global = global;
2910
3062
  }
2911
3063
  /**
2912
3064
  * Implementation of abstract method from FeatureProcessor
@@ -2955,6 +3107,15 @@ var McpProcessor = class extends FeatureProcessor {
2955
3107
  })
2956
3108
  ];
2957
3109
  }
3110
+ case "codexcli": {
3111
+ return [
3112
+ await CodexcliMcp.fromFile({
3113
+ baseDir: this.baseDir,
3114
+ validate: true,
3115
+ global: this.global
3116
+ })
3117
+ ];
3118
+ }
2958
3119
  case "copilot": {
2959
3120
  return [
2960
3121
  await CopilotMcp.fromFile({
@@ -3001,42 +3162,50 @@ var McpProcessor = class extends FeatureProcessor {
3001
3162
  if (!rulesyncMcp) {
3002
3163
  throw new Error(`No .rulesync/.mcp.json found.`);
3003
3164
  }
3004
- const toolMcps = [rulesyncMcp].map((rulesyncMcp2) => {
3005
- switch (this.toolTarget) {
3006
- case "amazonqcli":
3007
- return AmazonqcliMcp.fromRulesyncMcp({
3008
- baseDir: this.baseDir,
3009
- rulesyncMcp: rulesyncMcp2
3010
- });
3011
- case "claudecode":
3012
- return ClaudecodeMcp.fromRulesyncMcp({
3013
- baseDir: this.baseDir,
3014
- rulesyncMcp: rulesyncMcp2
3015
- });
3016
- case "cline":
3017
- return ClineMcp.fromRulesyncMcp({
3018
- baseDir: this.baseDir,
3019
- rulesyncMcp: rulesyncMcp2
3020
- });
3021
- case "copilot":
3022
- return CopilotMcp.fromRulesyncMcp({
3023
- baseDir: this.baseDir,
3024
- rulesyncMcp: rulesyncMcp2
3025
- });
3026
- case "cursor":
3027
- return CursorMcp.fromRulesyncMcp({
3028
- baseDir: this.baseDir,
3029
- rulesyncMcp: rulesyncMcp2
3030
- });
3031
- case "roo":
3032
- return RooMcp.fromRulesyncMcp({
3033
- baseDir: this.baseDir,
3034
- rulesyncMcp: rulesyncMcp2
3035
- });
3036
- default:
3037
- throw new Error(`Unsupported tool target: ${this.toolTarget}`);
3038
- }
3039
- });
3165
+ const toolMcps = await Promise.all(
3166
+ [rulesyncMcp].map(async (rulesyncMcp2) => {
3167
+ switch (this.toolTarget) {
3168
+ case "amazonqcli":
3169
+ return AmazonqcliMcp.fromRulesyncMcp({
3170
+ baseDir: this.baseDir,
3171
+ rulesyncMcp: rulesyncMcp2
3172
+ });
3173
+ case "claudecode":
3174
+ return ClaudecodeMcp.fromRulesyncMcp({
3175
+ baseDir: this.baseDir,
3176
+ rulesyncMcp: rulesyncMcp2
3177
+ });
3178
+ case "cline":
3179
+ return ClineMcp.fromRulesyncMcp({
3180
+ baseDir: this.baseDir,
3181
+ rulesyncMcp: rulesyncMcp2
3182
+ });
3183
+ case "copilot":
3184
+ return CopilotMcp.fromRulesyncMcp({
3185
+ baseDir: this.baseDir,
3186
+ rulesyncMcp: rulesyncMcp2
3187
+ });
3188
+ case "cursor":
3189
+ return CursorMcp.fromRulesyncMcp({
3190
+ baseDir: this.baseDir,
3191
+ rulesyncMcp: rulesyncMcp2
3192
+ });
3193
+ case "codexcli":
3194
+ return await CodexcliMcp.fromRulesyncMcp({
3195
+ baseDir: this.baseDir,
3196
+ rulesyncMcp: rulesyncMcp2,
3197
+ global: this.global
3198
+ });
3199
+ case "roo":
3200
+ return RooMcp.fromRulesyncMcp({
3201
+ baseDir: this.baseDir,
3202
+ rulesyncMcp: rulesyncMcp2
3203
+ });
3204
+ default:
3205
+ throw new Error(`Unsupported tool target: ${this.toolTarget}`);
3206
+ }
3207
+ })
3208
+ );
3040
3209
  return toolMcps;
3041
3210
  }
3042
3211
  /**
@@ -3057,15 +3226,18 @@ var McpProcessor = class extends FeatureProcessor {
3057
3226
  static getToolTargets() {
3058
3227
  return mcpProcessorToolTargets;
3059
3228
  }
3229
+ static getToolTargetsGlobal() {
3230
+ return mcpProcessorToolTargetsGlobal;
3231
+ }
3060
3232
  };
3061
3233
 
3062
3234
  // src/rules/rules-processor.ts
3063
- import { basename as basename17, join as join54 } from "path";
3235
+ import { basename as basename17, join as join55 } from "path";
3064
3236
  import { XMLBuilder } from "fast-xml-parser";
3065
3237
  import { z as z20 } from "zod/mini";
3066
3238
 
3067
3239
  // src/subagents/simulated-subagent.ts
3068
- import { basename as basename12, join as join31 } from "path";
3240
+ import { basename as basename12, join as join32 } from "path";
3069
3241
  import { z as z12 } from "zod/mini";
3070
3242
 
3071
3243
  // src/subagents/tool-subagent.ts
@@ -3167,7 +3339,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3167
3339
  relativeFilePath,
3168
3340
  validate = true
3169
3341
  }) {
3170
- const filePath = join31(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
3342
+ const filePath = join32(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
3171
3343
  const fileContent = await readFileContent(filePath);
3172
3344
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3173
3345
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -3324,15 +3496,15 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
3324
3496
  };
3325
3497
 
3326
3498
  // src/subagents/subagents-processor.ts
3327
- import { basename as basename14, join as join34 } from "path";
3499
+ import { basename as basename14, join as join35 } from "path";
3328
3500
  import { z as z15 } from "zod/mini";
3329
3501
 
3330
3502
  // src/subagents/claudecode-subagent.ts
3331
- import { join as join33 } from "path";
3503
+ import { join as join34 } from "path";
3332
3504
  import { z as z14 } from "zod/mini";
3333
3505
 
3334
3506
  // src/subagents/rulesync-subagent.ts
3335
- import { basename as basename13, join as join32 } from "path";
3507
+ import { basename as basename13, join as join33 } from "path";
3336
3508
  import { z as z13 } from "zod/mini";
3337
3509
  var RulesyncSubagentModelSchema = z13.enum(["opus", "sonnet", "haiku", "inherit"]);
3338
3510
  var RulesyncSubagentFrontmatterSchema = z13.object({
@@ -3386,7 +3558,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
3386
3558
  static async fromFile({
3387
3559
  relativeFilePath
3388
3560
  }) {
3389
- const fileContent = await readFileContent(join32(".rulesync/subagents", relativeFilePath));
3561
+ const fileContent = await readFileContent(join33(".rulesync/subagents", relativeFilePath));
3390
3562
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3391
3563
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
3392
3564
  if (!result.success) {
@@ -3504,7 +3676,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
3504
3676
  relativeFilePath,
3505
3677
  validate = true
3506
3678
  }) {
3507
- const fileContent = await readFileContent(join33(baseDir, ".claude/agents", relativeFilePath));
3679
+ const fileContent = await readFileContent(join34(baseDir, ".claude/agents", relativeFilePath));
3508
3680
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3509
3681
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
3510
3682
  if (!result.success) {
@@ -3646,7 +3818,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
3646
3818
  * Load and parse rulesync subagent files from .rulesync/subagents/ directory
3647
3819
  */
3648
3820
  async loadRulesyncFiles() {
3649
- const subagentsDir = join34(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
3821
+ const subagentsDir = join35(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
3650
3822
  const dirExists = await directoryExists(subagentsDir);
3651
3823
  if (!dirExists) {
3652
3824
  logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
@@ -3661,7 +3833,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
3661
3833
  logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
3662
3834
  const rulesyncSubagents = [];
3663
3835
  for (const mdFile of mdFiles) {
3664
- const filepath = join34(subagentsDir, mdFile);
3836
+ const filepath = join35(subagentsDir, mdFile);
3665
3837
  try {
3666
3838
  const rulesyncSubagent = await RulesyncSubagent.fromFile({
3667
3839
  relativeFilePath: mdFile,
@@ -3775,7 +3947,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
3775
3947
  relativeDirPath,
3776
3948
  fromFile
3777
3949
  }) {
3778
- const paths = await findFilesByGlobs(join34(this.baseDir, relativeDirPath, "*.md"));
3950
+ const paths = await findFilesByGlobs(join35(this.baseDir, relativeDirPath, "*.md"));
3779
3951
  const subagents = (await Promise.allSettled(paths.map((path2) => fromFile(basename14(path2))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
3780
3952
  logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
3781
3953
  return subagents;
@@ -3800,13 +3972,13 @@ var SubagentsProcessor = class extends FeatureProcessor {
3800
3972
  };
3801
3973
 
3802
3974
  // src/rules/agentsmd-rule.ts
3803
- import { join as join37 } from "path";
3975
+ import { join as join38 } from "path";
3804
3976
 
3805
3977
  // src/rules/tool-rule.ts
3806
- import { join as join36 } from "path";
3978
+ import { join as join37 } from "path";
3807
3979
 
3808
3980
  // src/rules/rulesync-rule.ts
3809
- import { basename as basename15, join as join35 } from "path";
3981
+ import { basename as basename15, join as join36 } from "path";
3810
3982
  import { z as z16 } from "zod/mini";
3811
3983
  var RulesyncRuleFrontmatterSchema = z16.object({
3812
3984
  root: z16.optional(z16.optional(z16.boolean())),
@@ -3872,7 +4044,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
3872
4044
  relativeFilePath,
3873
4045
  validate = true
3874
4046
  }) {
3875
- const filePath = join35(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
4047
+ const filePath = join36(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
3876
4048
  const fileContent = await readFileContent(filePath);
3877
4049
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3878
4050
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
@@ -3901,7 +4073,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
3901
4073
  relativeFilePath,
3902
4074
  validate = true
3903
4075
  }) {
3904
- const filePath = join35(this.getSettablePaths().recommended.relativeDirPath, relativeFilePath);
4076
+ const filePath = join36(this.getSettablePaths().recommended.relativeDirPath, relativeFilePath);
3905
4077
  const fileContent = await readFileContent(filePath);
3906
4078
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3907
4079
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
@@ -4005,7 +4177,7 @@ var ToolRule = class extends ToolFile {
4005
4177
  });
4006
4178
  const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
4007
4179
  if (!rulesyncFrontmatter.root && rulesyncFrontmatter.agentsmd?.subprojectPath) {
4008
- params.relativeDirPath = join36(rulesyncFrontmatter.agentsmd.subprojectPath);
4180
+ params.relativeDirPath = join37(rulesyncFrontmatter.agentsmd.subprojectPath);
4009
4181
  params.relativeFilePath = "AGENTS.md";
4010
4182
  }
4011
4183
  return params;
@@ -4081,8 +4253,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
4081
4253
  validate = true
4082
4254
  }) {
4083
4255
  const isRoot = relativeFilePath === "AGENTS.md";
4084
- const relativePath = isRoot ? "AGENTS.md" : join37(".agents/memories", relativeFilePath);
4085
- const fileContent = await readFileContent(join37(baseDir, relativePath));
4256
+ const relativePath = isRoot ? "AGENTS.md" : join38(".agents/memories", relativeFilePath);
4257
+ const fileContent = await readFileContent(join38(baseDir, relativePath));
4086
4258
  return new _AgentsMdRule({
4087
4259
  baseDir,
4088
4260
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -4122,7 +4294,7 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
4122
4294
  };
4123
4295
 
4124
4296
  // src/rules/amazonqcli-rule.ts
4125
- import { join as join38 } from "path";
4297
+ import { join as join39 } from "path";
4126
4298
  var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4127
4299
  static getSettablePaths() {
4128
4300
  return {
@@ -4137,7 +4309,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4137
4309
  validate = true
4138
4310
  }) {
4139
4311
  const fileContent = await readFileContent(
4140
- join38(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4312
+ join39(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4141
4313
  );
4142
4314
  return new _AmazonQCliRule({
4143
4315
  baseDir,
@@ -4177,7 +4349,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4177
4349
  };
4178
4350
 
4179
4351
  // src/rules/augmentcode-legacy-rule.ts
4180
- import { join as join39 } from "path";
4352
+ import { join as join40 } from "path";
4181
4353
  var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4182
4354
  toRulesyncRule() {
4183
4355
  const rulesyncFrontmatter = {
@@ -4238,8 +4410,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4238
4410
  }) {
4239
4411
  const settablePaths = this.getSettablePaths();
4240
4412
  const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
4241
- const relativePath = isRoot ? settablePaths.root.relativeFilePath : join39(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
4242
- const fileContent = await readFileContent(join39(baseDir, relativePath));
4413
+ const relativePath = isRoot ? settablePaths.root.relativeFilePath : join40(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
4414
+ const fileContent = await readFileContent(join40(baseDir, relativePath));
4243
4415
  return new _AugmentcodeLegacyRule({
4244
4416
  baseDir,
4245
4417
  relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
@@ -4252,7 +4424,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4252
4424
  };
4253
4425
 
4254
4426
  // src/rules/augmentcode-rule.ts
4255
- import { join as join40 } from "path";
4427
+ import { join as join41 } from "path";
4256
4428
  var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
4257
4429
  toRulesyncRule() {
4258
4430
  return this.toRulesyncRuleDefault();
@@ -4284,7 +4456,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
4284
4456
  validate = true
4285
4457
  }) {
4286
4458
  const fileContent = await readFileContent(
4287
- join40(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4459
+ join41(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4288
4460
  );
4289
4461
  const { body: content } = parseFrontmatter(fileContent);
4290
4462
  return new _AugmentcodeRule({
@@ -4307,7 +4479,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
4307
4479
  };
4308
4480
 
4309
4481
  // src/rules/claudecode-rule.ts
4310
- import { join as join41 } from "path";
4482
+ import { join as join42 } from "path";
4311
4483
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4312
4484
  static getSettablePaths() {
4313
4485
  return {
@@ -4316,7 +4488,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4316
4488
  relativeFilePath: "CLAUDE.md"
4317
4489
  },
4318
4490
  nonRoot: {
4319
- relativeDirPath: join41(".claude", "memories")
4491
+ relativeDirPath: join42(".claude", "memories")
4320
4492
  }
4321
4493
  };
4322
4494
  }
@@ -4339,7 +4511,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4339
4511
  if (isRoot) {
4340
4512
  const relativePath2 = paths.root.relativeFilePath;
4341
4513
  const fileContent2 = await readFileContent(
4342
- join41(baseDir, paths.root.relativeDirPath, relativePath2)
4514
+ join42(baseDir, paths.root.relativeDirPath, relativePath2)
4343
4515
  );
4344
4516
  return new _ClaudecodeRule({
4345
4517
  baseDir,
@@ -4353,8 +4525,8 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4353
4525
  if (!paths.nonRoot) {
4354
4526
  throw new Error("nonRoot path is not set");
4355
4527
  }
4356
- const relativePath = join41(paths.nonRoot.relativeDirPath, relativeFilePath);
4357
- const fileContent = await readFileContent(join41(baseDir, relativePath));
4528
+ const relativePath = join42(paths.nonRoot.relativeDirPath, relativeFilePath);
4529
+ const fileContent = await readFileContent(join42(baseDir, relativePath));
4358
4530
  return new _ClaudecodeRule({
4359
4531
  baseDir,
4360
4532
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -4396,7 +4568,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4396
4568
  };
4397
4569
 
4398
4570
  // src/rules/cline-rule.ts
4399
- import { join as join42 } from "path";
4571
+ import { join as join43 } from "path";
4400
4572
  import { z as z17 } from "zod/mini";
4401
4573
  var ClineRuleFrontmatterSchema = z17.object({
4402
4574
  description: z17.string()
@@ -4441,7 +4613,7 @@ var ClineRule = class _ClineRule extends ToolRule {
4441
4613
  validate = true
4442
4614
  }) {
4443
4615
  const fileContent = await readFileContent(
4444
- join42(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4616
+ join43(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4445
4617
  );
4446
4618
  return new _ClineRule({
4447
4619
  baseDir,
@@ -4454,7 +4626,7 @@ var ClineRule = class _ClineRule extends ToolRule {
4454
4626
  };
4455
4627
 
4456
4628
  // src/rules/codexcli-rule.ts
4457
- import { join as join43 } from "path";
4629
+ import { join as join44 } from "path";
4458
4630
  var CodexcliRule = class _CodexcliRule extends ToolRule {
4459
4631
  static getSettablePaths() {
4460
4632
  return {
@@ -4486,7 +4658,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
4486
4658
  if (isRoot) {
4487
4659
  const relativePath2 = paths.root.relativeFilePath;
4488
4660
  const fileContent2 = await readFileContent(
4489
- join43(baseDir, paths.root.relativeDirPath, relativePath2)
4661
+ join44(baseDir, paths.root.relativeDirPath, relativePath2)
4490
4662
  );
4491
4663
  return new _CodexcliRule({
4492
4664
  baseDir,
@@ -4500,8 +4672,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
4500
4672
  if (!paths.nonRoot) {
4501
4673
  throw new Error("nonRoot path is not set");
4502
4674
  }
4503
- const relativePath = join43(paths.nonRoot.relativeDirPath, relativeFilePath);
4504
- const fileContent = await readFileContent(join43(baseDir, relativePath));
4675
+ const relativePath = join44(paths.nonRoot.relativeDirPath, relativeFilePath);
4676
+ const fileContent = await readFileContent(join44(baseDir, relativePath));
4505
4677
  return new _CodexcliRule({
4506
4678
  baseDir,
4507
4679
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -4543,7 +4715,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
4543
4715
  };
4544
4716
 
4545
4717
  // src/rules/copilot-rule.ts
4546
- import { join as join44 } from "path";
4718
+ import { join as join45 } from "path";
4547
4719
  import { z as z18 } from "zod/mini";
4548
4720
  var CopilotRuleFrontmatterSchema = z18.object({
4549
4721
  description: z18.optional(z18.string()),
@@ -4636,11 +4808,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
4636
4808
  validate = true
4637
4809
  }) {
4638
4810
  const isRoot = relativeFilePath === "copilot-instructions.md";
4639
- const relativePath = isRoot ? join44(
4811
+ const relativePath = isRoot ? join45(
4640
4812
  this.getSettablePaths().root.relativeDirPath,
4641
4813
  this.getSettablePaths().root.relativeFilePath
4642
- ) : join44(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
4643
- const fileContent = await readFileContent(join44(baseDir, relativePath));
4814
+ ) : join45(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
4815
+ const fileContent = await readFileContent(join45(baseDir, relativePath));
4644
4816
  if (isRoot) {
4645
4817
  return new _CopilotRule({
4646
4818
  baseDir,
@@ -4659,7 +4831,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
4659
4831
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
4660
4832
  if (!result.success) {
4661
4833
  throw new Error(
4662
- `Invalid frontmatter in ${join44(baseDir, relativeFilePath)}: ${result.error.message}`
4834
+ `Invalid frontmatter in ${join45(baseDir, relativeFilePath)}: ${result.error.message}`
4663
4835
  );
4664
4836
  }
4665
4837
  return new _CopilotRule({
@@ -4698,7 +4870,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
4698
4870
  };
4699
4871
 
4700
4872
  // src/rules/cursor-rule.ts
4701
- import { basename as basename16, join as join45 } from "path";
4873
+ import { basename as basename16, join as join46 } from "path";
4702
4874
  import { z as z19 } from "zod/mini";
4703
4875
  var CursorRuleFrontmatterSchema = z19.object({
4704
4876
  description: z19.optional(z19.string()),
@@ -4825,13 +4997,13 @@ var CursorRule = class _CursorRule extends ToolRule {
4825
4997
  validate = true
4826
4998
  }) {
4827
4999
  const fileContent = await readFileContent(
4828
- join45(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5000
+ join46(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4829
5001
  );
4830
5002
  const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
4831
5003
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
4832
5004
  if (!result.success) {
4833
5005
  throw new Error(
4834
- `Invalid frontmatter in ${join45(baseDir, relativeFilePath)}: ${result.error.message}`
5006
+ `Invalid frontmatter in ${join46(baseDir, relativeFilePath)}: ${result.error.message}`
4835
5007
  );
4836
5008
  }
4837
5009
  return new _CursorRule({
@@ -4869,7 +5041,7 @@ var CursorRule = class _CursorRule extends ToolRule {
4869
5041
  };
4870
5042
 
4871
5043
  // src/rules/geminicli-rule.ts
4872
- import { join as join46 } from "path";
5044
+ import { join as join47 } from "path";
4873
5045
  var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4874
5046
  static getSettablePaths() {
4875
5047
  return {
@@ -4901,7 +5073,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4901
5073
  if (isRoot) {
4902
5074
  const relativePath2 = paths.root.relativeFilePath;
4903
5075
  const fileContent2 = await readFileContent(
4904
- join46(baseDir, paths.root.relativeDirPath, relativePath2)
5076
+ join47(baseDir, paths.root.relativeDirPath, relativePath2)
4905
5077
  );
4906
5078
  return new _GeminiCliRule({
4907
5079
  baseDir,
@@ -4915,8 +5087,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4915
5087
  if (!paths.nonRoot) {
4916
5088
  throw new Error("nonRoot path is not set");
4917
5089
  }
4918
- const relativePath = join46(paths.nonRoot.relativeDirPath, relativeFilePath);
4919
- const fileContent = await readFileContent(join46(baseDir, relativePath));
5090
+ const relativePath = join47(paths.nonRoot.relativeDirPath, relativeFilePath);
5091
+ const fileContent = await readFileContent(join47(baseDir, relativePath));
4920
5092
  return new _GeminiCliRule({
4921
5093
  baseDir,
4922
5094
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -4958,7 +5130,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4958
5130
  };
4959
5131
 
4960
5132
  // src/rules/junie-rule.ts
4961
- import { join as join47 } from "path";
5133
+ import { join as join48 } from "path";
4962
5134
  var JunieRule = class _JunieRule extends ToolRule {
4963
5135
  static getSettablePaths() {
4964
5136
  return {
@@ -4977,8 +5149,8 @@ var JunieRule = class _JunieRule extends ToolRule {
4977
5149
  validate = true
4978
5150
  }) {
4979
5151
  const isRoot = relativeFilePath === "guidelines.md";
4980
- const relativePath = isRoot ? "guidelines.md" : join47(".junie/memories", relativeFilePath);
4981
- const fileContent = await readFileContent(join47(baseDir, relativePath));
5152
+ const relativePath = isRoot ? "guidelines.md" : join48(".junie/memories", relativeFilePath);
5153
+ const fileContent = await readFileContent(join48(baseDir, relativePath));
4982
5154
  return new _JunieRule({
4983
5155
  baseDir,
4984
5156
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5018,7 +5190,7 @@ var JunieRule = class _JunieRule extends ToolRule {
5018
5190
  };
5019
5191
 
5020
5192
  // src/rules/kiro-rule.ts
5021
- import { join as join48 } from "path";
5193
+ import { join as join49 } from "path";
5022
5194
  var KiroRule = class _KiroRule extends ToolRule {
5023
5195
  static getSettablePaths() {
5024
5196
  return {
@@ -5033,7 +5205,7 @@ var KiroRule = class _KiroRule extends ToolRule {
5033
5205
  validate = true
5034
5206
  }) {
5035
5207
  const fileContent = await readFileContent(
5036
- join48(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5208
+ join49(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5037
5209
  );
5038
5210
  return new _KiroRule({
5039
5211
  baseDir,
@@ -5073,7 +5245,7 @@ var KiroRule = class _KiroRule extends ToolRule {
5073
5245
  };
5074
5246
 
5075
5247
  // src/rules/opencode-rule.ts
5076
- import { join as join49 } from "path";
5248
+ import { join as join50 } from "path";
5077
5249
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5078
5250
  static getSettablePaths() {
5079
5251
  return {
@@ -5092,8 +5264,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5092
5264
  validate = true
5093
5265
  }) {
5094
5266
  const isRoot = relativeFilePath === "AGENTS.md";
5095
- const relativePath = isRoot ? "AGENTS.md" : join49(".opencode/memories", relativeFilePath);
5096
- const fileContent = await readFileContent(join49(baseDir, relativePath));
5267
+ const relativePath = isRoot ? "AGENTS.md" : join50(".opencode/memories", relativeFilePath);
5268
+ const fileContent = await readFileContent(join50(baseDir, relativePath));
5097
5269
  return new _OpenCodeRule({
5098
5270
  baseDir,
5099
5271
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5133,7 +5305,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5133
5305
  };
5134
5306
 
5135
5307
  // src/rules/qwencode-rule.ts
5136
- import { join as join50 } from "path";
5308
+ import { join as join51 } from "path";
5137
5309
  var QwencodeRule = class _QwencodeRule extends ToolRule {
5138
5310
  static getSettablePaths() {
5139
5311
  return {
@@ -5152,8 +5324,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
5152
5324
  validate = true
5153
5325
  }) {
5154
5326
  const isRoot = relativeFilePath === "QWEN.md";
5155
- const relativePath = isRoot ? "QWEN.md" : join50(".qwen/memories", relativeFilePath);
5156
- const fileContent = await readFileContent(join50(baseDir, relativePath));
5327
+ const relativePath = isRoot ? "QWEN.md" : join51(".qwen/memories", relativeFilePath);
5328
+ const fileContent = await readFileContent(join51(baseDir, relativePath));
5157
5329
  return new _QwencodeRule({
5158
5330
  baseDir,
5159
5331
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5190,7 +5362,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
5190
5362
  };
5191
5363
 
5192
5364
  // src/rules/roo-rule.ts
5193
- import { join as join51 } from "path";
5365
+ import { join as join52 } from "path";
5194
5366
  var RooRule = class _RooRule extends ToolRule {
5195
5367
  static getSettablePaths() {
5196
5368
  return {
@@ -5205,7 +5377,7 @@ var RooRule = class _RooRule extends ToolRule {
5205
5377
  validate = true
5206
5378
  }) {
5207
5379
  const fileContent = await readFileContent(
5208
- join51(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5380
+ join52(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5209
5381
  );
5210
5382
  return new _RooRule({
5211
5383
  baseDir,
@@ -5260,7 +5432,7 @@ var RooRule = class _RooRule extends ToolRule {
5260
5432
  };
5261
5433
 
5262
5434
  // src/rules/warp-rule.ts
5263
- import { join as join52 } from "path";
5435
+ import { join as join53 } from "path";
5264
5436
  var WarpRule = class _WarpRule extends ToolRule {
5265
5437
  constructor({ fileContent, root, ...rest }) {
5266
5438
  super({
@@ -5286,8 +5458,8 @@ var WarpRule = class _WarpRule extends ToolRule {
5286
5458
  validate = true
5287
5459
  }) {
5288
5460
  const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
5289
- const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join52(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
5290
- const fileContent = await readFileContent(join52(baseDir, relativePath));
5461
+ const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join53(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
5462
+ const fileContent = await readFileContent(join53(baseDir, relativePath));
5291
5463
  return new _WarpRule({
5292
5464
  baseDir,
5293
5465
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
@@ -5327,7 +5499,7 @@ var WarpRule = class _WarpRule extends ToolRule {
5327
5499
  };
5328
5500
 
5329
5501
  // src/rules/windsurf-rule.ts
5330
- import { join as join53 } from "path";
5502
+ import { join as join54 } from "path";
5331
5503
  var WindsurfRule = class _WindsurfRule extends ToolRule {
5332
5504
  static getSettablePaths() {
5333
5505
  return {
@@ -5342,7 +5514,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
5342
5514
  validate = true
5343
5515
  }) {
5344
5516
  const fileContent = await readFileContent(
5345
- join53(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5517
+ join54(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5346
5518
  );
5347
5519
  return new _WindsurfRule({
5348
5520
  baseDir,
@@ -5736,7 +5908,7 @@ var RulesProcessor = class extends FeatureProcessor {
5736
5908
  * Load and parse rulesync rule files from .rulesync/rules/ directory
5737
5909
  */
5738
5910
  async loadRulesyncFiles() {
5739
- const files = await findFilesByGlobs(join54(".rulesync/rules", "*.md"));
5911
+ const files = await findFilesByGlobs(join55(".rulesync/rules", "*.md"));
5740
5912
  logger.debug(`Found ${files.length} rulesync files`);
5741
5913
  const rulesyncRules = await Promise.all(
5742
5914
  files.map((file) => RulesyncRule.fromFile({ relativeFilePath: basename17(file) }))
@@ -5757,7 +5929,7 @@ var RulesProcessor = class extends FeatureProcessor {
5757
5929
  return rulesyncRules;
5758
5930
  }
5759
5931
  async loadRulesyncFilesLegacy() {
5760
- const legacyFiles = await findFilesByGlobs(join54(".rulesync", "*.md"));
5932
+ const legacyFiles = await findFilesByGlobs(join55(".rulesync", "*.md"));
5761
5933
  logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
5762
5934
  return Promise.all(
5763
5935
  legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: basename17(file) }))
@@ -5824,7 +5996,7 @@ var RulesProcessor = class extends FeatureProcessor {
5824
5996
  return [];
5825
5997
  }
5826
5998
  const rootFilePaths = await findFilesByGlobs(
5827
- join54(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
5999
+ join55(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
5828
6000
  );
5829
6001
  return await Promise.all(
5830
6002
  rootFilePaths.map(
@@ -5842,7 +6014,7 @@ var RulesProcessor = class extends FeatureProcessor {
5842
6014
  return [];
5843
6015
  }
5844
6016
  const nonRootFilePaths = await findFilesByGlobs(
5845
- join54(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
6017
+ join55(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
5846
6018
  );
5847
6019
  return await Promise.all(
5848
6020
  nonRootFilePaths.map(
@@ -6218,14 +6390,14 @@ s/<command> [arguments]
6218
6390
  This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
6219
6391
  The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
6220
6392
 
6221
- When users call a custom slash command, you have to look for the markdown file, \`${join54(commands.relativeDirPath, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
6393
+ When users call a custom slash command, you have to look for the markdown file, \`${join55(commands.relativeDirPath, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
6222
6394
  const subagentsSection = subagents ? `## Simulated Subagents
6223
6395
 
6224
6396
  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.
6225
6397
 
6226
- When users call a simulated subagent, it will look for the corresponding markdown file, \`${join54(subagents.relativeDirPath, "{subagent}.md")}\`, and execute its contents as the block of operations.
6398
+ When users call a simulated subagent, it will look for the corresponding markdown file, \`${join55(subagents.relativeDirPath, "{subagent}.md")}\`, and execute its contents as the block of operations.
6227
6399
 
6228
- For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join54(subagents.relativeDirPath, "planner.md")}\`, and execute its contents as the block of operations.` : "";
6400
+ For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join55(subagents.relativeDirPath, "planner.md")}\`, and execute its contents as the block of operations.` : "";
6229
6401
  const result = [
6230
6402
  overview,
6231
6403
  ...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
@@ -6344,28 +6516,15 @@ async function generateMcp(config) {
6344
6516
  logger.debug("Skipping MCP configuration generation (not in --features)");
6345
6517
  return 0;
6346
6518
  }
6347
- if (config.getExperimentalGlobal()) {
6348
- logger.debug("Skipping MCP configuration generation (not supported in global mode)");
6349
- return 0;
6350
- }
6351
6519
  let totalMcpOutputs = 0;
6352
6520
  logger.info("Generating MCP files...");
6353
- const supportedMcpTargets = [
6354
- "amazonqcli",
6355
- "claudecode",
6356
- "cline",
6357
- "copilot",
6358
- "cursor",
6359
- "roo"
6360
- ];
6361
- const mcpSupportedTargets = config.getTargets().filter((target) => {
6362
- return supportedMcpTargets.some((supportedTarget) => supportedTarget === target);
6363
- });
6521
+ const toolTargets = config.getExperimentalGlobal() ? intersection(config.getTargets(), McpProcessor.getToolTargetsGlobal()) : intersection(config.getTargets(), McpProcessor.getToolTargets());
6364
6522
  for (const baseDir of config.getBaseDirs()) {
6365
- for (const toolTarget of intersection(mcpSupportedTargets, McpProcessor.getToolTargets())) {
6523
+ for (const toolTarget of toolTargets) {
6366
6524
  const processor = new McpProcessor({
6367
6525
  baseDir,
6368
- toolTarget
6526
+ toolTarget,
6527
+ global: config.getExperimentalGlobal()
6369
6528
  });
6370
6529
  if (config.getDelete()) {
6371
6530
  const oldToolFiles = await processor.loadToolFilesToDelete();
@@ -6450,9 +6609,9 @@ async function generateSubagents(config) {
6450
6609
  }
6451
6610
 
6452
6611
  // src/cli/commands/gitignore.ts
6453
- import { join as join55 } from "path";
6612
+ import { join as join56 } from "path";
6454
6613
  var gitignoreCommand = async () => {
6455
- const gitignorePath = join55(process.cwd(), ".gitignore");
6614
+ const gitignorePath = join56(process.cwd(), ".gitignore");
6456
6615
  const rulesFilesToIgnore = [
6457
6616
  "# Generated by rulesync - AI tool configuration files",
6458
6617
  "**/.amazonq/",
@@ -6553,12 +6712,9 @@ async function importRules(config, tool) {
6553
6712
  if (!config.getFeatures().includes("rules")) {
6554
6713
  return 0;
6555
6714
  }
6556
- if (!RulesProcessor.getToolTargets().includes(tool)) {
6557
- return 0;
6558
- }
6559
6715
  const global = config.getExperimentalGlobal();
6560
- if (global && !RulesProcessor.getToolTargetsGlobal().includes(tool)) {
6561
- logger.error(`${tool} is not supported in global mode`);
6716
+ const supportedTargets = global ? RulesProcessor.getToolTargetsGlobal() : RulesProcessor.getToolTargets();
6717
+ if (!supportedTargets.includes(tool)) {
6562
6718
  return 0;
6563
6719
  }
6564
6720
  const rulesProcessor = new RulesProcessor({
@@ -6610,16 +6766,15 @@ async function importMcp(config, tool) {
6610
6766
  if (!config.getFeatures().includes("mcp")) {
6611
6767
  return 0;
6612
6768
  }
6613
- if (config.getExperimentalGlobal()) {
6614
- logger.debug("Skipping MCP file import (not supported in global mode)");
6615
- return 0;
6616
- }
6617
- if (!McpProcessor.getToolTargets().includes(tool)) {
6769
+ const global = config.getExperimentalGlobal();
6770
+ const supportedTargets = global ? McpProcessor.getToolTargetsGlobal() : McpProcessor.getToolTargets();
6771
+ if (!supportedTargets.includes(tool)) {
6618
6772
  return 0;
6619
6773
  }
6620
6774
  const mcpProcessor = new McpProcessor({
6621
6775
  baseDir: config.getBaseDirs()[0] ?? ".",
6622
- toolTarget: tool
6776
+ toolTarget: tool,
6777
+ global
6623
6778
  });
6624
6779
  const toolFiles = await mcpProcessor.loadToolFiles();
6625
6780
  if (toolFiles.length === 0) {
@@ -6639,9 +6794,6 @@ async function importCommands(config, tool) {
6639
6794
  const global = config.getExperimentalGlobal();
6640
6795
  const supportedTargets = global ? CommandsProcessor.getToolTargetsGlobal() : CommandsProcessor.getToolTargets({ includeSimulated: false });
6641
6796
  if (!supportedTargets.includes(tool)) {
6642
- if (global) {
6643
- logger.debug(`${tool} is not supported for commands in global mode`);
6644
- }
6645
6797
  return 0;
6646
6798
  }
6647
6799
  const commandsProcessor = new CommandsProcessor({
@@ -6689,7 +6841,7 @@ async function importSubagents(config, tool) {
6689
6841
  }
6690
6842
 
6691
6843
  // src/cli/commands/init.ts
6692
- import { join as join56 } from "path";
6844
+ import { join as join57 } from "path";
6693
6845
  async function initCommand() {
6694
6846
  logger.info("Initializing rulesync...");
6695
6847
  await ensureDir(".rulesync");
@@ -6760,7 +6912,7 @@ globs: ["**/*"]
6760
6912
  - Follow single responsibility principle
6761
6913
  `
6762
6914
  };
6763
- const filepath = join56(".rulesync/rules", sampleFile.filename);
6915
+ const filepath = join57(".rulesync/rules", sampleFile.filename);
6764
6916
  await ensureDir(".rulesync/rules");
6765
6917
  await ensureDir(RulesyncCommand.getSettablePaths().relativeDirPath);
6766
6918
  await ensureDir(".rulesync/subagents");
@@ -6773,7 +6925,7 @@ globs: ["**/*"]
6773
6925
  }
6774
6926
 
6775
6927
  // src/cli/index.ts
6776
- var getVersion = () => "3.1.1";
6928
+ var getVersion = () => "3.2.0";
6777
6929
  var main = async () => {
6778
6930
  const program = new Command();
6779
6931
  const version = getVersion();