rulesync 2.1.0 → 2.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/README.md CHANGED
@@ -60,9 +60,9 @@ Rulesync supports both **generation** and **import** for All of the major AI cod
60
60
  | AGENTS.md | ✅ | | | | |
61
61
  | Claude Code | ✅ 🌏 | ✅ | ✅ | ✅ 🌏 | ✅ |
62
62
  | Codex CLI | ✅ 🌏 | ✅ | | 🎮 | 🎮 |
63
- | Gemini CLI | ✅ | ✅ | | ✅ | 🎮 |
63
+ | Gemini CLI | ✅ 🌏 | ✅ | | ✅ 🌏 | 🎮 |
64
64
  | GitHub Copilot | ✅ | | ✅ | 🎮 | 🎮 |
65
- | Cursor | ✅ | ✅ | ✅ | ✅ | 🎮 |
65
+ | Cursor | ✅ | ✅ | ✅ | ✅ 🌏 | 🎮 |
66
66
  | OpenCode | ✅ | | | | |
67
67
  | Cline | ✅ | ✅ | ✅ | | |
68
68
  | Roo Code | ✅ | ✅ | ✅ | ✅ | 🎮 |
@@ -75,8 +75,8 @@ Rulesync supports both **generation** and **import** for All of the major AI cod
75
75
  | Warp | ✅ | | | | |
76
76
 
77
77
  * ✅: Supports project mode
78
- * 🌏: Supports global mode (Experimental Feature)
79
- * 🎮: Supports Simulated Commands/Subagents (Experimental Feature)
78
+ * 🌏: Supports global mode (Experimental)
79
+ * 🎮: Supports simulated commands/subagents (Project mode only, experimental)
80
80
 
81
81
  ## Why Rulesync?
82
82
 
