rulesync 3.25.0 → 3.27.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
@@ -142,13 +142,13 @@ Rulesync supports both **generation** and **import** for All of the major AI cod
142
142
  | Gemini CLI | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ 🌏 | 🎮 | 🎮 |
143
143
  | GitHub Copilot | ✅ | | ✅ | ✅ | 🎮 | 🎮 |
144
144
  | Cursor | ✅ | ✅ | ✅ | ✅ 🌏 | 🎮 | 🎮 |
145
- | OpenCode | ✅ | | | | | |
145
+ | OpenCode | ✅ | || | | |
146
146
  | Cline | ✅ | ✅ | ✅ | | | |
147
147
  | Roo Code | ✅ | ✅ | ✅ | ✅ | 🎮 | |
148
148
  | Qwen Code | ✅ | ✅ | | | | |
149
149
  | Kiro IDE | ✅ | ✅ | | | | |
150
150
  | Amazon Q Developer CLI | ✅ | | ✅ | | | |
151
- | JetBrains Junie | ✅ | ✅ | | | | |
151
+ | JetBrains Junie | ✅ | ✅ || | | |
152
152
  | AugmentCode | ✅ | ✅ | | | | |
153
153
  | Windsurf | ✅ | ✅ | | | | |
154
154
  | Warp | ✅ | | | | | |
@@ -390,7 +390,21 @@ Example:
390
390
  }
