rulesync 3.1.0 → 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);
@@ -99,6 +107,12 @@ async function readFileContent(filepath) {
99
107
  logger.debug(`Reading file: ${filepath}`);
100
108
  return readFile(filepath, "utf-8");
101
109
  }
110
+ function addTrailingNewline(content) {
111
+ if (!content) {
112
+ return "\n";
113
+ }
114
+ return content.trimEnd() + "\n";
115
+ }
102
116
  async function writeFileContent(filepath, content) {
103
117
  logger.debug(`Writing file: ${filepath}`);
104
118
  await ensureDir(dirname(filepath));
@@ -176,7 +190,8 @@ var FeatureProcessor = class {
176
190
  */
177
191
  async writeAiFiles(aiFiles) {
178
192
  for (const aiFile of aiFiles) {
179
- await writeFileContent(aiFile.getFilePath(), aiFile.getFileContent());
193
+ const contentWithNewline = addTrailingNewline(aiFile.getFileContent());
194
+ await writeFileContent(aiFile.getFilePath(), contentWithNewline);
180
195
  }
181
196
  return aiFiles.length;
182
197
  }
@@ -2494,11 +2509,11 @@ var McpServerBaseSchema = z10.object({
2494
2509
  kiroAutoBlock: z10.optional(z10.array(z10.string())),
2495
2510
  headers: z10.optional(z10.record(z10.string(), z10.string()))
2496
2511
  });
2497
- var RulesyncMcpServerSchema = z10.extend(McpServerBaseSchema, {
2512
+ var RulesyncMcpServersSchema = z10.extend(McpServerBaseSchema, {
2498
2513
  targets: z10.optional(RulesyncTargetsSchema)
2499
2514
  });
2500
2515
  var RulesyncMcpConfigSchema = z10.object({
2501
- mcpServers: z10.record(z10.string(), RulesyncMcpServerSchema)
2516
+ mcpServers: z10.record(z10.string(), RulesyncMcpServersSchema)
2502
2517
  });
2503
2518
  var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2504
2519
  json;
@@ -2540,14 +2555,12 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2540
2555
 
2541
2556
  // src/mcp/tool-mcp.ts
2542
2557
  var ToolMcp = class extends ToolFile {
2543
- json;
2544
2558
  constructor({ ...rest }) {
2545
2559
  super({
2546
2560
  ...rest,
2547
2561
  validate: true
2548
2562
  // Skip validation during construction
2549
2563
  });
2550
- this.json = JSON.parse(this.fileContent);
2551
2564
  if (rest.validate) {
2552
2565
  const result = this.validate();
2553
2566
  if (!result.success) {
@@ -2555,9 +2568,6 @@ var ToolMcp = class extends ToolFile {
2555
2568
  }
2556
2569
  }
2557
2570
  }
2558
- getJson() {
2559
- return this.json;
2560
- }
2561
2571
  static getSettablePaths() {
2562
2572
  throw new Error("Please implement this method in the subclass.");
2563
2573
  }
@@ -2579,6 +2589,14 @@ var ToolMcp = class extends ToolFile {
2579
2589
 
2580
2590
  // src/mcp/amazonqcli-mcp.ts
2581
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
+ }
2582
2600
  static getSettablePaths() {
2583
2601
  return {
2584
2602
  relativeDirPath: ".amazonq",
@@ -2628,6 +2646,14 @@ var AmazonqcliMcp = class _AmazonqcliMcp extends ToolMcp {
2628
2646
  // src/mcp/claudecode-mcp.ts
2629
2647
  import { join as join26 } from "path";
2630
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
+ }
2631
2657
  static getSettablePaths() {
2632
2658
  return {
2633
2659
  relativeDirPath: ".",
@@ -2677,6 +2703,14 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
2677
2703
  // src/mcp/cline-mcp.ts
2678
2704
  import { join as join27 } from "path";
2679
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
+ }
2680
2714
  static getSettablePaths() {
2681
2715
  return {
2682
2716
  relativeDirPath: ".cline",
@@ -2723,9 +2757,111 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
2723
2757
  }
2724
2758
  };
2725
2759
 
2726
- // src/mcp/copilot-mcp.ts
2760
+ // src/mcp/codex-mcp.ts
2727
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";
2728
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
+ }
2729
2865
  static getSettablePaths() {
2730
2866
  return {
2731
2867
  relativeDirPath: ".vscode",
@@ -2737,7 +2873,7 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
2737
2873
  validate = true
2738
2874
  }) {
2739
2875
  const fileContent = await readFileContent(
2740
- join28(
2876
+ join29(
2741
2877
  baseDir,
2742
2878
  this.getSettablePaths().relativeDirPath,
2743
2879
  this.getSettablePaths().relativeFilePath
@@ -2773,8 +2909,16 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
2773
2909
  };
2774
2910
 
2775
2911
  // src/mcp/cursor-mcp.ts
2776
- import { join as join29 } from "path";
2912
+ import { join as join30 } from "path";
2777
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
+ }
2778
2922
  static getSettablePaths() {
2779
2923
  return {
2780
2924
  relativeDirPath: ".cursor",
@@ -2786,7 +2930,7 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
2786
2930
  validate = true
2787
2931
  }) {
2788
2932
  const fileContent = await readFileContent(
2789
- join29(
2933
+ join30(
2790
2934
  baseDir,
2791
2935
  this.getSettablePaths().relativeDirPath,
2792
2936
  this.getSettablePaths().relativeFilePath
@@ -2833,8 +2977,16 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
2833
2977
  };
2834
2978
 
2835
2979
  // src/mcp/roo-mcp.ts
2836
- import { join as join30 } from "path";
2980
+ import { join as join31 } from "path";
2837
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
+ }
2838
2990
  static getSettablePaths() {
2839
2991
  return {
2840
2992
  relativeDirPath: ".roo",
@@ -2846,7 +2998,7 @@ var RooMcp = class _RooMcp extends ToolMcp {
2846
2998
  validate = true
2847
2999
  }) {
2848
3000
  const fileContent = await readFileContent(
2849
- join30(
3001
+ join31(
2850
3002
  baseDir,
2851
3003
  this.getSettablePaths().relativeDirPath,
2852
3004
  this.getSettablePaths().relativeFilePath
@@ -2891,15 +3043,22 @@ var mcpProcessorToolTargets = [
2891
3043
  "cursor",
2892
3044
  "roo"
2893
3045
  ];
2894
- 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"];
2895
3051
  var McpProcessor = class extends FeatureProcessor {
2896
3052
  toolTarget;
3053
+ global;
2897
3054
  constructor({
2898
3055
  baseDir = ".",
2899
- toolTarget
3056
+ toolTarget,
3057
+ global = false
2900
3058
  }) {
2901
3059
  super({ baseDir });
2902
3060
  this.toolTarget = McpProcessorToolTargetSchema.parse(toolTarget);
3061
+ this.global = global;
2903
3062
  }
2904
3063
  /**
2905
3064
  * Implementation of abstract method from FeatureProcessor
@@ -2948,6 +3107,15 @@ var McpProcessor = class extends FeatureProcessor {
2948
3107
  })
2949
3108
  ];
2950
3109
  }
3110
+ case "codexcli": {
3111
+ return [
3112
+ await CodexcliMcp.fromFile({
3113
+ baseDir: this.baseDir,
3114
+ validate: true,
3115
+ global: this.global
3116
+ })
3117
+ ];
3118
+ }
2951
3119
  case "copilot": {
2952
3120
  return [
2953
3121
  await CopilotMcp.fromFile({
@@ -2994,42 +3162,50 @@ var McpProcessor = class extends FeatureProcessor {
2994
3162
  if (!rulesyncMcp) {
2995
3163
  throw new Error(`No .rulesync/.mcp.json found.`);
2996
3164
  }
2997
- const toolMcps = [rulesyncMcp].map((rulesyncMcp2) => {
2998
- switch (this.toolTarget) {
2999
- case "amazonqcli":
3000
- return AmazonqcliMcp.fromRulesyncMcp({
3001
- baseDir: this.baseDir,
3002
- rulesyncMcp: rulesyncMcp2
3003
- });
3004
- case "claudecode":
3005
- return ClaudecodeMcp.fromRulesyncMcp({
3006
- baseDir: this.baseDir,
3007
- rulesyncMcp: rulesyncMcp2
3008
- });
3009
- case "cline":
3010
- return ClineMcp.fromRulesyncMcp({
3011
- baseDir: this.baseDir,
3012
- rulesyncMcp: rulesyncMcp2
3013
- });
3014
- case "copilot":
3015
- return CopilotMcp.fromRulesyncMcp({
3016
- baseDir: this.baseDir,
3017
- rulesyncMcp: rulesyncMcp2
3018
- });
3019
- case "cursor":
3020
- return CursorMcp.fromRulesyncMcp({
3021
- baseDir: this.baseDir,
3022
- rulesyncMcp: rulesyncMcp2
3023
- });
3024
- case "roo":
3025
- return RooMcp.fromRulesyncMcp({
3026
- baseDir: this.baseDir,
3027
- rulesyncMcp: rulesyncMcp2
3028
- });
3029
- default:
3030
- throw new Error(`Unsupported tool target: ${this.toolTarget}`);
3031
- }
3032
- });
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
+ );
3033
3209
  return toolMcps;
3034
3210
  }
3035
3211
  /**
@@ -3050,15 +3226,18 @@ var McpProcessor = class extends FeatureProcessor {
3050
3226
  static getToolTargets() {
3051
3227
  return mcpProcessorToolTargets;
3052
3228
  }
3229
+ static getToolTargetsGlobal() {
3230
+ return mcpProcessorToolTargetsGlobal;
3231
+ }
3053
3232
  };
3054
3233
 
3055
3234
  // src/rules/rules-processor.ts
3056
- import { basename as basename17, join as join54 } from "path";
3235
+ import { basename as basename17, join as join55 } from "path";
3057
3236
  import { XMLBuilder } from "fast-xml-parser";
3058
3237
  import { z as z20 } from "zod/mini";
3059
3238
 
3060
3239
  // src/subagents/simulated-subagent.ts
3061
- import { basename as basename12, join as join31 } from "path";
3240
+ import { basename as basename12, join as join32 } from "path";
3062
3241
  import { z as z12 } from "zod/mini";
3063
3242
 
3064
3243
  // src/subagents/tool-subagent.ts
@@ -3160,7 +3339,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3160
3339
  relativeFilePath,
3161
3340
  validate = true
3162
3341
  }) {
3163
- const filePath = join31(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
3342
+ const filePath = join32(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
3164
3343
  const fileContent = await readFileContent(filePath);
3165
3344
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3166
3345
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -3317,15 +3496,15 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
3317
3496
  };
3318
3497
 
3319
3498
  // src/subagents/subagents-processor.ts
3320
- import { basename as basename14, join as join34 } from "path";
3499
+ import { basename as basename14, join as join35 } from "path";
3321
3500
  import { z as z15 } from "zod/mini";
3322
3501
 
3323
3502
  // src/subagents/claudecode-subagent.ts
3324
- import { join as join33 } from "path";
3503
+ import { join as join34 } from "path";
3325
3504
  import { z as z14 } from "zod/mini";
3326
3505
 
3327
3506
  // src/subagents/rulesync-subagent.ts
3328
- import { basename as basename13, join as join32 } from "path";
3507
+ import { basename as basename13, join as join33 } from "path";
3329
3508
  import { z as z13 } from "zod/mini";
3330
3509
  var RulesyncSubagentModelSchema = z13.enum(["opus", "sonnet", "haiku", "inherit"]);
3331
3510
  var RulesyncSubagentFrontmatterSchema = z13.object({
@@ -3379,7 +3558,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
3379
3558
  static async fromFile({
3380
3559
  relativeFilePath
3381
3560
  }) {
3382
- const fileContent = await readFileContent(join32(".rulesync/subagents", relativeFilePath));
3561
+ const fileContent = await readFileContent(join33(".rulesync/subagents", relativeFilePath));
3383
3562
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3384
3563
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
3385
3564
  if (!result.success) {
@@ -3497,7 +3676,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
3497
3676
  relativeFilePath,
3498
3677
  validate = true
3499
3678
  }) {
3500
- const fileContent = await readFileContent(join33(baseDir, ".claude/agents", relativeFilePath));
3679
+ const fileContent = await readFileContent(join34(baseDir, ".claude/agents", relativeFilePath));
3501
3680
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3502
3681
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
3503
3682
  if (!result.success) {
@@ -3639,7 +3818,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
3639
3818
  * Load and parse rulesync subagent files from .rulesync/subagents/ directory
3640
3819
  */
3641
3820
  async loadRulesyncFiles() {
3642
- const subagentsDir = join34(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
3821
+ const subagentsDir = join35(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
3643
3822
  const dirExists = await directoryExists(subagentsDir);
3644
3823
  if (!dirExists) {
3645
3824
  logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
@@ -3654,7 +3833,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
3654
3833
  logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
3655
3834
  const rulesyncSubagents = [];
3656
3835
  for (const mdFile of mdFiles) {
3657
- const filepath = join34(subagentsDir, mdFile);
3836
+ const filepath = join35(subagentsDir, mdFile);
3658
3837
  try {
3659
3838
  const rulesyncSubagent = await RulesyncSubagent.fromFile({
3660
3839
  relativeFilePath: mdFile,
@@ -3768,7 +3947,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
3768
3947
  relativeDirPath,
3769
3948
  fromFile
3770
3949
  }) {
3771
- const paths = await findFilesByGlobs(join34(this.baseDir, relativeDirPath, "*.md"));
3950
+ const paths = await findFilesByGlobs(join35(this.baseDir, relativeDirPath, "*.md"));
3772
3951
  const subagents = (await Promise.allSettled(paths.map((path2) => fromFile(basename14(path2))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
3773
3952
  logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
3774
3953
  return subagents;
@@ -3793,13 +3972,13 @@ var SubagentsProcessor = class extends FeatureProcessor {
3793
3972
  };
3794
3973
 
3795
3974
  // src/rules/agentsmd-rule.ts
3796
- import { join as join37 } from "path";
3975
+ import { join as join38 } from "path";
3797
3976
 
3798
3977
  // src/rules/tool-rule.ts
3799
- import { join as join36 } from "path";
3978
+ import { join as join37 } from "path";
3800
3979
 
3801
3980
  // src/rules/rulesync-rule.ts
3802
- import { basename as basename15, join as join35 } from "path";
3981
+ import { basename as basename15, join as join36 } from "path";
3803
3982
  import { z as z16 } from "zod/mini";
3804
3983
  var RulesyncRuleFrontmatterSchema = z16.object({
3805
3984
  root: z16.optional(z16.optional(z16.boolean())),
@@ -3865,7 +4044,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
3865
4044
  relativeFilePath,
3866
4045
  validate = true
3867
4046
  }) {
3868
- const filePath = join35(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
4047
+ const filePath = join36(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
3869
4048
  const fileContent = await readFileContent(filePath);
3870
4049
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3871
4050
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
@@ -3894,7 +4073,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
3894
4073
  relativeFilePath,
3895
4074
  validate = true
3896
4075
  }) {
3897
- const filePath = join35(this.getSettablePaths().recommended.relativeDirPath, relativeFilePath);
4076
+ const filePath = join36(this.getSettablePaths().recommended.relativeDirPath, relativeFilePath);
3898
4077
  const fileContent = await readFileContent(filePath);
3899
4078
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3900
4079
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
@@ -3998,7 +4177,7 @@ var ToolRule = class extends ToolFile {
3998
4177
  });
3999
4178
  const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
4000
4179
  if (!rulesyncFrontmatter.root && rulesyncFrontmatter.agentsmd?.subprojectPath) {
4001
- params.relativeDirPath = join36(rulesyncFrontmatter.agentsmd.subprojectPath);
4180
+ params.relativeDirPath = join37(rulesyncFrontmatter.agentsmd.subprojectPath);
4002
4181
  params.relativeFilePath = "AGENTS.md";
4003
4182
  }
4004
4183
  return params;
@@ -4074,8 +4253,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
4074
4253
  validate = true
4075
4254
  }) {
4076
4255
  const isRoot = relativeFilePath === "AGENTS.md";
4077
- const relativePath = isRoot ? "AGENTS.md" : join37(".agents/memories", relativeFilePath);
4078
- 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));
4079
4258
  return new _AgentsMdRule({
4080
4259
  baseDir,
4081
4260
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -4115,7 +4294,7 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
4115
4294
  };
4116
4295
 
4117
4296
  // src/rules/amazonqcli-rule.ts
4118
- import { join as join38 } from "path";
4297
+ import { join as join39 } from "path";
4119
4298
  var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4120
4299
  static getSettablePaths() {
4121
4300
  return {
@@ -4130,7 +4309,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4130
4309
  validate = true
4131
4310
  }) {
4132
4311
  const fileContent = await readFileContent(
4133
- join38(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4312
+ join39(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4134
4313
  );
4135
4314
  return new _AmazonQCliRule({
4136
4315
  baseDir,
@@ -4170,7 +4349,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4170
4349
  };
4171
4350
 
4172
4351
  // src/rules/augmentcode-legacy-rule.ts
4173
- import { join as join39 } from "path";
4352
+ import { join as join40 } from "path";
4174
4353
  var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4175
4354
  toRulesyncRule() {
4176
4355
  const rulesyncFrontmatter = {
@@ -4231,8 +4410,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4231
4410
  }) {
4232
4411
  const settablePaths = this.getSettablePaths();
4233
4412
  const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
4234
- const relativePath = isRoot ? settablePaths.root.relativeFilePath : join39(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
4235
- 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));
4236
4415
  return new _AugmentcodeLegacyRule({
4237
4416
  baseDir,
4238
4417
  relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
@@ -4245,7 +4424,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4245
4424
  };
4246
4425
 
4247
4426
  // src/rules/augmentcode-rule.ts
4248
- import { join as join40 } from "path";
4427
+ import { join as join41 } from "path";
4249
4428
  var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
4250
4429
  toRulesyncRule() {
4251
4430
  return this.toRulesyncRuleDefault();
@@ -4277,7 +4456,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
4277
4456
  validate = true
4278
4457
  }) {
4279
4458
  const fileContent = await readFileContent(
4280
- join40(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4459
+ join41(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4281
4460
  );
4282
4461
  const { body: content } = parseFrontmatter(fileContent);
4283
4462
  return new _AugmentcodeRule({
@@ -4300,7 +4479,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
4300
4479
  };
4301
4480
 
4302
4481
  // src/rules/claudecode-rule.ts
4303
- import { join as join41 } from "path";
4482
+ import { join as join42 } from "path";
4304
4483
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4305
4484
  static getSettablePaths() {
4306
4485
  return {
@@ -4309,7 +4488,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4309
4488
  relativeFilePath: "CLAUDE.md"
4310
4489
  },
4311
4490
  nonRoot: {
4312
- relativeDirPath: join41(".claude", "memories")
4491
+ relativeDirPath: join42(".claude", "memories")
4313
4492
  }
4314
4493
  };
4315
4494
  }
@@ -4332,7 +4511,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4332
4511
  if (isRoot) {
4333
4512
  const relativePath2 = paths.root.relativeFilePath;
4334
4513
  const fileContent2 = await readFileContent(
4335
- join41(baseDir, paths.root.relativeDirPath, relativePath2)
4514
+ join42(baseDir, paths.root.relativeDirPath, relativePath2)
4336
4515
  );
4337
4516
  return new _ClaudecodeRule({
4338
4517
  baseDir,
@@ -4346,8 +4525,8 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4346
4525
  if (!paths.nonRoot) {
4347
4526
  throw new Error("nonRoot path is not set");
4348
4527
  }
4349
- const relativePath = join41(paths.nonRoot.relativeDirPath, relativeFilePath);
4350
- const fileContent = await readFileContent(join41(baseDir, relativePath));
4528
+ const relativePath = join42(paths.nonRoot.relativeDirPath, relativeFilePath);
4529
+ const fileContent = await readFileContent(join42(baseDir, relativePath));
4351
4530
  return new _ClaudecodeRule({
4352
4531
  baseDir,
4353
4532
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -4389,7 +4568,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
4389
4568
  };
4390
4569
 
4391
4570
  // src/rules/cline-rule.ts
4392
- import { join as join42 } from "path";
4571
+ import { join as join43 } from "path";
4393
4572
  import { z as z17 } from "zod/mini";
4394
4573
  var ClineRuleFrontmatterSchema = z17.object({
4395
4574
  description: z17.string()
@@ -4434,7 +4613,7 @@ var ClineRule = class _ClineRule extends ToolRule {
4434
4613
  validate = true
4435
4614
  }) {
4436
4615
  const fileContent = await readFileContent(
4437
- join42(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4616
+ join43(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4438
4617
  );
4439
4618
  return new _ClineRule({
4440
4619
  baseDir,
@@ -4447,7 +4626,7 @@ var ClineRule = class _ClineRule extends ToolRule {
4447
4626
  };
4448
4627
 
4449
4628
  // src/rules/codexcli-rule.ts
4450
- import { join as join43 } from "path";
4629
+ import { join as join44 } from "path";
4451
4630
  var CodexcliRule = class _CodexcliRule extends ToolRule {
4452
4631
  static getSettablePaths() {
4453
4632
  return {
@@ -4479,7 +4658,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
4479
4658
  if (isRoot) {
4480
4659
  const relativePath2 = paths.root.relativeFilePath;
4481
4660
  const fileContent2 = await readFileContent(
4482
- join43(baseDir, paths.root.relativeDirPath, relativePath2)
4661
+ join44(baseDir, paths.root.relativeDirPath, relativePath2)
4483
4662
  );
4484
4663
  return new _CodexcliRule({
4485
4664
  baseDir,
@@ -4493,8 +4672,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
4493
4672
  if (!paths.nonRoot) {
4494
4673
  throw new Error("nonRoot path is not set");
4495
4674
  }
4496
- const relativePath = join43(paths.nonRoot.relativeDirPath, relativeFilePath);
4497
- const fileContent = await readFileContent(join43(baseDir, relativePath));
4675
+ const relativePath = join44(paths.nonRoot.relativeDirPath, relativeFilePath);
4676
+ const fileContent = await readFileContent(join44(baseDir, relativePath));
4498
4677
  return new _CodexcliRule({
4499
4678
  baseDir,
4500
4679
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -4536,7 +4715,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
4536
4715
  };
4537
4716
 
4538
4717
  // src/rules/copilot-rule.ts
4539
- import { join as join44 } from "path";
4718
+ import { join as join45 } from "path";
4540
4719
  import { z as z18 } from "zod/mini";
4541
4720
  var CopilotRuleFrontmatterSchema = z18.object({
4542
4721
  description: z18.optional(z18.string()),
@@ -4629,11 +4808,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
4629
4808
  validate = true
4630
4809
  }) {
4631
4810
  const isRoot = relativeFilePath === "copilot-instructions.md";
4632
- const relativePath = isRoot ? join44(
4811
+ const relativePath = isRoot ? join45(
4633
4812
  this.getSettablePaths().root.relativeDirPath,
4634
4813
  this.getSettablePaths().root.relativeFilePath
4635
- ) : join44(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
4636
- const fileContent = await readFileContent(join44(baseDir, relativePath));
4814
+ ) : join45(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
4815
+ const fileContent = await readFileContent(join45(baseDir, relativePath));
4637
4816
  if (isRoot) {
4638
4817
  return new _CopilotRule({
4639
4818
  baseDir,
@@ -4652,7 +4831,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
4652
4831
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
4653
4832
  if (!result.success) {
4654
4833
  throw new Error(
4655
- `Invalid frontmatter in ${join44(baseDir, relativeFilePath)}: ${result.error.message}`
4834
+ `Invalid frontmatter in ${join45(baseDir, relativeFilePath)}: ${result.error.message}`
4656
4835
  );
4657
4836
  }
4658
4837
  return new _CopilotRule({
@@ -4691,7 +4870,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
4691
4870
  };
4692
4871
 
4693
4872
  // src/rules/cursor-rule.ts
4694
- import { basename as basename16, join as join45 } from "path";
4873
+ import { basename as basename16, join as join46 } from "path";
4695
4874
  import { z as z19 } from "zod/mini";
4696
4875
  var CursorRuleFrontmatterSchema = z19.object({
4697
4876
  description: z19.optional(z19.string()),
@@ -4818,13 +4997,13 @@ var CursorRule = class _CursorRule extends ToolRule {
4818
4997
  validate = true
4819
4998
  }) {
4820
4999
  const fileContent = await readFileContent(
4821
- join45(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5000
+ join46(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4822
5001
  );
4823
5002
  const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
4824
5003
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
4825
5004
  if (!result.success) {
4826
5005
  throw new Error(
4827
- `Invalid frontmatter in ${join45(baseDir, relativeFilePath)}: ${result.error.message}`
5006
+ `Invalid frontmatter in ${join46(baseDir, relativeFilePath)}: ${result.error.message}`
4828
5007
  );
4829
5008
  }
4830
5009
  return new _CursorRule({
@@ -4862,7 +5041,7 @@ var CursorRule = class _CursorRule extends ToolRule {
4862
5041
  };
4863
5042
 
4864
5043
  // src/rules/geminicli-rule.ts
4865
- import { join as join46 } from "path";
5044
+ import { join as join47 } from "path";
4866
5045
  var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4867
5046
  static getSettablePaths() {
4868
5047
  return {
@@ -4894,7 +5073,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4894
5073
  if (isRoot) {
4895
5074
  const relativePath2 = paths.root.relativeFilePath;
4896
5075
  const fileContent2 = await readFileContent(
4897
- join46(baseDir, paths.root.relativeDirPath, relativePath2)
5076
+ join47(baseDir, paths.root.relativeDirPath, relativePath2)
4898
5077
  );
4899
5078
  return new _GeminiCliRule({
4900
5079
  baseDir,
@@ -4908,8 +5087,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4908
5087
  if (!paths.nonRoot) {
4909
5088
  throw new Error("nonRoot path is not set");
4910
5089
  }
4911
- const relativePath = join46(paths.nonRoot.relativeDirPath, relativeFilePath);
4912
- const fileContent = await readFileContent(join46(baseDir, relativePath));
5090
+ const relativePath = join47(paths.nonRoot.relativeDirPath, relativeFilePath);
5091
+ const fileContent = await readFileContent(join47(baseDir, relativePath));
4913
5092
  return new _GeminiCliRule({
4914
5093
  baseDir,
4915
5094
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -4951,7 +5130,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4951
5130
  };
4952
5131
 
4953
5132
  // src/rules/junie-rule.ts
4954
- import { join as join47 } from "path";
5133
+ import { join as join48 } from "path";
4955
5134
  var JunieRule = class _JunieRule extends ToolRule {
4956
5135
  static getSettablePaths() {
4957
5136
  return {
@@ -4970,8 +5149,8 @@ var JunieRule = class _JunieRule extends ToolRule {
4970
5149
  validate = true
4971
5150
  }) {
4972
5151
  const isRoot = relativeFilePath === "guidelines.md";
4973
- const relativePath = isRoot ? "guidelines.md" : join47(".junie/memories", relativeFilePath);
4974
- 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));
4975
5154
  return new _JunieRule({
4976
5155
  baseDir,
4977
5156
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5011,7 +5190,7 @@ var JunieRule = class _JunieRule extends ToolRule {
5011
5190
  };
5012
5191
 
5013
5192
  // src/rules/kiro-rule.ts
5014
- import { join as join48 } from "path";
5193
+ import { join as join49 } from "path";
5015
5194
  var KiroRule = class _KiroRule extends ToolRule {
5016
5195
  static getSettablePaths() {
5017
5196
  return {
@@ -5026,7 +5205,7 @@ var KiroRule = class _KiroRule extends ToolRule {
5026
5205
  validate = true
5027
5206
  }) {
5028
5207
  const fileContent = await readFileContent(
5029
- join48(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5208
+ join49(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5030
5209
  );
5031
5210
  return new _KiroRule({
5032
5211
  baseDir,
@@ -5066,7 +5245,7 @@ var KiroRule = class _KiroRule extends ToolRule {
5066
5245
  };
5067
5246
 
5068
5247
  // src/rules/opencode-rule.ts
5069
- import { join as join49 } from "path";
5248
+ import { join as join50 } from "path";
5070
5249
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5071
5250
  static getSettablePaths() {
5072
5251
  return {
@@ -5085,8 +5264,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5085
5264
  validate = true
5086
5265
  }) {
5087
5266
  const isRoot = relativeFilePath === "AGENTS.md";
5088
- const relativePath = isRoot ? "AGENTS.md" : join49(".opencode/memories", relativeFilePath);
5089
- 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));
5090
5269
  return new _OpenCodeRule({
5091
5270
  baseDir,
5092
5271
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5126,7 +5305,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5126
5305
  };
5127
5306
 
5128
5307
  // src/rules/qwencode-rule.ts
5129
- import { join as join50 } from "path";
5308
+ import { join as join51 } from "path";
5130
5309
  var QwencodeRule = class _QwencodeRule extends ToolRule {
5131
5310
  static getSettablePaths() {
5132
5311
  return {
@@ -5145,8 +5324,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
5145
5324
  validate = true
5146
5325
  }) {
5147
5326
  const isRoot = relativeFilePath === "QWEN.md";
5148
- const relativePath = isRoot ? "QWEN.md" : join50(".qwen/memories", relativeFilePath);
5149
- 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));
5150
5329
  return new _QwencodeRule({
5151
5330
  baseDir,
5152
5331
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5183,7 +5362,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
5183
5362
  };
5184
5363
 
5185
5364
  // src/rules/roo-rule.ts
5186
- import { join as join51 } from "path";
5365
+ import { join as join52 } from "path";
5187
5366
  var RooRule = class _RooRule extends ToolRule {
5188
5367
  static getSettablePaths() {
5189
5368
  return {
@@ -5198,7 +5377,7 @@ var RooRule = class _RooRule extends ToolRule {
5198
5377
  validate = true
5199
5378
  }) {
5200
5379
  const fileContent = await readFileContent(
5201
- join51(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5380
+ join52(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5202
5381
  );
5203
5382
  return new _RooRule({
5204
5383
  baseDir,
@@ -5253,7 +5432,7 @@ var RooRule = class _RooRule extends ToolRule {
5253
5432
  };
5254
5433
 
5255
5434
  // src/rules/warp-rule.ts
5256
- import { join as join52 } from "path";
5435
+ import { join as join53 } from "path";
5257
5436
  var WarpRule = class _WarpRule extends ToolRule {
5258
5437
  constructor({ fileContent, root, ...rest }) {
5259
5438
  super({
@@ -5279,8 +5458,8 @@ var WarpRule = class _WarpRule extends ToolRule {
5279
5458
  validate = true
5280
5459
  }) {
5281
5460
  const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
5282
- const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join52(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
5283
- 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));
5284
5463
  return new _WarpRule({
5285
5464
  baseDir,
5286
5465
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
@@ -5320,7 +5499,7 @@ var WarpRule = class _WarpRule extends ToolRule {
5320
5499
  };
5321
5500
 
5322
5501
  // src/rules/windsurf-rule.ts
5323
- import { join as join53 } from "path";
5502
+ import { join as join54 } from "path";
5324
5503
  var WindsurfRule = class _WindsurfRule extends ToolRule {
5325
5504
  static getSettablePaths() {
5326
5505
  return {
@@ -5335,7 +5514,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
5335
5514
  validate = true
5336
5515
  }) {
5337
5516
  const fileContent = await readFileContent(
5338
- join53(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5517
+ join54(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5339
5518
  );
5340
5519
  return new _WindsurfRule({
5341
5520
  baseDir,
@@ -5729,7 +5908,7 @@ var RulesProcessor = class extends FeatureProcessor {
5729
5908
  * Load and parse rulesync rule files from .rulesync/rules/ directory
5730
5909
  */
5731
5910
  async loadRulesyncFiles() {
5732
- const files = await findFilesByGlobs(join54(".rulesync/rules", "*.md"));
5911
+ const files = await findFilesByGlobs(join55(".rulesync/rules", "*.md"));
5733
5912
  logger.debug(`Found ${files.length} rulesync files`);
5734
5913
  const rulesyncRules = await Promise.all(
5735
5914
  files.map((file) => RulesyncRule.fromFile({ relativeFilePath: basename17(file) }))
@@ -5750,7 +5929,7 @@ var RulesProcessor = class extends FeatureProcessor {
5750
5929
  return rulesyncRules;
5751
5930
  }
5752
5931
  async loadRulesyncFilesLegacy() {
5753
- const legacyFiles = await findFilesByGlobs(join54(".rulesync", "*.md"));
5932
+ const legacyFiles = await findFilesByGlobs(join55(".rulesync", "*.md"));
5754
5933
  logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
5755
5934
  return Promise.all(
5756
5935
  legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: basename17(file) }))
@@ -5817,7 +5996,7 @@ var RulesProcessor = class extends FeatureProcessor {
5817
5996
  return [];
5818
5997
  }
5819
5998
  const rootFilePaths = await findFilesByGlobs(
5820
- join54(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
5999
+ join55(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
5821
6000
  );
5822
6001
  return await Promise.all(
5823
6002
  rootFilePaths.map(
@@ -5835,7 +6014,7 @@ var RulesProcessor = class extends FeatureProcessor {
5835
6014
  return [];
5836
6015
  }
5837
6016
  const nonRootFilePaths = await findFilesByGlobs(
5838
- join54(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
6017
+ join55(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
5839
6018
  );
5840
6019
  return await Promise.all(
5841
6020
  nonRootFilePaths.map(
@@ -6211,14 +6390,14 @@ s/<command> [arguments]
6211
6390
  This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
6212
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.
6213
6392
 
6214
- 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.` : "";
6215
6394
  const subagentsSection = subagents ? `## Simulated Subagents
6216
6395
 
6217
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.
6218
6397
 
6219
- 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.
6220
6399
 
6221
- 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.` : "";
6222
6401
  const result = [
6223
6402
  overview,
6224
6403
  ...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
@@ -6337,28 +6516,15 @@ async function generateMcp(config) {
6337
6516
  logger.debug("Skipping MCP configuration generation (not in --features)");
6338
6517
  return 0;
6339
6518
  }
6340
- if (config.getExperimentalGlobal()) {
6341
- logger.debug("Skipping MCP configuration generation (not supported in global mode)");
6342
- return 0;
6343
- }
6344
6519
  let totalMcpOutputs = 0;
6345
6520
  logger.info("Generating MCP files...");
6346
- const supportedMcpTargets = [
6347
- "amazonqcli",
6348
- "claudecode",
6349
- "cline",
6350
- "copilot",
6351
- "cursor",
6352
- "roo"
6353
- ];
6354
- const mcpSupportedTargets = config.getTargets().filter((target) => {
6355
- return supportedMcpTargets.some((supportedTarget) => supportedTarget === target);
6356
- });
6521
+ const toolTargets = config.getExperimentalGlobal() ? intersection(config.getTargets(), McpProcessor.getToolTargetsGlobal()) : intersection(config.getTargets(), McpProcessor.getToolTargets());
6357
6522
  for (const baseDir of config.getBaseDirs()) {
6358
- for (const toolTarget of intersection(mcpSupportedTargets, McpProcessor.getToolTargets())) {
6523
+ for (const toolTarget of toolTargets) {
6359
6524
  const processor = new McpProcessor({
6360
6525
  baseDir,
6361
- toolTarget
6526
+ toolTarget,
6527
+ global: config.getExperimentalGlobal()
6362
6528
  });
6363
6529
  if (config.getDelete()) {
6364
6530
  const oldToolFiles = await processor.loadToolFilesToDelete();
@@ -6443,9 +6609,9 @@ async function generateSubagents(config) {
6443
6609
  }
6444
6610
 
6445
6611
  // src/cli/commands/gitignore.ts
6446
- import { join as join55 } from "path";
6612
+ import { join as join56 } from "path";
6447
6613
  var gitignoreCommand = async () => {
6448
- const gitignorePath = join55(process.cwd(), ".gitignore");
6614
+ const gitignorePath = join56(process.cwd(), ".gitignore");
6449
6615
  const rulesFilesToIgnore = [
6450
6616
  "# Generated by rulesync - AI tool configuration files",
6451
6617
  "**/.amazonq/",
@@ -6546,12 +6712,9 @@ async function importRules(config, tool) {
6546
6712
  if (!config.getFeatures().includes("rules")) {
6547
6713
  return 0;
6548
6714
  }
6549
- if (!RulesProcessor.getToolTargets().includes(tool)) {
6550
- return 0;
6551
- }
6552
6715
  const global = config.getExperimentalGlobal();
6553
- if (global && !RulesProcessor.getToolTargetsGlobal().includes(tool)) {
6554
- logger.error(`${tool} is not supported in global mode`);
6716
+ const supportedTargets = global ? RulesProcessor.getToolTargetsGlobal() : RulesProcessor.getToolTargets();
6717
+ if (!supportedTargets.includes(tool)) {
6555
6718
  return 0;
6556
6719
  }
6557
6720
  const rulesProcessor = new RulesProcessor({
@@ -6603,16 +6766,15 @@ async function importMcp(config, tool) {
6603
6766
  if (!config.getFeatures().includes("mcp")) {
6604
6767
  return 0;
6605
6768
  }
6606
- if (config.getExperimentalGlobal()) {
6607
- logger.debug("Skipping MCP file import (not supported in global mode)");
6608
- return 0;
6609
- }
6610
- if (!McpProcessor.getToolTargets().includes(tool)) {
6769
+ const global = config.getExperimentalGlobal();
6770
+ const supportedTargets = global ? McpProcessor.getToolTargetsGlobal() : McpProcessor.getToolTargets();
6771
+ if (!supportedTargets.includes(tool)) {
6611
6772
  return 0;
6612
6773
  }
6613
6774
  const mcpProcessor = new McpProcessor({
6614
6775
  baseDir: config.getBaseDirs()[0] ?? ".",
6615
- toolTarget: tool
6776
+ toolTarget: tool,
6777
+ global
6616
6778
  });
6617
6779
  const toolFiles = await mcpProcessor.loadToolFiles();
6618
6780
  if (toolFiles.length === 0) {
@@ -6632,9 +6794,6 @@ async function importCommands(config, tool) {
6632
6794
  const global = config.getExperimentalGlobal();
6633
6795
  const supportedTargets = global ? CommandsProcessor.getToolTargetsGlobal() : CommandsProcessor.getToolTargets({ includeSimulated: false });
6634
6796
  if (!supportedTargets.includes(tool)) {
6635
- if (global) {
6636
- logger.debug(`${tool} is not supported for commands in global mode`);
6637
- }
6638
6797
  return 0;
6639
6798
  }
6640
6799
  const commandsProcessor = new CommandsProcessor({
@@ -6682,7 +6841,7 @@ async function importSubagents(config, tool) {
6682
6841
  }
6683
6842
 
6684
6843
  // src/cli/commands/init.ts
6685
- import { join as join56 } from "path";
6844
+ import { join as join57 } from "path";
6686
6845
  async function initCommand() {
6687
6846
  logger.info("Initializing rulesync...");
6688
6847
  await ensureDir(".rulesync");
@@ -6753,7 +6912,7 @@ globs: ["**/*"]
6753
6912
  - Follow single responsibility principle
6754
6913
  `
6755
6914
  };
6756
- const filepath = join56(".rulesync/rules", sampleFile.filename);
6915
+ const filepath = join57(".rulesync/rules", sampleFile.filename);
6757
6916
  await ensureDir(".rulesync/rules");
6758
6917
  await ensureDir(RulesyncCommand.getSettablePaths().relativeDirPath);
6759
6918
  await ensureDir(".rulesync/subagents");
@@ -6766,7 +6925,7 @@ globs: ["**/*"]
6766
6925
  }
6767
6926
 
6768
6927
  // src/cli/index.ts
6769
- var getVersion = () => "3.1.0";
6928
+ var getVersion = () => "3.2.0";
6770
6929
  var main = async () => {
6771
6930
  const program = new Command();
6772
6931
  const version = getVersion();