rulesync 3.28.2 → 3.29.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 +10 -0
- package/dist/index.cjs +261 -23
- package/dist/index.js +262 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -687,6 +687,16 @@ The Rulesync MCP server provides the following tools:
|
|
|
687
687
|
|
|
688
688
|
</details>
|
|
689
689
|
|
|
690
|
+
<details>
|
|
691
|
+
<summary>Skills Management</summary>
|
|
692
|
+
|
|
693
|
+
- `listSkills` - List all skill directories
|
|
694
|
+
- `getSkill` - Get a specific skill (SKILL.md and other files)
|
|
695
|
+
- `putSkill` - Create or update a skill directory
|
|
696
|
+
- `deleteSkill` - Delete a skill directory
|
|
697
|
+
|
|
698
|
+
</details>
|
|
699
|
+
|
|
690
700
|
<details>
|
|
691
701
|
<summary>Ignore Files Management</summary>
|
|
692
702
|
|
package/dist/index.cjs
CHANGED
|
@@ -10052,13 +10052,247 @@ var ruleTools = {
|
|
|
10052
10052
|
}
|
|
10053
10053
|
};
|
|
10054
10054
|
|
|
10055
|
-
// src/mcp/
|
|
10055
|
+
// src/mcp/skills.ts
|
|
10056
10056
|
var import_node_path88 = require("path");
|
|
10057
10057
|
var import_mini35 = require("zod/mini");
|
|
10058
|
+
var maxSkillSizeBytes = 1024 * 1024;
|
|
10059
|
+
var maxSkillsCount = 1e3;
|
|
10060
|
+
function aiDirFileToMcpSkillFile(file) {
|
|
10061
|
+
return {
|
|
10062
|
+
name: file.relativeFilePathToDirPath,
|
|
10063
|
+
body: file.fileBuffer.toString("utf-8")
|
|
10064
|
+
};
|
|
10065
|
+
}
|
|
10066
|
+
function mcpSkillFileToAiDirFile(file) {
|
|
10067
|
+
return {
|
|
10068
|
+
relativeFilePathToDirPath: file.name,
|
|
10069
|
+
fileBuffer: Buffer.from(file.body, "utf-8")
|
|
10070
|
+
};
|
|
10071
|
+
}
|
|
10072
|
+
function extractDirName(relativeDirPathFromCwd) {
|
|
10073
|
+
const dirName = (0, import_node_path88.basename)(relativeDirPathFromCwd);
|
|
10074
|
+
if (!dirName) {
|
|
10075
|
+
throw new Error(`Invalid path: ${relativeDirPathFromCwd}`);
|
|
10076
|
+
}
|
|
10077
|
+
return dirName;
|
|
10078
|
+
}
|
|
10079
|
+
async function listSkills() {
|
|
10080
|
+
const skillsDir = (0, import_node_path88.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
|
|
10081
|
+
try {
|
|
10082
|
+
const skillDirPaths = await findFilesByGlobs((0, import_node_path88.join)(skillsDir, "*"), { type: "dir" });
|
|
10083
|
+
const skills = await Promise.all(
|
|
10084
|
+
skillDirPaths.map(async (dirPath) => {
|
|
10085
|
+
const dirName = (0, import_node_path88.basename)(dirPath);
|
|
10086
|
+
if (!dirName) return null;
|
|
10087
|
+
try {
|
|
10088
|
+
const skill = await RulesyncSkill.fromDir({
|
|
10089
|
+
dirName
|
|
10090
|
+
});
|
|
10091
|
+
const frontmatter = skill.getFrontmatter();
|
|
10092
|
+
return {
|
|
10093
|
+
relativeDirPathFromCwd: (0, import_node_path88.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
10094
|
+
frontmatter
|
|
10095
|
+
};
|
|
10096
|
+
} catch (error) {
|
|
10097
|
+
logger.error(`Failed to read skill directory ${dirName}: ${formatError(error)}`);
|
|
10098
|
+
return null;
|
|
10099
|
+
}
|
|
10100
|
+
})
|
|
10101
|
+
);
|
|
10102
|
+
return skills.filter((skill) => skill !== null);
|
|
10103
|
+
} catch (error) {
|
|
10104
|
+
logger.error(`Failed to read skills directory: ${formatError(error)}`);
|
|
10105
|
+
return [];
|
|
10106
|
+
}
|
|
10107
|
+
}
|
|
10108
|
+
async function getSkill({ relativeDirPathFromCwd }) {
|
|
10109
|
+
checkPathTraversal({
|
|
10110
|
+
relativePath: relativeDirPathFromCwd,
|
|
10111
|
+
intendedRootDir: process.cwd()
|
|
10112
|
+
});
|
|
10113
|
+
const dirName = extractDirName(relativeDirPathFromCwd);
|
|
10114
|
+
try {
|
|
10115
|
+
const skill = await RulesyncSkill.fromDir({
|
|
10116
|
+
dirName
|
|
10117
|
+
});
|
|
10118
|
+
return {
|
|
10119
|
+
relativeDirPathFromCwd: (0, import_node_path88.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
10120
|
+
frontmatter: skill.getFrontmatter(),
|
|
10121
|
+
body: skill.getBody(),
|
|
10122
|
+
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
10123
|
+
};
|
|
10124
|
+
} catch (error) {
|
|
10125
|
+
throw new Error(
|
|
10126
|
+
`Failed to read skill directory ${relativeDirPathFromCwd}: ${formatError(error)}`,
|
|
10127
|
+
{
|
|
10128
|
+
cause: error
|
|
10129
|
+
}
|
|
10130
|
+
);
|
|
10131
|
+
}
|
|
10132
|
+
}
|
|
10133
|
+
async function putSkill({
|
|
10134
|
+
relativeDirPathFromCwd,
|
|
10135
|
+
frontmatter,
|
|
10136
|
+
body,
|
|
10137
|
+
otherFiles = []
|
|
10138
|
+
}) {
|
|
10139
|
+
checkPathTraversal({
|
|
10140
|
+
relativePath: relativeDirPathFromCwd,
|
|
10141
|
+
intendedRootDir: process.cwd()
|
|
10142
|
+
});
|
|
10143
|
+
const dirName = extractDirName(relativeDirPathFromCwd);
|
|
10144
|
+
const estimatedSize = JSON.stringify(frontmatter).length + body.length + otherFiles.reduce((acc, file) => acc + file.name.length + file.body.length, 0);
|
|
10145
|
+
if (estimatedSize > maxSkillSizeBytes) {
|
|
10146
|
+
throw new Error(
|
|
10147
|
+
`Skill size ${estimatedSize} bytes exceeds maximum ${maxSkillSizeBytes} bytes (1MB)`
|
|
10148
|
+
);
|
|
10149
|
+
}
|
|
10150
|
+
try {
|
|
10151
|
+
const existingSkills = await listSkills();
|
|
10152
|
+
const isUpdate = existingSkills.some(
|
|
10153
|
+
(skill2) => skill2.relativeDirPathFromCwd === (0, import_node_path88.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
10154
|
+
);
|
|
10155
|
+
if (!isUpdate && existingSkills.length >= maxSkillsCount) {
|
|
10156
|
+
throw new Error(`Maximum number of skills (${maxSkillsCount}) reached`);
|
|
10157
|
+
}
|
|
10158
|
+
const aiDirFiles = otherFiles.map(mcpSkillFileToAiDirFile);
|
|
10159
|
+
const skill = new RulesyncSkill({
|
|
10160
|
+
baseDir: process.cwd(),
|
|
10161
|
+
relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
10162
|
+
dirName,
|
|
10163
|
+
frontmatter,
|
|
10164
|
+
body,
|
|
10165
|
+
otherFiles: aiDirFiles,
|
|
10166
|
+
validate: true
|
|
10167
|
+
});
|
|
10168
|
+
const skillDirPath = (0, import_node_path88.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
10169
|
+
await ensureDir(skillDirPath);
|
|
10170
|
+
const skillFilePath = (0, import_node_path88.join)(skillDirPath, SKILL_FILE_NAME);
|
|
10171
|
+
const skillFileContent = stringifyFrontmatter(body, frontmatter);
|
|
10172
|
+
await writeFileContent(skillFilePath, skillFileContent);
|
|
10173
|
+
for (const file of otherFiles) {
|
|
10174
|
+
checkPathTraversal({
|
|
10175
|
+
relativePath: file.name,
|
|
10176
|
+
intendedRootDir: skillDirPath
|
|
10177
|
+
});
|
|
10178
|
+
const filePath = (0, import_node_path88.join)(skillDirPath, file.name);
|
|
10179
|
+
const fileDir = (0, import_node_path88.join)(skillDirPath, (0, import_node_path88.dirname)(file.name));
|
|
10180
|
+
if (fileDir !== skillDirPath) {
|
|
10181
|
+
await ensureDir(fileDir);
|
|
10182
|
+
}
|
|
10183
|
+
await writeFileContent(filePath, file.body);
|
|
10184
|
+
}
|
|
10185
|
+
return {
|
|
10186
|
+
relativeDirPathFromCwd: (0, import_node_path88.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
10187
|
+
frontmatter: skill.getFrontmatter(),
|
|
10188
|
+
body: skill.getBody(),
|
|
10189
|
+
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
10190
|
+
};
|
|
10191
|
+
} catch (error) {
|
|
10192
|
+
throw new Error(
|
|
10193
|
+
`Failed to write skill directory ${relativeDirPathFromCwd}: ${formatError(error)}`,
|
|
10194
|
+
{
|
|
10195
|
+
cause: error
|
|
10196
|
+
}
|
|
10197
|
+
);
|
|
10198
|
+
}
|
|
10199
|
+
}
|
|
10200
|
+
async function deleteSkill({
|
|
10201
|
+
relativeDirPathFromCwd
|
|
10202
|
+
}) {
|
|
10203
|
+
checkPathTraversal({
|
|
10204
|
+
relativePath: relativeDirPathFromCwd,
|
|
10205
|
+
intendedRootDir: process.cwd()
|
|
10206
|
+
});
|
|
10207
|
+
const dirName = extractDirName(relativeDirPathFromCwd);
|
|
10208
|
+
const skillDirPath = (0, import_node_path88.join)(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
10209
|
+
try {
|
|
10210
|
+
if (await directoryExists(skillDirPath)) {
|
|
10211
|
+
await removeDirectory(skillDirPath);
|
|
10212
|
+
}
|
|
10213
|
+
return {
|
|
10214
|
+
relativeDirPathFromCwd: (0, import_node_path88.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
10215
|
+
};
|
|
10216
|
+
} catch (error) {
|
|
10217
|
+
throw new Error(
|
|
10218
|
+
`Failed to delete skill directory ${relativeDirPathFromCwd}: ${formatError(error)}`,
|
|
10219
|
+
{
|
|
10220
|
+
cause: error
|
|
10221
|
+
}
|
|
10222
|
+
);
|
|
10223
|
+
}
|
|
10224
|
+
}
|
|
10225
|
+
var McpSkillFileSchema = import_mini35.z.object({
|
|
10226
|
+
name: import_mini35.z.string(),
|
|
10227
|
+
body: import_mini35.z.string()
|
|
10228
|
+
});
|
|
10229
|
+
var skillToolSchemas = {
|
|
10230
|
+
listSkills: import_mini35.z.object({}),
|
|
10231
|
+
getSkill: import_mini35.z.object({
|
|
10232
|
+
relativeDirPathFromCwd: import_mini35.z.string()
|
|
10233
|
+
}),
|
|
10234
|
+
putSkill: import_mini35.z.object({
|
|
10235
|
+
relativeDirPathFromCwd: import_mini35.z.string(),
|
|
10236
|
+
frontmatter: RulesyncSkillFrontmatterSchema,
|
|
10237
|
+
body: import_mini35.z.string(),
|
|
10238
|
+
otherFiles: import_mini35.z.optional(import_mini35.z.array(McpSkillFileSchema))
|
|
10239
|
+
}),
|
|
10240
|
+
deleteSkill: import_mini35.z.object({
|
|
10241
|
+
relativeDirPathFromCwd: import_mini35.z.string()
|
|
10242
|
+
})
|
|
10243
|
+
};
|
|
10244
|
+
var skillTools = {
|
|
10245
|
+
listSkills: {
|
|
10246
|
+
name: "listSkills",
|
|
10247
|
+
description: `List all skills from ${(0, import_node_path88.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
|
|
10248
|
+
parameters: skillToolSchemas.listSkills,
|
|
10249
|
+
execute: async () => {
|
|
10250
|
+
const skills = await listSkills();
|
|
10251
|
+
const output = { skills };
|
|
10252
|
+
return JSON.stringify(output, null, 2);
|
|
10253
|
+
}
|
|
10254
|
+
},
|
|
10255
|
+
getSkill: {
|
|
10256
|
+
name: "getSkill",
|
|
10257
|
+
description: "Get detailed information about a specific skill including SKILL.md content and other files. relativeDirPathFromCwd parameter is required.",
|
|
10258
|
+
parameters: skillToolSchemas.getSkill,
|
|
10259
|
+
execute: async (args) => {
|
|
10260
|
+
const result = await getSkill({ relativeDirPathFromCwd: args.relativeDirPathFromCwd });
|
|
10261
|
+
return JSON.stringify(result, null, 2);
|
|
10262
|
+
}
|
|
10263
|
+
},
|
|
10264
|
+
putSkill: {
|
|
10265
|
+
name: "putSkill",
|
|
10266
|
+
description: "Create or update a skill (upsert operation). relativeDirPathFromCwd, frontmatter, and body parameters are required. otherFiles is optional.",
|
|
10267
|
+
parameters: skillToolSchemas.putSkill,
|
|
10268
|
+
execute: async (args) => {
|
|
10269
|
+
const result = await putSkill({
|
|
10270
|
+
relativeDirPathFromCwd: args.relativeDirPathFromCwd,
|
|
10271
|
+
frontmatter: args.frontmatter,
|
|
10272
|
+
body: args.body,
|
|
10273
|
+
otherFiles: args.otherFiles
|
|
10274
|
+
});
|
|
10275
|
+
return JSON.stringify(result, null, 2);
|
|
10276
|
+
}
|
|
10277
|
+
},
|
|
10278
|
+
deleteSkill: {
|
|
10279
|
+
name: "deleteSkill",
|
|
10280
|
+
description: "Delete a skill directory and all its contents. relativeDirPathFromCwd parameter is required.",
|
|
10281
|
+
parameters: skillToolSchemas.deleteSkill,
|
|
10282
|
+
execute: async (args) => {
|
|
10283
|
+
const result = await deleteSkill({ relativeDirPathFromCwd: args.relativeDirPathFromCwd });
|
|
10284
|
+
return JSON.stringify(result, null, 2);
|
|
10285
|
+
}
|
|
10286
|
+
}
|
|
10287
|
+
};
|
|
10288
|
+
|
|
10289
|
+
// src/mcp/subagents.ts
|
|
10290
|
+
var import_node_path89 = require("path");
|
|
10291
|
+
var import_mini36 = require("zod/mini");
|
|
10058
10292
|
var maxSubagentSizeBytes = 1024 * 1024;
|
|
10059
10293
|
var maxSubagentsCount = 1e3;
|
|
10060
10294
|
async function listSubagents() {
|
|
10061
|
-
const subagentsDir = (0,
|
|
10295
|
+
const subagentsDir = (0, import_node_path89.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
10062
10296
|
try {
|
|
10063
10297
|
const files = await listDirectoryFiles(subagentsDir);
|
|
10064
10298
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -10071,7 +10305,7 @@ async function listSubagents() {
|
|
|
10071
10305
|
});
|
|
10072
10306
|
const frontmatter = subagent.getFrontmatter();
|
|
10073
10307
|
return {
|
|
10074
|
-
relativePathFromCwd: (0,
|
|
10308
|
+
relativePathFromCwd: (0, import_node_path89.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
|
|
10075
10309
|
frontmatter
|
|
10076
10310
|
};
|
|
10077
10311
|
} catch (error) {
|
|
@@ -10093,14 +10327,14 @@ async function getSubagent({ relativePathFromCwd }) {
|
|
|
10093
10327
|
relativePath: relativePathFromCwd,
|
|
10094
10328
|
intendedRootDir: process.cwd()
|
|
10095
10329
|
});
|
|
10096
|
-
const filename = (0,
|
|
10330
|
+
const filename = (0, import_node_path89.basename)(relativePathFromCwd);
|
|
10097
10331
|
try {
|
|
10098
10332
|
const subagent = await RulesyncSubagent.fromFile({
|
|
10099
10333
|
relativeFilePath: filename,
|
|
10100
10334
|
validate: true
|
|
10101
10335
|
});
|
|
10102
10336
|
return {
|
|
10103
|
-
relativePathFromCwd: (0,
|
|
10337
|
+
relativePathFromCwd: (0, import_node_path89.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
10104
10338
|
frontmatter: subagent.getFrontmatter(),
|
|
10105
10339
|
body: subagent.getBody()
|
|
10106
10340
|
};
|
|
@@ -10119,7 +10353,7 @@ async function putSubagent({
|
|
|
10119
10353
|
relativePath: relativePathFromCwd,
|
|
10120
10354
|
intendedRootDir: process.cwd()
|
|
10121
10355
|
});
|
|
10122
|
-
const filename = (0,
|
|
10356
|
+
const filename = (0, import_node_path89.basename)(relativePathFromCwd);
|
|
10123
10357
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
10124
10358
|
if (estimatedSize > maxSubagentSizeBytes) {
|
|
10125
10359
|
throw new Error(
|
|
@@ -10129,7 +10363,7 @@ async function putSubagent({
|
|
|
10129
10363
|
try {
|
|
10130
10364
|
const existingSubagents = await listSubagents();
|
|
10131
10365
|
const isUpdate = existingSubagents.some(
|
|
10132
|
-
(subagent2) => subagent2.relativePathFromCwd === (0,
|
|
10366
|
+
(subagent2) => subagent2.relativePathFromCwd === (0, import_node_path89.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
10133
10367
|
);
|
|
10134
10368
|
if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
|
|
10135
10369
|
throw new Error(`Maximum number of subagents (${maxSubagentsCount}) reached`);
|
|
@@ -10142,11 +10376,11 @@ async function putSubagent({
|
|
|
10142
10376
|
body,
|
|
10143
10377
|
validate: true
|
|
10144
10378
|
});
|
|
10145
|
-
const subagentsDir = (0,
|
|
10379
|
+
const subagentsDir = (0, import_node_path89.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
10146
10380
|
await ensureDir(subagentsDir);
|
|
10147
10381
|
await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
|
|
10148
10382
|
return {
|
|
10149
|
-
relativePathFromCwd: (0,
|
|
10383
|
+
relativePathFromCwd: (0, import_node_path89.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
10150
10384
|
frontmatter: subagent.getFrontmatter(),
|
|
10151
10385
|
body: subagent.getBody()
|
|
10152
10386
|
};
|
|
@@ -10161,12 +10395,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
10161
10395
|
relativePath: relativePathFromCwd,
|
|
10162
10396
|
intendedRootDir: process.cwd()
|
|
10163
10397
|
});
|
|
10164
|
-
const filename = (0,
|
|
10165
|
-
const fullPath = (0,
|
|
10398
|
+
const filename = (0, import_node_path89.basename)(relativePathFromCwd);
|
|
10399
|
+
const fullPath = (0, import_node_path89.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
|
|
10166
10400
|
try {
|
|
10167
10401
|
await removeFile(fullPath);
|
|
10168
10402
|
return {
|
|
10169
|
-
relativePathFromCwd: (0,
|
|
10403
|
+
relativePathFromCwd: (0, import_node_path89.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
10170
10404
|
};
|
|
10171
10405
|
} catch (error) {
|
|
10172
10406
|
throw new Error(
|
|
@@ -10178,23 +10412,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
10178
10412
|
}
|
|
10179
10413
|
}
|
|
10180
10414
|
var subagentToolSchemas = {
|
|
10181
|
-
listSubagents:
|
|
10182
|
-
getSubagent:
|
|
10183
|
-
relativePathFromCwd:
|
|
10415
|
+
listSubagents: import_mini36.z.object({}),
|
|
10416
|
+
getSubagent: import_mini36.z.object({
|
|
10417
|
+
relativePathFromCwd: import_mini36.z.string()
|
|
10184
10418
|
}),
|
|
10185
|
-
putSubagent:
|
|
10186
|
-
relativePathFromCwd:
|
|
10419
|
+
putSubagent: import_mini36.z.object({
|
|
10420
|
+
relativePathFromCwd: import_mini36.z.string(),
|
|
10187
10421
|
frontmatter: RulesyncSubagentFrontmatterSchema,
|
|
10188
|
-
body:
|
|
10422
|
+
body: import_mini36.z.string()
|
|
10189
10423
|
}),
|
|
10190
|
-
deleteSubagent:
|
|
10191
|
-
relativePathFromCwd:
|
|
10424
|
+
deleteSubagent: import_mini36.z.object({
|
|
10425
|
+
relativePathFromCwd: import_mini36.z.string()
|
|
10192
10426
|
})
|
|
10193
10427
|
};
|
|
10194
10428
|
var subagentTools = {
|
|
10195
10429
|
listSubagents: {
|
|
10196
10430
|
name: "listSubagents",
|
|
10197
|
-
description: `List all subagents from ${(0,
|
|
10431
|
+
description: `List all subagents from ${(0, import_node_path89.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
10198
10432
|
parameters: subagentToolSchemas.listSubagents,
|
|
10199
10433
|
execute: async () => {
|
|
10200
10434
|
const subagents = await listSubagents();
|
|
@@ -10241,7 +10475,7 @@ async function mcpCommand({ version }) {
|
|
|
10241
10475
|
name: "Rulesync MCP Server",
|
|
10242
10476
|
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
10243
10477
|
version,
|
|
10244
|
-
instructions: "This server handles Rulesync files including rules, commands, MCP, ignore files, and
|
|
10478
|
+
instructions: "This server handles Rulesync files including rules, commands, MCP, ignore files, subagents and skills for any AI agents. It should be used when you need those files."
|
|
10245
10479
|
});
|
|
10246
10480
|
server.addTool(ruleTools.listRules);
|
|
10247
10481
|
server.addTool(ruleTools.getRule);
|
|
@@ -10255,6 +10489,10 @@ async function mcpCommand({ version }) {
|
|
|
10255
10489
|
server.addTool(subagentTools.getSubagent);
|
|
10256
10490
|
server.addTool(subagentTools.putSubagent);
|
|
10257
10491
|
server.addTool(subagentTools.deleteSubagent);
|
|
10492
|
+
server.addTool(skillTools.listSkills);
|
|
10493
|
+
server.addTool(skillTools.getSkill);
|
|
10494
|
+
server.addTool(skillTools.putSkill);
|
|
10495
|
+
server.addTool(skillTools.deleteSkill);
|
|
10258
10496
|
server.addTool(ignoreTools.getIgnoreFile);
|
|
10259
10497
|
server.addTool(ignoreTools.putIgnoreFile);
|
|
10260
10498
|
server.addTool(ignoreTools.deleteIgnoreFile);
|
|
@@ -10268,7 +10506,7 @@ async function mcpCommand({ version }) {
|
|
|
10268
10506
|
}
|
|
10269
10507
|
|
|
10270
10508
|
// src/cli/index.ts
|
|
10271
|
-
var getVersion = () => "3.
|
|
10509
|
+
var getVersion = () => "3.29.0";
|
|
10272
10510
|
var main = async () => {
|
|
10273
10511
|
const program = new import_commander.Command();
|
|
10274
10512
|
const version = getVersion();
|
package/dist/index.js
CHANGED
|
@@ -10029,13 +10029,247 @@ var ruleTools = {
|
|
|
10029
10029
|
}
|
|
10030
10030
|
};
|
|
10031
10031
|
|
|
10032
|
-
// src/mcp/
|
|
10033
|
-
import { basename as basename23, join as join86 } from "path";
|
|
10032
|
+
// src/mcp/skills.ts
|
|
10033
|
+
import { basename as basename23, dirname as dirname2, join as join86 } from "path";
|
|
10034
10034
|
import { z as z35 } from "zod/mini";
|
|
10035
|
+
var maxSkillSizeBytes = 1024 * 1024;
|
|
10036
|
+
var maxSkillsCount = 1e3;
|
|
10037
|
+
function aiDirFileToMcpSkillFile(file) {
|
|
10038
|
+
return {
|
|
10039
|
+
name: file.relativeFilePathToDirPath,
|
|
10040
|
+
body: file.fileBuffer.toString("utf-8")
|
|
10041
|
+
};
|
|
10042
|
+
}
|
|
10043
|
+
function mcpSkillFileToAiDirFile(file) {
|
|
10044
|
+
return {
|
|
10045
|
+
relativeFilePathToDirPath: file.name,
|
|
10046
|
+
fileBuffer: Buffer.from(file.body, "utf-8")
|
|
10047
|
+
};
|
|
10048
|
+
}
|
|
10049
|
+
function extractDirName(relativeDirPathFromCwd) {
|
|
10050
|
+
const dirName = basename23(relativeDirPathFromCwd);
|
|
10051
|
+
if (!dirName) {
|
|
10052
|
+
throw new Error(`Invalid path: ${relativeDirPathFromCwd}`);
|
|
10053
|
+
}
|
|
10054
|
+
return dirName;
|
|
10055
|
+
}
|
|
10056
|
+
async function listSkills() {
|
|
10057
|
+
const skillsDir = join86(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH);
|
|
10058
|
+
try {
|
|
10059
|
+
const skillDirPaths = await findFilesByGlobs(join86(skillsDir, "*"), { type: "dir" });
|
|
10060
|
+
const skills = await Promise.all(
|
|
10061
|
+
skillDirPaths.map(async (dirPath) => {
|
|
10062
|
+
const dirName = basename23(dirPath);
|
|
10063
|
+
if (!dirName) return null;
|
|
10064
|
+
try {
|
|
10065
|
+
const skill = await RulesyncSkill.fromDir({
|
|
10066
|
+
dirName
|
|
10067
|
+
});
|
|
10068
|
+
const frontmatter = skill.getFrontmatter();
|
|
10069
|
+
return {
|
|
10070
|
+
relativeDirPathFromCwd: join86(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
10071
|
+
frontmatter
|
|
10072
|
+
};
|
|
10073
|
+
} catch (error) {
|
|
10074
|
+
logger.error(`Failed to read skill directory ${dirName}: ${formatError(error)}`);
|
|
10075
|
+
return null;
|
|
10076
|
+
}
|
|
10077
|
+
})
|
|
10078
|
+
);
|
|
10079
|
+
return skills.filter((skill) => skill !== null);
|
|
10080
|
+
} catch (error) {
|
|
10081
|
+
logger.error(`Failed to read skills directory: ${formatError(error)}`);
|
|
10082
|
+
return [];
|
|
10083
|
+
}
|
|
10084
|
+
}
|
|
10085
|
+
async function getSkill({ relativeDirPathFromCwd }) {
|
|
10086
|
+
checkPathTraversal({
|
|
10087
|
+
relativePath: relativeDirPathFromCwd,
|
|
10088
|
+
intendedRootDir: process.cwd()
|
|
10089
|
+
});
|
|
10090
|
+
const dirName = extractDirName(relativeDirPathFromCwd);
|
|
10091
|
+
try {
|
|
10092
|
+
const skill = await RulesyncSkill.fromDir({
|
|
10093
|
+
dirName
|
|
10094
|
+
});
|
|
10095
|
+
return {
|
|
10096
|
+
relativeDirPathFromCwd: join86(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
10097
|
+
frontmatter: skill.getFrontmatter(),
|
|
10098
|
+
body: skill.getBody(),
|
|
10099
|
+
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
10100
|
+
};
|
|
10101
|
+
} catch (error) {
|
|
10102
|
+
throw new Error(
|
|
10103
|
+
`Failed to read skill directory ${relativeDirPathFromCwd}: ${formatError(error)}`,
|
|
10104
|
+
{
|
|
10105
|
+
cause: error
|
|
10106
|
+
}
|
|
10107
|
+
);
|
|
10108
|
+
}
|
|
10109
|
+
}
|
|
10110
|
+
async function putSkill({
|
|
10111
|
+
relativeDirPathFromCwd,
|
|
10112
|
+
frontmatter,
|
|
10113
|
+
body,
|
|
10114
|
+
otherFiles = []
|
|
10115
|
+
}) {
|
|
10116
|
+
checkPathTraversal({
|
|
10117
|
+
relativePath: relativeDirPathFromCwd,
|
|
10118
|
+
intendedRootDir: process.cwd()
|
|
10119
|
+
});
|
|
10120
|
+
const dirName = extractDirName(relativeDirPathFromCwd);
|
|
10121
|
+
const estimatedSize = JSON.stringify(frontmatter).length + body.length + otherFiles.reduce((acc, file) => acc + file.name.length + file.body.length, 0);
|
|
10122
|
+
if (estimatedSize > maxSkillSizeBytes) {
|
|
10123
|
+
throw new Error(
|
|
10124
|
+
`Skill size ${estimatedSize} bytes exceeds maximum ${maxSkillSizeBytes} bytes (1MB)`
|
|
10125
|
+
);
|
|
10126
|
+
}
|
|
10127
|
+
try {
|
|
10128
|
+
const existingSkills = await listSkills();
|
|
10129
|
+
const isUpdate = existingSkills.some(
|
|
10130
|
+
(skill2) => skill2.relativeDirPathFromCwd === join86(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
10131
|
+
);
|
|
10132
|
+
if (!isUpdate && existingSkills.length >= maxSkillsCount) {
|
|
10133
|
+
throw new Error(`Maximum number of skills (${maxSkillsCount}) reached`);
|
|
10134
|
+
}
|
|
10135
|
+
const aiDirFiles = otherFiles.map(mcpSkillFileToAiDirFile);
|
|
10136
|
+
const skill = new RulesyncSkill({
|
|
10137
|
+
baseDir: process.cwd(),
|
|
10138
|
+
relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
10139
|
+
dirName,
|
|
10140
|
+
frontmatter,
|
|
10141
|
+
body,
|
|
10142
|
+
otherFiles: aiDirFiles,
|
|
10143
|
+
validate: true
|
|
10144
|
+
});
|
|
10145
|
+
const skillDirPath = join86(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
10146
|
+
await ensureDir(skillDirPath);
|
|
10147
|
+
const skillFilePath = join86(skillDirPath, SKILL_FILE_NAME);
|
|
10148
|
+
const skillFileContent = stringifyFrontmatter(body, frontmatter);
|
|
10149
|
+
await writeFileContent(skillFilePath, skillFileContent);
|
|
10150
|
+
for (const file of otherFiles) {
|
|
10151
|
+
checkPathTraversal({
|
|
10152
|
+
relativePath: file.name,
|
|
10153
|
+
intendedRootDir: skillDirPath
|
|
10154
|
+
});
|
|
10155
|
+
const filePath = join86(skillDirPath, file.name);
|
|
10156
|
+
const fileDir = join86(skillDirPath, dirname2(file.name));
|
|
10157
|
+
if (fileDir !== skillDirPath) {
|
|
10158
|
+
await ensureDir(fileDir);
|
|
10159
|
+
}
|
|
10160
|
+
await writeFileContent(filePath, file.body);
|
|
10161
|
+
}
|
|
10162
|
+
return {
|
|
10163
|
+
relativeDirPathFromCwd: join86(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName),
|
|
10164
|
+
frontmatter: skill.getFrontmatter(),
|
|
10165
|
+
body: skill.getBody(),
|
|
10166
|
+
otherFiles: skill.getOtherFiles().map(aiDirFileToMcpSkillFile)
|
|
10167
|
+
};
|
|
10168
|
+
} catch (error) {
|
|
10169
|
+
throw new Error(
|
|
10170
|
+
`Failed to write skill directory ${relativeDirPathFromCwd}: ${formatError(error)}`,
|
|
10171
|
+
{
|
|
10172
|
+
cause: error
|
|
10173
|
+
}
|
|
10174
|
+
);
|
|
10175
|
+
}
|
|
10176
|
+
}
|
|
10177
|
+
async function deleteSkill({
|
|
10178
|
+
relativeDirPathFromCwd
|
|
10179
|
+
}) {
|
|
10180
|
+
checkPathTraversal({
|
|
10181
|
+
relativePath: relativeDirPathFromCwd,
|
|
10182
|
+
intendedRootDir: process.cwd()
|
|
10183
|
+
});
|
|
10184
|
+
const dirName = extractDirName(relativeDirPathFromCwd);
|
|
10185
|
+
const skillDirPath = join86(process.cwd(), RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName);
|
|
10186
|
+
try {
|
|
10187
|
+
if (await directoryExists(skillDirPath)) {
|
|
10188
|
+
await removeDirectory(skillDirPath);
|
|
10189
|
+
}
|
|
10190
|
+
return {
|
|
10191
|
+
relativeDirPathFromCwd: join86(RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName)
|
|
10192
|
+
};
|
|
10193
|
+
} catch (error) {
|
|
10194
|
+
throw new Error(
|
|
10195
|
+
`Failed to delete skill directory ${relativeDirPathFromCwd}: ${formatError(error)}`,
|
|
10196
|
+
{
|
|
10197
|
+
cause: error
|
|
10198
|
+
}
|
|
10199
|
+
);
|
|
10200
|
+
}
|
|
10201
|
+
}
|
|
10202
|
+
var McpSkillFileSchema = z35.object({
|
|
10203
|
+
name: z35.string(),
|
|
10204
|
+
body: z35.string()
|
|
10205
|
+
});
|
|
10206
|
+
var skillToolSchemas = {
|
|
10207
|
+
listSkills: z35.object({}),
|
|
10208
|
+
getSkill: z35.object({
|
|
10209
|
+
relativeDirPathFromCwd: z35.string()
|
|
10210
|
+
}),
|
|
10211
|
+
putSkill: z35.object({
|
|
10212
|
+
relativeDirPathFromCwd: z35.string(),
|
|
10213
|
+
frontmatter: RulesyncSkillFrontmatterSchema,
|
|
10214
|
+
body: z35.string(),
|
|
10215
|
+
otherFiles: z35.optional(z35.array(McpSkillFileSchema))
|
|
10216
|
+
}),
|
|
10217
|
+
deleteSkill: z35.object({
|
|
10218
|
+
relativeDirPathFromCwd: z35.string()
|
|
10219
|
+
})
|
|
10220
|
+
};
|
|
10221
|
+
var skillTools = {
|
|
10222
|
+
listSkills: {
|
|
10223
|
+
name: "listSkills",
|
|
10224
|
+
description: `List all skills from ${join86(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "*", SKILL_FILE_NAME)} with their frontmatter.`,
|
|
10225
|
+
parameters: skillToolSchemas.listSkills,
|
|
10226
|
+
execute: async () => {
|
|
10227
|
+
const skills = await listSkills();
|
|
10228
|
+
const output = { skills };
|
|
10229
|
+
return JSON.stringify(output, null, 2);
|
|
10230
|
+
}
|
|
10231
|
+
},
|
|
10232
|
+
getSkill: {
|
|
10233
|
+
name: "getSkill",
|
|
10234
|
+
description: "Get detailed information about a specific skill including SKILL.md content and other files. relativeDirPathFromCwd parameter is required.",
|
|
10235
|
+
parameters: skillToolSchemas.getSkill,
|
|
10236
|
+
execute: async (args) => {
|
|
10237
|
+
const result = await getSkill({ relativeDirPathFromCwd: args.relativeDirPathFromCwd });
|
|
10238
|
+
return JSON.stringify(result, null, 2);
|
|
10239
|
+
}
|
|
10240
|
+
},
|
|
10241
|
+
putSkill: {
|
|
10242
|
+
name: "putSkill",
|
|
10243
|
+
description: "Create or update a skill (upsert operation). relativeDirPathFromCwd, frontmatter, and body parameters are required. otherFiles is optional.",
|
|
10244
|
+
parameters: skillToolSchemas.putSkill,
|
|
10245
|
+
execute: async (args) => {
|
|
10246
|
+
const result = await putSkill({
|
|
10247
|
+
relativeDirPathFromCwd: args.relativeDirPathFromCwd,
|
|
10248
|
+
frontmatter: args.frontmatter,
|
|
10249
|
+
body: args.body,
|
|
10250
|
+
otherFiles: args.otherFiles
|
|
10251
|
+
});
|
|
10252
|
+
return JSON.stringify(result, null, 2);
|
|
10253
|
+
}
|
|
10254
|
+
},
|
|
10255
|
+
deleteSkill: {
|
|
10256
|
+
name: "deleteSkill",
|
|
10257
|
+
description: "Delete a skill directory and all its contents. relativeDirPathFromCwd parameter is required.",
|
|
10258
|
+
parameters: skillToolSchemas.deleteSkill,
|
|
10259
|
+
execute: async (args) => {
|
|
10260
|
+
const result = await deleteSkill({ relativeDirPathFromCwd: args.relativeDirPathFromCwd });
|
|
10261
|
+
return JSON.stringify(result, null, 2);
|
|
10262
|
+
}
|
|
10263
|
+
}
|
|
10264
|
+
};
|
|
10265
|
+
|
|
10266
|
+
// src/mcp/subagents.ts
|
|
10267
|
+
import { basename as basename24, join as join87 } from "path";
|
|
10268
|
+
import { z as z36 } from "zod/mini";
|
|
10035
10269
|
var maxSubagentSizeBytes = 1024 * 1024;
|
|
10036
10270
|
var maxSubagentsCount = 1e3;
|
|
10037
10271
|
async function listSubagents() {
|
|
10038
|
-
const subagentsDir =
|
|
10272
|
+
const subagentsDir = join87(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
10039
10273
|
try {
|
|
10040
10274
|
const files = await listDirectoryFiles(subagentsDir);
|
|
10041
10275
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -10048,7 +10282,7 @@ async function listSubagents() {
|
|
|
10048
10282
|
});
|
|
10049
10283
|
const frontmatter = subagent.getFrontmatter();
|
|
10050
10284
|
return {
|
|
10051
|
-
relativePathFromCwd:
|
|
10285
|
+
relativePathFromCwd: join87(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
|
|
10052
10286
|
frontmatter
|
|
10053
10287
|
};
|
|
10054
10288
|
} catch (error) {
|
|
@@ -10070,14 +10304,14 @@ async function getSubagent({ relativePathFromCwd }) {
|
|
|
10070
10304
|
relativePath: relativePathFromCwd,
|
|
10071
10305
|
intendedRootDir: process.cwd()
|
|
10072
10306
|
});
|
|
10073
|
-
const filename =
|
|
10307
|
+
const filename = basename24(relativePathFromCwd);
|
|
10074
10308
|
try {
|
|
10075
10309
|
const subagent = await RulesyncSubagent.fromFile({
|
|
10076
10310
|
relativeFilePath: filename,
|
|
10077
10311
|
validate: true
|
|
10078
10312
|
});
|
|
10079
10313
|
return {
|
|
10080
|
-
relativePathFromCwd:
|
|
10314
|
+
relativePathFromCwd: join87(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
10081
10315
|
frontmatter: subagent.getFrontmatter(),
|
|
10082
10316
|
body: subagent.getBody()
|
|
10083
10317
|
};
|
|
@@ -10096,7 +10330,7 @@ async function putSubagent({
|
|
|
10096
10330
|
relativePath: relativePathFromCwd,
|
|
10097
10331
|
intendedRootDir: process.cwd()
|
|
10098
10332
|
});
|
|
10099
|
-
const filename =
|
|
10333
|
+
const filename = basename24(relativePathFromCwd);
|
|
10100
10334
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
10101
10335
|
if (estimatedSize > maxSubagentSizeBytes) {
|
|
10102
10336
|
throw new Error(
|
|
@@ -10106,7 +10340,7 @@ async function putSubagent({
|
|
|
10106
10340
|
try {
|
|
10107
10341
|
const existingSubagents = await listSubagents();
|
|
10108
10342
|
const isUpdate = existingSubagents.some(
|
|
10109
|
-
(subagent2) => subagent2.relativePathFromCwd ===
|
|
10343
|
+
(subagent2) => subagent2.relativePathFromCwd === join87(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
10110
10344
|
);
|
|
10111
10345
|
if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
|
|
10112
10346
|
throw new Error(`Maximum number of subagents (${maxSubagentsCount}) reached`);
|
|
@@ -10119,11 +10353,11 @@ async function putSubagent({
|
|
|
10119
10353
|
body,
|
|
10120
10354
|
validate: true
|
|
10121
10355
|
});
|
|
10122
|
-
const subagentsDir =
|
|
10356
|
+
const subagentsDir = join87(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
10123
10357
|
await ensureDir(subagentsDir);
|
|
10124
10358
|
await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
|
|
10125
10359
|
return {
|
|
10126
|
-
relativePathFromCwd:
|
|
10360
|
+
relativePathFromCwd: join87(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
10127
10361
|
frontmatter: subagent.getFrontmatter(),
|
|
10128
10362
|
body: subagent.getBody()
|
|
10129
10363
|
};
|
|
@@ -10138,12 +10372,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
10138
10372
|
relativePath: relativePathFromCwd,
|
|
10139
10373
|
intendedRootDir: process.cwd()
|
|
10140
10374
|
});
|
|
10141
|
-
const filename =
|
|
10142
|
-
const fullPath =
|
|
10375
|
+
const filename = basename24(relativePathFromCwd);
|
|
10376
|
+
const fullPath = join87(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
|
|
10143
10377
|
try {
|
|
10144
10378
|
await removeFile(fullPath);
|
|
10145
10379
|
return {
|
|
10146
|
-
relativePathFromCwd:
|
|
10380
|
+
relativePathFromCwd: join87(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
10147
10381
|
};
|
|
10148
10382
|
} catch (error) {
|
|
10149
10383
|
throw new Error(
|
|
@@ -10155,23 +10389,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
10155
10389
|
}
|
|
10156
10390
|
}
|
|
10157
10391
|
var subagentToolSchemas = {
|
|
10158
|
-
listSubagents:
|
|
10159
|
-
getSubagent:
|
|
10160
|
-
relativePathFromCwd:
|
|
10392
|
+
listSubagents: z36.object({}),
|
|
10393
|
+
getSubagent: z36.object({
|
|
10394
|
+
relativePathFromCwd: z36.string()
|
|
10161
10395
|
}),
|
|
10162
|
-
putSubagent:
|
|
10163
|
-
relativePathFromCwd:
|
|
10396
|
+
putSubagent: z36.object({
|
|
10397
|
+
relativePathFromCwd: z36.string(),
|
|
10164
10398
|
frontmatter: RulesyncSubagentFrontmatterSchema,
|
|
10165
|
-
body:
|
|
10399
|
+
body: z36.string()
|
|
10166
10400
|
}),
|
|
10167
|
-
deleteSubagent:
|
|
10168
|
-
relativePathFromCwd:
|
|
10401
|
+
deleteSubagent: z36.object({
|
|
10402
|
+
relativePathFromCwd: z36.string()
|
|
10169
10403
|
})
|
|
10170
10404
|
};
|
|
10171
10405
|
var subagentTools = {
|
|
10172
10406
|
listSubagents: {
|
|
10173
10407
|
name: "listSubagents",
|
|
10174
|
-
description: `List all subagents from ${
|
|
10408
|
+
description: `List all subagents from ${join87(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
10175
10409
|
parameters: subagentToolSchemas.listSubagents,
|
|
10176
10410
|
execute: async () => {
|
|
10177
10411
|
const subagents = await listSubagents();
|
|
@@ -10218,7 +10452,7 @@ async function mcpCommand({ version }) {
|
|
|
10218
10452
|
name: "Rulesync MCP Server",
|
|
10219
10453
|
// eslint-disable-next-line no-type-assertion/no-type-assertion
|
|
10220
10454
|
version,
|
|
10221
|
-
instructions: "This server handles Rulesync files including rules, commands, MCP, ignore files, and
|
|
10455
|
+
instructions: "This server handles Rulesync files including rules, commands, MCP, ignore files, subagents and skills for any AI agents. It should be used when you need those files."
|
|
10222
10456
|
});
|
|
10223
10457
|
server.addTool(ruleTools.listRules);
|
|
10224
10458
|
server.addTool(ruleTools.getRule);
|
|
@@ -10232,6 +10466,10 @@ async function mcpCommand({ version }) {
|
|
|
10232
10466
|
server.addTool(subagentTools.getSubagent);
|
|
10233
10467
|
server.addTool(subagentTools.putSubagent);
|
|
10234
10468
|
server.addTool(subagentTools.deleteSubagent);
|
|
10469
|
+
server.addTool(skillTools.listSkills);
|
|
10470
|
+
server.addTool(skillTools.getSkill);
|
|
10471
|
+
server.addTool(skillTools.putSkill);
|
|
10472
|
+
server.addTool(skillTools.deleteSkill);
|
|
10235
10473
|
server.addTool(ignoreTools.getIgnoreFile);
|
|
10236
10474
|
server.addTool(ignoreTools.putIgnoreFile);
|
|
10237
10475
|
server.addTool(ignoreTools.deleteIgnoreFile);
|
|
@@ -10245,7 +10483,7 @@ async function mcpCommand({ version }) {
|
|
|
10245
10483
|
}
|
|
10246
10484
|
|
|
10247
10485
|
// src/cli/index.ts
|
|
10248
|
-
var getVersion = () => "3.
|
|
10486
|
+
var getVersion = () => "3.29.0";
|
|
10249
10487
|
var main = async () => {
|
|
10250
10488
|
const program = new Command();
|
|
10251
10489
|
const version = getVersion();
|