rulesync 3.26.0 → 3.27.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 +17 -2
- package/dist/index.cjs +75 -36
- package/dist/index.js +75 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
[](https://deepwiki.com/dyoshikawa/rulesync)
|
|
11
11
|
[](https://github.com/hesreallyhim/awesome-claude-code)
|
|
12
12
|
[](https://github.com/Piebald-AI/awesome-gemini-cli)
|
|
13
|
+
<a href="https://flatt.tech/oss/gmo/trampoline" target="_blank"><img src="https://flatt.tech/assets/images/badges/gmo-oss.svg" height="24px"/></a>
|
|
13
14
|
|
|
14
15
|
A Node.js CLI tool that automatically generates configuration files for various AI development tools from unified AI rule files. Features selective generation, comprehensive import/export capabilities, and supports major AI development tools with rules, commands, MCP, ignore files, subagents and skills.
|
|
15
16
|
|
|
@@ -142,7 +143,7 @@ Rulesync supports both **generation** and **import** for All of the major AI cod
|
|
|
142
143
|
| Gemini CLI | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ 🌏 | 🎮 | 🎮 |
|
|
143
144
|
| GitHub Copilot | ✅ | | ✅ | ✅ | 🎮 | 🎮 |
|
|
144
145
|
| Cursor | ✅ | ✅ | ✅ | ✅ 🌏 | 🎮 | 🎮 |
|
|
145
|
-
| OpenCode | ✅ | |
|
|
146
|
+
| OpenCode | ✅ | | ✅ | | | |
|
|
146
147
|
| Cline | ✅ | ✅ | ✅ | | | |
|
|
147
148
|
| Roo Code | ✅ | ✅ | ✅ | ✅ | 🎮 | |
|
|
148
149
|
| Qwen Code | ✅ | ✅ | | | | |
|
|
@@ -390,7 +391,21 @@ Example:
|
|
|
390
391
|
}
|
|
391
392
|
```
|
|
392
393
|
|
|
393
|
-
### `.rulesyncignore`
|
|
394
|
+
### `.rulesync/.aiignore` or `.rulesyncignore`
|
|
395
|
+
|
|
396
|
+
Rulesync supports a single ignore list that can live in either location below:
|
|
397
|
+
|
|
398
|
+
- `.rulesync/.aiignore` (recommended)
|
|
399
|
+
- `.rulesyncignore` (project root)
|
|
400
|
+
|
|
401
|
+
Rules and behavior:
|
|
402
|
+
|
|
403
|
+
- You may use either location.
|
|
404
|
+
- When both exist, Rulesync prefers `.rulesync/.aiignore` (recommended) over `.rulesyncignore` (legacy) when reading.
|
|
405
|
+
- If neither file exists yet, Rulesync defaults to creating `.rulesync/.aiignore`.
|
|
406
|
+
|
|
407
|
+
Notes:
|
|
408
|
+
- Running `rulesync init` will create `.rulesync/.aiignore` if no ignore file is present.
|
|
394
409
|
|
|
395
410
|
Example:
|
|
396
411
|
|
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");
|
|
@@ -1938,18 +1940,48 @@ var RulesyncIgnore = class _RulesyncIgnore extends RulesyncFile {
|
|
|
1938
1940
|
}
|
|
1939
1941
|
static getSettablePaths() {
|
|
1940
1942
|
return {
|
|
1941
|
-
|
|
1942
|
-
|
|
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
|
|
1948
|
-
const
|
|
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:
|
|
1952
|
-
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:
|
|
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:
|
|
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 ${
|
|
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) => {
|
|
@@ -4551,7 +4583,8 @@ var DirFeatureProcessor = class {
|
|
|
4551
4583
|
const mainFile = aiDir.getMainFile();
|
|
4552
4584
|
if (mainFile) {
|
|
4553
4585
|
const mainFilePath = (0, import_node_path44.join)(dirPath, mainFile.name);
|
|
4554
|
-
const
|
|
4586
|
+
const content = stringifyFrontmatter(mainFile.body, mainFile.frontmatter);
|
|
4587
|
+
const contentWithNewline = addTrailingNewline(content);
|
|
4555
4588
|
await writeFileContent(mainFilePath, contentWithNewline);
|
|
4556
4589
|
}
|
|
4557
4590
|
const otherFiles = aiDir.getOtherFiles();
|
|
@@ -8698,7 +8731,6 @@ var gitignoreCommand = async () => {
|
|
|
8698
8731
|
// AGENTS.md
|
|
8699
8732
|
"**/AGENTS.md",
|
|
8700
8733
|
"**/.agents/",
|
|
8701
|
-
"**/.agents/skills/",
|
|
8702
8734
|
// Amazon Q
|
|
8703
8735
|
"**/.amazonq/",
|
|
8704
8736
|
// Augment
|
|
@@ -8724,9 +8756,6 @@ var gitignoreCommand = async () => {
|
|
|
8724
8756
|
// Cursor
|
|
8725
8757
|
"**/.cursor/",
|
|
8726
8758
|
"**/.cursorignore",
|
|
8727
|
-
"**/.cursor/mcp.json",
|
|
8728
|
-
"**/.cursor/subagents/",
|
|
8729
|
-
"**/.cursor/skills/",
|
|
8730
8759
|
// Gemini
|
|
8731
8760
|
"**/GEMINI.md",
|
|
8732
8761
|
"**/.gemini/memories/",
|
|
@@ -8762,7 +8791,8 @@ var gitignoreCommand = async () => {
|
|
|
8762
8791
|
"**/.warp/",
|
|
8763
8792
|
"**/WARP.md",
|
|
8764
8793
|
// Others
|
|
8765
|
-
"**/modular-mcp.json"
|
|
8794
|
+
"**/modular-mcp.json",
|
|
8795
|
+
"!.rulesync/.aiignore"
|
|
8766
8796
|
];
|
|
8767
8797
|
let gitignoreContent = "";
|
|
8768
8798
|
if (await fileExists(gitignorePath)) {
|
|
@@ -8977,7 +9007,7 @@ async function initCommand() {
|
|
|
8977
9007
|
logger.success("rulesync initialized successfully!");
|
|
8978
9008
|
logger.info("Next steps:");
|
|
8979
9009
|
logger.info(
|
|
8980
|
-
`1. Edit ${RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${RULESYNC_MCP_RELATIVE_FILE_PATH} and ${
|
|
9010
|
+
`1. Edit ${RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${RULESYNC_MCP_RELATIVE_FILE_PATH} and ${RULESYNC_AIIGNORE_RELATIVE_FILE_PATH}`
|
|
8981
9011
|
);
|
|
8982
9012
|
logger.info("2. Run 'rulesync generate' to create configuration files");
|
|
8983
9013
|
}
|
|
@@ -9130,7 +9160,7 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
9130
9160
|
await ensureDir(mcpPaths.recommended.relativeDirPath);
|
|
9131
9161
|
await ensureDir(commandPaths.relativeDirPath);
|
|
9132
9162
|
await ensureDir(subagentPaths.relativeDirPath);
|
|
9133
|
-
await ensureDir(ignorePaths.relativeDirPath);
|
|
9163
|
+
await ensureDir(ignorePaths.recommended.relativeDirPath);
|
|
9134
9164
|
const ruleFilepath = (0, import_node_path81.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
|
|
9135
9165
|
if (!await fileExists(ruleFilepath)) {
|
|
9136
9166
|
await writeFileContent(ruleFilepath, sampleRuleFile.content);
|
|
@@ -9162,7 +9192,10 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
9162
9192
|
} else {
|
|
9163
9193
|
logger.info(`Skipped ${subagentFilepath} (already exists)`);
|
|
9164
9194
|
}
|
|
9165
|
-
const ignoreFilepath = (0, import_node_path81.join)(
|
|
9195
|
+
const ignoreFilepath = (0, import_node_path81.join)(
|
|
9196
|
+
ignorePaths.recommended.relativeDirPath,
|
|
9197
|
+
ignorePaths.recommended.relativeFilePath
|
|
9198
|
+
);
|
|
9166
9199
|
if (!await fileExists(ignoreFilepath)) {
|
|
9167
9200
|
await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
|
|
9168
9201
|
logger.success(`Created ${ignoreFilepath}`);
|
|
@@ -9357,21 +9390,21 @@ var import_node_path83 = require("path");
|
|
|
9357
9390
|
var import_mini31 = require("zod/mini");
|
|
9358
9391
|
var maxIgnoreFileSizeBytes = 100 * 1024;
|
|
9359
9392
|
async function getIgnoreFile() {
|
|
9360
|
-
const ignoreFilePath = (0, import_node_path83.join)(process.cwd(),
|
|
9393
|
+
const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
9361
9394
|
try {
|
|
9362
9395
|
const content = await readFileContent(ignoreFilePath);
|
|
9363
9396
|
return {
|
|
9364
|
-
relativePathFromCwd:
|
|
9397
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
|
|
9365
9398
|
content
|
|
9366
9399
|
};
|
|
9367
9400
|
} catch (error) {
|
|
9368
|
-
throw new Error(`Failed to read .
|
|
9401
|
+
throw new Error(`Failed to read .rulesync/.aiignore file: ${formatError(error)}`, {
|
|
9369
9402
|
cause: error
|
|
9370
9403
|
});
|
|
9371
9404
|
}
|
|
9372
9405
|
}
|
|
9373
9406
|
async function putIgnoreFile({ content }) {
|
|
9374
|
-
const ignoreFilePath = (0, import_node_path83.join)(process.cwd(),
|
|
9407
|
+
const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
9375
9408
|
const contentSizeBytes = Buffer.byteLength(content, "utf8");
|
|
9376
9409
|
if (contentSizeBytes > maxIgnoreFileSizeBytes) {
|
|
9377
9410
|
throw new Error(
|
|
@@ -9382,26 +9415,32 @@ async function putIgnoreFile({ content }) {
|
|
|
9382
9415
|
await ensureDir(process.cwd());
|
|
9383
9416
|
await writeFileContent(ignoreFilePath, content);
|
|
9384
9417
|
return {
|
|
9385
|
-
relativePathFromCwd:
|
|
9418
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
|
|
9386
9419
|
content
|
|
9387
9420
|
};
|
|
9388
9421
|
} catch (error) {
|
|
9389
|
-
throw new Error(`Failed to write .
|
|
9422
|
+
throw new Error(`Failed to write .rulesync/.aiignore file: ${formatError(error)}`, {
|
|
9390
9423
|
cause: error
|
|
9391
9424
|
});
|
|
9392
9425
|
}
|
|
9393
9426
|
}
|
|
9394
9427
|
async function deleteIgnoreFile() {
|
|
9395
|
-
const
|
|
9428
|
+
const aiignorePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
9429
|
+
const legacyIgnorePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
|
|
9396
9430
|
try {
|
|
9397
|
-
await removeFile(
|
|
9431
|
+
await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
|
|
9398
9432
|
return {
|
|
9399
|
-
|
|
9433
|
+
// Keep the historical return shape — point to the recommended file path
|
|
9434
|
+
// for backward compatibility.
|
|
9435
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH
|
|
9400
9436
|
};
|
|
9401
9437
|
} catch (error) {
|
|
9402
|
-
throw new Error(
|
|
9403
|
-
|
|
9404
|
-
|
|
9438
|
+
throw new Error(
|
|
9439
|
+
`Failed to delete .rulesyncignore and .rulesync/.aiignore files: ${formatError(error)}`,
|
|
9440
|
+
{
|
|
9441
|
+
cause: error
|
|
9442
|
+
}
|
|
9443
|
+
);
|
|
9405
9444
|
}
|
|
9406
9445
|
}
|
|
9407
9446
|
var ignoreToolSchemas = {
|
|
@@ -9423,7 +9462,7 @@ var ignoreTools = {
|
|
|
9423
9462
|
},
|
|
9424
9463
|
putIgnoreFile: {
|
|
9425
9464
|
name: "putIgnoreFile",
|
|
9426
|
-
description: "Create or update the .
|
|
9465
|
+
description: "Create or update the .rulesync/.aiignore file (upsert operation). content parameter is required.",
|
|
9427
9466
|
parameters: ignoreToolSchemas.putIgnoreFile,
|
|
9428
9467
|
execute: async (args) => {
|
|
9429
9468
|
const result = await putIgnoreFile({ content: args.content });
|
|
@@ -9432,7 +9471,7 @@ var ignoreTools = {
|
|
|
9432
9471
|
},
|
|
9433
9472
|
deleteIgnoreFile: {
|
|
9434
9473
|
name: "deleteIgnoreFile",
|
|
9435
|
-
description: "Delete the .rulesyncignore
|
|
9474
|
+
description: "Delete the .rulesyncignore and .rulesync/.aiignore files.",
|
|
9436
9475
|
parameters: ignoreToolSchemas.deleteIgnoreFile,
|
|
9437
9476
|
execute: async () => {
|
|
9438
9477
|
const result = await deleteIgnoreFile();
|
|
@@ -9963,7 +10002,7 @@ async function mcpCommand({ version }) {
|
|
|
9963
10002
|
}
|
|
9964
10003
|
|
|
9965
10004
|
// src/cli/index.ts
|
|
9966
|
-
var getVersion = () => "3.
|
|
10005
|
+
var getVersion = () => "3.27.1";
|
|
9967
10006
|
var main = async () => {
|
|
9968
10007
|
const program = new import_commander.Command();
|
|
9969
10008
|
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");
|
|
@@ -1915,18 +1917,48 @@ var RulesyncIgnore = class _RulesyncIgnore extends RulesyncFile {
|
|
|
1915
1917
|
}
|
|
1916
1918
|
static getSettablePaths() {
|
|
1917
1919
|
return {
|
|
1918
|
-
|
|
1919
|
-
|
|
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
|
|
1925
|
-
const
|
|
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:
|
|
1929
|
-
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:
|
|
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:
|
|
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 ${
|
|
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) => {
|
|
@@ -4528,7 +4560,8 @@ var DirFeatureProcessor = class {
|
|
|
4528
4560
|
const mainFile = aiDir.getMainFile();
|
|
4529
4561
|
if (mainFile) {
|
|
4530
4562
|
const mainFilePath = join42(dirPath, mainFile.name);
|
|
4531
|
-
const
|
|
4563
|
+
const content = stringifyFrontmatter(mainFile.body, mainFile.frontmatter);
|
|
4564
|
+
const contentWithNewline = addTrailingNewline(content);
|
|
4532
4565
|
await writeFileContent(mainFilePath, contentWithNewline);
|
|
4533
4566
|
}
|
|
4534
4567
|
const otherFiles = aiDir.getOtherFiles();
|
|
@@ -8675,7 +8708,6 @@ var gitignoreCommand = async () => {
|
|
|
8675
8708
|
// AGENTS.md
|
|
8676
8709
|
"**/AGENTS.md",
|
|
8677
8710
|
"**/.agents/",
|
|
8678
|
-
"**/.agents/skills/",
|
|
8679
8711
|
// Amazon Q
|
|
8680
8712
|
"**/.amazonq/",
|
|
8681
8713
|
// Augment
|
|
@@ -8701,9 +8733,6 @@ var gitignoreCommand = async () => {
|
|
|
8701
8733
|
// Cursor
|
|
8702
8734
|
"**/.cursor/",
|
|
8703
8735
|
"**/.cursorignore",
|
|
8704
|
-
"**/.cursor/mcp.json",
|
|
8705
|
-
"**/.cursor/subagents/",
|
|
8706
|
-
"**/.cursor/skills/",
|
|
8707
8736
|
// Gemini
|
|
8708
8737
|
"**/GEMINI.md",
|
|
8709
8738
|
"**/.gemini/memories/",
|
|
@@ -8739,7 +8768,8 @@ var gitignoreCommand = async () => {
|
|
|
8739
8768
|
"**/.warp/",
|
|
8740
8769
|
"**/WARP.md",
|
|
8741
8770
|
// Others
|
|
8742
|
-
"**/modular-mcp.json"
|
|
8771
|
+
"**/modular-mcp.json",
|
|
8772
|
+
"!.rulesync/.aiignore"
|
|
8743
8773
|
];
|
|
8744
8774
|
let gitignoreContent = "";
|
|
8745
8775
|
if (await fileExists(gitignorePath)) {
|
|
@@ -8954,7 +8984,7 @@ async function initCommand() {
|
|
|
8954
8984
|
logger.success("rulesync initialized successfully!");
|
|
8955
8985
|
logger.info("Next steps:");
|
|
8956
8986
|
logger.info(
|
|
8957
|
-
`1. Edit ${RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${RULESYNC_MCP_RELATIVE_FILE_PATH} and ${
|
|
8987
|
+
`1. Edit ${RULESYNC_RELATIVE_DIR_PATH}/**/*.md, ${RULESYNC_MCP_RELATIVE_FILE_PATH} and ${RULESYNC_AIIGNORE_RELATIVE_FILE_PATH}`
|
|
8958
8988
|
);
|
|
8959
8989
|
logger.info("2. Run 'rulesync generate' to create configuration files");
|
|
8960
8990
|
}
|
|
@@ -9107,7 +9137,7 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
9107
9137
|
await ensureDir(mcpPaths.recommended.relativeDirPath);
|
|
9108
9138
|
await ensureDir(commandPaths.relativeDirPath);
|
|
9109
9139
|
await ensureDir(subagentPaths.relativeDirPath);
|
|
9110
|
-
await ensureDir(ignorePaths.relativeDirPath);
|
|
9140
|
+
await ensureDir(ignorePaths.recommended.relativeDirPath);
|
|
9111
9141
|
const ruleFilepath = join79(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
|
|
9112
9142
|
if (!await fileExists(ruleFilepath)) {
|
|
9113
9143
|
await writeFileContent(ruleFilepath, sampleRuleFile.content);
|
|
@@ -9139,7 +9169,10 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
9139
9169
|
} else {
|
|
9140
9170
|
logger.info(`Skipped ${subagentFilepath} (already exists)`);
|
|
9141
9171
|
}
|
|
9142
|
-
const ignoreFilepath = join79(
|
|
9172
|
+
const ignoreFilepath = join79(
|
|
9173
|
+
ignorePaths.recommended.relativeDirPath,
|
|
9174
|
+
ignorePaths.recommended.relativeFilePath
|
|
9175
|
+
);
|
|
9143
9176
|
if (!await fileExists(ignoreFilepath)) {
|
|
9144
9177
|
await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
|
|
9145
9178
|
logger.success(`Created ${ignoreFilepath}`);
|
|
@@ -9334,21 +9367,21 @@ import { join as join81 } from "path";
|
|
|
9334
9367
|
import { z as z31 } from "zod/mini";
|
|
9335
9368
|
var maxIgnoreFileSizeBytes = 100 * 1024;
|
|
9336
9369
|
async function getIgnoreFile() {
|
|
9337
|
-
const ignoreFilePath = join81(process.cwd(),
|
|
9370
|
+
const ignoreFilePath = join81(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
9338
9371
|
try {
|
|
9339
9372
|
const content = await readFileContent(ignoreFilePath);
|
|
9340
9373
|
return {
|
|
9341
|
-
relativePathFromCwd:
|
|
9374
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
|
|
9342
9375
|
content
|
|
9343
9376
|
};
|
|
9344
9377
|
} catch (error) {
|
|
9345
|
-
throw new Error(`Failed to read .
|
|
9378
|
+
throw new Error(`Failed to read .rulesync/.aiignore file: ${formatError(error)}`, {
|
|
9346
9379
|
cause: error
|
|
9347
9380
|
});
|
|
9348
9381
|
}
|
|
9349
9382
|
}
|
|
9350
9383
|
async function putIgnoreFile({ content }) {
|
|
9351
|
-
const ignoreFilePath = join81(process.cwd(),
|
|
9384
|
+
const ignoreFilePath = join81(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
9352
9385
|
const contentSizeBytes = Buffer.byteLength(content, "utf8");
|
|
9353
9386
|
if (contentSizeBytes > maxIgnoreFileSizeBytes) {
|
|
9354
9387
|
throw new Error(
|
|
@@ -9359,26 +9392,32 @@ async function putIgnoreFile({ content }) {
|
|
|
9359
9392
|
await ensureDir(process.cwd());
|
|
9360
9393
|
await writeFileContent(ignoreFilePath, content);
|
|
9361
9394
|
return {
|
|
9362
|
-
relativePathFromCwd:
|
|
9395
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
|
|
9363
9396
|
content
|
|
9364
9397
|
};
|
|
9365
9398
|
} catch (error) {
|
|
9366
|
-
throw new Error(`Failed to write .
|
|
9399
|
+
throw new Error(`Failed to write .rulesync/.aiignore file: ${formatError(error)}`, {
|
|
9367
9400
|
cause: error
|
|
9368
9401
|
});
|
|
9369
9402
|
}
|
|
9370
9403
|
}
|
|
9371
9404
|
async function deleteIgnoreFile() {
|
|
9372
|
-
const
|
|
9405
|
+
const aiignorePath = join81(process.cwd(), RULESYNC_AIIGNORE_RELATIVE_FILE_PATH);
|
|
9406
|
+
const legacyIgnorePath = join81(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
|
|
9373
9407
|
try {
|
|
9374
|
-
await removeFile(
|
|
9408
|
+
await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
|
|
9375
9409
|
return {
|
|
9376
|
-
|
|
9410
|
+
// Keep the historical return shape — point to the recommended file path
|
|
9411
|
+
// for backward compatibility.
|
|
9412
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH
|
|
9377
9413
|
};
|
|
9378
9414
|
} catch (error) {
|
|
9379
|
-
throw new Error(
|
|
9380
|
-
|
|
9381
|
-
|
|
9415
|
+
throw new Error(
|
|
9416
|
+
`Failed to delete .rulesyncignore and .rulesync/.aiignore files: ${formatError(error)}`,
|
|
9417
|
+
{
|
|
9418
|
+
cause: error
|
|
9419
|
+
}
|
|
9420
|
+
);
|
|
9382
9421
|
}
|
|
9383
9422
|
}
|
|
9384
9423
|
var ignoreToolSchemas = {
|
|
@@ -9400,7 +9439,7 @@ var ignoreTools = {
|
|
|
9400
9439
|
},
|
|
9401
9440
|
putIgnoreFile: {
|
|
9402
9441
|
name: "putIgnoreFile",
|
|
9403
|
-
description: "Create or update the .
|
|
9442
|
+
description: "Create or update the .rulesync/.aiignore file (upsert operation). content parameter is required.",
|
|
9404
9443
|
parameters: ignoreToolSchemas.putIgnoreFile,
|
|
9405
9444
|
execute: async (args) => {
|
|
9406
9445
|
const result = await putIgnoreFile({ content: args.content });
|
|
@@ -9409,7 +9448,7 @@ var ignoreTools = {
|
|
|
9409
9448
|
},
|
|
9410
9449
|
deleteIgnoreFile: {
|
|
9411
9450
|
name: "deleteIgnoreFile",
|
|
9412
|
-
description: "Delete the .rulesyncignore
|
|
9451
|
+
description: "Delete the .rulesyncignore and .rulesync/.aiignore files.",
|
|
9413
9452
|
parameters: ignoreToolSchemas.deleteIgnoreFile,
|
|
9414
9453
|
execute: async () => {
|
|
9415
9454
|
const result = await deleteIgnoreFile();
|
|
@@ -9940,7 +9979,7 @@ async function mcpCommand({ version }) {
|
|
|
9940
9979
|
}
|
|
9941
9980
|
|
|
9942
9981
|
// src/cli/index.ts
|
|
9943
|
-
var getVersion = () => "3.
|
|
9982
|
+
var getVersion = () => "3.27.1";
|
|
9944
9983
|
var main = async () => {
|
|
9945
9984
|
const program = new Command();
|
|
9946
9985
|
const version = getVersion();
|