rulesync 3.23.6 → 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 +802 -112
  3. package/dist/index.js +802 -112
  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:
@@ -4570,7 +4595,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
4570
4595
  fromFile
4571
4596
  }) {
4572
4597
  const paths = await findFilesByGlobs((0, import_node_path46.join)(this.baseDir, relativeDirPath, "*.md"));
4573
- 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);
4574
4599
  logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
4575
4600
  return subagents;
4576
4601
  }
@@ -7092,6 +7117,614 @@ For example, if the user instructs \`Call planner subagent to plan the refactori
7092
7117
  }
7093
7118
  };
7094
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
+
7095
7728
  // src/cli/commands/generate.ts
7096
7729
  async function generateCommand(options) {
7097
7730
  const config = await ConfigResolver.resolve(options);
@@ -7107,7 +7740,8 @@ async function generateCommand(options) {
7107
7740
  const totalMcpOutputs = await generateMcp(config);
7108
7741
  const totalCommandOutputs = await generateCommands(config);
7109
7742
  const totalSubagentOutputs = await generateSubagents(config);
7110
- const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs;
7743
+ const totalSkillOutputs = await generateSkills(config);
7744
+ const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + totalSkillOutputs;
7111
7745
  if (totalGenerated === 0) {
7112
7746
  const enabledFeatures = config.getFeatures().join(", ");
7113
7747
  logger.warn(`\u26A0\uFE0F No files generated for enabled features: ${enabledFeatures}`);
@@ -7120,6 +7754,7 @@ async function generateCommand(options) {
7120
7754
  if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP files`);
7121
7755
  if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
7122
7756
  if (totalSubagentOutputs > 0) parts.push(`${totalSubagentOutputs} subagents`);
7757
+ if (totalSkillOutputs > 0) parts.push(`${totalSkillOutputs} skills`);
7123
7758
  logger.success(`\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`);
7124
7759
  }
7125
7760
  }
@@ -7294,11 +7929,39 @@ async function generateSubagents(config) {
7294
7929
  }
7295
7930
  return totalSubagentOutputs;
7296
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
+ }
7297
7960
 
7298
7961
  // src/cli/commands/gitignore.ts
