rulesync 3.23.5 → 3.24.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.
Files changed (4) hide show
  1. package/README.md +53 -23
  2. package/dist/index.cjs +815 -119
  3. package/dist/index.js +815 -119
  4. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -31,7 +31,7 @@ var ANNOUNCEMENT = "".trim();
31
31
 
32
32
  // src/types/features.ts
33
33
  var import_mini = require("zod/mini");
34
- var ALL_FEATURES = ["rules", "ignore", "mcp", "subagents", "commands"];
34
+ var ALL_FEATURES = ["rules", "ignore", "mcp", "subagents", "commands", "skills"];
35
35
  var ALL_FEATURES_WITH_WILDCARD = [...ALL_FEATURES, "*"];
36
36
  var FeatureSchema = import_mini.z.enum(ALL_FEATURES);
37
37
  var FeaturesSchema = import_mini.z.array(FeatureSchema);
@@ -160,6 +160,10 @@ async function readFileContent(filepath) {
160
160
  logger.debug(`Reading file: ${filepath}`);
161
161
  return (0, import_promises.readFile)(filepath, "utf-8");
162
162
  }
163
+ async function readFileBuffer(filepath) {
164
+ logger.debug(`Reading file buffer: ${filepath}`);
165
+ return (0, import_promises.readFile)(filepath);
166
+ }
163
167
  function addTrailingNewline(content) {
164
168
  if (!content) {
165
169
  return "\n";
@@ -187,11 +191,32 @@ async function listDirectoryFiles(dir) {
187
191
  }
188
192
  }
189
193
  async function findFilesByGlobs(globs, options = {}) {
194
+ const { type = "all" } = options;
190
195
  const items = (0, import_node_fs.globSync)(globs, { withFileTypes: true });
191
- if (!options.fileOnly) {
192
- return items.map((item) => (0, import_node_path.join)(item.parentPath, item.name));
196
+ switch (type) {
197
+ case "file":
198
+ return items.filter((item) => item.isFile()).map((item) => (0, import_node_path.join)(item.parentPath, item.name));
199
+ case "dir":
200
+ return items.filter((item) => item.isDirectory()).map((item) => (0, import_node_path.join)(item.parentPath, item.name));
201
+ case "all":
202
+ return items.map((item) => (0, import_node_path.join)(item.parentPath, item.name));
203
+ default:
204
+ throw new Error(`Invalid type: ${type}`);
205
+ }
206
+ }
207
+ async function removeDirectory(dirPath) {
208
+ const dangerousPaths = [".", "/", "~", "src", "node_modules"];
209
+ if (dangerousPaths.includes(dirPath) || dirPath === "") {
210
+ logger.warn(`Skipping deletion of dangerous path: ${dirPath}`);
211
+ return;
212
+ }
213
+ try {
214
+ if (await fileExists(dirPath)) {
215
+ await (0, import_promises.rm)(dirPath, { recursive: true, force: true });
216
+ }
217
+ } catch (error) {
218
+ logger.warn(`Failed to remove directory ${dirPath}:`, error);
193
219
  }
194
- return items.filter((item) => item.isFile()).map((item) => (0, import_node_path.join)(item.parentPath, item.name));
195
220
  }
196
221
  async function removeFile(filepath) {
197
222
  logger.debug(`Removing file: ${filepath}`);
@@ -1697,7 +1722,7 @@ var CommandsProcessor = class extends FeatureProcessor {
1697
1722
  );
1698
1723
  const rulesyncCommands = (await Promise.allSettled(
1699
1724
  rulesyncCommandPaths.map(
1700
- (path2) => RulesyncCommand.fromFile({ relativeFilePath: (0, import_node_path14.basename)(path2) })
1725
+ (path3) => RulesyncCommand.fromFile({ relativeFilePath: (0, import_node_path14.basename)(path3) })
1701
1726
  )
1702
1727
  )).filter((result) => result.status === "fulfilled").map((result) => result.value);
1703
1728
  logger.info(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
@@ -1739,45 +1764,45 @@ var CommandsProcessor = class extends FeatureProcessor {
1739
1764
  (0, import_node_path14.join)(this.baseDir, relativeDirPath, `*.${extension}`)
1740
1765
  );
1741
1766
  const toolCommands = (await Promise.allSettled(
1742
- commandFilePaths.map((path2) => {
1767
+ commandFilePaths.map((path3) => {
1743
1768
  switch (toolTarget) {
1744
1769
  case "agentsmd":
1745
1770
  return AgentsmdCommand.fromFile({
1746
1771
  baseDir: this.baseDir,
1747
- relativeFilePath: (0, import_node_path14.basename)(path2)
1772
+ relativeFilePath: (0, import_node_path14.basename)(path3)
1748
1773
  });
1749
1774
  case "claudecode":
1750
1775
  return ClaudecodeCommand.fromFile({
1751
1776
  baseDir: this.baseDir,
1752
- relativeFilePath: (0, import_node_path14.basename)(path2),
1777
+ relativeFilePath: (0, import_node_path14.basename)(path3),
1753
1778
  global: this.global
1754
1779
  });
1755
1780
  case "geminicli":
1756
1781
  return GeminiCliCommand.fromFile({
1757
1782
  baseDir: this.baseDir,
1758
- relativeFilePath: (0, import_node_path14.basename)(path2),
1783
+ relativeFilePath: (0, import_node_path14.basename)(path3),
1759
1784
  global: this.global
1760
1785
  });
1761
1786
  case "roo":
1762
1787
  return RooCommand.fromFile({
1763
1788
  baseDir: this.baseDir,
1764
- relativeFilePath: (0, import_node_path14.basename)(path2)
1789
+ relativeFilePath: (0, import_node_path14.basename)(path3)
1765
1790
  });
1766
1791
  case "copilot":
1767
1792
  return CopilotCommand.fromFile({
1768
1793
  baseDir: this.baseDir,
1769
- relativeFilePath: (0, import_node_path14.basename)(path2)
1794
+ relativeFilePath: (0, import_node_path14.basename)(path3)
1770
1795
  });
1771
1796
  case "cursor":
1772
1797
  return CursorCommand.fromFile({
1773
1798
  baseDir: this.baseDir,
1774
- relativeFilePath: (0, import_node_path14.basename)(path2),
1799
+ relativeFilePath: (0, import_node_path14.basename)(path3),
1775
1800
  global: this.global
1776
1801
  });
1777
1802
  case "codexcli":
1778
1803
  return CodexcliCommand.fromFile({
1779
1804
  baseDir: this.baseDir,
1780
- relativeFilePath: (0, import_node_path14.basename)(path2),
1805
+ relativeFilePath: (0, import_node_path14.basename)(path3),
1781
1806
  global: this.global
1782
1807
  });
1783
1808
  default:
@@ -2574,7 +2599,12 @@ var IgnoreProcessor = class extends FeatureProcessor {
2574
2599
  const toolIgnores = await this.loadToolIgnores();
2575
2600
  return toolIgnores;
2576
2601
  } catch (error) {
2577
- logger.error(`Failed to load tool files: ${formatError(error)}`);
2602
+ const errorMessage = `Failed to load tool files: ${formatError(error)}`;
2603
+ if (error instanceof Error && error.message.includes("no such file or directory")) {
2604
+ logger.debug(errorMessage);
2605
+ } else {
2606
+ logger.error(errorMessage);
2607
+ }
2578
2608
  return [];
2579
2609
  }
2580
2610
  }
@@ -3595,9 +3625,7 @@ var McpProcessor = class extends FeatureProcessor {
3595
3625
  try {
3596
3626
  return [await RulesyncMcp.fromFile({ modularMcp: this.modularMcp })];
3597
3627
  } catch (error) {
3598
- logger.error(
3599
- `Failed to load MCP files for tool target: ${this.toolTarget}: ${formatError(error)}`
3600
- );
3628
+ logger.error(`Failed to load a Rulesync MCP file: ${formatError(error)}`);
3601
3629
  return [];
3602
3630
  }
3603
3631
  }
@@ -3691,9 +3719,12 @@ var McpProcessor = class extends FeatureProcessor {
3691
3719
  logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
3692
3720
  return toolMcps;
3693
3721
  } catch (error) {
3694
- logger.error(
3695
- `Failed to load MCP files for tool target: ${this.toolTarget}: ${formatError(error)}`
3696
- );
3722
+ const errorMessage = `Failed to load MCP files for tool target: ${this.toolTarget}: ${formatError(error)}`;
3723
+ if (error instanceof Error && error.message.includes("no such file or directory")) {
3724
+ logger.debug(errorMessage);
3725
+ } else {
3726
+ logger.error(errorMessage);
3727
+ }
3697
3728
  return [];
3698
3729
  }
3699
3730
  }
@@ -4564,7 +4595,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
4564
4595
  fromFile
4565
4596
  }) {
4566
4597
  const paths = await findFilesByGlobs((0, import_node_path46.join)(this.baseDir, relativeDirPath, "*.md"));
4567
- const subagents = (await Promise.allSettled(paths.map((path2) => fromFile((0, import_node_path46.basename)(path2))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
4598
+ const subagents = (await Promise.allSettled(paths.map((path3) => fromFile((0, import_node_path46.basename)(path3))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
4568
4599
  logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
4569
4600
  return subagents;
4570
4601
  }
@@ -7086,6 +7117,614 @@ For example, if the user instructs \`Call planner subagent to plan the refactori
7086
7117
  }
7087
7118
  };
7088
7119
 
7120
+ // src/features/skills/skills-processor.ts
7121
+ var import_node_path71 = require("path");
7122
+ var import_mini27 = require("zod/mini");
7123
+
7124
+ // src/types/dir-feature-processor.ts
7125
+ var import_node_path67 = require("path");
7126
+ var DirFeatureProcessor = class {
7127
+ baseDir;
7128
+ constructor({ baseDir = process.cwd() }) {
7129
+ this.baseDir = baseDir;
7130
+ }
7131
+ /**
7132
+ * Return tool targets that this feature supports.
7133
+ */
7134
+ static getToolTargets(_params = {}) {
7135
+ throw new Error("Not implemented");
7136
+ }
7137
+ /**
7138
+ * Once converted to rulesync/tool dirs, write them to the filesystem.
7139
+ * Returns the number of directories written.
7140
+ */
7141
+ async writeAiDirs(aiDirs) {
7142
+ for (const aiDir of aiDirs) {
7143
+ const dirPath = aiDir.getDirPath();
7144
+ await ensureDir(dirPath);
7145
+ const mainFile = aiDir.getMainFile();
7146
+ if (mainFile) {
7147
+ const mainFilePath = (0, import_node_path67.join)(dirPath, mainFile.name);
7148
+ const contentWithNewline = addTrailingNewline(mainFile.body);
7149
+ await writeFileContent(mainFilePath, contentWithNewline);
7150
+ }
7151
+ const otherFiles = aiDir.getOtherFiles();
7152
+ for (const file of otherFiles) {
7153
+ const filePath = (0, import_node_path67.join)(dirPath, file.relativeFilePathToDirPath);
7154
+ const contentWithNewline = addTrailingNewline(file.fileBuffer.toString("utf-8"));
7155
+ await writeFileContent(filePath, contentWithNewline);
7156
+ }
7157
+ }
7158
+ return aiDirs.length;
7159
+ }
7160
+ async removeAiDirs(aiDirs) {
7161
+ for (const aiDir of aiDirs) {
7162
+ await removeDirectory(aiDir.getDirPath());
7163
+ }
7164
+ }
7165
+ };
7166
+
7167
+ // src/features/skills/claudecode-skill.ts
7168
+ var import_node_path70 = require("path");
7169
+ var import_mini26 = require("zod/mini");
7170
+
7171
+ // src/constants/general.ts
7172
+ var SKILL_FILE_NAME = "SKILL.md";
7173
+
7174
+ // src/features/skills/rulesync-skill.ts
7175
+ var import_node_path69 = require("path");
7176
+ var import_mini25 = require("zod/mini");
7177
+
7178
+ // src/types/ai-dir.ts
7179
+ var import_node_path68 = __toESM(require("path"), 1);
7180
+ var AiDir = class {
7181
+ /**
7182
+ * @example "."
7183
+ */
7184
+ baseDir;
7185
+ /**
7186
+ * @example ".rulesync/skills"
7187
+ */
7188
+ relativeDirPath;
7189
+ /**
7190
+ * @example "my-skill"
7191
+ */
7192
+ dirName;
7193
+ /**
7194
+ * Optional main file with frontmatter support
7195
+ */
7196
+ mainFile;
7197
+ /**
7198
+ * Additional files in the directory
7199
+ */
7200
+ otherFiles;
7201
+ /**
7202
+ * @example false
7203
+ */
7204
+ global;
7205
+ constructor({
7206
+ baseDir = process.cwd(),
7207
+ relativeDirPath,
7208
+ dirName,
7209
+ mainFile,
7210
+ otherFiles = [],
7211
+ global = false
7212
+ }) {
7213
+ if (dirName.includes(import_node_path68.default.sep) || dirName.includes("/") || dirName.includes("\\")) {
7214
+ throw new Error(`Directory name cannot contain path separators: dirName="${dirName}"`);
7215
+ }
7216
+ this.baseDir = baseDir;
7217
+ this.relativeDirPath = relativeDirPath;
7218
+ this.dirName = dirName;
7219
+ this.mainFile = mainFile;
7220
+ this.otherFiles = otherFiles;
7221
+ this.global = global;
7222
+ }
7223
+ static async fromDir(_params) {
7224
+ throw new Error("Please implement this method in the subclass.");
7225
+ }
7226
+ getBaseDir() {
7227
+ return this.baseDir;
7228
+ }
7229
+ getRelativeDirPath() {
7230
+ return this.relativeDirPath;
7231
+ }
7232
+ getDirName() {
7233
+ return this.dirName;
7234
+ }
7235
+ getDirPath() {
7236
+ const fullPath = import_node_path68.default.join(this.baseDir, this.relativeDirPath, this.dirName);
7237
+ const resolvedFull = (0, import_node_path68.resolve)(fullPath);
7238
+ const resolvedBase = (0, import_node_path68.resolve)(this.baseDir);
7239
+ const rel = (0, import_node_path68.relative)(resolvedBase, resolvedFull);
7240
+ if (rel.startsWith("..") || import_node_path68.default.isAbsolute(rel)) {
7241
+ throw new Error(
7242
+ `Path traversal detected: Final path escapes baseDir. baseDir="${this.baseDir}", relativeDirPath="${this.relativeDirPath}", dirName="${this.dirName}"`
7243
+ );
7244
+ }
7245
+ return fullPath;
7246
+ }
7247
+ getMainFile() {
7248
+ return this.mainFile;
7249
+ }
7250
+ getOtherFiles() {
7251
+ return this.otherFiles;
7252
+ }
7253
+ getRelativePathFromCwd() {
7254
+ return import_node_path68.default.join(this.relativeDirPath, this.dirName);
7255
+ }
7256
+ getGlobal() {
7257
+ return this.global;
7258
+ }
7259
+ setMainFile(name, body, frontmatter) {
7260
+ this.mainFile = { name, body, frontmatter };
7261
+ }
7262
+ /**
7263
+ * Recursively collects all files from a directory, excluding the specified main file.
7264
+ * This is a common utility for loading additional files alongside the main file.
7265
+ *
7266
+ * @param baseDir - The base directory path
7267
+ * @param relativeDirPath - The relative path to the directory containing the skill
7268
+ * @param dirName - The name of the directory
7269
+ * @param excludeFileName - The name of the file to exclude (typically the main file)
7270
+ * @returns Array of files with their relative paths and buffers
7271
+ */
7272
+ static async collectOtherFiles(baseDir, relativeDirPath, dirName, excludeFileName) {
7273
+ const dirPath = (0, import_node_path68.join)(baseDir, relativeDirPath, dirName);
7274
+ const glob = (0, import_node_path68.join)(dirPath, "**", "*");
7275
+ const filePaths = await findFilesByGlobs(glob, { type: "file" });
7276
+ const filteredPaths = filePaths.filter((filePath) => (0, import_node_path68.basename)(filePath) !== excludeFileName);
7277
+ const files = await Promise.all(
7278
+ filteredPaths.map(async (filePath) => {
7279
+ const fileBuffer = await readFileBuffer(filePath);
7280
+ return {
7281
+ relativeFilePathToDirPath: (0, import_node_path68.relative)(dirPath, filePath),
7282
+ fileBuffer
7283
+ };
7284
+ })
7285
+ );
7286
+ return files;
7287
+ }
7288
+ };
7289
+
7290
+ // src/features/skills/rulesync-skill.ts
7291
+ var RulesyncSkillFrontmatterSchema = import_mini25.z.object({
7292
+ name: import_mini25.z.string(),
7293
+ description: import_mini25.z.string(),
7294
+ claudecode: import_mini25.z.optional(
7295
+ import_mini25.z.object({
7296
+ "allowed-tools": import_mini25.z.optional(import_mini25.z.array(import_mini25.z.string()))
7297
+ })
7298
+ )
7299
+ });
7300
+ var RulesyncSkill = class _RulesyncSkill extends AiDir {
7301
+ constructor({
7302
+ baseDir = process.cwd(),
7303
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
7304
+ dirName,
7305
+ frontmatter,
7306
+ body,
7307
+ otherFiles = [],
7308
+ validate = true,
7309
+ global = false
7310
+ }) {
7311
+ super({
7312
+ baseDir,
7313
+ relativeDirPath,
7314
+ dirName,
7315
+ mainFile: {
7316
+ name: SKILL_FILE_NAME,
7317
+ body,
7318
+ frontmatter: { ...frontmatter }
7319
+ },
7320
+ otherFiles,
7321
+ global
7322
+ });
7323
+ if (validate) {
7324
+ const result = this.validate();
7325
+ if (!result.success) {
7326
+ throw result.error;
7327
+ }
7328
+ }
7329
+ }
7330
+ static getSettablePaths() {
7331
+ return {
7332
+ relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
7333
+ };
7334
+ }
7335
+ getFrontmatter() {
7336
+ if (!this.mainFile?.frontmatter) {
7337
+ throw new Error("Frontmatter is not defined");
7338
+ }
7339
+ const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
7340
+ return result;
7341
+ }
7342
+ getBody() {
7343
+ return this.mainFile?.body ?? "";
7344
+ }
7345
+ validate() {
7346
+ const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
7347
+ if (!result.success) {
7348
+ return {
7349
+ success: false,
7350
+ error: new Error(
7351
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
7352
+ )
7353
+ };
7354
+ }
7355
+ return { success: true, error: null };
7356
+ }
7357
+ static async fromDir({
7358
+ baseDir = process.cwd(),
7359
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
7360
+ dirName,
7361
+ global = false
7362
+ }) {
7363
+ const skillDirPath = (0, import_node_path69.join)(baseDir, relativeDirPath, dirName);
7364
+ const skillFilePath = (0, import_node_path69.join)(skillDirPath, SKILL_FILE_NAME);
7365
+ if (!await fileExists(skillFilePath)) {
7366
+ throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
7367
+ }
7368
+ const fileContent = await readFileContent(skillFilePath);
7369
+ const { frontmatter, body: content } = parseFrontmatter(fileContent);
7370
+ const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
7371
+ if (!result.success) {
7372
+ throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
7373
+ }
7374
+ const otherFiles = await this.collectOtherFiles(
7375
+ baseDir,
7376
+ relativeDirPath,
7377
+ dirName,
7378
+ SKILL_FILE_NAME
7379
+ );
7380
+ return new _RulesyncSkill({
7381
+ baseDir,
7382
+ relativeDirPath,
7383
+ dirName,
7384
+ frontmatter: result.data,
7385
+ body: content.trim(),
7386
+ otherFiles,
7387
+ validate: true,
7388
+ global
7389
+ });
7390
+ }
7391
+ };
7392
+
7393
+ // src/features/skills/tool-skill.ts
7394
+ var ToolSkill = class extends AiDir {
7395
+ /**
7396
+ * Get the settable paths for this tool's skill directories.
7397
+ *
7398
+ * @param options - Optional configuration including global mode
7399
+ * @returns Object containing the relative directory path
7400
+ */
7401
+ static getSettablePaths(_options) {
7402
+ throw new Error("Please implement this method in the subclass.");
7403
+ }
7404
+ /**
7405
+ * Load a skill from a tool-specific directory.
7406
+ *
7407
+ * This method should:
7408
+ * 1. Read the SKILL.md file content
7409
+ * 2. Parse tool-specific frontmatter format
7410
+ * 3. Validate the parsed data
7411
+ * 4. Collect other skill files in the directory
7412
+ * 5. Return a concrete ToolSkill instance
7413
+ *
7414
+ * @param params - Parameters including the skill directory name
7415
+ * @returns Promise resolving to a concrete ToolSkill instance
7416
+ */
7417
+ static async fromDir(_params) {
7418
+ throw new Error("Please implement this method in the subclass.");
7419
+ }
7420
+ /**
7421
+ * Convert a RulesyncSkill to the tool-specific skill format.
7422
+ *
7423
+ * This method should:
7424
+ * 1. Extract relevant data from the RulesyncSkill
7425
+ * 2. Transform frontmatter to tool-specific format
7426
+ * 3. Transform body content if needed
7427
+ * 4. Preserve other skill files
7428
+ * 5. Return a concrete ToolSkill instance
7429
+ *
7430
+ * @param params - Parameters including the RulesyncSkill to convert
7431
+ * @returns A concrete ToolSkill instance
7432
+ */
7433
+ static fromRulesyncSkill(_params) {
7434
+ throw new Error("Please implement this method in the subclass.");
7435
+ }
7436
+ /**
7437
+ * Check if this tool is targeted by a RulesyncSkill.
7438
+ * Since skills don't have targets field like commands/subagents,
7439
+ * the default behavior may vary by tool.
7440
+ *
7441
+ * @param rulesyncSkill - The RulesyncSkill to check
7442
+ * @returns True if this tool should use the skill
7443
+ */
7444
+ static isTargetedByRulesyncSkill(_rulesyncSkill) {
7445
+ throw new Error("Please implement this method in the subclass.");
7446
+ }
7447
+ };
7448
+
7449
+ // src/features/skills/claudecode-skill.ts
7450
+ var ClaudecodeSkillFrontmatterSchema = import_mini26.z.object({
7451
+ name: import_mini26.z.string(),
7452
+ description: import_mini26.z.string(),
7453
+ "allowed-tools": import_mini26.z.optional(import_mini26.z.array(import_mini26.z.string()))
7454
+ });
7455
+ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
7456
+ constructor({
7457
+ baseDir = process.cwd(),
7458
+ relativeDirPath = (0, import_node_path70.join)(".claude", "skills"),
7459
+ dirName,
7460
+ frontmatter,
7461
+ body,
7462
+ otherFiles = [],
7463
+ validate = true,
7464
+ global = false
7465
+ }) {
7466
+ super({
7467
+ baseDir,
7468
+ relativeDirPath,
7469
+ dirName,
7470
+ mainFile: {
7471
+ name: SKILL_FILE_NAME,
7472
+ body,
7473
+ frontmatter: { ...frontmatter }
7474
+ },
7475
+ otherFiles,
7476
+ global
7477
+ });
7478
+ if (validate) {
7479
+ const result = this.validate();
7480
+ if (!result.success) {
7481
+ throw result.error;
7482
+ }
7483
+ }
7484
+ }
7485
+ static getSettablePaths({
7486
+ global: _global = false
7487
+ } = {}) {
7488
+ return {
7489
+ relativeDirPath: (0, import_node_path70.join)(".claude", "skills")
7490
+ };
7491
+ }
7492
+ getFrontmatter() {
7493
+ if (!this.mainFile?.frontmatter) {
7494
+ throw new Error("Frontmatter is not defined");
7495
+ }
7496
+ const result = ClaudecodeSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
7497
+ return result;
7498
+ }
7499
+ getBody() {
7500
+ return this.mainFile?.body ?? "";
7501
+ }
7502
+ validate() {
7503
+ if (this.mainFile === void 0) {
7504
+ return {
7505
+ success: false,
7506
+ error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
7507
+ };
7508
+ }
7509
+ const result = ClaudecodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
7510
+ if (!result.success) {
7511
+ return {
7512
+ success: false,
7513
+ error: new Error(
7514
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
7515
+ )
7516
+ };
7517
+ }
7518
+ return { success: true, error: null };
7519
+ }
7520
+ toRulesyncSkill() {
7521
+ const frontmatter = this.getFrontmatter();
7522
+ const rulesyncFrontmatter = {
7523
+ name: frontmatter.name,
7524
+ description: frontmatter.description,
7525
+ ...frontmatter["allowed-tools"] && {
7526
+ claudecode: {
7527
+ "allowed-tools": frontmatter["allowed-tools"]
7528
+ }
7529
+ }
7530
+ };
7531
+ return new RulesyncSkill({
7532
+ baseDir: this.baseDir,
7533
+ relativeDirPath: this.relativeDirPath,
7534
+ dirName: this.getDirName(),
7535
+ frontmatter: rulesyncFrontmatter,
7536
+ body: this.getBody(),
7537
+ otherFiles: this.getOtherFiles(),
7538
+ validate: true,
7539
+ global: this.global
7540
+ });
7541
+ }
7542
+ static fromRulesyncSkill({
7543
+ rulesyncSkill,
7544
+ validate = true,
7545
+ global = false
7546
+ }) {
7547
+ const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
7548
+ const claudecodeFrontmatter = {
7549
+ name: rulesyncFrontmatter.name,
7550
+ description: rulesyncFrontmatter.description,
7551
+ "allowed-tools": rulesyncFrontmatter.claudecode?.["allowed-tools"]
7552
+ };
7553
+ const settablePaths = _ClaudecodeSkill.getSettablePaths({ global });
7554
+ return new _ClaudecodeSkill({
7555
+ baseDir: rulesyncSkill.getBaseDir(),
7556
+ relativeDirPath: settablePaths.relativeDirPath,
7557
+ dirName: rulesyncSkill.getDirName(),
7558
+ frontmatter: claudecodeFrontmatter,
7559
+ body: rulesyncSkill.getBody(),
7560
+ otherFiles: rulesyncSkill.getOtherFiles(),
7561
+ validate,
7562
+ global
7563
+ });
7564
+ }
7565
+ static isTargetedByRulesyncSkill(_rulesyncSkill) {
7566
+ return true;
7567
+ }
7568
+ static async fromDir({
7569
+ baseDir = process.cwd(),
7570
+ relativeDirPath,
7571
+ dirName,
7572
+ global = false
7573
+ }) {
7574
+ const settablePaths = this.getSettablePaths({ global });
7575
+ const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
7576
+ const skillDirPath = (0, import_node_path70.join)(baseDir, actualRelativeDirPath, dirName);
7577
+ const skillFilePath = (0, import_node_path70.join)(skillDirPath, SKILL_FILE_NAME);
7578
+ if (!await fileExists(skillFilePath)) {
7579
+ throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
7580
+ }
7581
+ const fileContent = await readFileContent(skillFilePath);
7582
+ const { frontmatter, body: content } = parseFrontmatter(fileContent);
7583
+ const result = ClaudecodeSkillFrontmatterSchema.safeParse(frontmatter);
7584
+ if (!result.success) {
7585
+ throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
7586
+ }
7587
+ const otherFiles = await this.collectOtherFiles(
7588
+ baseDir,
7589
+ actualRelativeDirPath,
7590
+ dirName,
7591
+ SKILL_FILE_NAME
7592
+ );
7593
+ return new _ClaudecodeSkill({
7594
+ baseDir,
7595
+ relativeDirPath: actualRelativeDirPath,
7596
+ dirName,
7597
+ frontmatter: result.data,
7598
+ body: content.trim(),
7599
+ otherFiles,
7600
+ validate: true,
7601
+ global
7602
+ });
7603
+ }
7604
+ };
7605
+
7606
+ // src/features/skills/skills-processor.ts
7607
+ var skillsProcessorToolTargets = ["claudecode"];
7608
+ var skillsProcessorToolTargetsGlobal = ["claudecode"];
7609
+ var SkillsProcessorToolTargetSchema = import_mini27.z.enum(skillsProcessorToolTargets);
7610
+ var SkillsProcessor = class extends DirFeatureProcessor {
7611
+ toolTarget;
7612
+ global;
7613
+ constructor({
7614
+ baseDir = process.cwd(),
7615
+ toolTarget,
7616
+ global = false
7617
+ }) {
7618
+ super({ baseDir });
7619
+ const result = SkillsProcessorToolTargetSchema.safeParse(toolTarget);
7620
+ if (!result.success) {
7621
+ throw new Error(
7622
+ `Invalid tool target for SkillsProcessor: ${toolTarget}. ${formatError(result.error)}`
7623
+ );
7624
+ }
7625
+ this.toolTarget = result.data;
7626
+ this.global = global;
7627
+ }
7628
+ async convertRulesyncDirsToToolDirs(rulesyncDirs) {
7629
+ const rulesyncSkills = rulesyncDirs.filter(
7630
+ (dir) => dir instanceof RulesyncSkill
7631
+ );
7632
+ const toolSkills = rulesyncSkills.map((rulesyncSkill) => {
7633
+ switch (this.toolTarget) {
7634
+ case "claudecode":
7635
+ if (!ClaudecodeSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
7636
+ return null;
7637
+ }
7638
+ return ClaudecodeSkill.fromRulesyncSkill({
7639
+ rulesyncSkill,
7640
+ global: this.global
7641
+ });
7642
+ default:
7643
+ throw new Error(`Unsupported tool target: ${this.toolTarget}`);
7644
+ }
7645
+ }).filter((skill) => skill !== null);
7646
+ return toolSkills;
7647
+ }
7648
+ async convertToolDirsToRulesyncDirs(toolDirs) {
7649
+ const toolSkills = toolDirs.filter((dir) => dir instanceof ToolSkill);
7650
+ const rulesyncSkills = toolSkills.map((toolSkill) => {
7651
+ return toolSkill.toRulesyncSkill();
7652
+ });
7653
+ return rulesyncSkills;
7654
+ }
7655
+ /**
7656
+ * Implementation of abstract method from DirFeatureProcessor
7657
+ * Load and parse rulesync skill directories from .rulesync/skills/ directory
7658
+ */
7659
+ async loadRulesyncDirs() {
7660
+ const paths = RulesyncSkill.getSettablePaths();
7661
+ const rulesyncSkillsDirPath = (0, import_node_path71.join)(this.baseDir, paths.relativeDirPath);
7662
+ const dirPaths = await findFilesByGlobs((0, import_node_path71.join)(rulesyncSkillsDirPath, "*"), { type: "dir" });
7663
+ const dirNames = dirPaths.map((path3) => (0, import_node_path71.basename)(path3));
7664
+ const results = await Promise.allSettled(
7665
+ dirNames.map(
7666
+ (dirName) => RulesyncSkill.fromDir({ baseDir: this.baseDir, dirName, global: this.global })
7667
+ )
7668
+ );
7669
+ const rulesyncSkills = [];
7670
+ for (const result of results) {
7671
+ if (result.status === "fulfilled") {
7672
+ rulesyncSkills.push(result.value);
7673
+ }
7674
+ }
7675
+ logger.info(`Successfully loaded ${rulesyncSkills.length} rulesync skills`);
7676
+ return rulesyncSkills;
7677
+ }
7678
+ /**
7679
+ * Implementation of abstract method from DirFeatureProcessor
7680
+ * Load tool-specific skill configurations and parse them into ToolSkill instances
7681
+ */
7682
+ async loadToolDirs() {
7683
+ switch (this.toolTarget) {
7684
+ case "claudecode":
7685
+ return await this.loadClaudecodeSkills();
7686
+ default:
7687
+ throw new Error(`Unsupported tool target: ${this.toolTarget}`);
7688
+ }
7689
+ }
7690
+ async loadToolDirsToDelete() {
7691
+ return this.loadToolDirs();
7692
+ }
7693
+ /**
7694
+ * Load Claude Code skill configurations from .claude/skills/ directory
7695
+ */
7696
+ async loadClaudecodeSkills() {
7697
+ const paths = ClaudecodeSkill.getSettablePaths({ global: this.global });
7698
+ const skillsDirPath = (0, import_node_path71.join)(this.baseDir, paths.relativeDirPath);
7699
+ const dirPaths = await findFilesByGlobs((0, import_node_path71.join)(skillsDirPath, "*"), { type: "dir" });
7700
+ const dirNames = dirPaths.map((path3) => (0, import_node_path71.basename)(path3));
7701
+ const toolSkills = (await Promise.allSettled(
7702
+ dirNames.map(
7703
+ (dirName) => ClaudecodeSkill.fromDir({
7704
+ baseDir: this.baseDir,
7705
+ dirName,
7706
+ global: this.global
7707
+ })
7708
+ )
7709
+ )).filter((result) => result.status === "fulfilled").map((result) => result.value);
7710
+ logger.info(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
7711
+ return toolSkills;
7712
+ }
7713
+ /**
7714
+ * Implementation of abstract method from DirFeatureProcessor
7715
+ * Return the tool targets that this processor supports
7716
+ */
7717
+ static getToolTargets(_params = {}) {
7718
+ return skillsProcessorToolTargets;
7719
+ }
7720
+ /**
7721
+ * Return the tool targets that this processor supports in global mode
7722
+ */
7723
+ static getToolTargetsGlobal() {
7724
+ return skillsProcessorToolTargetsGlobal;
7725
+ }
7726
+ };
7727
+
7089
7728
  // src/cli/commands/generate.ts
7090
7729
  async function generateCommand(options) {
7091
7730
  const config = await ConfigResolver.resolve(options);
@@ -7101,7 +7740,8 @@ async function generateCommand(options) {
7101
7740
  const totalMcpOutputs = await generateMcp(config);
7102
7741
  const totalCommandOutputs = await generateCommands(config);
7103
7742
  const totalSubagentOutputs = await generateSubagents(config);
7104
- const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs;
7743
+ const totalSkillOutputs = await generateSkills(config);
7744
+ const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + totalSkillOutputs;
7105
7745
  if (totalGenerated === 0) {
7106
7746
  const enabledFeatures = config.getFeatures().join(", ");
7107
7747
  logger.warn(`\u26A0\uFE0F No files generated for enabled features: ${enabledFeatures}`);
@@ -7114,6 +7754,7 @@ async function generateCommand(options) {
7114
7754
  if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP files`);
7115
7755
  if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
7116
7756
  if (totalSubagentOutputs > 0) parts.push(`${totalSubagentOutputs} subagents`);
7757
+ if (totalSkillOutputs > 0) parts.push(`${totalSkillOutputs} skills`);
7117
7758
  logger.success(`\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`);
7118
7759
  }
7119
7760
  }
@@ -7288,11 +7929,39 @@ async function generateSubagents(config) {
7288
7929
  }
7289
7930
  return totalSubagentOutputs;
7290
7931
  }
7932
+ async function generateSkills(config) {
7933
+ if (!config.getFeatures().includes("skills")) {
7934
+ logger.debug("Skipping skill generation (not in --features)");
7935
+ return 0;
7936
+ }
7937
+ let totalSkillOutputs = 0;
7938
+ logger.info("Generating skill files...");
7939
+ const toolTargets = config.getGlobal() ? (0, import_es_toolkit2.intersection)(config.getTargets(), SkillsProcessor.getToolTargetsGlobal()) : (0, import_es_toolkit2.intersection)(config.getTargets(), SkillsProcessor.getToolTargets());
7940
+ for (const baseDir of config.getBaseDirs()) {
7941
+ for (const toolTarget of toolTargets) {
7942
+ const processor = new SkillsProcessor({
7943
+ baseDir,
7944
+ toolTarget,
7945
+ global: config.getGlobal()
7946
+ });
7947
+ if (config.getDelete()) {
7948
+ const oldToolDirs = await processor.loadToolDirsToDelete();
7949
+ await processor.removeAiDirs(oldToolDirs);
7950
+ }
7951
+ const rulesyncDirs = await processor.loadRulesyncDirs();
7952
+ const toolDirs = await processor.convertRulesyncDirsToToolDirs(rulesyncDirs);
7953
+ const writtenCount = await processor.writeAiDirs(toolDirs);
7954
+ totalSkillOutputs += writtenCount;
7955
+ logger.success(`Generated ${writtenCount} ${toolTarget} skill(s) in ${baseDir}`);
7956
+ }
7957
+ }
7958
+ return totalSkillOutputs;
7959
+ }
7291
7960
 
7292
7961
  // src/cli/commands/gitignore.ts
7293
- var import_node_path67 = require("path");
7962
+ var import_node_path72 = require("path");
7294
7963
  var gitignoreCommand = async () => {
7295
- const gitignorePath = (0, import_node_path67.join)(process.cwd(), ".gitignore");
7964
+ const gitignorePath = (0, import_node_path72.join)(process.cwd(), ".gitignore");
7296
7965
  const rulesFilesToIgnore = [
7297
7966
  "# Generated by rulesync - AI tool configuration files",
7298
7967
  // AGENTS.md
@@ -7309,6 +7978,7 @@ var gitignoreCommand = async () => {
7309
7978
  "**/.claude/memories/",
7310
7979
  "**/.claude/commands/",
7311
7980
  "**/.claude/agents/",
7981
+ "**/.claude/skills/",
7312
7982
  "**/.claude/settings.local.json",
7313
7983
  "**/.mcp.json",
7314
7984
  // Cline
@@ -7402,6 +8072,7 @@ async function importCommand(options) {
7402
8072
  await importMcp(config, tool);
7403
8073
  await importCommands(config, tool);
7404
8074
  await importSubagents(config, tool);
8075
+ await importSkills(config, tool);
7405
8076
  }
7406
8077
  async function importRules(config, tool) {
7407
8078
  if (!config.getFeatures().includes("rules")) {
@@ -7531,9 +8202,34 @@ async function importSubagents(config, tool) {
7531
8202
  }
7532
8203
  return writtenCount;
7533
8204
  }
8205
+ async function importSkills(config, tool) {
8206
+ if (!config.getFeatures().includes("skills")) {
8207
+ return 0;
8208
+ }
8209
+ const global = config.getGlobal();
8210
+ const supportedTargets = SkillsProcessor.getToolTargets();
8211
+ if (!supportedTargets.includes(tool)) {
8212
+ return 0;
8213
+ }
8214
+ const skillsProcessor = new SkillsProcessor({
8215
+ baseDir: config.getBaseDirs()[0] ?? ".",
8216
+ toolTarget: tool,
8217
+ global
8218
+ });
8219
+ const toolDirs = await skillsProcessor.loadToolDirs();
8220
+ if (toolDirs.length === 0) {
8221
+ return 0;
8222
+ }
8223
+ const rulesyncDirs = await skillsProcessor.convertToolDirsToRulesyncDirs(toolDirs);
8224
+ const writtenCount = await skillsProcessor.writeAiDirs(rulesyncDirs);
8225
+ if (config.getVerbose() && writtenCount > 0) {
8226
+ logger.success(`Created ${writtenCount} skill directories`);
8227
+ }
8228
+ return writtenCount;
8229
+ }
7534
8230
 
7535
8231
  // src/cli/commands/init.ts
7536
- var import_node_path68 = require("path");
8232
+ var import_node_path73 = require("path");
7537
8233
  async function initCommand() {
7538
8234
  logger.info("Initializing rulesync...");
7539
8235
  await ensureDir(RULESYNC_RELATIVE_DIR_PATH);
@@ -7696,14 +8392,14 @@ Attention, again, you are just the planner, so though you can read any files and
7696
8392
  await ensureDir(commandPaths.relativeDirPath);
7697
8393
  await ensureDir(subagentPaths.relativeDirPath);
7698
8394
  await ensureDir(ignorePaths.relativeDirPath);
7699
- const ruleFilepath = (0, import_node_path68.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
8395
+ const ruleFilepath = (0, import_node_path73.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
7700
8396
  if (!await fileExists(ruleFilepath)) {
7701
8397
  await writeFileContent(ruleFilepath, sampleRuleFile.content);
7702
8398
  logger.success(`Created ${ruleFilepath}`);
7703
8399
  } else {
7704
8400
  logger.info(`Skipped ${ruleFilepath} (already exists)`);
7705
8401
  }
7706
- const mcpFilepath = (0, import_node_path68.join)(
8402
+ const mcpFilepath = (0, import_node_path73.join)(
7707
8403
  mcpPaths.recommended.relativeDirPath,
7708
8404
  mcpPaths.recommended.relativeFilePath
7709
8405
  );
@@ -7713,21 +8409,21 @@ Attention, again, you are just the planner, so though you can read any files and
7713
8409
  } else {
7714
8410
  logger.info(`Skipped ${mcpFilepath} (already exists)`);
7715
8411
  }
7716
- const commandFilepath = (0, import_node_path68.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
8412
+ const commandFilepath = (0, import_node_path73.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
7717
8413
  if (!await fileExists(commandFilepath)) {
7718
8414
  await writeFileContent(commandFilepath, sampleCommandFile.content);
7719
8415
  logger.success(`Created ${commandFilepath}`);
7720
8416
  } else {
7721
8417
  logger.info(`Skipped ${commandFilepath} (already exists)`);
7722
8418
  }
7723
- const subagentFilepath = (0, import_node_path68.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
8419
+ const subagentFilepath = (0, import_node_path73.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
7724
8420
  if (!await fileExists(subagentFilepath)) {
7725
8421
  await writeFileContent(subagentFilepath, sampleSubagentFile.content);
7726
8422
  logger.success(`Created ${subagentFilepath}`);
7727
8423
  } else {
7728
8424
  logger.info(`Skipped ${subagentFilepath} (already exists)`);
7729
8425
  }
7730
- const ignoreFilepath = (0, import_node_path68.join)(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
8426
+ const ignoreFilepath = (0, import_node_path73.join)(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
7731
8427
  if (!await fileExists(ignoreFilepath)) {
7732
8428
  await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
7733
8429
  logger.success(`Created ${ignoreFilepath}`);
@@ -7740,12 +8436,12 @@ Attention, again, you are just the planner, so though you can read any files and
7740
8436
  var import_fastmcp = require("fastmcp");
7741
8437
 
7742
8438
  // src/mcp/commands.ts
7743
- var import_node_path69 = require("path");
7744
- var import_mini25 = require("zod/mini");
8439
+ var import_node_path74 = require("path");
8440
+ var import_mini28 = require("zod/mini");
7745
8441
  var maxCommandSizeBytes = 1024 * 1024;
7746
8442
  var maxCommandsCount = 1e3;
7747
8443
  async function listCommands() {
7748
- const commandsDir = (0, import_node_path69.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
8444
+ const commandsDir = (0, import_node_path74.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
7749
8445
  try {
7750
8446
  const files = await listDirectoryFiles(commandsDir);
7751
8447
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -7757,7 +8453,7 @@ async function listCommands() {
7757
8453
  });
7758
8454
  const frontmatter = command.getFrontmatter();
7759
8455
  return {
7760
- relativePathFromCwd: (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
8456
+ relativePathFromCwd: (0, import_node_path74.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
7761
8457
  frontmatter
7762
8458
  };
7763
8459
  } catch (error) {
@@ -7777,13 +8473,13 @@ async function getCommand({ relativePathFromCwd }) {
7777
8473
  relativePath: relativePathFromCwd,
7778
8474
  intendedRootDir: process.cwd()
7779
8475
  });
7780
- const filename = (0, import_node_path69.basename)(relativePathFromCwd);
8476
+ const filename = (0, import_node_path74.basename)(relativePathFromCwd);
7781
8477
  try {
7782
8478
  const command = await RulesyncCommand.fromFile({
7783
8479
  relativeFilePath: filename
7784
8480
  });
7785
8481
  return {
7786
- relativePathFromCwd: (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
8482
+ relativePathFromCwd: (0, import_node_path74.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
7787
8483
  frontmatter: command.getFrontmatter(),
7788
8484
  body: command.getBody()
7789
8485
  };
@@ -7802,7 +8498,7 @@ async function putCommand({
7802
8498
  relativePath: relativePathFromCwd,
7803
8499
  intendedRootDir: process.cwd()
7804
8500
  });
7805
- const filename = (0, import_node_path69.basename)(relativePathFromCwd);
8501
+ const filename = (0, import_node_path74.basename)(relativePathFromCwd);
7806
8502
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
7807
8503
  if (estimatedSize > maxCommandSizeBytes) {
7808
8504
  throw new Error(
@@ -7812,7 +8508,7 @@ async function putCommand({
7812
8508
  try {
7813
8509
  const existingCommands = await listCommands();
7814
8510
  const isUpdate = existingCommands.some(
7815
- (command2) => command2.relativePathFromCwd === (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
8511
+ (command2) => command2.relativePathFromCwd === (0, import_node_path74.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
7816
8512
  );
7817
8513
  if (!isUpdate && existingCommands.length >= maxCommandsCount) {
7818
8514
  throw new Error(`Maximum number of commands (${maxCommandsCount}) reached`);
@@ -7827,11 +8523,11 @@ async function putCommand({
7827
8523
  fileContent,
7828
8524
  validate: true
7829
8525
  });
7830
- const commandsDir = (0, import_node_path69.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
8526
+ const commandsDir = (0, import_node_path74.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
7831
8527
  await ensureDir(commandsDir);
7832
8528
  await writeFileContent(command.getFilePath(), command.getFileContent());
7833
8529
  return {
7834
- relativePathFromCwd: (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
8530
+ relativePathFromCwd: (0, import_node_path74.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
7835
8531
  frontmatter: command.getFrontmatter(),
7836
8532
  body: command.getBody()
7837
8533
  };
@@ -7846,12 +8542,12 @@ async function deleteCommand({ relativePathFromCwd }) {
7846
8542
  relativePath: relativePathFromCwd,
7847
8543
  intendedRootDir: process.cwd()
7848
8544
  });
7849
- const filename = (0, import_node_path69.basename)(relativePathFromCwd);
7850
- const fullPath = (0, import_node_path69.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
8545
+ const filename = (0, import_node_path74.basename)(relativePathFromCwd);
8546
+ const fullPath = (0, import_node_path74.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
7851
8547
  try {
7852
8548
  await removeFile(fullPath);
7853
8549
  return {
7854
- relativePathFromCwd: (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
8550
+ relativePathFromCwd: (0, import_node_path74.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
7855
8551
  };
7856
8552
  } catch (error) {
7857
8553
  throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -7860,23 +8556,23 @@ async function deleteCommand({ relativePathFromCwd }) {
7860
8556
  }
7861
8557
  }
7862
8558
  var commandToolSchemas = {
7863
- listCommands: import_mini25.z.object({}),
7864
- getCommand: import_mini25.z.object({
7865
- relativePathFromCwd: import_mini25.z.string()
8559
+ listCommands: import_mini28.z.object({}),
8560
+ getCommand: import_mini28.z.object({
8561
+ relativePathFromCwd: import_mini28.z.string()
7866
8562
  }),
7867
- putCommand: import_mini25.z.object({
7868
- relativePathFromCwd: import_mini25.z.string(),
8563
+ putCommand: import_mini28.z.object({
8564
+ relativePathFromCwd: import_mini28.z.string(),
7869
8565
  frontmatter: RulesyncCommandFrontmatterSchema,
7870
- body: import_mini25.z.string()
8566
+ body: import_mini28.z.string()
7871
8567
  }),
7872
- deleteCommand: import_mini25.z.object({
7873
- relativePathFromCwd: import_mini25.z.string()
8568
+ deleteCommand: import_mini28.z.object({
8569
+ relativePathFromCwd: import_mini28.z.string()
7874
8570
  })
7875
8571
  };
7876
8572
  var commandTools = {
7877
8573
  listCommands: {
7878
8574
  name: "listCommands",
7879
- description: `List all commands from ${(0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
8575
+ description: `List all commands from ${(0, import_node_path74.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
7880
8576
  parameters: commandToolSchemas.listCommands,
7881
8577
  execute: async () => {
7882
8578
  const commands = await listCommands();
@@ -7918,11 +8614,11 @@ var commandTools = {
7918
8614
  };
7919
8615
 
7920
8616
  // src/mcp/ignore.ts
7921
- var import_node_path70 = require("path");
7922
- var import_mini26 = require("zod/mini");
8617
+ var import_node_path75 = require("path");
8618
+ var import_mini29 = require("zod/mini");
7923
8619
  var maxIgnoreFileSizeBytes = 100 * 1024;
7924
8620
  async function getIgnoreFile() {
7925
- const ignoreFilePath = (0, import_node_path70.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
8621
+ const ignoreFilePath = (0, import_node_path75.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
7926
8622
  try {
7927
8623
  const content = await readFileContent(ignoreFilePath);
7928
8624
  return {
@@ -7936,7 +8632,7 @@ async function getIgnoreFile() {
7936
8632
  }
7937
8633
  }
7938
8634
  async function putIgnoreFile({ content }) {
7939
- const ignoreFilePath = (0, import_node_path70.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
8635
+ const ignoreFilePath = (0, import_node_path75.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
7940
8636
  const contentSizeBytes = Buffer.byteLength(content, "utf8");
7941
8637
  if (contentSizeBytes > maxIgnoreFileSizeBytes) {
7942
8638
  throw new Error(
@@ -7957,7 +8653,7 @@ async function putIgnoreFile({ content }) {
7957
8653
  }
7958
8654
  }
7959
8655
  async function deleteIgnoreFile() {
7960
- const ignoreFilePath = (0, import_node_path70.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
8656
+ const ignoreFilePath = (0, import_node_path75.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
7961
8657
  try {
7962
8658
  await removeFile(ignoreFilePath);
7963
8659
  return {
@@ -7970,11 +8666,11 @@ async function deleteIgnoreFile() {
7970
8666
  }
7971
8667
  }
7972
8668
  var ignoreToolSchemas = {
7973
- getIgnoreFile: import_mini26.z.object({}),
7974
- putIgnoreFile: import_mini26.z.object({
7975
- content: import_mini26.z.string()
8669
+ getIgnoreFile: import_mini29.z.object({}),
8670
+ putIgnoreFile: import_mini29.z.object({
8671
+ content: import_mini29.z.string()
7976
8672
  }),
7977
- deleteIgnoreFile: import_mini26.z.object({})
8673
+ deleteIgnoreFile: import_mini29.z.object({})
7978
8674
  };
7979
8675
  var ignoreTools = {
7980
8676
  getIgnoreFile: {
@@ -8007,8 +8703,8 @@ var ignoreTools = {
8007
8703
  };
8008
8704
 
8009
8705
  // src/mcp/mcp.ts
8010
- var import_node_path71 = require("path");
8011
- var import_mini27 = require("zod/mini");
8706
+ var import_node_path76 = require("path");
8707
+ var import_mini30 = require("zod/mini");
8012
8708
  var maxMcpSizeBytes = 1024 * 1024;
8013
8709
  async function getMcpFile() {
8014
8710
  const config = await ConfigResolver.resolve({});
@@ -8017,7 +8713,7 @@ async function getMcpFile() {
8017
8713
  validate: true,
8018
8714
  modularMcp: config.getModularMcp()
8019
8715
  });
8020
- const relativePathFromCwd = (0, import_node_path71.join)(
8716
+ const relativePathFromCwd = (0, import_node_path76.join)(
8021
8717
  rulesyncMcp.getRelativeDirPath(),
8022
8718
  rulesyncMcp.getRelativeFilePath()
8023
8719
  );
@@ -8050,7 +8746,7 @@ async function putMcpFile({ content }) {
8050
8746
  const paths = RulesyncMcp.getSettablePaths();
8051
8747
  const relativeDirPath = paths.recommended.relativeDirPath;
8052
8748
  const relativeFilePath = paths.recommended.relativeFilePath;
8053
- const fullPath = (0, import_node_path71.join)(baseDir, relativeDirPath, relativeFilePath);
8749
+ const fullPath = (0, import_node_path76.join)(baseDir, relativeDirPath, relativeFilePath);
8054
8750
  const rulesyncMcp = new RulesyncMcp({
8055
8751
  baseDir,
8056
8752
  relativeDirPath,
@@ -8059,9 +8755,9 @@ async function putMcpFile({ content }) {
8059
8755
  validate: true,
8060
8756
  modularMcp: config.getModularMcp()
8061
8757
  });
8062
- await ensureDir((0, import_node_path71.join)(baseDir, relativeDirPath));
8758
+ await ensureDir((0, import_node_path76.join)(baseDir, relativeDirPath));
8063
8759
  await writeFileContent(fullPath, content);
8064
- const relativePathFromCwd = (0, import_node_path71.join)(relativeDirPath, relativeFilePath);
8760
+ const relativePathFromCwd = (0, import_node_path76.join)(relativeDirPath, relativeFilePath);
8065
8761
  return {
8066
8762
  relativePathFromCwd,
8067
8763
  content: rulesyncMcp.getFileContent()
@@ -8076,15 +8772,15 @@ async function deleteMcpFile() {
8076
8772
  try {
8077
8773
  const baseDir = process.cwd();
8078
8774
  const paths = RulesyncMcp.getSettablePaths();
8079
- const recommendedPath = (0, import_node_path71.join)(
8775
+ const recommendedPath = (0, import_node_path76.join)(
8080
8776
  baseDir,
8081
8777
  paths.recommended.relativeDirPath,
8082
8778
  paths.recommended.relativeFilePath
8083
8779
  );
8084
- const legacyPath = (0, import_node_path71.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
8780
+ const legacyPath = (0, import_node_path76.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
8085
8781
  await removeFile(recommendedPath);
8086
8782
  await removeFile(legacyPath);
8087
- const relativePathFromCwd = (0, import_node_path71.join)(
8783
+ const relativePathFromCwd = (0, import_node_path76.join)(
8088
8784
  paths.recommended.relativeDirPath,
8089
8785
  paths.recommended.relativeFilePath
8090
8786
  );
@@ -8098,11 +8794,11 @@ async function deleteMcpFile() {
8098
8794
  }
8099
8795
  }
8100
8796
  var mcpToolSchemas = {
8101
- getMcpFile: import_mini27.z.object({}),
8102
- putMcpFile: import_mini27.z.object({
8103
- content: import_mini27.z.string()
8797
+ getMcpFile: import_mini30.z.object({}),
8798
+ putMcpFile: import_mini30.z.object({
8799
+ content: import_mini30.z.string()
8104
8800
  }),
8105
- deleteMcpFile: import_mini27.z.object({})
8801
+ deleteMcpFile: import_mini30.z.object({})
8106
8802
  };
8107
8803
  var mcpTools = {
8108
8804
  getMcpFile: {
@@ -8135,12 +8831,12 @@ var mcpTools = {
8135
8831
  };
8136
8832
 
8137
8833
  // src/mcp/rules.ts
8138
- var import_node_path72 = require("path");
8139
- var import_mini28 = require("zod/mini");
8834
+ var import_node_path77 = require("path");
8835
+ var import_mini31 = require("zod/mini");
8140
8836
  var maxRuleSizeBytes = 1024 * 1024;
8141
8837
  var maxRulesCount = 1e3;
8142
8838
  async function listRules() {
8143
- const rulesDir = (0, import_node_path72.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
8839
+ const rulesDir = (0, import_node_path77.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
8144
8840
  try {
8145
8841
  const files = await listDirectoryFiles(rulesDir);
8146
8842
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -8153,7 +8849,7 @@ async function listRules() {
8153
8849
  });
8154
8850
  const frontmatter = rule.getFrontmatter();
8155
8851
  return {
8156
- relativePathFromCwd: (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
8852
+ relativePathFromCwd: (0, import_node_path77.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
8157
8853
  frontmatter
8158
8854
  };
8159
8855
  } catch (error) {
@@ -8173,14 +8869,14 @@ async function getRule({ relativePathFromCwd }) {
8173
8869
  relativePath: relativePathFromCwd,
8174
8870
  intendedRootDir: process.cwd()
8175
8871
  });
8176
- const filename = (0, import_node_path72.basename)(relativePathFromCwd);
8872
+ const filename = (0, import_node_path77.basename)(relativePathFromCwd);
8177
8873
  try {
8178
8874
  const rule = await RulesyncRule.fromFile({
8179
8875
  relativeFilePath: filename,
8180
8876
  validate: true
8181
8877
  });
8182
8878
  return {
8183
- relativePathFromCwd: (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
8879
+ relativePathFromCwd: (0, import_node_path77.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
8184
8880
  frontmatter: rule.getFrontmatter(),
8185
8881
  body: rule.getBody()
8186
8882
  };
@@ -8199,7 +8895,7 @@ async function putRule({
8199
8895
  relativePath: relativePathFromCwd,
8200
8896
  intendedRootDir: process.cwd()
8201
8897
  });
8202
- const filename = (0, import_node_path72.basename)(relativePathFromCwd);
8898
+ const filename = (0, import_node_path77.basename)(relativePathFromCwd);
8203
8899
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
8204
8900
  if (estimatedSize > maxRuleSizeBytes) {
8205
8901
  throw new Error(
@@ -8209,7 +8905,7 @@ async function putRule({
8209
8905
  try {
8210
8906
  const existingRules = await listRules();
8211
8907
  const isUpdate = existingRules.some(
8212
- (rule2) => rule2.relativePathFromCwd === (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
8908
+ (rule2) => rule2.relativePathFromCwd === (0, import_node_path77.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
8213
8909
  );
8214
8910
  if (!isUpdate && existingRules.length >= maxRulesCount) {
8215
8911
  throw new Error(`Maximum number of rules (${maxRulesCount}) reached`);
@@ -8222,11 +8918,11 @@ async function putRule({
8222
8918
  body,
8223
8919
  validate: true
8224
8920
  });
8225
- const rulesDir = (0, import_node_path72.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
8921
+ const rulesDir = (0, import_node_path77.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
8226
8922
  await ensureDir(rulesDir);
8227
8923
  await writeFileContent(rule.getFilePath(), rule.getFileContent());
8228
8924
  return {
8229
- relativePathFromCwd: (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
8925
+ relativePathFromCwd: (0, import_node_path77.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
8230
8926
  frontmatter: rule.getFrontmatter(),
8231
8927
  body: rule.getBody()
8232
8928
  };
@@ -8241,12 +8937,12 @@ async function deleteRule({ relativePathFromCwd }) {
8241
8937
  relativePath: relativePathFromCwd,
8242
8938
  intendedRootDir: process.cwd()
8243
8939
  });
8244
- const filename = (0, import_node_path72.basename)(relativePathFromCwd);
8245
- const fullPath = (0, import_node_path72.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
8940
+ const filename = (0, import_node_path77.basename)(relativePathFromCwd);
8941
+ const fullPath = (0, import_node_path77.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
8246
8942
  try {
8247
8943
  await removeFile(fullPath);
8248
8944
  return {
8249
- relativePathFromCwd: (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
8945
+ relativePathFromCwd: (0, import_node_path77.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
8250
8946
  };
8251
8947
  } catch (error) {
8252
8948
  throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -8255,23 +8951,23 @@ async function deleteRule({ relativePathFromCwd }) {
8255
8951
  }
8256
8952
  }
8257
8953
  var ruleToolSchemas = {
8258
- listRules: import_mini28.z.object({}),
8259
- getRule: import_mini28.z.object({
8260
- relativePathFromCwd: import_mini28.z.string()
8954
+ listRules: import_mini31.z.object({}),
8955
+ getRule: import_mini31.z.object({
8956
+ relativePathFromCwd: import_mini31.z.string()
8261
8957
  }),
8262
- putRule: import_mini28.z.object({
8263
- relativePathFromCwd: import_mini28.z.string(),
8958
+ putRule: import_mini31.z.object({
8959
+ relativePathFromCwd: import_mini31.z.string(),
8264
8960
  frontmatter: RulesyncRuleFrontmatterSchema,
8265
- body: import_mini28.z.string()
8961
+ body: import_mini31.z.string()
8266
8962
  }),
8267
- deleteRule: import_mini28.z.object({
8268
- relativePathFromCwd: import_mini28.z.string()
8963
+ deleteRule: import_mini31.z.object({
8964
+ relativePathFromCwd: import_mini31.z.string()
8269
8965
  })
8270
8966
  };
8271
8967
  var ruleTools = {
8272
8968
  listRules: {
8273
8969
  name: "listRules",
8274
- description: `List all rules from ${(0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
8970
+ description: `List all rules from ${(0, import_node_path77.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
8275
8971
  parameters: ruleToolSchemas.listRules,
8276
8972
  execute: async () => {
8277
8973
  const rules = await listRules();
@@ -8313,12 +9009,12 @@ var ruleTools = {
8313
9009
  };
8314
9010
 
8315
9011
  // src/mcp/subagents.ts
8316
- var import_node_path73 = require("path");
8317
- var import_mini29 = require("zod/mini");
9012
+ var import_node_path78 = require("path");
9013
+ var import_mini32 = require("zod/mini");
8318
9014
  var maxSubagentSizeBytes = 1024 * 1024;
8319
9015
  var maxSubagentsCount = 1e3;
8320
9016
  async function listSubagents() {
8321
- const subagentsDir = (0, import_node_path73.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
9017
+ const subagentsDir = (0, import_node_path78.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
8322
9018
  try {
8323
9019
  const files = await listDirectoryFiles(subagentsDir);
8324
9020
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -8331,7 +9027,7 @@ async function listSubagents() {
8331
9027
  });
8332
9028
  const frontmatter = subagent.getFrontmatter();
8333
9029
  return {
8334
- relativePathFromCwd: (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
9030
+ relativePathFromCwd: (0, import_node_path78.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
8335
9031
  frontmatter
8336
9032
  };
8337
9033
  } catch (error) {
@@ -8353,14 +9049,14 @@ async function getSubagent({ relativePathFromCwd }) {
8353
9049
  relativePath: relativePathFromCwd,
8354
9050
  intendedRootDir: process.cwd()
8355
9051
  });
8356
- const filename = (0, import_node_path73.basename)(relativePathFromCwd);
9052
+ const filename = (0, import_node_path78.basename)(relativePathFromCwd);
8357
9053
  try {
8358
9054
  const subagent = await RulesyncSubagent.fromFile({
8359
9055
  relativeFilePath: filename,
8360
9056
  validate: true
8361
9057
  });
8362
9058
  return {
8363
- relativePathFromCwd: (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
9059
+ relativePathFromCwd: (0, import_node_path78.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
8364
9060
  frontmatter: subagent.getFrontmatter(),
8365
9061
  body: subagent.getBody()
8366
9062
  };
@@ -8379,7 +9075,7 @@ async function putSubagent({
8379
9075
  relativePath: relativePathFromCwd,
8380
9076
  intendedRootDir: process.cwd()
8381
9077
  });
8382
- const filename = (0, import_node_path73.basename)(relativePathFromCwd);
9078
+ const filename = (0, import_node_path78.basename)(relativePathFromCwd);
8383
9079
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
8384
9080
  if (estimatedSize > maxSubagentSizeBytes) {
8385
9081
  throw new Error(
@@ -8389,7 +9085,7 @@ async function putSubagent({
8389
9085
  try {
8390
9086
  const existingSubagents = await listSubagents();
8391
9087
  const isUpdate = existingSubagents.some(
8392
- (subagent2) => subagent2.relativePathFromCwd === (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
9088
+ (subagent2) => subagent2.relativePathFromCwd === (0, import_node_path78.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
8393
9089
  );
8394
9090
  if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
8395
9091
  throw new Error(`Maximum number of subagents (${maxSubagentsCount}) reached`);
@@ -8402,11 +9098,11 @@ async function putSubagent({
8402
9098
  body,
8403
9099
  validate: true
8404
9100
  });
8405
- const subagentsDir = (0, import_node_path73.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
9101
+ const subagentsDir = (0, import_node_path78.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
8406
9102
  await ensureDir(subagentsDir);
8407
9103
  await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
8408
9104
  return {
8409
- relativePathFromCwd: (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
9105
+ relativePathFromCwd: (0, import_node_path78.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
8410
9106
  frontmatter: subagent.getFrontmatter(),
8411
9107
  body: subagent.getBody()
8412
9108
  };
@@ -8421,12 +9117,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
8421
9117
  relativePath: relativePathFromCwd,
8422
9118
  intendedRootDir: process.cwd()
8423
9119
  });
8424
- const filename = (0, import_node_path73.basename)(relativePathFromCwd);
8425
- const fullPath = (0, import_node_path73.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
9120
+ const filename = (0, import_node_path78.basename)(relativePathFromCwd);
9121
+ const fullPath = (0, import_node_path78.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
8426
9122
  try {
8427
9123
  await removeFile(fullPath);
8428
9124
  return {
8429
- relativePathFromCwd: (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
9125
+ relativePathFromCwd: (0, import_node_path78.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
8430
9126
  };
8431
9127
  } catch (error) {
8432
9128
  throw new Error(
@@ -8438,23 +9134,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
8438
9134
  }
8439
9135
  }
8440
9136
  var subagentToolSchemas = {
8441
- listSubagents: import_mini29.z.object({}),
8442
- getSubagent: import_mini29.z.object({
8443
- relativePathFromCwd: import_mini29.z.string()
9137
+ listSubagents: import_mini32.z.object({}),
9138
+ getSubagent: import_mini32.z.object({
9139
+ relativePathFromCwd: import_mini32.z.string()
8444
9140
  }),
8445
- putSubagent: import_mini29.z.object({
8446
- relativePathFromCwd: import_mini29.z.string(),
9141
+ putSubagent: import_mini32.z.object({
9142
+ relativePathFromCwd: import_mini32.z.string(),
8447
9143
  frontmatter: RulesyncSubagentFrontmatterSchema,
8448
- body: import_mini29.z.string()
9144
+ body: import_mini32.z.string()
8449
9145
  }),
8450
- deleteSubagent: import_mini29.z.object({
8451
- relativePathFromCwd: import_mini29.z.string()
9146
+ deleteSubagent: import_mini32.z.object({
9147
+ relativePathFromCwd: import_mini32.z.string()
8452
9148
  })
8453
9149
  };
8454
9150
  var subagentTools = {
8455
9151
  listSubagents: {
8456
9152
  name: "listSubagents",
8457
- description: `List all subagents from ${(0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
9153
+ description: `List all subagents from ${(0, import_node_path78.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
8458
9154
  parameters: subagentToolSchemas.listSubagents,
8459
9155
  execute: async () => {
8460
9156
  const subagents = await listSubagents();
@@ -8528,7 +9224,7 @@ async function mcpCommand({ version }) {
8528
9224
  }
8529
9225
 
8530
9226
  // src/cli/index.ts
8531
- var getVersion = () => "3.23.5";
9227
+ var getVersion = () => "3.24.0";
8532
9228
  var main = async () => {
8533
9229
  const program = new import_commander.Command();
8534
9230
  const version = getVersion();