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 +17 -3
- package/dist/index.cjs +82 -46
- package/dist/index.js +82 -46
- package/package.json +1 -1
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 =
|
|
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
|
-
)
|
|
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 =
|
|
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
|
-
)
|
|
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
|
-
|
|
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) => {
|
|
@@ -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
|
|
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 =
|
|
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
|
-
)
|
|
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 =
|
|
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
|
-
)
|
|
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 =
|
|
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 ${
|
|
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)(
|
|
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(),
|
|
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:
|
|
9399
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
|
|
9370
9400
|
content
|
|
9371
9401
|
};
|
|
9372
9402
|
} catch (error) {
|
|
9373
|
-
throw new Error(`Failed to read .
|
|
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(),
|
|
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:
|
|
9420
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
|
|
9391
9421
|
content
|
|
9392
9422
|
};
|
|
9393
9423
|
} catch (error) {
|
|
9394
|
-
throw new Error(`Failed to write .
|
|
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
|
|
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(
|
|
9433
|
+
await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
|
|
9403
9434
|
return {
|
|
9404
|
-
|
|
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(
|
|
9408
|
-
|
|
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 .
|
|
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
|
|
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.
|
|
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 =
|
|
1713
|
+
const rulesyncCommands = await Promise.all(
|
|
1712
1714
|
rulesyncCommandPaths.map(
|
|
1713
1715
|
(path3) => RulesyncCommand.fromFile({ relativeFilePath: basename11(path3) })
|
|
1714
1716
|
)
|
|
1715
|
-
)
|
|
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 =
|
|
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
|
-
)
|
|
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
|
-
|
|
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) => {
|
|
@@ -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
|
|
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 =
|
|
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
|
-
)
|
|
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 =
|
|
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
|
-
)
|
|
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 =
|
|
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 ${
|
|
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(
|
|
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(),
|
|
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:
|
|
9376
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
|
|
9347
9377
|
content
|
|
9348
9378
|
};
|
|
9349
9379
|
} catch (error) {
|
|
9350
|
-
throw new Error(`Failed to read .
|
|
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(),
|
|
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:
|
|
9397
|
+
relativePathFromCwd: RULESYNC_AIIGNORE_RELATIVE_FILE_PATH,
|
|
9368
9398
|
content
|
|
9369
9399
|
};
|
|
9370
9400
|
} catch (error) {
|
|
9371
|
-
throw new Error(`Failed to write .
|
|
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
|
|
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(
|
|
9410
|
+
await Promise.all([removeFile(aiignorePath), removeFile(legacyIgnorePath)]);
|
|
9380
9411
|
return {
|
|
9381
|
-
|
|
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(
|
|
9385
|
-
|
|
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 .
|
|
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
|
|
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.
|
|
9984
|
+
var getVersion = () => "3.27.0";
|
|
9949
9985
|
var main = async () => {
|
|
9950
9986
|
const program = new Command();
|
|
9951
9987
|
const version = getVersion();
|