rulesync 3.10.0 → 3.11.1

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
@@ -240,7 +240,7 @@ Based on the user's instruction, create a plan while analyzing the related files
240
240
  Attention, again, you are just the planner, so though you can read any files and run any commands for analysis, please don't write any code.
241
241
  ```
242
242
 
243
- ### `.rulesync/.mcp.json`
243
+ ### `.rulesync/mcp.json`
244
244
 
245
245
  Example:
246
246
 
package/dist/index.cjs CHANGED
@@ -2722,21 +2722,54 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2722
2722
  }
2723
2723
  static getSettablePaths() {
2724
2724
  return {
2725
- relativeDirPath: ".rulesync",
2726
- relativeFilePath: ".mcp.json"
2725
+ recommended: {
2726
+ relativeDirPath: ".rulesync",
2727
+ relativeFilePath: "mcp.json"
2728
+ },
2729
+ legacy: {
2730
+ relativeDirPath: ".rulesync",
2731
+ relativeFilePath: ".mcp.json"
2732
+ }
2727
2733
  };
2728
2734
  }
2729
2735
  validate() {
2730
2736
  return { success: true, error: null };
2731
2737
  }
2732
2738
  static async fromFile({ validate = true }) {
2733
- const fileContent = await readFileContent(
2734
- (0, import_node_path25.join)(this.getSettablePaths().relativeDirPath, this.getSettablePaths().relativeFilePath)
2739
+ const paths = this.getSettablePaths();
2740
+ const recommendedPath = (0, import_node_path25.join)(
2741
+ paths.recommended.relativeDirPath,
2742
+ paths.recommended.relativeFilePath
2735
2743
  );
2744
+ const legacyPath = (0, import_node_path25.join)(paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
2745
+ if (await fileExists(recommendedPath)) {
2746
+ const fileContent2 = await readFileContent(recommendedPath);
2747
+ return new _RulesyncMcp({
2748
+ baseDir: ".",
2749
+ relativeDirPath: paths.recommended.relativeDirPath,
2750
+ relativeFilePath: paths.recommended.relativeFilePath,
2751
+ fileContent: fileContent2,
2752
+ validate
2753
+ });
2754
+ }
2755
+ if (await fileExists(legacyPath)) {
2756
+ logger.warn(
2757
+ `\u26A0\uFE0F Using deprecated path "${legacyPath}". Please migrate to "${recommendedPath}"`
2758
+ );
2759
+ const fileContent2 = await readFileContent(legacyPath);
2760
+ return new _RulesyncMcp({
2761
+ baseDir: ".",
2762
+ relativeDirPath: paths.legacy.relativeDirPath,
2763
+ relativeFilePath: paths.legacy.relativeFilePath,
2764
+ fileContent: fileContent2,
2765
+ validate
2766
+ });
2767
+ }
2768
+ const fileContent = await readFileContent(recommendedPath);
2736
2769
  return new _RulesyncMcp({
2737
2770
  baseDir: ".",
2738
- relativeDirPath: this.getSettablePaths().relativeDirPath,
2739
- relativeFilePath: this.getSettablePaths().relativeFilePath,
2771
+ relativeDirPath: paths.recommended.relativeDirPath,
2772
+ relativeFilePath: paths.recommended.relativeFilePath,
2740
2773
  fileContent,
2741
2774
  validate
2742
2775
  });
@@ -3471,7 +3504,7 @@ var McpProcessor = class extends FeatureProcessor {
3471
3504
  (file) => file instanceof RulesyncMcp
3472
3505
  );
3473
3506
  if (!rulesyncMcp) {
3474
- throw new Error(`No .rulesync/.mcp.json found.`);
3507
+ throw new Error(`No .rulesync/mcp.json found.`);
3475
3508
  }
3476
3509
  const toolMcps = await Promise.all(
3477
3510
  [rulesyncMcp].map(async (rulesyncMcp2) => {
@@ -4415,12 +4448,17 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4415
4448
  relativeFilePath,
4416
4449
  validate = true
4417
4450
  }) {
4418
- const filePath = (0, import_node_path38.join)(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
4419
- const fileContent = await readFileContent(filePath);
4451
+ const legacyPath = (0, import_node_path38.join)(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
4452
+ const recommendedPath = (0, import_node_path38.join)(
4453
+ this.getSettablePaths().recommended.relativeDirPath,
4454
+ relativeFilePath
4455
+ );
4456
+ logger.warn(`\u26A0\uFE0F Using deprecated path "${legacyPath}". Please migrate to "${recommendedPath}"`);
4457
+ const fileContent = await readFileContent(legacyPath);
4420
4458
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4421
4459
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
4422
4460
  if (!result.success) {
4423
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
4461
+ throw new Error(`Invalid frontmatter in ${legacyPath}: ${result.error.message}`);
4424
4462
  }
4425
4463
  const validatedFrontmatter = {
4426
4464
  root: result.data.root ?? false,
@@ -4430,7 +4468,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4430
4468
  agentsmd: result.data.agentsmd,
4431
4469
  cursor: result.data.cursor
4432
4470
  };
4433
- const filename = (0, import_node_path38.basename)(filePath);
4471
+ const filename = (0, import_node_path38.basename)(legacyPath);
4434
4472
  return new _RulesyncRule({
4435
4473
  baseDir: ".",
4436
4474
  relativeDirPath: this.getSettablePaths().recommended.relativeDirPath,
@@ -7262,7 +7300,7 @@ async function initCommand() {
7262
7300
  await createConfigFile();
7263
7301
  logger.success("rulesync initialized successfully!");
7264
7302
  logger.info("Next steps:");
7265
- logger.info(`1. Edit .rulesync/**/*.md, .rulesync/.mcp.json and .rulesyncignore`);
7303
+ logger.info(`1. Edit .rulesync/**/*.md, .rulesync/mcp.json and .rulesyncignore`);
7266
7304
  logger.info("2. Run 'rulesync generate' to create configuration files");
7267
7305
  }
7268
7306
  async function createConfigFile() {
@@ -7326,7 +7364,7 @@ globs: ["**/*"]
7326
7364
  `