package/dist/index.cjs CHANGED
@@ -831,7 +831,12 @@ var import_node_path8 = require("path");
831
831
  var CursorCommand = class _CursorCommand extends ToolCommand {
832
832
  static getSettablePaths() {
833
833
  return {
834
- relativeDirPath: ".cursor/commands"
834
+ relativeDirPath: (0, import_node_path8.join)(".cursor", "commands")
835
+ };
836
+ }
837
+ static getSettablePathsGlobal() {
838
+ return {
839
+ relativeDirPath: (0, import_node_path8.join)(".cursor", "commands")
835
840
  };
836
841
  }
837
842
  toRulesyncCommand() {
@@ -853,12 +858,14 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
853
858
  static fromRulesyncCommand({
854
859
  baseDir = ".",
855
860
  rulesyncCommand,
856
- validate = true
861
+ validate = true,
862
+ global = false
857
863
  }) {
864
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
858
865
  return new _CursorCommand({
859
866
  baseDir,
860
867
  fileContent: rulesyncCommand.getBody(),
861
- relativeDirPath: _CursorCommand.getSettablePaths().relativeDirPath,
868
+ relativeDirPath: paths.relativeDirPath,
862
869
  relativeFilePath: rulesyncCommand.getRelativeFilePath(),
863
870
  validate
864
871
  });
@@ -878,18 +885,16 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
878
885
  static async fromFile({
879
886
  baseDir = ".",
880
887
  relativeFilePath,
881
- validate = true
888
+ validate = true,
889
+ global = false
882
890
  }) {
883
- const filePath = (0, import_node_path8.join)(
884
- baseDir,
885
- _CursorCommand.getSettablePaths().relativeDirPath,
886
- relativeFilePath
887
- );
891
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
892
+ const filePath = (0, import_node_path8.join)(baseDir, paths.relativeDirPath, relativeFilePath);
888
893
  const fileContent = await readFileContent(filePath);
889
894
  const { body: content } = parseFrontmatter(fileContent);
890
895
  return new _CursorCommand({
891
896
  baseDir,
892
- relativeDirPath: _CursorCommand.getSettablePaths().relativeDirPath,
897
+ relativeDirPath: paths.relativeDirPath,
893
898
  relativeFilePath: (0, import_node_path8.basename)(relativeFilePath),
894
899
  fileContent: content.trim(),
895
900
  validate
@@ -919,6 +924,11 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
919
924
  relativeDirPath: ".gemini/commands"
920
925
  };
921
926
  }
927
+ static getSettablePathsGlobal() {
928
+ return {
929
+ relativeDirPath: (0, import_node_path9.join)(".gemini", "commands")
930
+ };
931
+ }
922
932
  parseTomlContent(content) {
923
933
  try {
924
934
  const parsed = (0, import_smol_toml.parse)(content);
@@ -960,7 +970,8 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
960
970
  static fromRulesyncCommand({
961
971
  baseDir = ".",
962
972
  rulesyncCommand,
963
- validate = true
973
+ validate = true,
974
+ global = false
964
975
  }) {
965
976
  const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
966
977
  const geminiFrontmatter = {
@@ -971,9 +982,10 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
971
982
  prompt = """
972
983
  ${geminiFrontmatter.prompt}
973
984
  """`;
985
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
974
986
  return new _GeminiCliCommand({
975
987
  baseDir,
976
- relativeDirPath: _GeminiCliCommand.getSettablePaths().relativeDirPath,
988
+ relativeDirPath: paths.relativeDirPath,
977
989
  relativeFilePath: rulesyncCommand.getRelativeFilePath().replace(".md", ".toml"),
978
990
  fileContent: tomlContent,
979
991
  validate
@@ -982,17 +994,15 @@ ${geminiFrontmatter.prompt}
982
994
  static async fromFile({
983
995
  baseDir = ".",
984
996
  relativeFilePath,
985
- validate = true
997
+ validate = true,
998
+ global = false
986
999
  }) {
987
- const filePath = (0, import_node_path9.join)(
988
- baseDir,
989
- _GeminiCliCommand.getSettablePaths().relativeDirPath,
990
- relativeFilePath
991
- );
1000
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
1001
+ const filePath = (0, import_node_path9.join)(baseDir, paths.relativeDirPath, relativeFilePath);
992
1002
  const fileContent = await readFileContent(filePath);
993
1003
  return new _GeminiCliCommand({
994
1004
  baseDir,
995
- relativeDirPath: _GeminiCliCommand.getSettablePaths().relativeDirPath,
1005
+ relativeDirPath: paths.relativeDirPath,
996
1006
  relativeFilePath: (0, import_node_path9.basename)(relativeFilePath),
997
1007
  fileContent,
998
1008
  validate
@@ -1172,7 +1182,8 @@ var CommandsProcessor = class extends FeatureProcessor {
1172
1182
  }
1173
1183
  return GeminiCliCommand.fromRulesyncCommand({
1174
1184
  baseDir: this.baseDir,
1175
- rulesyncCommand
1185
+ rulesyncCommand,
1186
+ global: this.global
1176
1187
  });
1177
1188
  case "roo":
1178
1189
  if (!RooCommand.isTargetedByRulesyncCommand(rulesyncCommand)) {
@@ -1196,7 +1207,8 @@ var CommandsProcessor = class extends FeatureProcessor {
1196
1207
  }
1197
1208
  return CursorCommand.fromRulesyncCommand({
1198
1209
  baseDir: this.baseDir,
1199
- rulesyncCommand
1210
+ rulesyncCommand,
1211
+ global: this.global
1200
1212
  });
1201
1213
  case "codexcli":
1202
1214
  if (!CodexCliCommand.isTargetedByRulesyncCommand(rulesyncCommand)) {
@@ -1284,7 +1296,8 @@ var CommandsProcessor = class extends FeatureProcessor {
1284
1296
  case "geminicli":
1285
1297
  return GeminiCliCommand.fromFile({
1286
1298
  baseDir: this.baseDir,
1287
- relativeFilePath: (0, import_node_path11.basename)(path2)
1299
+ relativeFilePath: (0, import_node_path11.basename)(path2),
1300
+ global: this.global
1288
1301
  });
1289
1302
  case "roo":
1290
1303
  return RooCommand.fromFile({
@@ -1299,7 +1312,8 @@ var CommandsProcessor = class extends FeatureProcessor {
1299
1312
  case "cursor":
1300
1313
  return CursorCommand.fromFile({
1301
1314
  baseDir: this.baseDir,
1302
- relativeFilePath: (0, import_node_path11.basename)(path2)
1315
+ relativeFilePath: (0, import_node_path11.basename)(path2),
1316
+ global: this.global
1303
1317
  });
1304
1318
  case "codexcli":
1305
1319
  return CodexCliCommand.fromFile({
@@ -1336,12 +1350,13 @@ var CommandsProcessor = class extends FeatureProcessor {
1336
1350
  });
1337
1351
  }
1338
1352
  /**
1339
- * Load Gemini CLI command configurations from .gemini/commands/ directory
1353
+ * Load Cursor command configurations from .cursor/commands/ directory
1340
1354
  */
1341
1355
  async loadCursorCommands() {
1356
+ const paths = this.global ? CursorCommand.getSettablePathsGlobal() : CursorCommand.getSettablePaths();
1342
1357
  return await this.loadToolCommandDefault({
1343
1358
  toolTarget: "cursor",
1344
- relativeDirPath: CursorCommand.getSettablePaths().relativeDirPath,
1359
+ relativeDirPath: paths.relativeDirPath,
1345
1360
  extension: "md"
1346
1361
  });
1347
1362
  }
@@ -1349,10 +1364,11 @@ var CommandsProcessor = class extends FeatureProcessor {
1349
1364
  * Load Gemini CLI command configurations from .gemini/commands/ directory
1350
1365
  */
1351
1366
  async loadGeminicliCommands() {
1367
+ const paths = this.global ? GeminiCliCommand.getSettablePathsGlobal() : GeminiCliCommand.getSettablePaths();
1352
1368
  return await this.loadToolCommandDefault({
1353
1369
  toolTarget: "geminicli",
1354
- relativeDirPath: GeminiCliCommand.getSettablePaths().relativeDirPath,
1355
- extension: "md"
1370
+ relativeDirPath: paths.relativeDirPath,
1371
+ extension: "toml"
1356
1372
  });
1357
1373
  }
1358
1374
  /**
@@ -1393,7 +1409,7 @@ var CommandsProcessor = class extends FeatureProcessor {
1393
1409
  return commandsProcessorToolTargetsSimulated;
1394
1410
  }
1395
1411
  static getToolTargetsGlobal() {
1396
- return ["claudecode"];
1412
+ return ["claudecode", "cursor", "geminicli"];
1397
1413
  }
1398
1414
  };
1399
1415
 
@@ -4779,35 +4795,64 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4779
4795
  }
4780
4796
  };
4781
4797
  }
4798
+ static getSettablePathsGlobal() {
4799
+ return {
4800
+ root: {
4801
+ relativeDirPath: ".gemini",
4802
+ relativeFilePath: "GEMINI.md"
4803
+ }
4804
+ };
4805
+ }
4782
4806
  static async fromFile({
4783
4807
  baseDir = ".",
4784
4808
  relativeFilePath,
4785
- validate = true
4809
+ validate = true,
4810
+ global = false
4786
4811
  }) {
4787
- const isRoot = relativeFilePath === "GEMINI.md";
4788
- const relativePath = isRoot ? "GEMINI.md" : (0, import_node_path47.join)(".gemini/memories", relativeFilePath);
4812
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
4813
+ const isRoot = relativeFilePath === paths.root.relativeFilePath;
4814
+ if (isRoot) {
4815
+ const relativePath2 = paths.root.relativeFilePath;
4816
+ const fileContent2 = await readFileContent(
4817
+ (0, import_node_path47.join)(baseDir, paths.root.relativeDirPath, relativePath2)
4818
+ );
4819
+ return new _GeminiCliRule({
4820
+ baseDir,
4821
+ relativeDirPath: paths.root.relativeDirPath,
4822
+ relativeFilePath: paths.root.relativeFilePath,
4823
+ fileContent: fileContent2,
4824
+ validate,
4825
+ root: true
4826
+ });
4827
+ }
4828
+ if (!paths.nonRoot) {
4829
+ throw new Error("nonRoot path is not set");
4830
+ }
4831
+ const relativePath = (0, import_node_path47.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
4789
4832
  const fileContent = await readFileContent((0, import_node_path47.join)(baseDir, relativePath));
4790
4833
  return new _GeminiCliRule({
4791
4834
  baseDir,
4792
- relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
4793
- relativeFilePath: isRoot ? "GEMINI.md" : relativeFilePath,
4835
+ relativeDirPath: paths.nonRoot.relativeDirPath,
4836
+ relativeFilePath,
4794
4837
  fileContent,
4795
4838
  validate,
4796
- root: isRoot
4839
+ root: false
4797
4840
  });
4798
4841
  }
4799
4842
  static fromRulesyncRule({
4800
4843
  baseDir = ".",
4801
4844
  rulesyncRule,
4802
- validate = true
4845
+ validate = true,
4846
+ global = false
4803
4847
  }) {
4848
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
4804
4849
  return new _GeminiCliRule(
4805
4850
  this.buildToolRuleParamsDefault({
4806
4851
  baseDir,
4807
4852
  rulesyncRule,
4808
4853
  validate,
4809
- rootPath: this.getSettablePaths().root,
4810
- nonRootPath: this.getSettablePaths().nonRoot
4854
+ rootPath: paths.root,
4855
+ nonRootPath: paths.nonRoot
4811
4856
  })
4812
4857
  );
4813
4858
  }
@@ -5269,7 +5314,11 @@ var rulesProcessorToolTargets = [
5269
5314
  "windsurf"
5270
5315
  ];
5271
5316
  var RulesProcessorToolTargetSchema = import_mini20.z.enum(rulesProcessorToolTargets);
5272
- var rulesProcessorToolTargetsGlobal = ["claudecode", "codexcli"];
5317
+ var rulesProcessorToolTargetsGlobal = [
5318
+ "claudecode",
5319
+ "codexcli",
5320
+ "geminicli"
5321
+ ];
5273
5322
  var RulesProcessor = class extends FeatureProcessor {
5274
5323
  toolTarget;
5275
5324
  simulateCommands;
@@ -5384,7 +5433,8 @@ var RulesProcessor = class extends FeatureProcessor {
5384
5433
  return GeminiCliRule.fromRulesyncRule({
5385
5434
  baseDir: this.baseDir,
5386
5435
  rulesyncRule,
5387
- validate: true
5436
+ validate: true,
5437
+ global: this.global
5388
5438
  });
5389
5439
  case "junie":
5390
5440
  if (!JunieRule.isTargetedByRulesyncRule(rulesyncRule)) {
@@ -5881,18 +5931,20 @@ var RulesProcessor = class extends FeatureProcessor {
5881
5931
  * Load Gemini CLI rule configuration from GEMINI.md file
5882
5932
  */
5883
5933
  async loadGeminicliRules() {
5884
- const settablePaths = GeminiCliRule.getSettablePaths();
5934
+ const settablePaths = this.global ? GeminiCliRule.getSettablePathsGlobal() : GeminiCliRule.getSettablePaths();
5885
5935
  return await this.loadToolRulesDefault({
5886
5936
  root: {
5887
5937
  relativeDirPath: settablePaths.root.relativeDirPath,
5888
5938
  relativeFilePath: settablePaths.root.relativeFilePath,
5889
5939
  fromFile: (params) => GeminiCliRule.fromFile(params)
5890
5940
  },
5891
- nonRoot: {
5892
- relativeDirPath: settablePaths.nonRoot.relativeDirPath,
5893
- fromFile: (params) => GeminiCliRule.fromFile(params),
5894
- extension: "md"
5895
- }
5941
+ ...settablePaths.nonRoot ? {
5942
+ nonRoot: {
5943
+ relativeDirPath: settablePaths.nonRoot.relativeDirPath,
5944
+ fromFile: (params) => GeminiCliRule.fromFile(params),
5945
+ extension: "md"
5946
+ }
5947
+ } : {}
5896
5948
  });
5897
5949
  }
5898
5950
  /**
@@ -6630,7 +6682,7 @@ globs: ["**/*"]
6630
6682
  }
6631
6683
 
6632
6684
  // src/cli/index.ts
6633
- var getVersion = () => "2.1.0";
6685
+ var getVersion = () => "2.2.0";
6634
6686
  var main = async () => {
6635
6687
  const program = new import_commander.Command();
6636
6688
  const version = getVersion();
package/dist/index.js CHANGED
@@ -808,7 +808,12 @@ import { basename as basename7, join as join7 } from "path";
808
808
  var CursorCommand = class _CursorCommand extends ToolCommand {
809
809
  static getSettablePaths() {
810
810
  return {
811
- relativeDirPath: ".cursor/commands"
811
+ relativeDirPath: join7(".cursor", "commands")
812
+ };
813
+ }
814
+ static getSettablePathsGlobal() {
815
+ return {
816
+ relativeDirPath: join7(".cursor", "commands")
812
817
  };
813
818
  }
814
819
  toRulesyncCommand() {
@@ -830,12 +835,14 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
830
835
  static fromRulesyncCommand({
831
836
  baseDir = ".",
832
837
  rulesyncCommand,
833
- validate = true
838
+ validate = true,
839
+ global = false
834
840
  }) {
841
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
835
842
  return new _CursorCommand({
836
843
  baseDir,
837
844
  fileContent: rulesyncCommand.getBody(),
838
- relativeDirPath: _CursorCommand.getSettablePaths().relativeDirPath,
845
+ relativeDirPath: paths.relativeDirPath,
839
846
  relativeFilePath: rulesyncCommand.getRelativeFilePath(),
840
847
  validate
841
848
  });
@@ -855,18 +862,16 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
855
862
  static async fromFile({
856
863
  baseDir = ".",
857
864
  relativeFilePath,
858
- validate = true
865
+ validate = true,
866
+ global = false
859
867
  }) {
860
- const filePath = join7(
861
- baseDir,
862
- _CursorCommand.getSettablePaths().relativeDirPath,
863
- relativeFilePath
864
- );
868
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
869
+ const filePath = join7(baseDir, paths.relativeDirPath, relativeFilePath);
865
870
  const fileContent = await readFileContent(filePath);
866
871
  const { body: content } = parseFrontmatter(fileContent);
867
872
  return new _CursorCommand({
868
873
  baseDir,
869
- relativeDirPath: _CursorCommand.getSettablePaths().relativeDirPath,
874
+ relativeDirPath: paths.relativeDirPath,
870
875
  relativeFilePath: basename7(relativeFilePath),
871
876
  fileContent: content.trim(),
872
877
  validate
@@ -896,6 +901,11 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
896
901
  relativeDirPath: ".gemini/commands"
897
902
  };
898
903
  }
904
+ static getSettablePathsGlobal() {
905
+ return {
906
+ relativeDirPath: join8(".gemini", "commands")
907
+ };
908
+ }
899
909
  parseTomlContent(content) {
900
910
  try {
901
911
  const parsed = parseToml(content);
@@ -937,7 +947,8 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
937
947
  static fromRulesyncCommand({
938
948
  baseDir = ".",
939
949
  rulesyncCommand,
940
- validate = true
950
+ validate = true,
951
+ global = false
941
952
  }) {
942
953
  const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
943
954
  const geminiFrontmatter = {
@@ -948,9 +959,10 @@ var GeminiCliCommand = class _GeminiCliCommand extends ToolCommand {
948
959
  prompt = """
949
960
  ${geminiFrontmatter.prompt}
950
961
  """`;
962
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
951
963
  return new _GeminiCliCommand({
952
964
  baseDir,
953
- relativeDirPath: _GeminiCliCommand.getSettablePaths().relativeDirPath,
965
+ relativeDirPath: paths.relativeDirPath,
954
966
  relativeFilePath: rulesyncCommand.getRelativeFilePath().replace(".md", ".toml"),
955
967
  fileContent: tomlContent,
956
968
  validate
@@ -959,17 +971,15 @@ ${geminiFrontmatter.prompt}
959
971
  static async fromFile({
960
972
  baseDir = ".",
961
973
  relativeFilePath,
962
- validate = true
974
+ validate = true,
975
+ global = false
963
976
  }) {
964
- const filePath = join8(
965
- baseDir,
966
- _GeminiCliCommand.getSettablePaths().relativeDirPath,
967
- relativeFilePath
968
- );
977
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
978
+ const filePath = join8(baseDir, paths.relativeDirPath, relativeFilePath);
969
979
  const fileContent = await readFileContent(filePath);
970
980
  return new _GeminiCliCommand({
971
981
  baseDir,
972
- relativeDirPath: _GeminiCliCommand.getSettablePaths().relativeDirPath,
982
+ relativeDirPath: paths.relativeDirPath,
973
983
  relativeFilePath: basename8(relativeFilePath),
974
984
  fileContent,
975
985
  validate
@@ -1149,7 +1159,8 @@ var CommandsProcessor = class extends FeatureProcessor {
1149
1159
  }
1150
1160
  return GeminiCliCommand.fromRulesyncCommand({
1151
1161
  baseDir: this.baseDir,
1152
- rulesyncCommand
1162
+ rulesyncCommand,
1163
+ global: this.global
1153
1164
  });
1154
1165
  case "roo":
1155
1166
  if (!RooCommand.isTargetedByRulesyncCommand(rulesyncCommand)) {
@@ -1173,7 +1184,8 @@ var CommandsProcessor = class extends FeatureProcessor {
1173
1184
  }
1174
1185
  return CursorCommand.fromRulesyncCommand({
1175
1186
  baseDir: this.baseDir,
1176
- rulesyncCommand
1187
+ rulesyncCommand,
1188
+ global: this.global
1177
1189
  });
1178
1190
  case "codexcli":
1179
1191
  if (!CodexCliCommand.isTargetedByRulesyncCommand(rulesyncCommand)) {
@@ -1261,7 +1273,8 @@ var CommandsProcessor = class extends FeatureProcessor {
1261
1273
  case "geminicli":
1262
1274
  return GeminiCliCommand.fromFile({
1263
1275
  baseDir: this.baseDir,
1264
- relativeFilePath: basename10(path2)
1276
+ relativeFilePath: basename10(path2),
1277
+ global: this.global
1265
1278
  });
1266
1279
  case "roo":
1267
1280
  return RooCommand.fromFile({
@@ -1276,7 +1289,8 @@ var CommandsProcessor = class extends FeatureProcessor {
1276
1289
  case "cursor":
1277
1290
  return CursorCommand.fromFile({
1278
1291
  baseDir: this.baseDir,
1279
- relativeFilePath: basename10(path2)
1292
+ relativeFilePath: basename10(path2),
1293
+ global: this.global
1280
1294
  });
1281
1295
  case "codexcli":
1282
1296
  return CodexCliCommand.fromFile({
@@ -1313,12 +1327,13 @@ var CommandsProcessor = class extends FeatureProcessor {
1313
1327
  });
1314
1328
  }
1315
1329
  /**
1316
- * Load Gemini CLI command configurations from .gemini/commands/ directory
1330
+ * Load Cursor command configurations from .cursor/commands/ directory
1317
1331
  */
1318
1332
  async loadCursorCommands() {
1333
+ const paths = this.global ? CursorCommand.getSettablePathsGlobal() : CursorCommand.getSettablePaths();
1319
1334
  return await this.loadToolCommandDefault({
1320
1335
  toolTarget: "cursor",
1321
- relativeDirPath: CursorCommand.getSettablePaths().relativeDirPath,
1336
+ relativeDirPath: paths.relativeDirPath,
1322
1337
  extension: "md"
1323
1338
  });
1324
1339
  }
@@ -1326,10 +1341,11 @@ var CommandsProcessor = class extends FeatureProcessor {
1326
1341
  * Load Gemini CLI command configurations from .gemini/commands/ directory
1327
1342
  */
1328
1343
  async loadGeminicliCommands() {
1344
+ const paths = this.global ? GeminiCliCommand.getSettablePathsGlobal() : GeminiCliCommand.getSettablePaths();
1329
1345
  return await this.loadToolCommandDefault({
1330
1346
  toolTarget: "geminicli",
1331
- relativeDirPath: GeminiCliCommand.getSettablePaths().relativeDirPath,
1332
- extension: "md"
1347
+ relativeDirPath: paths.relativeDirPath,
1348
+ extension: "toml"
1333
1349
  });
1334
1350
  }
1335
1351
  /**
@@ -1370,7 +1386,7 @@ var CommandsProcessor = class extends FeatureProcessor {
1370
1386
  return commandsProcessorToolTargetsSimulated;
1371
1387
  }
1372
1388
  static getToolTargetsGlobal() {
1373
- return ["claudecode"];
1389
+ return ["claudecode", "cursor", "geminicli"];
1374
1390
  }
1375
1391
  };
1376
1392
 
@@ -4756,35 +4772,64 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
4756
4772
  }
4757
4773
  };
4758
4774
  }
4775
+ static getSettablePathsGlobal() {
4776
+ return {
4777
+ root: {
4778
+ relativeDirPath: ".gemini",
4779
+ relativeFilePath: "GEMINI.md"
4780
+ }
4781
+ };
4782
+ }
4759
4783
  static async fromFile({
4760
4784
  baseDir = ".",
4761
4785
  relativeFilePath,
4762
- validate = true
4786
+ validate = true,
4787
+ global = false
4763
4788
  }) {
4764
- const isRoot = relativeFilePath === "GEMINI.md";
4765
- const relativePath = isRoot ? "GEMINI.md" : join46(".gemini/memories", relativeFilePath);
4789
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
4790
+ const isRoot = relativeFilePath === paths.root.relativeFilePath;
4791
+ if (isRoot) {
4792
+ const relativePath2 = paths.root.relativeFilePath;
4793
+ const fileContent2 = await readFileContent(
4794
+ join46(baseDir, paths.root.relativeDirPath, relativePath2)
4795
+ );
4796
+ return new _GeminiCliRule({
4797
+ baseDir,
4798
+ relativeDirPath: paths.root.relativeDirPath,
4799
+ relativeFilePath: paths.root.relativeFilePath,
4800
+ fileContent: fileContent2,
4801
+ validate,
4802
+ root: true
4803
+ });
4804
+ }
4805
+ if (!paths.nonRoot) {
4806
+ throw new Error("nonRoot path is not set");
4807
+ }
4808
+ const relativePath = join46(paths.nonRoot.relativeDirPath, relativeFilePath);
4766
4809
  const fileContent = await readFileContent(join46(baseDir, relativePath));
4767
4810
  return new _GeminiCliRule({
4768
4811
  baseDir,
4769
- relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
4770
- relativeFilePath: isRoot ? "GEMINI.md" : relativeFilePath,
4812
+ relativeDirPath: paths.nonRoot.relativeDirPath,
4813
+ relativeFilePath,
4771
4814
  fileContent,
4772
4815
  validate,
4773
- root: isRoot
4816
+ root: false
4774
4817
  });
4775
4818
  }
4776
4819
  static fromRulesyncRule({
4777
4820
  baseDir = ".",
4778
4821
  rulesyncRule,
4779
- validate = true
4822
+ validate = true,
4823
+ global = false
4780
4824
  }) {
4825
+ const paths = global ? this.getSettablePathsGlobal() : this.getSettablePaths();
4781
4826
  return new _GeminiCliRule(
4782
4827
  this.buildToolRuleParamsDefault({
4783
4828
  baseDir,
4784
4829
  rulesyncRule,
4785
4830
  validate,
4786
- rootPath: this.getSettablePaths().root,
4787
- nonRootPath: this.getSettablePaths().nonRoot
4831
+ rootPath: paths.root,
4832
+ nonRootPath: paths.nonRoot
4788
4833
  })
4789
4834
  );
4790
4835
  }
@@ -5246,7 +5291,11 @@ var rulesProcessorToolTargets = [
5246
5291
  "windsurf"
5247
5292
  ];
5248
5293
  var RulesProcessorToolTargetSchema = z20.enum(rulesProcessorToolTargets);
5249
- var rulesProcessorToolTargetsGlobal = ["claudecode", "codexcli"];
5294
+ var rulesProcessorToolTargetsGlobal = [
5295
+ "claudecode",
5296
+ "codexcli",
5297
+ "geminicli"
5298
+ ];
5250
5299
  var RulesProcessor = class extends FeatureProcessor {
5251
5300
  toolTarget;
5252
5301
  simulateCommands;
@@ -5361,7 +5410,8 @@ var RulesProcessor = class extends FeatureProcessor {
5361
5410
  return GeminiCliRule.fromRulesyncRule({
5362
5411
  baseDir: this.baseDir,
5363
5412
  rulesyncRule,
5364
- validate: true
5413
+ validate: true,
5414
+ global: this.global
5365
5415
  });
5366
5416
  case "junie":
5367
5417
  if (!JunieRule.isTargetedByRulesyncRule(rulesyncRule)) {
@@ -5858,18 +5908,20 @@ var RulesProcessor = class extends FeatureProcessor {
5858
5908
  * Load Gemini CLI rule configuration from GEMINI.md file
5859
5909
  */
5860
5910
  async loadGeminicliRules() {
5861
- const settablePaths = GeminiCliRule.getSettablePaths();
5911
+ const settablePaths = this.global ? GeminiCliRule.getSettablePathsGlobal() : GeminiCliRule.getSettablePaths();
5862
5912
  return await this.loadToolRulesDefault({
5863
5913
  root: {
5864
5914
  relativeDirPath: settablePaths.root.relativeDirPath,
5865
5915
  relativeFilePath: settablePaths.root.relativeFilePath,
5866
5916
  fromFile: (params) => GeminiCliRule.fromFile(params)
5867
5917
  },
5868
- nonRoot: {
5869
- relativeDirPath: settablePaths.nonRoot.relativeDirPath,
5870
- fromFile: (params) => GeminiCliRule.fromFile(params),
5871
- extension: "md"
5872
- }
5918
+ ...settablePaths.nonRoot ? {
5919
+ nonRoot: {
5920
+ relativeDirPath: settablePaths.nonRoot.relativeDirPath,
5921
+ fromFile: (params) => GeminiCliRule.fromFile(params),
5922
+ extension: "md"
5923
+ }
5924
+ } : {}
5873
5925
  });
5874
5926
  }
5875
5927
  /**
@@ -6607,7 +6659,7 @@ globs: ["**/*"]
6607
6659
  }
6608
6660
 
6609
6661
  // src/cli/index.ts
6610
- var getVersion = () => "2.1.0";
6662
+ var getVersion = () => "2.2.0";
6611
6663
  var main = async () => {
6612
6664
  const program = new Command();
6613
6665
  const version = getVersion();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulesync",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Unified AI rules management CLI tool that generates configuration files for various AI development tools",
5
5
  "keywords": [
6
6
  "ai",