7299
- var import_node_path67 = require("path");
7962
+ var import_node_path72 = require("path");
7300
7963
  var gitignoreCommand = async () => {
7301
- const gitignorePath = (0, import_node_path67.join)(process.cwd(), ".gitignore");
7964
+ const gitignorePath = (0, import_node_path72.join)(process.cwd(), ".gitignore");
7302
7965
  const rulesFilesToIgnore = [
7303
7966
  "# Generated by rulesync - AI tool configuration files",
7304
7967
  // AGENTS.md
@@ -7315,6 +7978,7 @@ var gitignoreCommand = async () => {
7315
7978
  "**/.claude/memories/",
7316
7979
  "**/.claude/commands/",
7317
7980
  "**/.claude/agents/",
7981
+ "**/.claude/skills/",
7318
7982
  "**/.claude/settings.local.json",
7319
7983
  "**/.mcp.json",
7320
7984
  // Cline
@@ -7408,6 +8072,7 @@ async function importCommand(options) {
7408
8072
  await importMcp(config, tool);
7409
8073
  await importCommands(config, tool);
7410
8074
  await importSubagents(config, tool);
8075
+ await importSkills(config, tool);
7411
8076
  }
7412
8077
  async function importRules(config, tool) {
7413
8078
  if (!config.getFeatures().includes("rules")) {
@@ -7537,9 +8202,34 @@ async function importSubagents(config, tool) {
7537
8202
  }
7538
8203
  return writtenCount;
7539
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
+ }
7540
8230
 
7541
8231
  // src/cli/commands/init.ts
7542
- var import_node_path68 = require("path");
8232
+ var import_node_path73 = require("path");
7543
8233
  async function initCommand() {
7544
8234
  logger.info("Initializing rulesync...");
7545
8235
  await ensureDir(RULESYNC_RELATIVE_DIR_PATH);
@@ -7702,14 +8392,14 @@ Attention, again, you are just the planner, so though you can read any files and
7702
8392
  await ensureDir(commandPaths.relativeDirPath);
7703
8393
  await ensureDir(subagentPaths.relativeDirPath);
7704
8394
  await ensureDir(ignorePaths.relativeDirPath);
7705
- 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);
7706
8396
  if (!await fileExists(ruleFilepath)) {
7707
8397
  await writeFileContent(ruleFilepath, sampleRuleFile.content);
7708
8398
  logger.success(`Created ${ruleFilepath}`);
7709
8399
  } else {
7710
8400
  logger.info(`Skipped ${ruleFilepath} (already exists)`);
7711
8401
  }
7712
- const mcpFilepath = (0, import_node_path68.join)(
8402
+ const mcpFilepath = (0, import_node_path73.join)(
7713
8403
  mcpPaths.recommended.relativeDirPath,
7714
8404
  mcpPaths.recommended.relativeFilePath
7715
8405
  );
@@ -7719,21 +8409,21 @@ Attention, again, you are just the planner, so though you can read any files and
7719
8409
  } else {
7720
8410
  logger.info(`Skipped ${mcpFilepath} (already exists)`);
7721
8411
  }
7722
- const commandFilepath = (0, import_node_path68.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
8412
+ const commandFilepath = (0, import_node_path73.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
7723
8413
  if (!await fileExists(commandFilepath)) {
7724
8414
  await writeFileContent(commandFilepath, sampleCommandFile.content);
7725
8415
  logger.success(`Created ${commandFilepath}`);
7726
8416
  } else {
7727
8417
  logger.info(`Skipped ${commandFilepath} (already exists)`);
7728
8418
  }
7729
- const subagentFilepath = (0, import_node_path68.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
8419
+ const subagentFilepath = (0, import_node_path73.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
7730
8420
  if (!await fileExists(subagentFilepath)) {
7731
8421
  await writeFileContent(subagentFilepath, sampleSubagentFile.content);
7732
8422
  logger.success(`Created ${subagentFilepath}`);
7733
8423
  } else {
7734
8424
  logger.info(`Skipped ${subagentFilepath} (already exists)`);
7735
8425
  }
7736
- const ignoreFilepath = (0, import_node_path68.join)(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
8426
+ const ignoreFilepath = (0, import_node_path73.join)(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
7737
8427
  if (!await fileExists(ignoreFilepath)) {
7738
8428
  await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
7739
8429
  logger.success(`Created ${ignoreFilepath}`);
@@ -7746,12 +8436,12 @@ Attention, again, you are just the planner, so though you can read any files and
7746
8436
  var import_fastmcp = require("fastmcp");
7747
8437
 
7748
8438
  // src/mcp/commands.ts
7749
- var import_node_path69 = require("path");
7750
- var import_mini25 = require("zod/mini");
8439
+ var import_node_path74 = require("path");
8440
+ var import_mini28 = require("zod/mini");
7751
8441
  var maxCommandSizeBytes = 1024 * 1024;
7752
8442
  var maxCommandsCount = 1e3;
7753
8443
  async function listCommands() {
7754
- 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);
7755
8445
  try {
7756
8446
  const files = await listDirectoryFiles(commandsDir);
7757
8447
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -7763,7 +8453,7 @@ async function listCommands() {
7763
8453
  });
7764
8454
  const frontmatter = command.getFrontmatter();
7765
8455
  return {
7766
- 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),
7767
8457
  frontmatter
7768
8458
  };
7769
8459
  } catch (error) {
@@ -7783,13 +8473,13 @@ async function getCommand({ relativePathFromCwd }) {
7783
8473
  relativePath: relativePathFromCwd,
7784
8474
  intendedRootDir: process.cwd()
7785
8475
  });
7786
- const filename = (0, import_node_path69.basename)(relativePathFromCwd);
8476
+ const filename = (0, import_node_path74.basename)(relativePathFromCwd);
7787
8477
  try {
7788
8478
  const command = await RulesyncCommand.fromFile({
7789
8479
  relativeFilePath: filename
7790
8480
  });
7791
8481
  return {
7792
- 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),
7793
8483
  frontmatter: command.getFrontmatter(),
7794
8484
  body: command.getBody()
7795
8485
  };
@@ -7808,7 +8498,7 @@ async function putCommand({
7808
8498
  relativePath: relativePathFromCwd,
7809
8499
  intendedRootDir: process.cwd()
7810
8500
  });
7811
- const filename = (0, import_node_path69.basename)(relativePathFromCwd);
8501
+ const filename = (0, import_node_path74.basename)(relativePathFromCwd);
7812
8502
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
7813
8503
  if (estimatedSize > maxCommandSizeBytes) {
7814
8504
  throw new Error(
@@ -7818,7 +8508,7 @@ async function putCommand({
7818
8508
  try {
7819
8509
  const existingCommands = await listCommands();
7820
8510
  const isUpdate = existingCommands.some(
7821
- (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)
7822
8512
  );
7823
8513
  if (!isUpdate && existingCommands.length >= maxCommandsCount) {
7824
8514
  throw new Error(`Maximum number of commands (${maxCommandsCount}) reached`);
@@ -7833,11 +8523,11 @@ async function putCommand({
7833
8523
  fileContent,
7834
8524
  validate: true
7835
8525
  });
7836
- 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);
7837
8527
  await ensureDir(commandsDir);
7838
8528
  await writeFileContent(command.getFilePath(), command.getFileContent());
7839
8529
  return {
7840
- 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),
7841
8531
  frontmatter: command.getFrontmatter(),
7842
8532
  body: command.getBody()
7843
8533
  };
@@ -7852,12 +8542,12 @@ async function deleteCommand({ relativePathFromCwd }) {
7852
8542
  relativePath: relativePathFromCwd,
7853
8543
  intendedRootDir: process.cwd()
7854
8544
  });
7855
- const filename = (0, import_node_path69.basename)(relativePathFromCwd);
7856
- 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);
7857
8547
  try {
7858
8548
  await removeFile(fullPath);
7859
8549
  return {
7860
- 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)
7861
8551
  };
7862
8552
  } catch (error) {
7863
8553
  throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -7866,23 +8556,23 @@ async function deleteCommand({ relativePathFromCwd }) {
7866
8556
  }
7867
8557
  }
7868
8558
  var commandToolSchemas = {
7869
- listCommands: import_mini25.z.object({}),
7870
- getCommand: import_mini25.z.object({
7871
- relativePathFromCwd: import_mini25.z.string()
8559
+ listCommands: import_mini28.z.object({}),
8560
+ getCommand: import_mini28.z.object({
8561
+ relativePathFromCwd: import_mini28.z.string()
7872
8562
  }),
7873
- putCommand: import_mini25.z.object({
7874
- relativePathFromCwd: import_mini25.z.string(),
8563
+ putCommand: import_mini28.z.object({
8564
+ relativePathFromCwd: import_mini28.z.string(),
7875
8565
  frontmatter: RulesyncCommandFrontmatterSchema,
7876
- body: import_mini25.z.string()
8566
+ body: import_mini28.z.string()
7877
8567
  }),
7878
- deleteCommand: import_mini25.z.object({
7879
- relativePathFromCwd: import_mini25.z.string()
8568
+ deleteCommand: import_mini28.z.object({
8569
+ relativePathFromCwd: import_mini28.z.string()
7880
8570
  })
7881
8571
  };
7882
8572
  var commandTools = {
7883
8573
  listCommands: {
7884
8574
  name: "listCommands",
7885
- 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.`,
7886
8576
  parameters: commandToolSchemas.listCommands,
7887
8577
  execute: async () => {
7888
8578
  const commands = await listCommands();
@@ -7924,11 +8614,11 @@ var commandTools = {
7924
8614
  };
7925
8615
 
7926
8616
  // src/mcp/ignore.ts
7927
- var import_node_path70 = require("path");
7928
- var import_mini26 = require("zod/mini");
8617
+ var import_node_path75 = require("path");
8618
+ var import_mini29 = require("zod/mini");
7929
8619
  var maxIgnoreFileSizeBytes = 100 * 1024;
7930
8620
  async function getIgnoreFile() {
7931
- 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);
7932
8622
  try {
7933
8623
  const content = await readFileContent(ignoreFilePath);
7934
8624
  return {
@@ -7942,7 +8632,7 @@ async function getIgnoreFile() {
7942
8632
  }
7943
8633
  }
7944
8634
  async function putIgnoreFile({ content }) {
7945
- 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);
7946
8636
  const contentSizeBytes = Buffer.byteLength(content, "utf8");
7947
8637
  if (contentSizeBytes > maxIgnoreFileSizeBytes) {
7948
8638
  throw new Error(
@@ -7963,7 +8653,7 @@ async function putIgnoreFile({ content }) {
7963
8653
  }
7964
8654
  }
7965
8655
  async function deleteIgnoreFile() {
7966
- 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);
7967
8657
  try {
7968
8658
  await removeFile(ignoreFilePath);
7969
8659
  return {
@@ -7976,11 +8666,11 @@ async function deleteIgnoreFile() {
7976
8666
  }
7977
8667
  }
7978
8668
  var ignoreToolSchemas = {
7979
- getIgnoreFile: import_mini26.z.object({}),
7980
- putIgnoreFile: import_mini26.z.object({
7981
- content: import_mini26.z.string()
8669
+ getIgnoreFile: import_mini29.z.object({}),
8670
+ putIgnoreFile: import_mini29.z.object({
8671
+ content: import_mini29.z.string()
7982
8672
  }),
7983
- deleteIgnoreFile: import_mini26.z.object({})
8673
+ deleteIgnoreFile: import_mini29.z.object({})
7984
8674
  };
7985
8675
  var ignoreTools = {
7986
8676
  getIgnoreFile: {
@@ -8013,8 +8703,8 @@ var ignoreTools = {
8013
8703
  };
8014
8704
 
8015
8705
  // src/mcp/mcp.ts
8016
- var import_node_path71 = require("path");
8017
- var import_mini27 = require("zod/mini");
8706
+ var import_node_path76 = require("path");
8707
+ var import_mini30 = require("zod/mini");
8018
8708
  var maxMcpSizeBytes = 1024 * 1024;
8019
8709
  async function getMcpFile() {
8020
8710
  const config = await ConfigResolver.resolve({});
@@ -8023,7 +8713,7 @@ async function getMcpFile() {
8023
8713
  validate: true,
8024
8714
  modularMcp: config.getModularMcp()
8025
8715
  });
8026
- const relativePathFromCwd = (0, import_node_path71.join)(
8716
+ const relativePathFromCwd = (0, import_node_path76.join)(
8027
8717
  rulesyncMcp.getRelativeDirPath(),
8028
8718
  rulesyncMcp.getRelativeFilePath()
8029
8719
  );
@@ -8056,7 +8746,7 @@ async function putMcpFile({ content }) {
8056
8746
  const paths = RulesyncMcp.getSettablePaths();
8057
8747
  const relativeDirPath = paths.recommended.relativeDirPath;
8058
8748
  const relativeFilePath = paths.recommended.relativeFilePath;
8059
- const fullPath = (0, import_node_path71.join)(baseDir, relativeDirPath, relativeFilePath);
8749
+ const fullPath = (0, import_node_path76.join)(baseDir, relativeDirPath, relativeFilePath);
8060
8750
  const rulesyncMcp = new RulesyncMcp({
8061
8751
  baseDir,
8062
8752
  relativeDirPath,
@@ -8065,9 +8755,9 @@ async function putMcpFile({ content }) {
8065
8755
  validate: true,
8066
8756
  modularMcp: config.getModularMcp()
8067
8757
  });
8068
- await ensureDir((0, import_node_path71.join)(baseDir, relativeDirPath));
8758
+ await ensureDir((0, import_node_path76.join)(baseDir, relativeDirPath));
8069
8759
  await writeFileContent(fullPath, content);
8070
- const relativePathFromCwd = (0, import_node_path71.join)(relativeDirPath, relativeFilePath);
8760
+ const relativePathFromCwd = (0, import_node_path76.join)(relativeDirPath, relativeFilePath);
8071
8761
  return {
8072
8762
  relativePathFromCwd,
8073
8763
  content: rulesyncMcp.getFileContent()
@@ -8082,15 +8772,15 @@ async function deleteMcpFile() {
8082
8772
  try {
8083
8773
  const baseDir = process.cwd();
8084
8774
  const paths = RulesyncMcp.getSettablePaths();
8085
- const recommendedPath = (0, import_node_path71.join)(
8775
+ const recommendedPath = (0, import_node_path76.join)(
8086
8776
  baseDir,
8087
8777
  paths.recommended.relativeDirPath,
8088
8778
  paths.recommended.relativeFilePath
8089
8779
  );
8090
- 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);
8091
8781
  await removeFile(recommendedPath);
8092
8782
  await removeFile(legacyPath);
8093
- const relativePathFromCwd = (0, import_node_path71.join)(
8783
+ const relativePathFromCwd = (0, import_node_path76.join)(
8094
8784
  paths.recommended.relativeDirPath,
8095
8785
  paths.recommended.relativeFilePath
8096
8786
  );
@@ -8104,11 +8794,11 @@ async function deleteMcpFile() {
8104
8794
  }
8105
8795
  }
8106
8796
  var mcpToolSchemas = {
8107
- getMcpFile: import_mini27.z.object({}),
8108
- putMcpFile: import_mini27.z.object({
8109
- content: import_mini27.z.string()
8797
+ getMcpFile: import_mini30.z.object({}),
8798
+ putMcpFile: import_mini30.z.object({
8799
+ content: import_mini30.z.string()
8110
8800
  }),
8111
- deleteMcpFile: import_mini27.z.object({})
8801
+ deleteMcpFile: import_mini30.z.object({})
8112
8802
  };
8113
8803
  var mcpTools = {
8114
8804
  getMcpFile: {
@@ -8141,12 +8831,12 @@ var mcpTools = {
8141
8831
  };
8142
8832
 
8143
8833
  // src/mcp/rules.ts
8144
- var import_node_path72 = require("path");
8145
- var import_mini28 = require("zod/mini");
8834
+ var import_node_path77 = require("path");
8835
+ var import_mini31 = require("zod/mini");
8146
8836
  var maxRuleSizeBytes = 1024 * 1024;
8147
8837
  var maxRulesCount = 1e3;
8148
8838
  async function listRules() {
8149
- 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);
8150
8840
  try {
8151
8841
  const files = await listDirectoryFiles(rulesDir);
8152
8842
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -8159,7 +8849,7 @@ async function listRules() {
8159
8849
  });
8160
8850
  const frontmatter = rule.getFrontmatter();
8161
8851
  return {
8162
- 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),
8163
8853
  frontmatter
8164
8854
  };
8165
8855
  } catch (error) {
@@ -8179,14 +8869,14 @@ async function getRule({ relativePathFromCwd }) {
8179
8869
  relativePath: relativePathFromCwd,
8180
8870
  intendedRootDir: process.cwd()
8181
8871
  });
8182
- const filename = (0, import_node_path72.basename)(relativePathFromCwd);
8872
+ const filename = (0, import_node_path77.basename)(relativePathFromCwd);
8183
8873
  try {
8184
8874
  const rule = await RulesyncRule.fromFile({
8185
8875
  relativeFilePath: filename,
8186
8876
  validate: true
8187
8877
  });
8188
8878
  return {
8189
- 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),
8190
8880
  frontmatter: rule.getFrontmatter(),
8191
8881
  body: rule.getBody()
8192
8882
  };
@@ -8205,7 +8895,7 @@ async function putRule({
8205
8895
  relativePath: relativePathFromCwd,
8206
8896
  intendedRootDir: process.cwd()
8207
8897
  });
8208
- const filename = (0, import_node_path72.basename)(relativePathFromCwd);
8898
+ const filename = (0, import_node_path77.basename)(relativePathFromCwd);
8209
8899
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
8210
8900
  if (estimatedSize > maxRuleSizeBytes) {
8211
8901
  throw new Error(
@@ -8215,7 +8905,7 @@ async function putRule({
8215
8905
  try {
8216
8906
  const existingRules = await listRules();
8217
8907
  const isUpdate = existingRules.some(
8218
- (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)
8219
8909
  );
8220
8910
  if (!isUpdate && existingRules.length >= maxRulesCount) {
8221
8911
  throw new Error(`Maximum number of rules (${maxRulesCount}) reached`);
@@ -8228,11 +8918,11 @@ async function putRule({
8228
8918
  body,
8229
8919
  validate: true
8230
8920
  });
8231
- 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);
8232
8922
  await ensureDir(rulesDir);
8233
8923
  await writeFileContent(rule.getFilePath(), rule.getFileContent());
8234
8924
  return {
8235
- 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),
8236
8926
  frontmatter: rule.getFrontmatter(),
8237
8927
  body: rule.getBody()
8238
8928
  };
@@ -8247,12 +8937,12 @@ async function deleteRule({ relativePathFromCwd }) {
8247
8937
  relativePath: relativePathFromCwd,
8248
8938
  intendedRootDir: process.cwd()
8249
8939
  });
8250
- const filename = (0, import_node_path72.basename)(relativePathFromCwd);
8251
- 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);
8252
8942
  try {
8253
8943
  await removeFile(fullPath);
8254
8944
  return {
8255
- 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)
8256
8946
  };
8257
8947
  } catch (error) {
8258
8948
  throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -8261,23 +8951,23 @@ async function deleteRule({ relativePathFromCwd }) {
8261
8951
  }
8262
8952
  }
8263
8953
  var ruleToolSchemas = {
8264
- listRules: import_mini28.z.object({}),
8265
- getRule: import_mini28.z.object({
8266
- relativePathFromCwd: import_mini28.z.string()
8954
+ listRules: import_mini31.z.object({}),
8955
+ getRule: import_mini31.z.object({
8956
+ relativePathFromCwd: import_mini31.z.string()
8267
8957
  }),
8268
- putRule: import_mini28.z.object({
8269
- relativePathFromCwd: import_mini28.z.string(),
8958
+ putRule: import_mini31.z.object({
8959
+ relativePathFromCwd: import_mini31.z.string(),
8270
8960
  frontmatter: RulesyncRuleFrontmatterSchema,
8271
- body: import_mini28.z.string()
8961
+ body: import_mini31.z.string()
8272
8962
  }),
8273
- deleteRule: import_mini28.z.object({
8274
- relativePathFromCwd: import_mini28.z.string()
8963
+ deleteRule: import_mini31.z.object({
8964
+ relativePathFromCwd: import_mini31.z.string()
8275
8965
  })
8276
8966
  };
8277
8967
  var ruleTools = {
8278
8968
  listRules: {
8279
8969
  name: "listRules",
8280
- 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.`,
8281
8971
  parameters: ruleToolSchemas.listRules,
8282
8972
  execute: async () => {
8283
8973
  const rules = await listRules();
@@ -8319,12 +9009,12 @@ var ruleTools = {
8319
9009
  };
8320
9010
 
8321
9011
  // src/mcp/subagents.ts
8322
- var import_node_path73 = require("path");
8323
- var import_mini29 = require("zod/mini");
9012
+ var import_node_path78 = require("path");
9013
+ var import_mini32 = require("zod/mini");
8324
9014
  var maxSubagentSizeBytes = 1024 * 1024;
8325
9015
  var maxSubagentsCount = 1e3;
8326
9016
  async function listSubagents() {
8327
- 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);
8328
9018
  try {
8329
9019
  const files = await listDirectoryFiles(subagentsDir);
8330
9020
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -8337,7 +9027,7 @@ async function listSubagents() {
8337
9027
  });
8338
9028
  const frontmatter = subagent.getFrontmatter();
8339
9029
  return {
8340
- 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),
8341
9031
  frontmatter
8342
9032
  };
8343
9033
  } catch (error) {
@@ -8359,14 +9049,14 @@ async function getSubagent({ relativePathFromCwd }) {
8359
9049
  relativePath: relativePathFromCwd,
8360
9050
  intendedRootDir: process.cwd()
8361
9051
  });
8362
- const filename = (0, import_node_path73.basename)(relativePathFromCwd);
9052
+ const filename = (0, import_node_path78.basename)(relativePathFromCwd);
8363
9053
  try {
8364
9054
  const subagent = await RulesyncSubagent.fromFile({
8365
9055
  relativeFilePath: filename,
8366
9056
  validate: true
8367
9057
  });
8368
9058
  return {
8369
- 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),
8370
9060
  frontmatter: subagent.getFrontmatter(),
8371
9061
  body: subagent.getBody()
8372
9062
  };
@@ -8385,7 +9075,7 @@ async function putSubagent({
8385
9075
  relativePath: relativePathFromCwd,
8386
9076
  intendedRootDir: process.cwd()
8387
9077
  });
8388
- const filename = (0, import_node_path73.basename)(relativePathFromCwd);
9078
+ const filename = (0, import_node_path78.basename)(relativePathFromCwd);
8389
9079
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
8390
9080
  if (estimatedSize > maxSubagentSizeBytes) {
8391
9081
  throw new Error(
@@ -8395,7 +9085,7 @@ async function putSubagent({
8395
9085
  try {
8396
9086
  const existingSubagents = await listSubagents();
8397
9087
  const isUpdate = existingSubagents.some(
8398
- (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)
8399
9089
  );
8400
9090
  if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
8401
9091
  throw new Error(`Maximum number of subagents (${maxSubagentsCount}) reached`);
@@ -8408,11 +9098,11 @@ async function putSubagent({
8408
9098
  body,
8409
9099
  validate: true
8410
9100
  });
8411
- 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);
8412
9102
  await ensureDir(subagentsDir);
8413
9103
  await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
8414
9104
  return {
8415
- 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),
8416
9106
  frontmatter: subagent.getFrontmatter(),
8417
9107
  body: subagent.getBody()
8418
9108
  };
@@ -8427,12 +9117,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
8427
9117
  relativePath: relativePathFromCwd,
8428
9118
  intendedRootDir: process.cwd()
8429
9119
  });
8430
- const filename = (0, import_node_path73.basename)(relativePathFromCwd);
8431
- 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);
8432
9122
  try {
8433
9123
  await removeFile(fullPath);
8434
9124
  return {
8435
- 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)
8436
9126
  };
8437
9127
  } catch (error) {
8438
9128
  throw new Error(
@@ -8444,23 +9134,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
8444
9134
  }
8445
9135
  }
8446
9136
  var subagentToolSchemas = {
8447
- listSubagents: import_mini29.z.object({}),
8448
- getSubagent: import_mini29.z.object({
8449
- relativePathFromCwd: import_mini29.z.string()
9137
+ listSubagents: import_mini32.z.object({}),
9138
+ getSubagent: import_mini32.z.object({
9139
+ relativePathFromCwd: import_mini32.z.string()
8450
9140
  }),
8451
- putSubagent: import_mini29.z.object({
8452
- relativePathFromCwd: import_mini29.z.string(),
9141
+ putSubagent: import_mini32.z.object({
9142
+ relativePathFromCwd: import_mini32.z.string(),
8453
9143
  frontmatter: RulesyncSubagentFrontmatterSchema,
8454
- body: import_mini29.z.string()
9144
+ body: import_mini32.z.string()
8455
9145
  }),
8456
- deleteSubagent: import_mini29.z.object({
8457
- relativePathFromCwd: import_mini29.z.string()
9146
+ deleteSubagent: import_mini32.z.object({
9147
+ relativePathFromCwd: import_mini32.z.string()
8458
9148
  })
8459
9149
  };
8460
9150
  var subagentTools = {
8461
9151
  listSubagents: {
8462
9152
  name: "listSubagents",
8463
- 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.`,
8464
9154
  parameters: subagentToolSchemas.listSubagents,
8465
9155
  execute: async () => {
8466
9156
  const subagents = await listSubagents();
@@ -8534,7 +9224,7 @@ async function mcpCommand({ version }) {
8534
9224
  }
8535
9225
 
8536
9226
  // src/cli/index.ts
8537
- var getVersion = () => "3.23.6";
9227
+ var getVersion = () => "3.24.0";
8538
9228
  var main = async () => {
8539
9229
  const program = new import_commander.Command();
8540
9230
  const version = getVersion();