7327
7365
  };
7328
7366
  const sampleMcpFile = {
7329
- filename: ".mcp.json",
7367
+ filename: "mcp.json",
7330
7368
  content: `{
7331
7369
  "mcpServers": {
7332
7370
  "serena": {
@@ -7410,7 +7448,7 @@ Attention, again, you are just the planner, so though you can read any files and
7410
7448
  const subagentPaths = RulesyncSubagent.getSettablePaths();
7411
7449
  const ignorePaths = RulesyncIgnore.getSettablePaths();
7412
7450
  await ensureDir(rulePaths.recommended.relativeDirPath);
7413
- await ensureDir(mcpPaths.relativeDirPath);
7451
+ await ensureDir(mcpPaths.recommended.relativeDirPath);
7414
7452
  await ensureDir(commandPaths.relativeDirPath);
7415
7453
  await ensureDir(subagentPaths.relativeDirPath);
7416
7454
  await ensureDir(ignorePaths.relativeDirPath);
@@ -7421,7 +7459,10 @@ Attention, again, you are just the planner, so though you can read any files and
7421
7459
  } else {
7422
7460
  logger.info(`Skipped ${ruleFilepath} (already exists)`);
7423
7461
  }
7424
- const mcpFilepath = (0, import_node_path59.join)(mcpPaths.relativeDirPath, mcpPaths.relativeFilePath);
7462
+ const mcpFilepath = (0, import_node_path59.join)(
7463
+ mcpPaths.recommended.relativeDirPath,
7464
+ mcpPaths.recommended.relativeFilePath
7465
+ );
7425
7466
  if (!await fileExists(mcpFilepath)) {
7426
7467
  await writeFileContent(mcpFilepath, sampleMcpFile.content);
7427
7468
  logger.success(`Created ${mcpFilepath}`);
@@ -7452,7 +7493,7 @@ Attention, again, you are just the planner, so though you can read any files and
7452
7493
  }
7453
7494
 
7454
7495
  // src/cli/index.ts
7455
- var getVersion = () => "3.10.0";
7496
+ var getVersion = () => "3.11.1";
7456
7497
  var main = async () => {
7457
7498
  const program = new import_commander.Command();
7458
7499
  const version = getVersion();
package/dist/index.js CHANGED
@@ -2699,21 +2699,54 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2699
2699
  }
2700
2700
  static getSettablePaths() {
2701
2701
  return {
2702
- relativeDirPath: ".rulesync",
2703
- relativeFilePath: ".mcp.json"
2702
+ recommended: {
2703
+ relativeDirPath: ".rulesync",
2704
+ relativeFilePath: "mcp.json"
2705
+ },
2706
+ legacy: {
2707
+ relativeDirPath: ".rulesync",
2708
+ relativeFilePath: ".mcp.json"
2709
+ }
2704
2710
  };
2705
2711
  }
2706
2712
  validate() {
2707
2713
  return { success: true, error: null };
2708
2714
  }
2709
2715
  static async fromFile({ validate = true }) {
2710
- const fileContent = await readFileContent(
2711
- join24(this.getSettablePaths().relativeDirPath, this.getSettablePaths().relativeFilePath)
2716
+ const paths = this.getSettablePaths();
2717
+ const recommendedPath = join24(
2718
+ paths.recommended.relativeDirPath,
2719
+ paths.recommended.relativeFilePath
2712
2720
  );
2721
+ const legacyPath = join24(paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
2722
+ if (await fileExists(recommendedPath)) {
2723
+ const fileContent2 = await readFileContent(recommendedPath);
2724
+ return new _RulesyncMcp({
2725
+ baseDir: ".",
2726
+ relativeDirPath: paths.recommended.relativeDirPath,
2727
+ relativeFilePath: paths.recommended.relativeFilePath,
2728
+ fileContent: fileContent2,
2729
+ validate
2730
+ });
2731
+ }
2732
+ if (await fileExists(legacyPath)) {
2733
+ logger.warn(
2734
+ `\u26A0\uFE0F Using deprecated path "${legacyPath}". Please migrate to "${recommendedPath}"`
2735
+ );
2736
+ const fileContent2 = await readFileContent(legacyPath);
2737
+ return new _RulesyncMcp({
2738
+ baseDir: ".",
2739
+ relativeDirPath: paths.legacy.relativeDirPath,
2740
+ relativeFilePath: paths.legacy.relativeFilePath,
2741
+ fileContent: fileContent2,
2742
+ validate
2743
+ });
2744
+ }
2745
+ const fileContent = await readFileContent(recommendedPath);
2713
2746
  return new _RulesyncMcp({
2714
2747
  baseDir: ".",
2715
- relativeDirPath: this.getSettablePaths().relativeDirPath,
2716
- relativeFilePath: this.getSettablePaths().relativeFilePath,
2748
+ relativeDirPath: paths.recommended.relativeDirPath,
2749
+ relativeFilePath: paths.recommended.relativeFilePath,
2717
2750
  fileContent,
2718
2751
  validate
2719
2752
  });
@@ -3448,7 +3481,7 @@ var McpProcessor = class extends FeatureProcessor {
3448
3481
  (file) => file instanceof RulesyncMcp
3449
3482
  );
3450
3483
  if (!rulesyncMcp) {
3451
- throw new Error(`No .rulesync/.mcp.json found.`);
3484
+ throw new Error(`No .rulesync/mcp.json found.`);
3452
3485
  }
3453
3486
  const toolMcps = await Promise.all(
3454
3487
  [rulesyncMcp].map(async (rulesyncMcp2) => {
@@ -4392,12 +4425,17 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4392
4425
  relativeFilePath,
4393
4426
  validate = true
4394
4427
  }) {
4395
- const filePath = join37(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
4396
- const fileContent = await readFileContent(filePath);
4428
+ const legacyPath = join37(this.getSettablePaths().legacy.relativeDirPath, relativeFilePath);
4429
+ const recommendedPath = join37(
4430
+ this.getSettablePaths().recommended.relativeDirPath,
4431
+ relativeFilePath
4432
+ );
4433
+ logger.warn(`\u26A0\uFE0F Using deprecated path "${legacyPath}". Please migrate to "${recommendedPath}"`);
4434
+ const fileContent = await readFileContent(legacyPath);
4397
4435
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4398
4436
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
4399
4437
  if (!result.success) {
4400
- throw new Error(`Invalid frontmatter in ${filePath}: ${result.error.message}`);
4438
+ throw new Error(`Invalid frontmatter in ${legacyPath}: ${result.error.message}`);
4401
4439
  }
4402
4440
  const validatedFrontmatter = {
4403
4441
  root: result.data.root ?? false,
@@ -4407,7 +4445,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4407
4445
  agentsmd: result.data.agentsmd,
4408
4446
  cursor: result.data.cursor
4409
4447
  };
4410
- const filename = basename15(filePath);
4448
+ const filename = basename15(legacyPath);
4411
4449
  return new _RulesyncRule({
4412
4450
  baseDir: ".",
4413
4451
  relativeDirPath: this.getSettablePaths().recommended.relativeDirPath,
@@ -7239,7 +7277,7 @@ async function initCommand() {
7239
7277
  await createConfigFile();
7240
7278
  logger.success("rulesync initialized successfully!");
7241
7279
  logger.info("Next steps:");
7242
- logger.info(`1. Edit .rulesync/**/*.md, .rulesync/.mcp.json and .rulesyncignore`);
7280
+ logger.info(`1. Edit .rulesync/**/*.md, .rulesync/mcp.json and .rulesyncignore`);
7243
7281
  logger.info("2. Run 'rulesync generate' to create configuration files");
7244
7282
  }
7245
7283
  async function createConfigFile() {
@@ -7303,7 +7341,7 @@ globs: ["**/*"]
7303
7341
  `
7304
7342
  };