391
391
  ```
392
392
 
393
- ### `.rulesyncignore`
393
+ ### `.rulesync/.aiignore` or `.rulesyncignore`
394
+
395
+ Rulesync supports a single ignore list that can live in either location below:
396
+
397
+ - `.rulesync/.aiignore` (recommended)
398
+ - `.rulesyncignore` (project root)
399
+
400
+ Rules and behavior:
401
+
402
+ - You may use either location.
403
+ - When both exist, Rulesync prefers `.rulesync/.aiignore` (recommended) over `.rulesyncignore` (legacy) when reading.
404
+ - If neither file exists yet, Rulesync defaults to creating `.rulesync/.aiignore`.
405
+
406
+ Notes:
407
+ - Running `rulesync init` will create `.rulesync/.aiignore` if no ignore file is present.
394
408
 
395
409
  Example:
396
410
 
package/dist/index.cjs CHANGED
@@ -499,6 +499,8 @@ var RULESYNC_RULES_RELATIVE_DIR_PATH = (0, import_node_path3.join)(RULESYNC_RELA
499
499
  var RULESYNC_COMMANDS_RELATIVE_DIR_PATH = (0, import_node_path3.join)(RULESYNC_RELATIVE_DIR_PATH, "commands");
500
500
  var RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = (0, import_node_path3.join)(RULESYNC_RELATIVE_DIR_PATH, "subagents");
501
501
  var RULESYNC_MCP_RELATIVE_FILE_PATH = (0, import_node_path3.join)(RULESYNC_RELATIVE_DIR_PATH, "mcp.json");
502
+ var RULESYNC_AIIGNORE_FILE_NAME = ".aiignore";
503
+ var RULESYNC_AIIGNORE_RELATIVE_FILE_PATH = (0, import_node_path3.join)(RULESYNC_RELATIVE_DIR_PATH, ".aiignore");
502
504
  var RULESYNC_IGNORE_RELATIVE_FILE_PATH = ".rulesyncignore";
503
505
  var RULESYNC_OVERVIEW_FILE_NAME = "overview.md";
504
506
  var RULESYNC_SKILLS_RELATIVE_DIR_PATH = (0, import_node_path3.join)(RULESYNC_RELATIVE_DIR_PATH, "skills");
@@ -1731,11 +1733,11 @@ var CommandsProcessor = class extends FeatureProcessor {
1731
1733
  const rulesyncCommandPaths = await findFilesByGlobs(
1732
1734
  (0, import_node_path14.join)(RulesyncCommand.getSettablePaths().relativeDirPath, "*.md")
1733
1735
  );
1734
- const rulesyncCommands = (await Promise.allSettled(
1736
+ const rulesyncCommands = await Promise.all(
1735
1737
  rulesyncCommandPaths.map(
1736
1738
  (path3) => RulesyncCommand.fromFile({ relativeFilePath: (0, import_node_path14.basename)(path3) })
1737
1739
  )
1738
- )).filter((result) => result.status === "fulfilled").map((result) => result.value);
1740
+ );
1739
1741
  logger.info(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
1740
1742
  return rulesyncCommands;
1741
1743
  }
@@ -1773,7 +1775,7 @@ var CommandsProcessor = class extends FeatureProcessor {
1773
1775
  const commandFilePaths = await findFilesByGlobs(
1774
1776
  (0, import_node_path14.join)(this.baseDir, relativeDirPath, `*.${extension}`)
1775
1777
  );
1776
- const toolCommands = (await Promise.allSettled(
1778
+ const toolCommands = await Promise.all(
1777
1779
  commandFilePaths.map((path3) => {
1778
1780
  switch (toolTarget) {
1779
1781
  case "agentsmd":
@@ -1819,7 +1821,7 @@ var CommandsProcessor = class extends FeatureProcessor {
1819
1821
  throw new Error(`Unsupported tool target: ${toolTarget}`);
1820
1822
  }
1821
1823
  })
1822
- )).filter((result) => result.status === "fulfilled").map((result) => result.value);
1824
+ );
1823
1825
  logger.info(`Successfully loaded ${toolCommands.length} ${relativeDirPath} commands`);
1824
1826
  return toolCommands;
1825
1827
  }
@@ -1938,18 +1940,48 @@ var RulesyncIgnore = class _RulesyncIgnore extends RulesyncFile {
1938
1940
  }
1939
1941
  static getSettablePaths() {
1940
1942
  return {
1941
- relativeDirPath: ".",
1942
- relativeFilePath: RULESYNC_IGNORE_RELATIVE_FILE_PATH
1943
+ recommended: {
1944
+ relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
1945
+ relativeFilePath: RULESYNC_AIIGNORE_FILE_NAME
1946
+ },
1947
+ legacy: {
1948
+ relativeDirPath: ".",
1949
+ relativeFilePath: RULESYNC_IGNORE_RELATIVE_FILE_PATH
1950
+ }
1943
1951
  };
1944
1952
  }
1945
1953
  static async fromFile() {
1946
1954
  const baseDir = process.cwd();
1947
- const filePath = (0, import_node_path15.join)(baseDir, this.getSettablePaths().relativeFilePath);
1948
- const fileContent = await readFileContent(filePath);
1955
+ const paths = this.getSettablePaths();
1956
+ const recommendedPath = (0, import_node_path15.join)(
1957
+ baseDir,
1958
+ paths.recommended.relativeDirPath,
1959
+ paths.recommended.relativeFilePath
1960
+ );
1961
+ const legacyPath = (0, import_node_path15.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
1962
+ if (await fileExists(recommendedPath)) {
1963
+ const fileContent2 = await readFileContent(recommendedPath);
1964
+ return new _RulesyncIgnore({
1965
+ baseDir,
1966
+ relativeDirPath: paths.recommended.relativeDirPath,
1967
+ relativeFilePath: paths.recommended.relativeFilePath,
1968
+ fileContent: fileContent2
1969
+ });
1970
+ }
1971
+ if (await fileExists(legacyPath)) {
1972
+ const fileContent2 = await readFileContent(legacyPath);
1973
+ return new _RulesyncIgnore({
1974
+ baseDir,
1975
+ relativeDirPath: paths.legacy.relativeDirPath,
1976
+ relativeFilePath: paths.legacy.relativeFilePath,
1977
+ fileContent: fileContent2
1978
+ });
1979
+ }
1980
+ const fileContent = await readFileContent(recommendedPath);
1949
1981
  return new _RulesyncIgnore({
1950
1982
  baseDir,
1951
- relativeDirPath: this.getSettablePaths().relativeDirPath,
1952
- relativeFilePath: this.getSettablePaths().relativeFilePath,
1983
+ relativeDirPath: paths.recommended.relativeDirPath,
1984
+ relativeFilePath: paths.recommended.relativeFilePath,
1953
1985
  fileContent
1954
1986
  });
1955
1987
  }
@@ -1986,8 +2018,8 @@ var ToolIgnore = class extends ToolFile {
1986
2018
  toRulesyncIgnoreDefault() {
1987
2019
  return new RulesyncIgnore({
1988
2020
  baseDir: ".",
1989
- relativeDirPath: ".",
1990
- relativeFilePath: RULESYNC_IGNORE_RELATIVE_FILE_PATH,
2021
+ relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
2022
+ relativeFilePath: RULESYNC_AIIGNORE_FILE_NAME,
1991
2023
  fileContent: this.fileContent
1992
2024
  });
1993
2025
  }
@@ -2131,8 +2163,8 @@ var ClaudecodeIgnore = class _ClaudecodeIgnore extends ToolIgnore {
2131
2163
  const fileContent = rulesyncPatterns.join("\n");
2132
2164
  return new RulesyncIgnore({
2133
2165
  baseDir: this.baseDir,
2134
- relativeDirPath: RulesyncIgnore.getSettablePaths().relativeDirPath,
2135
- relativeFilePath: RulesyncIgnore.getSettablePaths().relativeFilePath,
2166
+ relativeDirPath: RulesyncIgnore.getSettablePaths().recommended.relativeDirPath,
2167
+ relativeFilePath: RulesyncIgnore.getSettablePaths().recommended.relativeFilePath,
2136
2168
  fileContent
2137
2169
  });
2138
2170
  }
@@ -2254,7 +2286,7 @@ var CursorIgnore = class _CursorIgnore extends ToolIgnore {
2254
2286
  return new RulesyncIgnore({
2255
2287
  baseDir: ".",
2256
2288
  relativeDirPath: ".",
2257
- relativeFilePath: RULESYNC_IGNORE_RELATIVE_FILE_PATH,
2289
+ relativeFilePath: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
2258
2290
  fileContent: this.fileContent
2259
2291
  });
2260
2292
  }
@@ -2661,7 +2693,7 @@ var IgnoreProcessor = class extends FeatureProcessor {
2661
2693
  (file) => file instanceof RulesyncIgnore
2662
2694
  );
2663
2695
  if (!rulesyncIgnore) {
2664
- throw new Error(`No ${RULESYNC_IGNORE_RELATIVE_FILE_PATH} found.`);
2696
+ throw new Error(`No ${RULESYNC_AIIGNORE_RELATIVE_FILE_PATH} found.`);
2665
2697
  }
2666
2698
  const toolIgnores = await Promise.all(
2667
2699
  [rulesyncIgnore].map(async (rulesyncIgnore2) => {
@@ -5030,17 +5062,11 @@ var SkillsProcessor = class extends DirFeatureProcessor {
5030
5062
  const rulesyncSkillsDirPath = (0, import_node_path49.join)(this.baseDir, paths.relativeDirPath);
5031
5063
  const dirPaths = await findFilesByGlobs((0, import_node_path49.join)(rulesyncSkillsDirPath, "*"), { type: "dir" });
5032
5064
  const dirNames = dirPaths.map((path3) => (0, import_node_path49.basename)(path3));
5033
- const results = await Promise.allSettled(
5065
+ const rulesyncSkills = await Promise.all(
5034
5066
  dirNames.map(
5035
5067
  (dirName) => RulesyncSkill.fromDir({ baseDir: this.baseDir, dirName, global: this.global })
5036
5068
  )
5037
5069
  );
5038
- const rulesyncSkills = [];
5039
- for (const result of results) {
5040
- if (result.status === "fulfilled") {
5041
- rulesyncSkills.push(result.value);
5042
- }
5043
- }
5044
5070
  logger.info(`Successfully loaded ${rulesyncSkills.length} rulesync skills`);
5045
5071
  return rulesyncSkills;
5046
5072
  }
@@ -5077,7 +5103,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
5077
5103
  const skillsDirPath = (0, import_node_path49.join)(this.baseDir, paths.relativeDirPath);
5078
5104
  const dirPaths = await findFilesByGlobs((0, import_node_path49.join)(skillsDirPath, "*"), { type: "dir" });
5079
5105
  const dirNames = dirPaths.map((path3) => (0, import_node_path49.basename)(path3));
5080
- const toolSkills = (await Promise.allSettled(
5106
+ const toolSkills = await Promise.all(
5081
5107
  dirNames.map(
5082
5108
  (dirName) => ClaudecodeSkill.fromDir({
5083
5109
  baseDir: this.baseDir,
@@ -5085,7 +5111,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
5085
5111
  global: this.global
5086
5112
  })
5087
5113
  )
5088
- )).filter((result) => result.status === "fulfilled").map((result) => result.value);
5114
+ );
5089
5115
  logger.info(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
5090
5116
  return toolSkills;
5091
5117
  }
@@ -5097,14 +5123,14 @@ var SkillsProcessor = class extends DirFeatureProcessor {
5097
5123
  const skillsDirPath = (0, import_node_path49.join)(this.baseDir, paths.relativeDirPath);
5098
5124
  const dirPaths = await findFilesByGlobs((0, import_node_path49.join)(skillsDirPath, "*"), { type: "dir" });
5099
5125
  const dirNames = dirPaths.map((path3) => (0, import_node_path49.basename)(path3));
5100
- const toolSkills = (await Promise.allSettled(
5126
+ const toolSkills = await Promise.all(
5101
5127
  dirNames.map(
5102
5128
  (dirName) => SkillClass.fromDir({
5103
5129
  baseDir: this.baseDir,
5104
5130
  dirName
5105
5131
  })
5106
5132
  )
5107
- )).filter((result) => result.status === "fulfilled").map((result) => result.value);
5133
+ );
5108
5134
  logger.info(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
5109
5135
  return toolSkills;
5110
5136
  }
@@ -5902,7 +5928,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
5902
5928
  fromFile
5903
5929
  }) {
5904
5930
  const paths = await findFilesByGlobs((0, import_node_path59.join)(this.baseDir, relativeDirPath, "*.md"));
5905
- const subagents = (await Promise.allSettled(paths.map((path3) => fromFile((0, import_node_path59.basename)(path3))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
5931
+ const subagents = await Promise.all(paths.map((path3) => fromFile((0, import_node_path59.basename)(path3))));
5906
5932
  logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
5907
5933
  return subagents;
5908
5934
  }
@@ -8748,6 +8774,7 @@ var gitignoreCommand = async () => {
8748
8774
  "**/.vscode/mcp.json",
8749
8775
  // Junie
8750
8776
  "**/.junie/guidelines.md",
8777
+ "**/.junie/mcp.json",
8751
8778
  // Kiro
8752
8779
  "**/.kiro/steering/",
8753
8780
  "**/.aiignore",
@@ -8982,7 +9009,7 @@ async function initCommand() {
8982
9009
  logger.success("rulesync initialized successfully!");
8983
9010
  logger.info("Next steps:");
8984
9011
  logger.info(
8985
- `1. Edit ${RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${RULESYNC_MCP_RELATIVE_FILE_PATH} and ${RULESYNC_IGNORE_RELATIVE_FILE_PATH}`
9012
+ `1. Edit ${RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${RULESYNC_MCP_RELATIVE_FILE_PATH} and ${RULESYNC_AIIGNORE_RELATIVE_FILE_PATH}`
8986
9013
  );
8987
9014
  logger.info("2. Run 'rulesync generate' to create configuration files");
8988
9015
  }
@@ -9135,7 +9162,7 @@ Attention, again, you are just the planner, so though you can read any files and
9135
9162
  await ensureDir(mcpPaths.recommended.relativeDirPath);
9136
9163
  await ensureDir(commandPaths.relativeDirPath);
9137
9164
  await ensureDir(subagentPaths.relativeDirPath);
9138
- await ensureDir(ignorePaths.relativeDirPath);
9165
+ await ensureDir(ignorePaths.recommended.relativeDirPath);
9139
9166
  const ruleFilepath = (0, import_node_path81.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
9140
9167
  if (!await fileExists(ruleFilepath)) {
9141
9168
  await writeFileContent(ruleFilepath, sampleRuleFile.content);
@@ -9167,7 +9194,10 @@ Attention, again, you are just the planner, so though you can read any files and
9167
9194
  } else {
9168
9195
  logger.info(`Skipped ${subagentFilepath} (already exists)`);
9169
9196
  }
9170
- const ignoreFilepath = (0, import_node_path81.join)(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
9197
+ const ignoreFilepath = (0, import_node_path81.join)(
9198
+ ignorePaths.recommended.relativeDirPath,
9199
+ ignorePaths.recommended.relativeFilePath
9200
+ );
9171
9201
  if (!await fileExists(ignoreFilepath)) {
9172
9202
  await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
9173
9203
  logger.success(`Created ${ignoreFilepath}`);
@@ -9362,21 +9392,21 @@ var import_node_path83 = require("path");
9362
9392
  var import_mini31 = require("zod/mini");
9363
9393
  var maxIgnoreFileSizeBytes = 100 * 1024;
9364
9394
  async function getIgnoreFile() {
9365
- const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9395
+ const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
9366
9396
  try {
9367
9397
  const content = await readFileContent(ignoreFilePath);
9368
9398
  return {
9369
- relativePathFromCwd: RULESYNC_IGNORE_RELATIVE_FILE_PATH,
9399
+ relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
9370
9400
  content
9371
9401
  };
9372
9402
  } catch (error) {
9373
- throw new Error(`Failed to read .rulesyncignore file: ${formatError(error)}`, {
9403
+ throw new Error(`Failed to read .rulesync/.aiignore file: ${formatError(error)}`, {
9374
9404
  cause: error
9375
9405
  });
9376
9406
  }
9377
9407
  }
9378
9408
  async function putIgnoreFile({ content }) {
9379
- const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9409
+ const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
9380
9410
  const contentSizeBytes = Buffer.byteLength(content, "utf8");
9381
9411
  if (contentSizeBytes > maxIgnoreFileSizeBytes) {
9382
9412
  throw new Error(
@@ -9387,26 +9417,32 @@ async function putIgnoreFile({ content }) {
9387
9417
  await ensureDir(process.cwd());
9388
9418
  await writeFileContent(ignoreFilePath, content);
9389
9419
  return {
9390
- relativePathFromCwd: RULESYNC_IGNORE_RELATIVE_FILE_PATH,
9420
+ relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
9391
9421
  content
9392
9422
  };
9393
9423
  } catch (error) {
9394
- throw new Error(`Failed to write .rulesyncignore file: ${formatError(error)}`, {
9424
+ throw new Error(`Failed to write .rulesync/.aiignore file: ${formatError(error)}`, {
9395
9425
  cause: error
9396
9426
  });
9397
9427
  }
9398
9428
  }
9399
9429
  async function deleteIgnoreFile() {
9400
- const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9430
+ const aiignorePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
9431
+ const legacyIgnorePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9401
9432
  try {
9402
- await removeFile(ignoreFilePath);
9433
+ await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
9403
9434
  return {
9404
- relativePathFromCwd: RULESYNC_IGNORE_RELATIVE_FILE_PATH
9435
+ // Keep the historical return shape — point to the recommended file path
9436
+ // for backward compatibility.
9437
+ relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH
9405
9438
  };
9406
9439
  } catch (error) {
9407
- throw new Error(`Failed to delete .rulesyncignore file: ${formatError(error)}`, {
9408
- cause: error
9409
- });
9440
+ throw new Error(
9441
+ `Failed to delete .rulesyncignore and .rulesync/.aiignore files: ${formatError(error)}`,
9442
+ {
9443
+ cause: error
9444
+ }
9445
+ );
9410
9446
  }
9411
9447
  }
9412
9448
  var ignoreToolSchemas = {
@@ -9428,7 +9464,7 @@ var ignoreTools = {
9428
9464
  },
9429
9465
  putIgnoreFile: {
9430
9466
  name: "putIgnoreFile",
9431
- description: "Create or update the .rulesyncignore file (upsert operation). content parameter is required.",
9467
+ description: "Create or update the .rulesync/.aiignore file (upsert operation). content parameter is required.",
9432
9468
  parameters: ignoreToolSchemas.putIgnoreFile,
9433
9469
  execute: async (args) => {
9434
9470
  const result = await putIgnoreFile({ content: args.content });
@@ -9437,7 +9473,7 @@ var ignoreTools = {
9437
9473
  },
9438
9474
  deleteIgnoreFile: {
9439
9475
  name: "deleteIgnoreFile",
9440
- description: "Delete the .rulesyncignore file from the project root.",
9476
+ description: "Delete the .rulesyncignore and .rulesync/.aiignore files.",
9441
9477
  parameters: ignoreToolSchemas.deleteIgnoreFile,
9442
9478
  execute: async () => {
9443
9479
  const result = await deleteIgnoreFile();
@@ -9968,7 +10004,7 @@ async function mcpCommand({ version }) {
9968
10004
  }
9969
10005
 
9970
10006
  // src/cli/index.ts
9971
- var getVersion = () => "3.25.0";
10007
+ var getVersion = () => "3.27.0";
9972
10008
  var main = async () => {
9973
10009
  const program = new import_commander.Command();
9974
10010
  const version = getVersion();
package/dist/index.js CHANGED
@@ -476,6 +476,8 @@ var RULESYNC_RULES_RELATIVE_DIR_PATH = join2(RULESYNC_RELATIVE_DIR_PATH, "rules"
476
476
  var RULESYNC_COMMANDS_RELATIVE_DIR_PATH = join2(RULESYNC_RELATIVE_DIR_PATH, "commands");
477
477
  var RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = join2(RULESYNC_RELATIVE_DIR_PATH, "subagents");
478
478
  var RULESYNC_MCP_RELATIVE_FILE_PATH = join2(RULESYNC_RELATIVE_DIR_PATH, "mcp.json");
479
+ var RULESYNC_AIIGNORE_FILE_NAME = ".aiignore";
480
+ var RULESYNC_AIIGNORE_RELATIVE_FILE_PATH = join2(RULESYNC_RELATIVE_DIR_PATH, ".aiignore");
479
481
  var RULESYNC_IGNORE_RELATIVE_FILE_PATH = ".rulesyncignore";
480
482
  var RULESYNC_OVERVIEW_FILE_NAME = "overview.md";
481
483
  var RULESYNC_SKILLS_RELATIVE_DIR_PATH = join2(RULESYNC_RELATIVE_DIR_PATH, "skills");
@@ -1708,11 +1710,11 @@ var CommandsProcessor = class extends FeatureProcessor {
1708
1710
  const rulesyncCommandPaths = await findFilesByGlobs(
1709
1711
  join12(RulesyncCommand.getSettablePaths().relativeDirPath, "*.md")
1710
1712
  );
1711
- const rulesyncCommands = (await Promise.allSettled(
1713
+ const rulesyncCommands = await Promise.all(
1712
1714
  rulesyncCommandPaths.map(
1713
1715
  (path3) => RulesyncCommand.fromFile({ relativeFilePath: basename11(path3) })
1714
1716
  )
1715
- )).filter((result) => result.status === "fulfilled").map((result) => result.value);
1717
+ );
1716
1718
  logger.info(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
1717
1719
  return rulesyncCommands;
1718
1720
  }
@@ -1750,7 +1752,7 @@ var CommandsProcessor = class extends FeatureProcessor {
1750
1752
  const commandFilePaths = await findFilesByGlobs(
1751
1753
  join12(this.baseDir, relativeDirPath, `*.${extension}`)
1752
1754
  );
1753
- const toolCommands = (await Promise.allSettled(
1755
+ const toolCommands = await Promise.all(
1754
1756
  commandFilePaths.map((path3) => {
1755
1757
  switch (toolTarget) {
1756
1758
  case "agentsmd":
@@ -1796,7 +1798,7 @@ var CommandsProcessor = class extends FeatureProcessor {
1796
1798
  throw new Error(`Unsupported tool target: ${toolTarget}`);
1797
1799
  }
1798
1800
  })
1799
- )).filter((result) => result.status === "fulfilled").map((result) => result.value);
1801
+ );
1800
1802
  logger.info(`Successfully loaded ${toolCommands.length} ${relativeDirPath} commands`);
1801
1803
  return toolCommands;
1802
1804
  }
@@ -1915,18 +1917,48 @@ var RulesyncIgnore = class _RulesyncIgnore extends RulesyncFile {
1915
1917
  }
1916
1918
  static getSettablePaths() {
1917
1919
  return {
1918
- relativeDirPath: ".",
1919
- relativeFilePath: RULESYNC_IGNORE_RELATIVE_FILE_PATH
1920
+ recommended: {
1921
+ relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
1922
+ relativeFilePath: RULESYNC_AIIGNORE_FILE_NAME
1923
+ },
1924
+ legacy: {
1925
+ relativeDirPath: ".",
1926
+ relativeFilePath: RULESYNC_IGNORE_RELATIVE_FILE_PATH
1927
+ }
1920
1928
  };
1921
1929
  }
1922
1930
  static async fromFile() {
1923
1931
  const baseDir = process.cwd();
1924
- const filePath = join13(baseDir, this.getSettablePaths().relativeFilePath);
1925
- const fileContent = await readFileContent(filePath);
1932
+ const paths = this.getSettablePaths();
1933
+ const recommendedPath = join13(
1934
+ baseDir,
1935
+ paths.recommended.relativeDirPath,
1936
+ paths.recommended.relativeFilePath
1937
+ );
1938
+ const legacyPath = join13(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
1939
+ if (await fileExists(recommendedPath)) {
1940
+ const fileContent2 = await readFileContent(recommendedPath);
1941
+ return new _RulesyncIgnore({
1942
+ baseDir,
1943
+ relativeDirPath: paths.recommended.relativeDirPath,
1944
+ relativeFilePath: paths.recommended.relativeFilePath,
1945
+ fileContent: fileContent2
1946
+ });
1947
+ }
1948
+ if (await fileExists(legacyPath)) {
1949
+ const fileContent2 = await readFileContent(legacyPath);
1950
+ return new _RulesyncIgnore({
1951
+ baseDir,
1952
+ relativeDirPath: paths.legacy.relativeDirPath,
1953
+ relativeFilePath: paths.legacy.relativeFilePath,
1954
+ fileContent: fileContent2
1955
+ });
1956
+ }
1957
+ const fileContent = await readFileContent(recommendedPath);
1926
1958
  return new _RulesyncIgnore({
1927
1959
  baseDir,
1928
- relativeDirPath: this.getSettablePaths().relativeDirPath,
1929
- relativeFilePath: this.getSettablePaths().relativeFilePath,
1960
+ relativeDirPath: paths.recommended.relativeDirPath,
1961
+ relativeFilePath: paths.recommended.relativeFilePath,
1930
1962
  fileContent
1931
1963
  });
1932
1964
  }
@@ -1963,8 +1995,8 @@ var ToolIgnore = class extends ToolFile {
1963
1995
  toRulesyncIgnoreDefault() {
1964
1996
  return new RulesyncIgnore({
1965
1997
  baseDir: ".",
1966
- relativeDirPath: ".",
1967
- relativeFilePath: RULESYNC_IGNORE_RELATIVE_FILE_PATH,
1998
+ relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
1999
+ relativeFilePath: RULESYNC_AIIGNORE_FILE_NAME,
1968
2000
  fileContent: this.fileContent
1969
2001
  });
1970
2002
  }
@@ -2108,8 +2140,8 @@ var ClaudecodeIgnore = class _ClaudecodeIgnore extends ToolIgnore {
2108
2140
  const fileContent = rulesyncPatterns.join("\n");
2109
2141
  return new RulesyncIgnore({
2110
2142
  baseDir: this.baseDir,
2111
- relativeDirPath: RulesyncIgnore.getSettablePaths().relativeDirPath,
2112
- relativeFilePath: RulesyncIgnore.getSettablePaths().relativeFilePath,
2143
+ relativeDirPath: RulesyncIgnore.getSettablePaths().recommended.relativeDirPath,
2144
+ relativeFilePath: RulesyncIgnore.getSettablePaths().recommended.relativeFilePath,
2113
2145
  fileContent
2114
2146
  });
2115
2147
  }
@@ -2231,7 +2263,7 @@ var CursorIgnore = class _CursorIgnore extends ToolIgnore {
2231
2263
  return new RulesyncIgnore({
2232
2264
  baseDir: ".",
2233
2265
  relativeDirPath: ".",
2234
- relativeFilePath: RULESYNC_IGNORE_RELATIVE_FILE_PATH,
2266
+ relativeFilePath: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
2235
2267
  fileContent: this.fileContent
2236
2268
  });
2237
2269
  }
@@ -2638,7 +2670,7 @@ var IgnoreProcessor = class extends FeatureProcessor {
2638
2670
  (file) => file instanceof RulesyncIgnore
2639
2671
  );
2640
2672
  if (!rulesyncIgnore) {
2641
- throw new Error(`No ${RULESYNC_IGNORE_RELATIVE_FILE_PATH} found.`);
2673
+ throw new Error(`No ${RULESYNC_AIIGNORE_RELATIVE_FILE_PATH} found.`);
2642
2674
  }
2643
2675
  const toolIgnores = await Promise.all(
2644
2676
  [rulesyncIgnore].map(async (rulesyncIgnore2) => {
@@ -5007,17 +5039,11 @@ var SkillsProcessor = class extends DirFeatureProcessor {
5007
5039
  const rulesyncSkillsDirPath = join47(this.baseDir, paths.relativeDirPath);
5008
5040
  const dirPaths = await findFilesByGlobs(join47(rulesyncSkillsDirPath, "*"), { type: "dir" });
5009
5041
  const dirNames = dirPaths.map((path3) => basename13(path3));
5010
- const results = await Promise.allSettled(
5042
+ const rulesyncSkills = await Promise.all(
5011
5043
  dirNames.map(
5012
5044
  (dirName) => RulesyncSkill.fromDir({ baseDir: this.baseDir, dirName, global: this.global })
5013
5045
  )
5014
5046
  );
5015
- const rulesyncSkills = [];
5016
- for (const result of results) {
5017
- if (result.status === "fulfilled") {
5018
- rulesyncSkills.push(result.value);
5019
- }
5020
- }
5021
5047
  logger.info(`Successfully loaded ${rulesyncSkills.length} rulesync skills`);
5022
5048
  return rulesyncSkills;
5023
5049
  }
@@ -5054,7 +5080,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
5054
5080
  const skillsDirPath = join47(this.baseDir, paths.relativeDirPath);
5055
5081
  const dirPaths = await findFilesByGlobs(join47(skillsDirPath, "*"), { type: "dir" });
5056
5082
  const dirNames = dirPaths.map((path3) => basename13(path3));
5057
- const toolSkills = (await Promise.allSettled(
5083
+ const toolSkills = await Promise.all(
5058
5084
  dirNames.map(
5059
5085
  (dirName) => ClaudecodeSkill.fromDir({
5060
5086
  baseDir: this.baseDir,
@@ -5062,7 +5088,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
5062
5088
  global: this.global
5063
5089
  })
5064
5090
  )
5065
- )).filter((result) => result.status === "fulfilled").map((result) => result.value);
5091
+ );
5066
5092
  logger.info(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
5067
5093
  return toolSkills;
5068
5094
  }
@@ -5074,14 +5100,14 @@ var SkillsProcessor = class extends DirFeatureProcessor {
5074
5100
  const skillsDirPath = join47(this.baseDir, paths.relativeDirPath);
5075
5101
  const dirPaths = await findFilesByGlobs(join47(skillsDirPath, "*"), { type: "dir" });
5076
5102
  const dirNames = dirPaths.map((path3) => basename13(path3));
5077
- const toolSkills = (await Promise.allSettled(
5103
+ const toolSkills = await Promise.all(
5078
5104
  dirNames.map(
5079
5105
  (dirName) => SkillClass.fromDir({
5080
5106
  baseDir: this.baseDir,
5081
5107
  dirName
5082
5108
  })
5083
5109
  )
5084
- )).filter((result) => result.status === "fulfilled").map((result) => result.value);
5110
+ );
5085
5111
  logger.info(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
5086
5112
  return toolSkills;
5087
5113
  }
@@ -5879,7 +5905,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
5879
5905
  fromFile
5880
5906
  }) {
5881
5907
  const paths = await findFilesByGlobs(join57(this.baseDir, relativeDirPath, "*.md"));
5882
- const subagents = (await Promise.allSettled(paths.map((path3) => fromFile(basename16(path3))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
5908
+ const subagents = await Promise.all(paths.map((path3) => fromFile(basename16(path3))));
5883
5909
  logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
5884
5910
  return subagents;
5885
5911
  }
@@ -8725,6 +8751,7 @@ var gitignoreCommand = async () => {
8725
8751
  "**/.vscode/mcp.json",
8726
8752
  // Junie
8727
8753
  "**/.junie/guidelines.md",
8754
+ "**/.junie/mcp.json",
8728
8755
  // Kiro
8729
8756
  "**/.kiro/steering/",
8730
8757
  "**/.aiignore",
@@ -8959,7 +8986,7 @@ async function initCommand() {
8959
8986
  logger.success("rulesync initialized successfully!");
8960
8987
  logger.info("Next steps:");
8961
8988
  logger.info(
8962
- `1. Edit ${RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${RULESYNC_MCP_RELATIVE_FILE_PATH} and ${RULESYNC_IGNORE_RELATIVE_FILE_PATH}`
8989
+ `1. Edit ${RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${RULESYNC_MCP_RELATIVE_FILE_PATH} and ${RULESYNC_AIIGNORE_RELATIVE_FILE_PATH}`
8963
8990
  );
8964
8991
  logger.info("2. Run 'rulesync generate' to create configuration files");
8965
8992
  }
@@ -9112,7 +9139,7 @@ Attention, again, you are just the planner, so though you can read any files and
9112
9139
  await ensureDir(mcpPaths.recommended.relativeDirPath);
9113
9140
  await ensureDir(commandPaths.relativeDirPath);
9114
9141
  await ensureDir(subagentPaths.relativeDirPath);
9115
- await ensureDir(ignorePaths.relativeDirPath);
9142
+ await ensureDir(ignorePaths.recommended.relativeDirPath);
9116
9143
  const ruleFilepath = join79(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
9117
9144
  if (!await fileExists(ruleFilepath)) {
9118
9145
  await writeFileContent(ruleFilepath, sampleRuleFile.content);
@@ -9144,7 +9171,10 @@ Attention, again, you are just the planner, so though you can read any files and
9144
9171
  } else {
9145
9172
  logger.info(`Skipped ${subagentFilepath} (already exists)`);
9146
9173
  }
9147
- const ignoreFilepath = join79(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
9174
+ const ignoreFilepath = join79(
9175
+ ignorePaths.recommended.relativeDirPath,
9176
+ ignorePaths.recommended.relativeFilePath
9177
+ );
9148
9178
  if (!await fileExists(ignoreFilepath)) {
9149
9179
  await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
9150
9180
  logger.success(`Created ${ignoreFilepath}`);
@@ -9339,21 +9369,21 @@ import { join as join81 } from "path";
9339
9369
  import { z as z31 } from "zod/mini";
9340
9370
  var maxIgnoreFileSizeBytes = 100 * 1024;
9341
9371
  async function getIgnoreFile() {
9342
- const ignoreFilePath = join81(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9372
+ const ignoreFilePath = join81(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
9343
9373
  try {
9344
9374
  const content = await readFileContent(ignoreFilePath);
9345
9375
  return {
9346
- relativePathFromCwd: RULESYNC_IGNORE_RELATIVE_FILE_PATH,
9376
+ relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
9347
9377
  content
9348
9378
  };
9349
9379
  } catch (error) {
9350
- throw new Error(`Failed to read .rulesyncignore file: ${formatError(error)}`, {
9380
+ throw new Error(`Failed to read .rulesync/.aiignore file: ${formatError(error)}`, {
9351
9381
  cause: error
9352
9382
  });
9353
9383
  }
9354
9384
  }
9355
9385
  async function putIgnoreFile({ content }) {
9356
- const ignoreFilePath = join81(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9386
+ const ignoreFilePath = join81(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
9357
9387
  const contentSizeBytes = Buffer.byteLength(content, "utf8");
9358
9388
  if (contentSizeBytes > maxIgnoreFileSizeBytes) {
9359
9389
  throw new Error(
@@ -9364,26 +9394,32 @@ async function putIgnoreFile({ content }) {
9364
9394
  await ensureDir(process.cwd());
9365
9395
  await writeFileContent(ignoreFilePath, content);
9366
9396
  return {
9367
- relativePathFromCwd: RULESYNC_IGNORE_RELATIVE_FILE_PATH,
9397
+ relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
9368
9398
  content
9369
9399
  };
9370
9400
  } catch (error) {
9371
- throw new Error(`Failed to write .rulesyncignore file: ${formatError(error)}`, {
9401
+ throw new Error(`Failed to write .rulesync/.aiignore file: ${formatError(error)}`, {
9372
9402
  cause: error
9373
9403
  });
9374
9404
  }
9375
9405
  }
9376
9406
  async function deleteIgnoreFile() {
9377
- const ignoreFilePath = join81(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9407
+ const aiignorePath = join81(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
9408
+ const legacyIgnorePath = join81(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9378
9409
  try {
9379
- await removeFile(ignoreFilePath);
9410
+ await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
9380
9411
  return {
9381
- relativePathFromCwd: RULESYNC_IGNORE_RELATIVE_FILE_PATH
9412
+ // Keep the historical return shape — point to the recommended file path
9413
+ // for backward compatibility.
9414
+ relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH
9382
9415
  };
9383
9416
  } catch (error) {
9384
- throw new Error(`Failed to delete .rulesyncignore file: ${formatError(error)}`, {
9385
- cause: error
9386
- });
9417
+ throw new Error(
9418
+ `Failed to delete .rulesyncignore and .rulesync/.aiignore files: ${formatError(error)}`,
9419
+ {
9420
+ cause: error
9421
+ }
9422
+ );
9387
9423
  }
9388
9424
  }
9389
9425
  var ignoreToolSchemas = {
@@ -9405,7 +9441,7 @@ var ignoreTools = {
9405
9441
  },
9406
9442
  putIgnoreFile: {
9407
9443
  name: "putIgnoreFile",
9408
- description: "Create or update the .rulesyncignore file (upsert operation). content parameter is required.",
9444
+ description: "Create or update the .rulesync/.aiignore file (upsert operation). content parameter is required.",
9409
9445
  parameters: ignoreToolSchemas.putIgnoreFile,
9410
9446
  execute: async (args) => {
9411
9447
  const result = await putIgnoreFile({ content: args.content });
@@ -9414,7 +9450,7 @@ var ignoreTools = {
9414
9450
  },
9415
9451
  deleteIgnoreFile: {
9416
9452
  name: "deleteIgnoreFile",
9417
- description: "Delete the .rulesyncignore file from the project root.",
9453
+ description: "Delete the .rulesyncignore and .rulesync/.aiignore files.",
9418
9454
  parameters: ignoreToolSchemas.deleteIgnoreFile,
9419
9455
  execute: async () => {
9420
9456
  const result = await deleteIgnoreFile();
@@ -9945,7 +9981,7 @@ async function mcpCommand({ version }) {
9945
9981
  }
9946
9982
 
9947
9983
  // src/cli/index.ts
9948
- var getVersion = () => "3.25.0";
9984
+ var getVersion = () => "3.27.0";
9949
9985
  var main = async () => {
9950
9986
  const program = new Command();
9951
9987
  const version = getVersion();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulesync",
3
- "version": "3.25.0",
3
+ "version": "3.27.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",