7305
7343
  const sampleMcpFile = {
7306
- filename: ".mcp.json",
7344
+ filename: "mcp.json",
7307
7345
  content: `{
7308
7346
  "mcpServers": {
7309
7347
  "serena": {
@@ -7387,7 +7425,7 @@ Attention, again, you are just the planner, so though you can read any files and
7387
7425
  const subagentPaths = RulesyncSubagent.getSettablePaths();
7388
7426
  const ignorePaths = RulesyncIgnore.getSettablePaths();
7389
7427
  await ensureDir(rulePaths.recommended.relativeDirPath);
7390
- await ensureDir(mcpPaths.relativeDirPath);
7428
+ await ensureDir(mcpPaths.recommended.relativeDirPath);
7391
7429
  await ensureDir(commandPaths.relativeDirPath);
7392
7430
  await ensureDir(subagentPaths.relativeDirPath);
7393
7431
  await ensureDir(ignorePaths.relativeDirPath);
@@ -7398,7 +7436,10 @@ Attention, again, you are just the planner, so though you can read any files and
7398
7436
  } else {
7399
7437
  logger.info(`Skipped ${ruleFilepath} (already exists)`);
7400
7438
  }
7401
- const mcpFilepath = join58(mcpPaths.relativeDirPath, mcpPaths.relativeFilePath);
7439
+ const mcpFilepath = join58(
7440
+ mcpPaths.recommended.relativeDirPath,
7441
+ mcpPaths.recommended.relativeFilePath
7442
+ );
7402
7443
  if (!await fileExists(mcpFilepath)) {
7403
7444
  await writeFileContent(mcpFilepath, sampleMcpFile.content);
7404
7445
  logger.success(`Created ${mcpFilepath}`);
@@ -7429,7 +7470,7 @@ Attention, again, you are just the planner, so though you can read any files and
7429
7470
  }
7430
7471
 
7431
7472
  // src/cli/index.ts
7432
- var getVersion = () => "3.10.0";
7473
+ var getVersion = () => "3.11.1";
7433
7474
  var main = async () => {
7434
7475
  const program = new Command();
7435
7476
  const version = getVersion();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulesync",
3
- "version": "3.10.0",
3
+ "version": "3.11.1",
4
4
  "description": "Unified AI rules management CLI tool that generates configuration files for various AI development tools",
5
5
  "keywords": [
6
6
  "ai",
@@ -49,15 +49,15 @@
49
49
  "zod": "4.1.12"
50
50
  },
51
51
  "devDependencies": {
52
- "@anthropic-ai/claude-agent-sdk": "0.1.22",
52
+ "@anthropic-ai/claude-agent-sdk": "0.1.25",
53
53
  "@biomejs/biome": "2.2.6",
54
54
  "@eslint/js": "9.38.0",
55
55
  "@secretlint/secretlint-rule-preset-recommend": "11.2.5",
56
56
  "@tsconfig/node24": "24.0.1",
57
57
  "@types/js-yaml": "4.0.9",
58
58
  "@types/micromatch": "4.0.9",
59
- "@types/node": "24.8.1",
60
- "@typescript/native-preview": "7.0.0-dev.20251019.1",
59
+ "@types/node": "24.9.1",
60
+ "@typescript/native-preview": "7.0.0-dev.20251021.1",
61
61
  "@vitest/coverage-v8": "3.2.4",
62
62
  "cspell": "9.2.1",
63
63
  "eslint": "9.38.0",
@@ -66,8 +66,8 @@
66
66
  "eslint-plugin-oxlint": "1.23.0",
67
67
  "eslint-plugin-strict-dependencies": "1.3.27",
68
68
  "eslint-plugin-zod-import": "0.3.0",
69
- "knip": "5.66.1",
70
- "lint-staged": "16.2.4",
69
+ "knip": "5.66.2",
70
+ "lint-staged": "16.2.5",
71
71
  "o3-search-mcp": "0.0.9",
72
72
  "oxlint": "1.23.0",
73
73
  "secretlint": "11.2.5",
@@ -76,7 +76,7 @@
76
76
  "tsup": "8.5.0",
77
77
  "tsx": "4.20.6",
78
78
  "typescript": "5.9.3",
79
- "typescript-eslint": "8.46.1",
79
+ "typescript-eslint": "8.46.2",
80
80
  "vitest": "3.2.4"
81
81
  },
82
82
  "engines": {