rulesync 3.23.6 → 3.25.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 +89 -33
  2. package/dist/index.cjs +1923 -485
  3. package/dist/index.js +1923 -485
  4. package/package.json +18 -18
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}`);
@@ -254,8 +279,9 @@ var ConfigParamsSchema = import_mini3.z.object({
254
279
  delete: import_mini3.z.boolean(),
255
280
  // New non-experimental options
256
281
  global: (0, import_mini3.optional)(import_mini3.z.boolean()),
257
- simulatedCommands: (0, import_mini3.optional)(import_mini3.z.boolean()),
258
- simulatedSubagents: (0, import_mini3.optional)(import_mini3.z.boolean()),
282
+ simulateCommands: (0, import_mini3.optional)(import_mini3.z.boolean()),
283
+ simulateSubagents: (0, import_mini3.optional)(import_mini3.z.boolean()),
284
+ simulateSkills: (0, import_mini3.optional)(import_mini3.z.boolean()),
259
285
  modularMcp: (0, import_mini3.optional)(import_mini3.z.boolean()),
260
286
  // Deprecated experimental options (for backward compatibility)
261
287
  experimentalGlobal: (0, import_mini3.optional)(import_mini3.z.boolean()),
@@ -271,8 +297,9 @@ var Config = class {
271
297
  verbose;
272
298
  delete;
273
299
  global;
274
- simulatedCommands;
275
- simulatedSubagents;
300
+ simulateCommands;
301
+ simulateSubagents;
302
+ simulateSkills;
276
303
  modularMcp;
277
304
  constructor({
278
305
  baseDirs,
@@ -281,8 +308,9 @@ var Config = class {
281
308
  verbose,
282
309
  delete: isDelete,
283
310
  global,
284
- simulatedCommands,
285
- simulatedSubagents,
311
+ simulateCommands,
312
+ simulateSubagents,
313
+ simulateSkills,
286
314
  modularMcp,
287
315
  experimentalGlobal,
288
316
  experimentalSimulateCommands,
@@ -294,8 +322,9 @@ var Config = class {
294
322
  this.verbose = verbose;
295
323
  this.delete = isDelete;
296
324
  this.global = global ?? experimentalGlobal ?? false;
297
- this.simulatedCommands = simulatedCommands ?? experimentalSimulateCommands ?? false;
298
- this.simulatedSubagents = simulatedSubagents ?? experimentalSimulateSubagents ?? false;
325
+ this.simulateCommands = simulateCommands ?? experimentalSimulateCommands ?? false;
326
+ this.simulateSubagents = simulateSubagents ?? experimentalSimulateSubagents ?? false;
327
+ this.simulateSkills = simulateSkills ?? false;
299
328
  this.modularMcp = modularMcp ?? false;
300
329
  }
301
330
  getBaseDirs() {
@@ -322,11 +351,14 @@ var Config = class {
322
351
  getGlobal() {
323
352
  return this.global;
324
353
  }
325
- getSimulatedCommands() {
326
- return this.simulatedCommands;
354
+ getSimulateCommands() {
355
+ return this.simulateCommands;
327
356
  }
328
- getSimulatedSubagents() {
329
- return this.simulatedSubagents;
357
+ getSimulateSubagents() {
358
+ return this.simulateSubagents;
359
+ }
360
+ getSimulateSkills() {
361
+ return this.simulateSkills;
330
362
  }
331
363
  getModularMcp() {
332
364
  return this.modularMcp;
@@ -336,13 +368,13 @@ var Config = class {
336
368
  getExperimentalGlobal() {
337
369
  return this.global;
338
370
  }
339
- /** @deprecated Use getSimulatedCommands() instead */
371
+ /** @deprecated Use getSimulateCommands() instead */
340
372
  getExperimentalSimulateCommands() {
341
- return this.simulatedCommands;
373
+ return this.simulateCommands;
342
374
  }
343
- /** @deprecated Use getSimulatedSubagents() instead */
375
+ /** @deprecated Use getSimulateSubagents() instead */
344
376
  getExperimentalSimulateSubagents() {
345
- return this.simulatedSubagents;
377
+ return this.simulateSubagents;
346
378
  }
347
379
  };
348
380
 
@@ -355,8 +387,9 @@ var getDefaults = () => ({
355
387
  baseDirs: [process.cwd()],
356
388
  configPath: "rulesync.jsonc",
357
389
  global: false,
358
- simulatedCommands: false,
359
- simulatedSubagents: false,
390
+ simulateCommands: false,
391
+ simulateSubagents: false,
392
+ simulateSkills: false,
360
393
  modularMcp: false,
361
394
  experimentalGlobal: false,
362
395
  experimentalSimulateCommands: false,
@@ -371,8 +404,9 @@ var ConfigResolver = class {
371
404
  baseDirs,
372
405
  configPath = getDefaults().configPath,
373
406
  global,
374
- simulatedCommands,
375
- simulatedSubagents,
407
+ simulateCommands,
408
+ simulateSubagents,
409
+ simulateSkills,
376
410
  modularMcp,
377
411
  experimentalGlobal,
378
412
  experimentalSimulateCommands,
@@ -403,8 +437,9 @@ var ConfigResolver = class {
403
437
  warnDeprecatedOptions({ experimentalSimulateSubagents: deprecatedSubagents });
404
438
  }
405
439
  const resolvedGlobal = global ?? configByFile.global ?? experimentalGlobal ?? configByFile.experimentalGlobal ?? getDefaults().global;
406
- const resolvedSimulatedCommands = simulatedCommands ?? configByFile.simulatedCommands ?? experimentalSimulateCommands ?? configByFile.experimentalSimulateCommands ?? getDefaults().simulatedCommands;
407
- const resolvedSimulatedSubagents = simulatedSubagents ?? configByFile.simulatedSubagents ?? experimentalSimulateSubagents ?? configByFile.experimentalSimulateSubagents ?? getDefaults().simulatedSubagents;
440
+ const resolvedSimulateCommands = simulateCommands ?? configByFile.simulateCommands ?? experimentalSimulateCommands ?? configByFile.experimentalSimulateCommands ?? getDefaults().simulateCommands;
441
+ const resolvedSimulateSubagents = simulateSubagents ?? configByFile.simulateSubagents ?? experimentalSimulateSubagents ?? configByFile.experimentalSimulateSubagents ?? getDefaults().simulateSubagents;
442
+ const resolvedSimulateSkills = simulateSkills ?? configByFile.simulateSkills ?? getDefaults().simulateSkills;
408
443
  const configParams = {
409
444
  targets: targets ?? configByFile.targets ?? getDefaults().targets,
410
445
  features: features ?? configByFile.features ?? getDefaults().features,
@@ -415,8 +450,9 @@ var ConfigResolver = class {
415
450
  global: resolvedGlobal
416
451
  }),
417
452
  global: resolvedGlobal,
418
- simulatedCommands: resolvedSimulatedCommands,
419
- simulatedSubagents: resolvedSimulatedSubagents,
453
+ simulateCommands: resolvedSimulateCommands,
454
+ simulateSubagents: resolvedSimulateSubagents,
455
+ simulateSkills: resolvedSimulateSkills,
420
456
  modularMcp: modularMcp ?? configByFile.modularMcp ?? getDefaults().modularMcp
421
457
  };
422
458
  return new Config(configParams);
@@ -432,12 +468,12 @@ function warnDeprecatedOptions({
432
468
  }
433
469
  if (experimentalSimulateCommands !== void 0) {
434
470
  logger.warn(
435
- "'experimentalSimulateCommands' option is deprecated. Please use 'simulatedCommands' instead."
471
+ "'experimentalSimulateCommands' option is deprecated. Please use 'simulateCommands' instead."
436
472
  );
437
473
  }
438
474
  if (experimentalSimulateSubagents !== void 0) {
439
475
  logger.warn(
440
- "'experimentalSimulateSubagents' option is deprecated. Please use 'simulatedSubagents' instead."
476
+ "'experimentalSimulateSubagents' option is deprecated. Please use 'simulateSubagents' instead."
441
477
  );
442
478
  }
443
479
  }
@@ -1697,7 +1733,7 @@ var CommandsProcessor = class extends FeatureProcessor {
1697
1733
  );
1698
1734
  const rulesyncCommands = (await Promise.allSettled(
1699
1735
  rulesyncCommandPaths.map(
1700
- (path2) => RulesyncCommand.fromFile({ relativeFilePath: (0, import_node_path14.basename)(path2) })
1736
+ (path3) => RulesyncCommand.fromFile({ relativeFilePath: (0, import_node_path14.basename)(path3) })
1701
1737
  )
1702
1738
  )).filter((result) => result.status === "fulfilled").map((result) => result.value);
1703
1739
  logger.info(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
@@ -1707,7 +1743,9 @@ var CommandsProcessor = class extends FeatureProcessor {
1707
1743
  * Implementation of abstract method from FeatureProcessor
1708
1744
  * Load tool-specific command configurations and parse them into ToolCommand instances
1709
1745
  */
1710
- async loadToolFiles() {
1746
+ async loadToolFiles({
1747
+ forDeletion: _forDeletion = false
1748
+ } = {}) {
1711
1749
  switch (this.toolTarget) {
1712
1750
  case "agentsmd":
1713
1751
  return await this.loadAgentsmdCommands();
@@ -1727,9 +1765,6 @@ var CommandsProcessor = class extends FeatureProcessor {
1727
1765
  throw new Error(`Unsupported tool target: ${this.toolTarget}`);
1728
1766
  }
1729
1767
  }
1730
- async loadToolFilesToDelete() {
1731
- return this.loadToolFiles();
1732
- }
1733
1768
  async loadToolCommandDefault({
1734
1769
  toolTarget,
1735
1770
  relativeDirPath,
@@ -1739,45 +1774,45 @@ var CommandsProcessor = class extends FeatureProcessor {
1739
1774
  (0, import_node_path14.join)(this.baseDir, relativeDirPath, `*.${extension}`)
1740
1775
  );
1741
1776
  const toolCommands = (await Promise.allSettled(
1742
- commandFilePaths.map((path2) => {
1777
+ commandFilePaths.map((path3) => {
1743
1778
  switch (toolTarget) {
1744
1779
  case "agentsmd":
1745
1780
  return AgentsmdCommand.fromFile({
1746
1781
  baseDir: this.baseDir,
1747
- relativeFilePath: (0, import_node_path14.basename)(path2)
1782
+ relativeFilePath: (0, import_node_path14.basename)(path3)
1748
1783
  });
1749
1784
  case "claudecode":
1750
1785
  return ClaudecodeCommand.fromFile({
1751
1786
  baseDir: this.baseDir,
1752
- relativeFilePath: (0, import_node_path14.basename)(path2),
1787
+ relativeFilePath: (0, import_node_path14.basename)(path3),
1753
1788
  global: this.global
1754
1789
  });
1755
1790
  case "geminicli":
1756
1791
  return GeminiCliCommand.fromFile({
1757
1792
  baseDir: this.baseDir,
1758
- relativeFilePath: (0, import_node_path14.basename)(path2),
1793
+ relativeFilePath: (0, import_node_path14.basename)(path3),
1759
1794
  global: this.global
1760
1795
  });
1761
1796
  case "roo":
1762
1797
  return RooCommand.fromFile({
1763
1798
  baseDir: this.baseDir,
1764
- relativeFilePath: (0, import_node_path14.basename)(path2)
1799
+ relativeFilePath: (0, import_node_path14.basename)(path3)
1765
1800
  });
1766
1801
  case "copilot":
1767
1802
  return CopilotCommand.fromFile({
1768
1803
  baseDir: this.baseDir,
1769
- relativeFilePath: (0, import_node_path14.basename)(path2)
1804
+ relativeFilePath: (0, import_node_path14.basename)(path3)
1770
1805
  });
1771
1806
  case "cursor":
1772
1807
  return CursorCommand.fromFile({
1773
1808
  baseDir: this.baseDir,
1774
- relativeFilePath: (0, import_node_path14.basename)(path2),
1809
+ relativeFilePath: (0, import_node_path14.basename)(path3),
1775
1810
  global: this.global
1776
1811
  });
1777
1812
  case "codexcli":
1778
1813
  return CodexcliCommand.fromFile({
1779
1814
  baseDir: this.baseDir,
1780
- relativeFilePath: (0, import_node_path14.basename)(path2),
1815
+ relativeFilePath: (0, import_node_path14.basename)(path3),
1781
1816
  global: this.global
1782
1817
  });
1783
1818
  default:
@@ -1867,8 +1902,12 @@ var CommandsProcessor = class extends FeatureProcessor {
1867
1902
  * Return the tool targets that this processor supports
1868
1903
  */
1869
1904
  static getToolTargets({
1905
+ global = false,
1870
1906
  includeSimulated = false
1871
1907
  } = {}) {
1908
+ if (global) {
1909
+ return commandsProcessorToolTargetsGlobal;
1910
+ }
1872
1911
  if (!includeSimulated) {
1873
1912
  return commandsProcessorToolTargets.filter(
1874
1913
  (target) => !commandsProcessorToolTargetsSimulated.includes(target)
@@ -1879,9 +1918,6 @@ var CommandsProcessor = class extends FeatureProcessor {
1879
1918
  static getToolTargetsSimulated() {
1880
1919
  return commandsProcessorToolTargetsSimulated;
1881
1920
  }
1882
- static getToolTargetsGlobal() {
1883
- return commandsProcessorToolTargetsGlobal;
1884
- }
1885
1921
  };
1886
1922
 
1887
1923
  // src/features/ignore/ignore-processor.ts
@@ -2305,7 +2341,7 @@ var JunieIgnore = class _JunieIgnore extends ToolIgnore {
2305
2341
  static getSettablePaths() {
2306
2342
  return {
2307
2343
  relativeDirPath: ".",
2308
- relativeFilePath: ".junieignore"
2344
+ relativeFilePath: ".aiignore"
2309
2345
  };
2310
2346
  }
2311
2347
  toRulesyncIgnore() {
@@ -2569,9 +2605,14 @@ var IgnoreProcessor = class extends FeatureProcessor {
2569
2605
  * Implementation of abstract method from FeatureProcessor
2570
2606
  * Load tool-specific ignore configurations and parse them into ToolIgnore instances
2571
2607
  */
2572
- async loadToolFiles() {
2608
+ async loadToolFiles({
2609
+ forDeletion = false
2610
+ } = {}) {
2573
2611
  try {
2574
2612
  const toolIgnores = await this.loadToolIgnores();
2613
+ if (forDeletion) {
2614
+ return toolIgnores.filter((toolFile) => !(toolFile instanceof ClaudecodeIgnore));
2615
+ }
2575
2616
  return toolIgnores;
2576
2617
  } catch (error) {
2577
2618
  const errorMessage = `Failed to load tool files: ${formatError(error)}`;
@@ -2611,11 +2652,6 @@ var IgnoreProcessor = class extends FeatureProcessor {
2611
2652
  throw new Error(`Unsupported tool target: ${this.toolTarget}`);
2612
2653
  }
2613
2654
  }
2614
- async loadToolFilesToDelete() {
2615
- return (await this.loadToolFiles()).filter(
2616
- (toolFile) => !(toolFile instanceof ClaudecodeIgnore)
2617
- );
2618
- }
2619
2655
  /**
2620
2656
  * Implementation of abstract method from FeatureProcessor
2621
2657
  * Convert RulesyncFile[] to ToolFile[]
@@ -2707,13 +2743,16 @@ var IgnoreProcessor = class extends FeatureProcessor {
2707
2743
  * Implementation of abstract method from FeatureProcessor
2708
2744
  * Return the tool targets that this processor supports
2709
2745
  */
2710
- static getToolTargets() {
2746
+ static getToolTargets({ global = false } = {}) {
2747
+ if (global) {
2748
+ throw new Error("IgnoreProcessor does not support global mode");
2749
+ }
2711
2750
  return ignoreProcessorToolTargets;
2712
2751
  }
2713
2752
  };
2714
2753
 
2715
2754
  // src/features/mcp/mcp-processor.ts
2716
- var import_mini15 = require("zod/mini");
2755
+ var import_mini16 = require("zod/mini");
2717
2756
 
2718
2757
  // src/features/mcp/amazonqcli-mcp.ts
2719
2758
  var import_node_path28 = require("path");
@@ -2842,21 +2881,23 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
2842
2881
  modularMcp
2843
2882
  });
2844
2883
  }
2845
- getExposedMcpServers() {
2846
- return Object.fromEntries(
2847
- Object.entries(this.json.mcpServers).filter(([, serverConfig]) => !this.modularMcp || serverConfig.exposed).map(([serverName, serverConfig]) => [
2848
- serverName,
2849
- (0, import_object.omit)(serverConfig, ["targets", "description", "exposed"])
2850
- ])
2851
- );
2852
- }
2853
- getModularizedMcpServers() {
2884
+ getMcpServers({ type = "all" } = {}) {
2885
+ const entries = Object.entries(this.json.mcpServers);
2886
+ const filteredEntries = entries.filter(([, serverConfig]) => {
2887
+ switch (type) {
2888
+ case "all":
2889
+ return true;
2890
+ case "exposed":
2891
+ return !this.modularMcp || serverConfig.exposed;
2892
+ case "modularized":
2893
+ return this.modularMcp && !serverConfig.exposed;
2894
+ }
2895
+ });
2854
2896
  return Object.fromEntries(
2855
- Object.entries(this.json.mcpServers).filter(([, serverConfig]) => this.modularMcp && !serverConfig.exposed).map(([serverName, serverConfig]) => [
2856
- serverName,
2857
- // description is required for modular-mcp servers
2858
- (0, import_object.omit)(serverConfig, ["targets", "exposed"])
2859
- ])
2897
+ filteredEntries.map(([serverName, serverConfig]) => {
2898
+ const fieldsToOmit = type === "modularized" ? ["targets", "exposed"] : ["targets", "description", "exposed"];
2899
+ return [serverName, (0, import_object.omit)(serverConfig, fieldsToOmit)];
2900
+ })
2860
2901
  );
2861
2902
  }
2862
2903
  getJson() {
@@ -3043,7 +3084,7 @@ var ModularMcp = class _ModularMcp extends AiFile {
3043
3084
  global && relativeDirPath ? { global: true, relativeDirPath } : { global: false, relativeDirPath: void 0 }
3044
3085
  );
3045
3086
  const modularMcpJson = {
3046
- mcpServers: rulesyncMcp.getModularizedMcpServers()
3087
+ mcpServers: rulesyncMcp.getMcpServers({ type: "modularized" })
3047
3088
  };
3048
3089
  return new _ModularMcp({
3049
3090
  baseDir,
@@ -3126,9 +3167,9 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
3126
3167
  relativeDirPath: this.getSettablePaths({ global: true }).relativeDirPath
3127
3168
  }) : ModularMcp.getMcpServers({ baseDir, global: false }),
3128
3169
  // Merge exposed servers
3129
- ...rulesyncMcp.getExposedMcpServers()
3170
+ ...rulesyncMcp.getMcpServers({ type: "exposed" })
3130
3171
  }
3131
- } : { ...json, mcpServers: rulesyncMcp.getExposedMcpServers() };
3172
+ } : { ...json, mcpServers: rulesyncMcp.getMcpServers({ type: "exposed" }) };
3132
3173
  return new _ClaudecodeMcp({
3133
3174
  baseDir,
3134
3175
  relativeDirPath: paths.relativeDirPath,
@@ -3497,8 +3538,235 @@ var GeminiCliMcp = class _GeminiCliMcp extends ToolMcp {
3497
3538
  }
3498
3539
  };
3499
3540
 
3500
- // src/features/mcp/roo-mcp.ts
3541
+ // src/features/mcp/junie-mcp.ts
3501
3542
  var import_node_path36 = require("path");
3543
+ var JunieMcp = class _JunieMcp extends ToolMcp {
3544
+ json;
3545
+ constructor(params) {
3546
+ super(params);
3547
+ this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
3548
+ }
3549
+ getJson() {
3550
+ return this.json;
3551
+ }
3552
+ static getSettablePaths() {
3553
+ return {
3554
+ relativeDirPath: (0, import_node_path36.join)(".junie", "mcp"),
3555
+ relativeFilePath: "mcp.json"
3556
+ };
3557
+ }
3558
+ static async fromFile({
3559
+ baseDir = process.cwd(),
3560
+ validate = true
3561
+ }) {
3562
+ const fileContent = await readFileContent(
3563
+ (0, import_node_path36.join)(
3564
+ baseDir,
3565
+ this.getSettablePaths().relativeDirPath,
3566
+ this.getSettablePaths().relativeFilePath
3567
+ )
3568
+ );
3569
+ return new _JunieMcp({
3570
+ baseDir,
3571
+ relativeDirPath: this.getSettablePaths().relativeDirPath,
3572
+ relativeFilePath: this.getSettablePaths().relativeFilePath,
3573
+ fileContent,
3574
+ validate
3575
+ });
3576
+ }
3577
+ static fromRulesyncMcp({
3578
+ baseDir = process.cwd(),
3579
+ rulesyncMcp,
3580
+ validate = true
3581
+ }) {
3582
+ return new _JunieMcp({
3583
+ baseDir,
3584
+ relativeDirPath: this.getSettablePaths().relativeDirPath,
3585
+ relativeFilePath: this.getSettablePaths().relativeFilePath,
3586
+ fileContent: rulesyncMcp.getFileContent(),
3587
+ validate
3588
+ });
3589
+ }
3590
+ toRulesyncMcp() {
3591
+ return this.toRulesyncMcpDefault();
3592
+ }
3593
+ validate() {
3594
+ return { success: true, error: null };
3595
+ }
3596
+ };
3597
+
3598
+ // src/features/mcp/opencode-mcp.ts
3599
+ var import_node_path37 = require("path");
3600
+ var import_mini15 = require("zod/mini");
3601
+ var OpencodeMcpLocalServerSchema = import_mini15.z.object({
3602
+ type: import_mini15.z.literal("local"),
3603
+ command: import_mini15.z.array(import_mini15.z.string()),
3604
+ environment: import_mini15.z.optional(import_mini15.z.record(import_mini15.z.string(), import_mini15.z.string())),
3605
+ enabled: import_mini15.z._default(import_mini15.z.boolean(), true),
3606
+ cwd: import_mini15.z.optional(import_mini15.z.string())
3607
+ });
3608
+ var OpencodeMcpRemoteServerSchema = import_mini15.z.object({
3609
+ type: import_mini15.z.literal("remote"),
3610
+ url: import_mini15.z.string(),
3611
+ headers: import_mini15.z.optional(import_mini15.z.record(import_mini15.z.string(), import_mini15.z.string())),
3612
+ enabled: import_mini15.z._default(import_mini15.z.boolean(), true)
3613
+ });
3614
+ var OpencodeMcpServerSchema = import_mini15.z.union([
3615
+ OpencodeMcpLocalServerSchema,
3616
+ OpencodeMcpRemoteServerSchema
3617
+ ]);
3618
+ var OpencodeConfigSchema = import_mini15.z.looseObject({
3619
+ $schema: import_mini15.z.optional(import_mini15.z.string()),
3620
+ mcp: import_mini15.z.optional(import_mini15.z.record(import_mini15.z.string(), OpencodeMcpServerSchema))
3621
+ });
3622
+ function convertFromOpencodeFormat(opencodeMcp) {
3623
+ return Object.fromEntries(
3624
+ Object.entries(opencodeMcp).map(([serverName, serverConfig]) => {
3625
+ if (serverConfig.type === "remote") {
3626
+ return [
3627
+ serverName,
3628
+ {
3629
+ type: "sse",
3630
+ url: serverConfig.url,
3631
+ ...serverConfig.enabled === false && { disabled: true },
3632
+ ...serverConfig.headers && { headers: serverConfig.headers }
3633
+ }
3634
+ ];
3635
+ }
3636
+ const [command, ...args] = serverConfig.command;
3637
+ if (!command) {
3638
+ throw new Error(`Server "${serverName}" has an empty command array`);
3639
+ }
3640
+ return [
3641
+ serverName,
3642
+ {
3643
+ type: "stdio",
3644
+ command,
3645
+ ...args.length > 0 && { args },
3646
+ ...serverConfig.enabled === false && { disabled: true },
3647
+ ...serverConfig.environment && { env: serverConfig.environment },
3648
+ ...serverConfig.cwd && { cwd: serverConfig.cwd }
3649
+ }
3650
+ ];
3651
+ })
3652
+ );
3653
+ }
3654
+ function convertToOpencodeFormat(mcpServers) {
3655
+ return Object.fromEntries(
3656
+ Object.entries(mcpServers).map(([serverName, serverConfig]) => {
3657
+ const isRemote = serverConfig.type === "sse" || serverConfig.type === "http" || serverConfig.url;
3658
+ if (isRemote) {
3659
+ const remoteServer = {
3660
+ type: "remote",
3661
+ url: serverConfig.url ?? serverConfig.httpUrl ?? "",
3662
+ enabled: serverConfig.disabled !== void 0 ? !serverConfig.disabled : true,
3663
+ ...serverConfig.headers && { headers: serverConfig.headers }
3664
+ };
3665
+ return [serverName, remoteServer];
3666
+ }
3667
+ const commandArray = [];
3668
+ if (serverConfig.command) {
3669
+ if (Array.isArray(serverConfig.command)) {
3670
+ commandArray.push(...serverConfig.command);
3671
+ } else {
3672
+ commandArray.push(serverConfig.command);
3673
+ }
3674
+ }
3675
+ if (serverConfig.args) {
3676
+ commandArray.push(...serverConfig.args);
3677
+ }
3678
+ const localServer = {
3679
+ type: "local",
3680
+ command: commandArray,
3681
+ enabled: serverConfig.disabled !== void 0 ? !serverConfig.disabled : true,
3682
+ ...serverConfig.env && { environment: serverConfig.env },
3683
+ ...serverConfig.cwd && { cwd: serverConfig.cwd }
3684
+ };
3685
+ return [serverName, localServer];
3686
+ })
3687
+ );
3688
+ }
3689
+ var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
3690
+ json;
3691
+ constructor(params) {
3692
+ super(params);
3693
+ this.json = OpencodeConfigSchema.parse(JSON.parse(this.fileContent || "{}"));
3694
+ }
3695
+ getJson() {
3696
+ return this.json;
3697
+ }
3698
+ static getSettablePaths({ global } = {}) {
3699
+ if (global) {
3700
+ return {
3701
+ relativeDirPath: ".",
3702
+ relativeFilePath: "opencode.json"
3703
+ };
3704
+ }
3705
+ return {
3706
+ relativeDirPath: ".",
3707
+ relativeFilePath: "opencode.json"
3708
+ };
3709
+ }
3710
+ static async fromFile({
3711
+ baseDir = process.cwd(),
3712
+ validate = true,
3713
+ global = false
3714
+ }) {
3715
+ const paths = this.getSettablePaths({ global });
3716
+ const fileContent = await readOrInitializeFileContent(
3717
+ (0, import_node_path37.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath),
3718
+ JSON.stringify({ mcp: {} }, null, 2)
3719
+ );
3720
+ const json = JSON.parse(fileContent);
3721
+ const newJson = { ...json, mcp: json.mcp ?? {} };
3722
+ return new _OpencodeMcp({
3723
+ baseDir,
3724
+ relativeDirPath: paths.relativeDirPath,
3725
+ relativeFilePath: paths.relativeFilePath,
3726
+ fileContent: JSON.stringify(newJson, null, 2),
3727
+ validate
3728
+ });
3729
+ }
3730
+ static async fromRulesyncMcp({
3731
+ baseDir = process.cwd(),
3732
+ rulesyncMcp,
3733
+ validate = true,
3734
+ global = false
3735
+ }) {
3736
+ const paths = this.getSettablePaths({ global });
3737
+ const fileContent = await readOrInitializeFileContent(
3738
+ (0, import_node_path37.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath),
3739
+ JSON.stringify({ mcp: {} }, null, 2)
3740
+ );
3741
+ const json = JSON.parse(fileContent);
3742
+ const convertedMcp = convertToOpencodeFormat(rulesyncMcp.getMcpServers());
3743
+ const newJson = { ...json, mcp: convertedMcp };
3744
+ return new _OpencodeMcp({
3745
+ baseDir,
3746
+ relativeDirPath: paths.relativeDirPath,
3747
+ relativeFilePath: paths.relativeFilePath,
3748
+ fileContent: JSON.stringify(newJson, null, 2),
3749
+ validate
3750
+ });
3751
+ }
3752
+ toRulesyncMcp() {
3753
+ const convertedMcpServers = convertFromOpencodeFormat(this.json.mcp ?? {});
3754
+ return this.toRulesyncMcpDefault({
3755
+ fileContent: JSON.stringify({ mcpServers: convertedMcpServers }, null, 2)
3756
+ });
3757
+ }
3758
+ validate() {
3759
+ const json = JSON.parse(this.fileContent || "{}");
3760
+ const result = OpencodeConfigSchema.safeParse(json);
3761
+ if (!result.success) {
3762
+ return { success: false, error: result.error };
3763
+ }
3764
+ return { success: true, error: null };
3765
+ }
3766
+ };
3767
+
3768
+ // src/features/mcp/roo-mcp.ts
3769
+ var import_node_path38 = require("path");
3502
3770
  var RooMcp = class _RooMcp extends ToolMcp {
3503
3771
  json;
3504
3772
  constructor(params) {
@@ -3519,7 +3787,7 @@ var RooMcp = class _RooMcp extends ToolMcp {
3519
3787
  validate = true
3520
3788
  }) {
3521
3789
  const fileContent = await readFileContent(
3522
- (0, import_node_path36.join)(
3790
+ (0, import_node_path38.join)(
3523
3791
  baseDir,
3524
3792
  this.getSettablePaths().relativeDirPath,
3525
3793
  this.getSettablePaths().relativeFilePath
@@ -3560,16 +3828,23 @@ var mcpProcessorToolTargets = [
3560
3828
  "amazonqcli",
3561
3829
  "claudecode",
3562
3830
  "cline",
3831
+ "junie",
3563
3832
  "copilot",
3564
3833
  "cursor",
3565
3834
  "geminicli",
3835
+ "opencode",
3566
3836
  "roo"
3567
3837
  ];
3568
- var McpProcessorToolTargetSchema = import_mini15.z.enum(
3838
+ var McpProcessorToolTargetSchema = import_mini16.z.enum(
3569
3839
  // codexcli is not in the list of tool targets but we add it here because it is a valid tool target for global mode generation
3570
3840
  mcpProcessorToolTargets.concat("codexcli")
3571
3841
  );
3572
- var mcpProcessorToolTargetsGlobal = ["claudecode", "codexcli", "geminicli"];
3842
+ var mcpProcessorToolTargetsGlobal = [
3843
+ "claudecode",
3844
+ "codexcli",
3845
+ "geminicli",
3846
+ "opencode"
3847
+ ];
3573
3848
  var mcpProcessorToolTargetsModular = ["claudecode"];
3574
3849
  var McpProcessor = class extends FeatureProcessor {
3575
3850
  toolTarget;
@@ -3604,19 +3879,13 @@ var McpProcessor = class extends FeatureProcessor {
3604
3879
  return [];
3605
3880
  }
3606
3881
  }
3607
- async loadToolFilesToDelete() {
3608
- if (this.global) {
3609
- return (await this.loadToolFiles()).filter(
3610
- (toolFile) => !(toolFile instanceof ClaudecodeMcp)
3611
- );
3612
- }
3613
- return this.loadToolFiles();
3614
- }
3615
3882
  /**
3616
3883
  * Implementation of abstract method from FeatureProcessor
3617
3884
  * Load tool-specific MCP configurations and parse them into ToolMcp instances
3618
3885
  */
3619
- async loadToolFiles() {
3886
+ async loadToolFiles({
3887
+ forDeletion = false
3888
+ } = {}) {
3620
3889
  try {
3621
3890
  const toolMcps = await (async () => {
3622
3891
  switch (this.toolTarget) {
@@ -3645,6 +3914,14 @@ var McpProcessor = class extends FeatureProcessor {
3645
3914
  })
3646
3915
  ];
3647
3916
  }
3917
+ case "junie": {
3918
+ return [
3919
+ await JunieMcp.fromFile({
3920
+ baseDir: this.baseDir,
3921
+ validate: true
3922
+ })
3923
+ ];
3924
+ }
3648
3925
  case "codexcli": {
3649
3926
  return [
3650
3927
  await CodexcliMcp.fromFile({
@@ -3679,6 +3956,15 @@ var McpProcessor = class extends FeatureProcessor {
3679
3956
  })
3680
3957
  ];
3681
3958
  }
3959
+ case "opencode": {
3960
+ return [
3961
+ await OpencodeMcp.fromFile({
3962
+ baseDir: this.baseDir,
3963
+ validate: true,
3964
+ global: this.global
3965
+ })
3966
+ ];
3967
+ }
3682
3968
  case "roo": {
3683
3969
  return [
3684
3970
  await RooMcp.fromFile({
@@ -3692,6 +3978,13 @@ var McpProcessor = class extends FeatureProcessor {
3692
3978
  }
3693
3979
  })();
3694
3980
  logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
3981
+ if (forDeletion) {
3982
+ let filteredMcps = toolMcps.filter((toolFile) => !(toolFile instanceof OpencodeMcp));
3983
+ if (this.global) {
3984
+ filteredMcps = filteredMcps.filter((toolFile) => !(toolFile instanceof ClaudecodeMcp));
3985
+ }
3986
+ return filteredMcps;
3987
+ }
3695
3988
  return toolMcps;
3696
3989
  } catch (error) {
3697
3990
  const errorMessage = `Failed to load MCP files for tool target: ${this.toolTarget}: ${formatError(error)}`;
@@ -3704,115 +3997,1155 @@ var McpProcessor = class extends FeatureProcessor {
3704
3997
  }
3705
3998
  }
3706
3999
  /**
3707
- * Implementation of abstract method from FeatureProcessor
3708
- * Convert RulesyncFile[] to ToolFile[]
4000
+ * Implementation of abstract method from FeatureProcessor
4001
+ * Convert RulesyncFile[] to ToolFile[]
4002
+ */
4003
+ async convertRulesyncFilesToToolFiles(rulesyncFiles) {
4004
+ const rulesyncMcp = rulesyncFiles.find(
4005
+ (file) => file instanceof RulesyncMcp
4006
+ );
4007
+ if (!rulesyncMcp) {
4008
+ throw new Error(`No ${RULESYNC_MCP_RELATIVE_FILE_PATH} found.`);
4009
+ }
4010
+ const toolMcps = await Promise.all(
4011
+ [rulesyncMcp].map(async (rulesyncMcp2) => {
4012
+ switch (this.toolTarget) {
4013
+ case "amazonqcli":
4014
+ return AmazonqcliMcp.fromRulesyncMcp({
4015
+ baseDir: this.baseDir,
4016
+ rulesyncMcp: rulesyncMcp2
4017
+ });
4018
+ case "claudecode":
4019
+ return await ClaudecodeMcp.fromRulesyncMcp({
4020
+ baseDir: this.baseDir,
4021
+ rulesyncMcp: rulesyncMcp2,
4022
+ global: this.global,
4023
+ modularMcp: this.modularMcp
4024
+ });
4025
+ case "cline":
4026
+ return ClineMcp.fromRulesyncMcp({
4027
+ baseDir: this.baseDir,
4028
+ rulesyncMcp: rulesyncMcp2
4029
+ });
4030
+ case "junie":
4031
+ return JunieMcp.fromRulesyncMcp({
4032
+ baseDir: this.baseDir,
4033
+ rulesyncMcp: rulesyncMcp2
4034
+ });
4035
+ case "copilot":
4036
+ return CopilotMcp.fromRulesyncMcp({
4037
+ baseDir: this.baseDir,
4038
+ rulesyncMcp: rulesyncMcp2
4039
+ });
4040
+ case "cursor":
4041
+ return CursorMcp.fromRulesyncMcp({
4042
+ baseDir: this.baseDir,
4043
+ rulesyncMcp: rulesyncMcp2
4044
+ });
4045
+ case "codexcli":
4046
+ return await CodexcliMcp.fromRulesyncMcp({
4047
+ baseDir: this.baseDir,
4048
+ rulesyncMcp: rulesyncMcp2,
4049
+ global: this.global
4050
+ });
4051
+ case "geminicli":
4052
+ return GeminiCliMcp.fromRulesyncMcp({
4053
+ baseDir: this.baseDir,
4054
+ rulesyncMcp: rulesyncMcp2,
4055
+ global: this.global
4056
+ });
4057
+ case "opencode":
4058
+ return OpencodeMcp.fromRulesyncMcp({
4059
+ baseDir: this.baseDir,
4060
+ rulesyncMcp: rulesyncMcp2,
4061
+ global: this.global
4062
+ });
4063
+ case "roo":
4064
+ return RooMcp.fromRulesyncMcp({
4065
+ baseDir: this.baseDir,
4066
+ rulesyncMcp: rulesyncMcp2
4067
+ });
4068
+ default:
4069
+ throw new Error(`Unsupported tool target: ${this.toolTarget}`);
4070
+ }
4071
+ })
4072
+ );
4073
+ const toolFiles = toolMcps;
4074
+ if (this.modularMcp && mcpProcessorToolTargetsModular.includes(this.toolTarget)) {
4075
+ const relativeDirPath = this.toolTarget === "claudecode" ? ClaudecodeMcp.getSettablePaths({ global: this.global }).relativeDirPath : void 0;
4076
+ toolFiles.push(
4077
+ ModularMcp.fromRulesyncMcp({
4078
+ baseDir: this.baseDir,
4079
+ rulesyncMcp,
4080
+ ...this.global && relativeDirPath ? { global: true, relativeDirPath } : { global: false }
4081
+ })
4082
+ );
4083
+ }
4084
+ return toolFiles;
4085
+ }
4086
+ /**
4087
+ * Implementation of abstract method from FeatureProcessor
4088
+ * Convert ToolFile[] to RulesyncFile[]
4089
+ */
4090
+ async convertToolFilesToRulesyncFiles(toolFiles) {
4091
+ const toolMcps = toolFiles.filter((file) => file instanceof ToolMcp);
4092
+ const rulesyncMcps = toolMcps.map((toolMcp) => {
4093
+ return toolMcp.toRulesyncMcp();
4094
+ });
4095
+ return rulesyncMcps;
4096
+ }
4097
+ /**
4098
+ * Implementation of abstract method from FeatureProcessor
4099
+ * Return the tool targets that this processor supports
4100
+ */
4101
+ static getToolTargets({ global = false } = {}) {
4102
+ if (global) {
4103
+ return mcpProcessorToolTargetsGlobal;
4104
+ }
4105
+ return mcpProcessorToolTargets;
4106
+ }
4107
+ };
4108
+
4109
+ // src/features/rules/rules-processor.ts
4110
+ var import_node_path79 = require("path");
4111
+ var import_fast_xml_parser = require("fast-xml-parser");
4112
+ var import_mini29 = require("zod/mini");
4113
+
4114
+ // src/features/skills/codexcli-skill.ts
4115
+ var import_node_path41 = require("path");
4116
+
4117
+ // src/features/skills/simulated-skill.ts
4118
+ var import_node_path40 = require("path");
4119
+ var import_mini17 = require("zod/mini");
4120
+
4121
+ // src/constants/general.ts
4122
+ var SKILL_FILE_NAME = "SKILL.md";
4123
+
4124
+ // src/types/ai-dir.ts
4125
+ var import_node_path39 = __toESM(require("path"), 1);
4126
+ var AiDir = class {
4127
+ /**
4128
+ * @example "."
4129
+ */
4130
+ baseDir;
4131
+ /**
4132
+ * @example ".rulesync/skills"
4133
+ */
4134
+ relativeDirPath;
4135
+ /**
4136
+ * @example "my-skill"
4137
+ */
4138
+ dirName;
4139
+ /**
4140
+ * Optional main file with frontmatter support
4141
+ */
4142
+ mainFile;
4143
+ /**
4144
+ * Additional files in the directory
4145
+ */
4146
+ otherFiles;
4147
+ /**
4148
+ * @example false
4149
+ */
4150
+ global;
4151
+ constructor({
4152
+ baseDir = process.cwd(),
4153
+ relativeDirPath,
4154
+ dirName,
4155
+ mainFile,
4156
+ otherFiles = [],
4157
+ global = false
4158
+ }) {
4159
+ if (dirName.includes(import_node_path39.default.sep) || dirName.includes("/") || dirName.includes("\\")) {
4160
+ throw new Error(`Directory name cannot contain path separators: dirName="${dirName}"`);
4161
+ }
4162
+ this.baseDir = baseDir;
4163
+ this.relativeDirPath = relativeDirPath;
4164
+ this.dirName = dirName;
4165
+ this.mainFile = mainFile;
4166
+ this.otherFiles = otherFiles;
4167
+ this.global = global;
4168
+ }
4169
+ static async fromDir(_params) {
4170
+ throw new Error("Please implement this method in the subclass.");
4171
+ }
4172
+ getBaseDir() {
4173
+ return this.baseDir;
4174
+ }
4175
+ getRelativeDirPath() {
4176
+ return this.relativeDirPath;
4177
+ }
4178
+ getDirName() {
4179
+ return this.dirName;
4180
+ }
4181
+ getDirPath() {
4182
+ const fullPath = import_node_path39.default.join(this.baseDir, this.relativeDirPath, this.dirName);
4183
+ const resolvedFull = (0, import_node_path39.resolve)(fullPath);
4184
+ const resolvedBase = (0, import_node_path39.resolve)(this.baseDir);
4185
+ const rel = (0, import_node_path39.relative)(resolvedBase, resolvedFull);
4186
+ if (rel.startsWith("..") || import_node_path39.default.isAbsolute(rel)) {
4187
+ throw new Error(
4188
+ `Path traversal detected: Final path escapes baseDir. baseDir="${this.baseDir}", relativeDirPath="${this.relativeDirPath}", dirName="${this.dirName}"`
4189
+ );
4190
+ }
4191
+ return fullPath;
4192
+ }
4193
+ getMainFile() {
4194
+ return this.mainFile;
4195
+ }
4196
+ getOtherFiles() {
4197
+ return this.otherFiles;
4198
+ }
4199
+ getRelativePathFromCwd() {
4200
+ return import_node_path39.default.join(this.relativeDirPath, this.dirName);
4201
+ }
4202
+ getGlobal() {
4203
+ return this.global;
4204
+ }
4205
+ setMainFile(name, body, frontmatter) {
4206
+ this.mainFile = { name, body, frontmatter };
4207
+ }
4208
+ /**
4209
+ * Recursively collects all files from a directory, excluding the specified main file.
4210
+ * This is a common utility for loading additional files alongside the main file.
4211
+ *
4212
+ * @param baseDir - The base directory path
4213
+ * @param relativeDirPath - The relative path to the directory containing the skill
4214
+ * @param dirName - The name of the directory
4215
+ * @param excludeFileName - The name of the file to exclude (typically the main file)
4216
+ * @returns Array of files with their relative paths and buffers
4217
+ */
4218
+ static async collectOtherFiles(baseDir, relativeDirPath, dirName, excludeFileName) {
4219
+ const dirPath = (0, import_node_path39.join)(baseDir, relativeDirPath, dirName);
4220
+ const glob = (0, import_node_path39.join)(dirPath, "**", "*");
4221
+ const filePaths = await findFilesByGlobs(glob, { type: "file" });
4222
+ const filteredPaths = filePaths.filter((filePath) => (0, import_node_path39.basename)(filePath) !== excludeFileName);
4223
+ const files = await Promise.all(
4224
+ filteredPaths.map(async (filePath) => {
4225
+ const fileBuffer = await readFileBuffer(filePath);
4226
+ return {
4227
+ relativeFilePathToDirPath: (0, import_node_path39.relative)(dirPath, filePath),
4228
+ fileBuffer
4229
+ };
4230
+ })
4231
+ );
4232
+ return files;
4233
+ }
4234
+ };
4235
+
4236
+ // src/features/skills/tool-skill.ts
4237
+ var ToolSkill = class extends AiDir {
4238
+ /**
4239
+ * Get the settable paths for this tool's skill directories.
4240
+ *
4241
+ * @param options - Optional configuration including global mode
4242
+ * @returns Object containing the relative directory path
4243
+ */
4244
+ static getSettablePaths(_options) {
4245
+ throw new Error("Please implement this method in the subclass.");
4246
+ }
4247
+ /**
4248
+ * Load a skill from a tool-specific directory.
4249
+ *
4250
+ * This method should:
4251
+ * 1. Read the SKILL.md file content
4252
+ * 2. Parse tool-specific frontmatter format
4253
+ * 3. Validate the parsed data
4254
+ * 4. Collect other skill files in the directory
4255
+ * 5. Return a concrete ToolSkill instance
4256
+ *
4257
+ * @param params - Parameters including the skill directory name
4258
+ * @returns Promise resolving to a concrete ToolSkill instance
4259
+ */
4260
+ static async fromDir(_params) {
4261
+ throw new Error("Please implement this method in the subclass.");
4262
+ }
4263
+ /**
4264
+ * Convert a RulesyncSkill to the tool-specific skill format.
4265
+ *
4266
+ * This method should:
4267
+ * 1. Extract relevant data from the RulesyncSkill
4268
+ * 2. Transform frontmatter to tool-specific format
4269
+ * 3. Transform body content if needed
4270
+ * 4. Preserve other skill files
4271
+ * 5. Return a concrete ToolSkill instance
4272
+ *
4273
+ * @param params - Parameters including the RulesyncSkill to convert
4274
+ * @returns A concrete ToolSkill instance
4275
+ */
4276
+ static fromRulesyncSkill(_params) {
4277
+ throw new Error("Please implement this method in the subclass.");
4278
+ }
4279
+ /**
4280
+ * Check if this tool is targeted by a RulesyncSkill.
4281
+ * Since skills don't have targets field like commands/subagents,
4282
+ * the default behavior may vary by tool.
4283
+ *
4284
+ * @param rulesyncSkill - The RulesyncSkill to check
4285
+ * @returns True if this tool should use the skill
4286
+ */
4287
+ static isTargetedByRulesyncSkill(_rulesyncSkill) {
4288
+ throw new Error("Please implement this method in the subclass.");
4289
+ }
4290
+ };
4291
+
4292
+ // src/features/skills/simulated-skill.ts
4293
+ var SimulatedSkillFrontmatterSchema = import_mini17.z.object({
4294
+ name: import_mini17.z.string(),
4295
+ description: import_mini17.z.string()
4296
+ });
4297
+ var SimulatedSkill = class extends ToolSkill {
4298
+ frontmatter;
4299
+ body;
4300
+ constructor({
4301
+ baseDir = process.cwd(),
4302
+ relativeDirPath,
4303
+ dirName,
4304
+ frontmatter,
4305
+ body,
4306
+ otherFiles = [],
4307
+ validate = true
4308
+ }) {
4309
+ super({
4310
+ baseDir,
4311
+ relativeDirPath,
4312
+ dirName,
4313
+ mainFile: {
4314
+ name: SKILL_FILE_NAME,
4315
+ body,
4316
+ frontmatter: { ...frontmatter }
4317
+ },
4318
+ otherFiles,
4319
+ global: false
4320
+ // Simulated skills are project mode only
4321
+ });
4322
+ if (validate) {
4323
+ const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4324
+ if (!result.success) {
4325
+ throw new Error(
4326
+ `Invalid frontmatter in ${(0, import_node_path40.join)(relativeDirPath, dirName)}: ${formatError(result.error)}`
4327
+ );
4328
+ }
4329
+ }
4330
+ this.frontmatter = frontmatter;
4331
+ this.body = body;
4332
+ }
4333
+ getBody() {
4334
+ return this.body;
4335
+ }
4336
+ getFrontmatter() {
4337
+ return this.frontmatter;
4338
+ }
4339
+ toRulesyncSkill() {
4340
+ throw new Error("Not implemented because it is a SIMULATED skill.");
4341
+ }
4342
+ validate() {
4343
+ if (!this.frontmatter) {
4344
+ return { success: true, error: null };
4345
+ }
4346
+ const result = SimulatedSkillFrontmatterSchema.safeParse(this.frontmatter);
4347
+ if (result.success) {
4348
+ return { success: true, error: null };
4349
+ } else {
4350
+ return {
4351
+ success: false,
4352
+ error: new Error(
4353
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
4354
+ )
4355
+ };
4356
+ }
4357
+ }
4358
+ static fromRulesyncSkillDefault({
4359
+ rulesyncSkill,
4360
+ validate = true
4361
+ }) {
4362
+ const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
4363
+ const simulatedFrontmatter = {
4364
+ name: rulesyncFrontmatter.name,
4365
+ description: rulesyncFrontmatter.description
4366
+ };
4367
+ const otherFiles = rulesyncSkill.getOtherFiles();
4368
+ if (otherFiles.length > 0) {
4369
+ logger.warn(
4370
+ `Skill "${rulesyncFrontmatter.name}" has ${otherFiles.length} additional file(s) that will be ignored for simulated skill generation.`
4371
+ );
4372
+ }
4373
+ return {
4374
+ baseDir: rulesyncSkill.getBaseDir(),
4375
+ relativeDirPath: this.getSettablePaths().relativeDirPath,
4376
+ dirName: rulesyncSkill.getDirName(),
4377
+ frontmatter: simulatedFrontmatter,
4378
+ body: rulesyncSkill.getBody(),
4379
+ otherFiles: [],
4380
+ // Simulated skills ignore otherFiles
4381
+ validate
4382
+ };
4383
+ }
4384
+ static async fromDirDefault({
4385
+ baseDir = process.cwd(),
4386
+ relativeDirPath,
4387
+ dirName
4388
+ }) {
4389
+ const settablePaths = this.getSettablePaths();
4390
+ const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
4391
+ const skillDirPath = (0, import_node_path40.join)(baseDir, actualRelativeDirPath, dirName);
4392
+ const skillFilePath = (0, import_node_path40.join)(skillDirPath, SKILL_FILE_NAME);
4393
+ if (!await fileExists(skillFilePath)) {
4394
+ throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4395
+ }
4396
+ const fileContent = await readFileContent(skillFilePath);
4397
+ const { frontmatter, body: content } = parseFrontmatter(fileContent);
4398
+ const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
4399
+ if (!result.success) {
4400
+ throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
4401
+ }
4402
+ return {
4403
+ baseDir,
4404
+ relativeDirPath: actualRelativeDirPath,
4405
+ dirName,
4406
+ frontmatter: result.data,
4407
+ body: content.trim(),
4408
+ otherFiles: [],
4409
+ // Simulated skills ignore otherFiles
4410
+ validate: true
4411
+ };
4412
+ }
4413
+ /**
4414
+ * Check if a RulesyncSkill should be converted to this simulated skill type.
4415
+ * Uses the targets field in the RulesyncSkill frontmatter to determine targeting.
4416
+ */
4417
+ static isTargetedByRulesyncSkillDefault({
4418
+ rulesyncSkill,
4419
+ toolTarget
4420
+ }) {
4421
+ const frontmatter = rulesyncSkill.getFrontmatter();
4422
+ const targets = frontmatter.targets;
4423
+ if (targets.includes("*")) {
4424
+ return true;
4425
+ }
4426
+ return targets.includes(toolTarget);
4427
+ }
4428
+ /**
4429
+ * Get the settable paths for this tool's skill directories.
4430
+ * Must be implemented by concrete subclasses.
4431
+ */
4432
+ static getSettablePaths(_options) {
4433
+ throw new Error("Please implement this method in the subclass.");
4434
+ }
4435
+ };
4436
+
4437
+ // src/features/skills/codexcli-skill.ts
4438
+ var CodexCliSkill = class _CodexCliSkill extends SimulatedSkill {
4439
+ static getSettablePaths(options) {
4440
+ if (options?.global) {
4441
+ throw new Error("CodexCliSkill does not support global mode.");
4442
+ }
4443
+ return {
4444
+ relativeDirPath: (0, import_node_path41.join)(".codex", "skills")
4445
+ };
4446
+ }
4447
+ static async fromDir(params) {
4448
+ const baseParams = await this.fromDirDefault(params);
4449
+ return new _CodexCliSkill(baseParams);
4450
+ }
4451
+ static fromRulesyncSkill(params) {
4452
+ const baseParams = {
4453
+ ...this.fromRulesyncSkillDefault(params),
4454
+ relativeDirPath: this.getSettablePaths().relativeDirPath
4455
+ };
4456
+ return new _CodexCliSkill(baseParams);
4457
+ }
4458
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4459
+ return this.isTargetedByRulesyncSkillDefault({
4460
+ rulesyncSkill,
4461
+ toolTarget: "codexcli"
4462
+ });
4463
+ }
4464
+ };
4465
+
4466
+ // src/features/skills/copilot-skill.ts
4467
+ var import_node_path42 = require("path");
4468
+ var CopilotSkill = class _CopilotSkill extends SimulatedSkill {
4469
+ static getSettablePaths(options) {
4470
+ if (options?.global) {
4471
+ throw new Error("CopilotSkill does not support global mode.");
4472
+ }
4473
+ return {
4474
+ relativeDirPath: (0, import_node_path42.join)(".github", "skills")
4475
+ };
4476
+ }
4477
+ static async fromDir(params) {
4478
+ const baseParams = await this.fromDirDefault(params);
4479
+ return new _CopilotSkill(baseParams);
4480
+ }
4481
+ static fromRulesyncSkill(params) {
4482
+ const baseParams = {
4483
+ ...this.fromRulesyncSkillDefault(params),
4484
+ relativeDirPath: this.getSettablePaths().relativeDirPath
4485
+ };
4486
+ return new _CopilotSkill(baseParams);
4487
+ }
4488
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4489
+ return this.isTargetedByRulesyncSkillDefault({
4490
+ rulesyncSkill,
4491
+ toolTarget: "copilot"
4492
+ });
4493
+ }
4494
+ };
4495
+
4496
+ // src/features/skills/cursor-skill.ts
4497
+ var import_node_path43 = require("path");
4498
+ var CursorSkill = class _CursorSkill extends SimulatedSkill {
4499
+ static getSettablePaths(options) {
4500
+ if (options?.global) {
4501
+ throw new Error("CursorSkill does not support global mode.");
4502
+ }
4503
+ return {
4504
+ relativeDirPath: (0, import_node_path43.join)(".cursor", "skills")
4505
+ };
4506
+ }
4507
+ static async fromDir(params) {
4508
+ const baseParams = await this.fromDirDefault(params);
4509
+ return new _CursorSkill(baseParams);
4510
+ }
4511
+ static fromRulesyncSkill(params) {
4512
+ const baseParams = {
4513
+ ...this.fromRulesyncSkillDefault(params),
4514
+ relativeDirPath: this.getSettablePaths().relativeDirPath
4515
+ };
4516
+ return new _CursorSkill(baseParams);
4517
+ }
4518
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4519
+ return this.isTargetedByRulesyncSkillDefault({
4520
+ rulesyncSkill,
4521
+ toolTarget: "cursor"
4522
+ });
4523
+ }
4524
+ };
4525
+
4526
+ // src/features/skills/skills-processor.ts
4527
+ var import_node_path49 = require("path");
4528
+ var import_mini20 = require("zod/mini");
4529
+
4530
+ // src/types/dir-feature-processor.ts
4531
+ var import_node_path44 = require("path");
4532
+ var DirFeatureProcessor = class {
4533
+ baseDir;
4534
+ constructor({ baseDir = process.cwd() }) {
4535
+ this.baseDir = baseDir;
4536
+ }
4537
+ /**
4538
+ * Return tool targets that this feature supports.
4539
+ */
4540
+ static getToolTargets(_params = {}) {
4541
+ throw new Error("Not implemented");
4542
+ }
4543
+ /**
4544
+ * Once converted to rulesync/tool dirs, write them to the filesystem.
4545
+ * Returns the number of directories written.
4546
+ */
4547
+ async writeAiDirs(aiDirs) {
4548
+ for (const aiDir of aiDirs) {
4549
+ const dirPath = aiDir.getDirPath();
4550
+ await ensureDir(dirPath);
4551
+ const mainFile = aiDir.getMainFile();
4552
+ if (mainFile) {
4553
+ const mainFilePath = (0, import_node_path44.join)(dirPath, mainFile.name);
4554
+ const contentWithNewline = addTrailingNewline(mainFile.body);
4555
+ await writeFileContent(mainFilePath, contentWithNewline);
4556
+ }
4557
+ const otherFiles = aiDir.getOtherFiles();
4558
+ for (const file of otherFiles) {
4559
+ const filePath = (0, import_node_path44.join)(dirPath, file.relativeFilePathToDirPath);
4560
+ const contentWithNewline = addTrailingNewline(file.fileBuffer.toString("utf-8"));
4561
+ await writeFileContent(filePath, contentWithNewline);
4562
+ }
4563
+ }
4564
+ return aiDirs.length;
4565
+ }
4566
+ async removeAiDirs(aiDirs) {
4567
+ for (const aiDir of aiDirs) {
4568
+ await removeDirectory(aiDir.getDirPath());
4569
+ }
4570
+ }
4571
+ };
4572
+
4573
+ // src/features/skills/agentsmd-skill.ts
4574
+ var import_node_path45 = require("path");
4575
+ var AgentsmdSkill = class _AgentsmdSkill extends SimulatedSkill {
4576
+ static getSettablePaths(options) {
4577
+ if (options?.global) {
4578
+ throw new Error("AgentsmdSkill does not support global mode.");
4579
+ }
4580
+ return {
4581
+ relativeDirPath: (0, import_node_path45.join)(".agents", "skills")
4582
+ };
4583
+ }
4584
+ static async fromDir(params) {
4585
+ const baseParams = await this.fromDirDefault(params);
4586
+ return new _AgentsmdSkill(baseParams);
4587
+ }
4588
+ static fromRulesyncSkill(params) {
4589
+ const baseParams = {
4590
+ ...this.fromRulesyncSkillDefault(params),
4591
+ relativeDirPath: this.getSettablePaths().relativeDirPath
4592
+ };
4593
+ return new _AgentsmdSkill(baseParams);
4594
+ }
4595
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4596
+ return this.isTargetedByRulesyncSkillDefault({
4597
+ rulesyncSkill,
4598
+ toolTarget: "agentsmd"
4599
+ });
4600
+ }
4601
+ };
4602
+
4603
+ // src/features/skills/claudecode-skill.ts
4604
+ var import_node_path47 = require("path");
4605
+ var import_mini19 = require("zod/mini");
4606
+
4607
+ // src/features/skills/rulesync-skill.ts
4608
+ var import_node_path46 = require("path");
4609
+ var import_mini18 = require("zod/mini");
4610
+ var RulesyncSkillFrontmatterSchemaInternal = import_mini18.z.object({
4611
+ name: import_mini18.z.string(),
4612
+ description: import_mini18.z.string(),
4613
+ targets: import_mini18.z._default(RulesyncTargetsSchema, ["*"]),
4614
+ claudecode: import_mini18.z.optional(
4615
+ import_mini18.z.object({
4616
+ "allowed-tools": import_mini18.z.optional(import_mini18.z.array(import_mini18.z.string()))
4617
+ })
4618
+ )
4619
+ });
4620
+ var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
4621
+ var RulesyncSkill = class _RulesyncSkill extends AiDir {
4622
+ constructor({
4623
+ baseDir = process.cwd(),
4624
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
4625
+ dirName,
4626
+ frontmatter,
4627
+ body,
4628
+ otherFiles = [],
4629
+ validate = true,
4630
+ global = false
4631
+ }) {
4632
+ super({
4633
+ baseDir,
4634
+ relativeDirPath,
4635
+ dirName,
4636
+ mainFile: {
4637
+ name: SKILL_FILE_NAME,
4638
+ body,
4639
+ frontmatter: { ...frontmatter }
4640
+ },
4641
+ otherFiles,
4642
+ global
4643
+ });
4644
+ if (validate) {
4645
+ const result = this.validate();
4646
+ if (!result.success) {
4647
+ throw result.error;
4648
+ }
4649
+ }
4650
+ }
4651
+ static getSettablePaths() {
4652
+ return {
4653
+ relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
4654
+ };
4655
+ }
4656
+ getFrontmatter() {
4657
+ if (!this.mainFile?.frontmatter) {
4658
+ throw new Error("Frontmatter is not defined");
4659
+ }
4660
+ const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
4661
+ return result;
4662
+ }
4663
+ getBody() {
4664
+ return this.mainFile?.body ?? "";
4665
+ }
4666
+ validate() {
4667
+ const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
4668
+ if (!result.success) {
4669
+ return {
4670
+ success: false,
4671
+ error: new Error(
4672
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
4673
+ )
4674
+ };
4675
+ }
4676
+ return { success: true, error: null };
4677
+ }
4678
+ static async fromDir({
4679
+ baseDir = process.cwd(),
4680
+ relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
4681
+ dirName,
4682
+ global = false
4683
+ }) {
4684
+ const skillDirPath = (0, import_node_path46.join)(baseDir, relativeDirPath, dirName);
4685
+ const skillFilePath = (0, import_node_path46.join)(skillDirPath, SKILL_FILE_NAME);
4686
+ if (!await fileExists(skillFilePath)) {
4687
+ throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4688
+ }
4689
+ const fileContent = await readFileContent(skillFilePath);
4690
+ const { frontmatter, body: content } = parseFrontmatter(fileContent);
4691
+ const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
4692
+ if (!result.success) {
4693
+ throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
4694
+ }
4695
+ const otherFiles = await this.collectOtherFiles(
4696
+ baseDir,
4697
+ relativeDirPath,
4698
+ dirName,
4699
+ SKILL_FILE_NAME
4700
+ );
4701
+ return new _RulesyncSkill({
4702
+ baseDir,
4703
+ relativeDirPath,
4704
+ dirName,
4705
+ frontmatter: result.data,
4706
+ body: content.trim(),
4707
+ otherFiles,
4708
+ validate: true,
4709
+ global
4710
+ });
4711
+ }
4712
+ };
4713
+
4714
+ // src/features/skills/claudecode-skill.ts
4715
+ var ClaudecodeSkillFrontmatterSchema = import_mini19.z.object({
4716
+ name: import_mini19.z.string(),
4717
+ description: import_mini19.z.string(),
4718
+ "allowed-tools": import_mini19.z.optional(import_mini19.z.array(import_mini19.z.string()))
4719
+ });
4720
+ var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
4721
+ constructor({
4722
+ baseDir = process.cwd(),
4723
+ relativeDirPath = (0, import_node_path47.join)(".claude", "skills"),
4724
+ dirName,
4725
+ frontmatter,
4726
+ body,
4727
+ otherFiles = [],
4728
+ validate = true,
4729
+ global = false
4730
+ }) {
4731
+ super({
4732
+ baseDir,
4733
+ relativeDirPath,
4734
+ dirName,
4735
+ mainFile: {
4736
+ name: SKILL_FILE_NAME,
4737
+ body,
4738
+ frontmatter: { ...frontmatter }
4739
+ },
4740
+ otherFiles,
4741
+ global
4742
+ });
4743
+ if (validate) {
4744
+ const result = this.validate();
4745
+ if (!result.success) {
4746
+ throw result.error;
4747
+ }
4748
+ }
4749
+ }
4750
+ static getSettablePaths({
4751
+ global: _global = false
4752
+ } = {}) {
4753
+ return {
4754
+ relativeDirPath: (0, import_node_path47.join)(".claude", "skills")
4755
+ };
4756
+ }
4757
+ getFrontmatter() {
4758
+ if (!this.mainFile?.frontmatter) {
4759
+ throw new Error("Frontmatter is not defined");
4760
+ }
4761
+ const result = ClaudecodeSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
4762
+ return result;
4763
+ }
4764
+ getBody() {
4765
+ return this.mainFile?.body ?? "";
4766
+ }
4767
+ validate() {
4768
+ if (this.mainFile === void 0) {
4769
+ return {
4770
+ success: false,
4771
+ error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
4772
+ };
4773
+ }
4774
+ const result = ClaudecodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
4775
+ if (!result.success) {
4776
+ return {
4777
+ success: false,
4778
+ error: new Error(
4779
+ `Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
4780
+ )
4781
+ };
4782
+ }
4783
+ return { success: true, error: null };
4784
+ }
4785
+ toRulesyncSkill() {
4786
+ const frontmatter = this.getFrontmatter();
4787
+ const rulesyncFrontmatter = {
4788
+ name: frontmatter.name,
4789
+ description: frontmatter.description,
4790
+ targets: ["*"],
4791
+ ...frontmatter["allowed-tools"] && {
4792
+ claudecode: {
4793
+ "allowed-tools": frontmatter["allowed-tools"]
4794
+ }
4795
+ }
4796
+ };
4797
+ return new RulesyncSkill({
4798
+ baseDir: this.baseDir,
4799
+ relativeDirPath: this.relativeDirPath,
4800
+ dirName: this.getDirName(),
4801
+ frontmatter: rulesyncFrontmatter,
4802
+ body: this.getBody(),
4803
+ otherFiles: this.getOtherFiles(),
4804
+ validate: true,
4805
+ global: this.global
4806
+ });
4807
+ }
4808
+ static fromRulesyncSkill({
4809
+ rulesyncSkill,
4810
+ validate = true,
4811
+ global = false
4812
+ }) {
4813
+ const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
4814
+ const claudecodeFrontmatter = {
4815
+ name: rulesyncFrontmatter.name,
4816
+ description: rulesyncFrontmatter.description,
4817
+ "allowed-tools": rulesyncFrontmatter.claudecode?.["allowed-tools"]
4818
+ };
4819
+ const settablePaths = _ClaudecodeSkill.getSettablePaths({ global });
4820
+ return new _ClaudecodeSkill({
4821
+ baseDir: rulesyncSkill.getBaseDir(),
4822
+ relativeDirPath: settablePaths.relativeDirPath,
4823
+ dirName: rulesyncSkill.getDirName(),
4824
+ frontmatter: claudecodeFrontmatter,
4825
+ body: rulesyncSkill.getBody(),
4826
+ otherFiles: rulesyncSkill.getOtherFiles(),
4827
+ validate,
4828
+ global
4829
+ });
4830
+ }
4831
+ static isTargetedByRulesyncSkill(_rulesyncSkill) {
4832
+ return true;
4833
+ }
4834
+ static async fromDir({
4835
+ baseDir = process.cwd(),
4836
+ relativeDirPath,
4837
+ dirName,
4838
+ global = false
4839
+ }) {
4840
+ const settablePaths = this.getSettablePaths({ global });
4841
+ const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
4842
+ const skillDirPath = (0, import_node_path47.join)(baseDir, actualRelativeDirPath, dirName);
4843
+ const skillFilePath = (0, import_node_path47.join)(skillDirPath, SKILL_FILE_NAME);
4844
+ if (!await fileExists(skillFilePath)) {
4845
+ throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
4846
+ }
4847
+ const fileContent = await readFileContent(skillFilePath);
4848
+ const { frontmatter, body: content } = parseFrontmatter(fileContent);
4849
+ const result = ClaudecodeSkillFrontmatterSchema.safeParse(frontmatter);
4850
+ if (!result.success) {
4851
+ throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
4852
+ }
4853
+ const otherFiles = await this.collectOtherFiles(
4854
+ baseDir,
4855
+ actualRelativeDirPath,
4856
+ dirName,
4857
+ SKILL_FILE_NAME
4858
+ );
4859
+ return new _ClaudecodeSkill({
4860
+ baseDir,
4861
+ relativeDirPath: actualRelativeDirPath,
4862
+ dirName,
4863
+ frontmatter: result.data,
4864
+ body: content.trim(),
4865
+ otherFiles,
4866
+ validate: true,
4867
+ global
4868
+ });
4869
+ }
4870
+ };
4871
+
4872
+ // src/features/skills/geminicli-skill.ts
4873
+ var import_node_path48 = require("path");
4874
+ var GeminiCliSkill = class _GeminiCliSkill extends SimulatedSkill {
4875
+ static getSettablePaths(options) {
4876
+ if (options?.global) {
4877
+ throw new Error("GeminiCliSkill does not support global mode.");
4878
+ }
4879
+ return {
4880
+ relativeDirPath: (0, import_node_path48.join)(".gemini", "skills")
4881
+ };
4882
+ }
4883
+ static async fromDir(params) {
4884
+ const baseParams = await this.fromDirDefault(params);
4885
+ return new _GeminiCliSkill(baseParams);
4886
+ }
4887
+ static fromRulesyncSkill(params) {
4888
+ const baseParams = {
4889
+ ...this.fromRulesyncSkillDefault(params),
4890
+ relativeDirPath: this.getSettablePaths().relativeDirPath
4891
+ };
4892
+ return new _GeminiCliSkill(baseParams);
4893
+ }
4894
+ static isTargetedByRulesyncSkill(rulesyncSkill) {
4895
+ return this.isTargetedByRulesyncSkillDefault({
4896
+ rulesyncSkill,
4897
+ toolTarget: "geminicli"
4898
+ });
4899
+ }
4900
+ };
4901
+
4902
+ // src/features/skills/skills-processor.ts
4903
+ var skillsProcessorToolTargets = [
4904
+ "claudecode",
4905
+ "copilot",
4906
+ "cursor",
4907
+ "codexcli",
4908
+ "geminicli",
4909
+ "agentsmd"
4910
+ ];
4911
+ var skillsProcessorToolTargetsSimulated = [
4912
+ "copilot",
4913
+ "cursor",
4914
+ "codexcli",
4915
+ "geminicli",
4916
+ "agentsmd"
4917
+ ];
4918
+ var skillsProcessorToolTargetsGlobal = ["claudecode"];
4919
+ var SkillsProcessorToolTargetSchema = import_mini20.z.enum(skillsProcessorToolTargets);
4920
+ var SkillsProcessor = class extends DirFeatureProcessor {
4921
+ toolTarget;
4922
+ global;
4923
+ constructor({
4924
+ baseDir = process.cwd(),
4925
+ toolTarget,
4926
+ global = false
4927
+ }) {
4928
+ super({ baseDir });
4929
+ const result = SkillsProcessorToolTargetSchema.safeParse(toolTarget);
4930
+ if (!result.success) {
4931
+ throw new Error(
4932
+ `Invalid tool target for SkillsProcessor: ${toolTarget}. ${formatError(result.error)}`
4933
+ );
4934
+ }
4935
+ this.toolTarget = result.data;
4936
+ this.global = global;
4937
+ }
4938
+ async convertRulesyncDirsToToolDirs(rulesyncDirs) {
4939
+ const rulesyncSkills = rulesyncDirs.filter(
4940
+ (dir) => dir instanceof RulesyncSkill
4941
+ );
4942
+ const toolSkills = [];
4943
+ for (const rulesyncSkill of rulesyncSkills) {
4944
+ switch (this.toolTarget) {
4945
+ case "claudecode":
4946
+ if (!ClaudecodeSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
4947
+ continue;
4948
+ }
4949
+ toolSkills.push(
4950
+ ClaudecodeSkill.fromRulesyncSkill({
4951
+ rulesyncSkill,
4952
+ global: this.global
4953
+ })
4954
+ );
4955
+ break;
4956
+ case "copilot":
4957
+ if (!CopilotSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
4958
+ continue;
4959
+ }
4960
+ toolSkills.push(
4961
+ CopilotSkill.fromRulesyncSkill({
4962
+ rulesyncSkill
4963
+ })
4964
+ );
4965
+ break;
4966
+ case "cursor":
4967
+ if (!CursorSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
4968
+ continue;
4969
+ }
4970
+ toolSkills.push(
4971
+ CursorSkill.fromRulesyncSkill({
4972
+ rulesyncSkill
4973
+ })
4974
+ );
4975
+ break;
4976
+ case "codexcli":
4977
+ if (!CodexCliSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
4978
+ continue;
4979
+ }
4980
+ toolSkills.push(
4981
+ CodexCliSkill.fromRulesyncSkill({
4982
+ rulesyncSkill
4983
+ })
4984
+ );
4985
+ break;
4986
+ case "geminicli":
4987
+ if (!GeminiCliSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
4988
+ continue;
4989
+ }
4990
+ toolSkills.push(
4991
+ GeminiCliSkill.fromRulesyncSkill({
4992
+ rulesyncSkill
4993
+ })
4994
+ );
4995
+ break;
4996
+ case "agentsmd":
4997
+ if (!AgentsmdSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
4998
+ continue;
4999
+ }
5000
+ toolSkills.push(
5001
+ AgentsmdSkill.fromRulesyncSkill({
5002
+ rulesyncSkill
5003
+ })
5004
+ );
5005
+ break;
5006
+ default:
5007
+ throw new Error(`Unsupported tool target: ${this.toolTarget}`);
5008
+ }
5009
+ }
5010
+ return toolSkills;
5011
+ }
5012
+ async convertToolDirsToRulesyncDirs(toolDirs) {
5013
+ const toolSkills = toolDirs.filter((dir) => dir instanceof ToolSkill);
5014
+ const rulesyncSkills = [];
5015
+ for (const toolSkill of toolSkills) {
5016
+ if (toolSkill instanceof SimulatedSkill) {
5017
+ logger.debug(`Skipping simulated skill conversion: ${toolSkill.getDirPath()}`);
5018
+ continue;
5019
+ }
5020
+ rulesyncSkills.push(toolSkill.toRulesyncSkill());
5021
+ }
5022
+ return rulesyncSkills;
5023
+ }
5024
+ /**
5025
+ * Implementation of abstract method from DirFeatureProcessor
5026
+ * Load and parse rulesync skill directories from .rulesync/skills/ directory
5027
+ */
5028
+ async loadRulesyncDirs() {
5029
+ const paths = RulesyncSkill.getSettablePaths();
5030
+ const rulesyncSkillsDirPath = (0, import_node_path49.join)(this.baseDir, paths.relativeDirPath);
5031
+ const dirPaths = await findFilesByGlobs((0, import_node_path49.join)(rulesyncSkillsDirPath, "*"), { type: "dir" });
5032
+ const dirNames = dirPaths.map((path3) => (0, import_node_path49.basename)(path3));
5033
+ const results = await Promise.allSettled(
5034
+ dirNames.map(
5035
+ (dirName) => RulesyncSkill.fromDir({ baseDir: this.baseDir, dirName, global: this.global })
5036
+ )
5037
+ );
5038
+ const rulesyncSkills = [];
5039
+ for (const result of results) {
5040
+ if (result.status === "fulfilled") {
5041
+ rulesyncSkills.push(result.value);
5042
+ }
5043
+ }
5044
+ logger.info(`Successfully loaded ${rulesyncSkills.length} rulesync skills`);
5045
+ return rulesyncSkills;
5046
+ }
5047
+ /**
5048
+ * Implementation of abstract method from DirFeatureProcessor
5049
+ * Load tool-specific skill configurations and parse them into ToolSkill instances
5050
+ */
5051
+ async loadToolDirs() {
5052
+ switch (this.toolTarget) {
5053
+ case "claudecode":
5054
+ return await this.loadClaudecodeSkills();
5055
+ case "copilot":
5056
+ return await this.loadSimulatedSkills(CopilotSkill);
5057
+ case "cursor":
5058
+ return await this.loadSimulatedSkills(CursorSkill);
5059
+ case "codexcli":
5060
+ return await this.loadSimulatedSkills(CodexCliSkill);
5061
+ case "geminicli":
5062
+ return await this.loadSimulatedSkills(GeminiCliSkill);
5063
+ case "agentsmd":
5064
+ return await this.loadSimulatedSkills(AgentsmdSkill);
5065
+ default:
5066
+ throw new Error(`Unsupported tool target: ${this.toolTarget}`);
5067
+ }
5068
+ }
5069
+ async loadToolDirsToDelete() {
5070
+ return this.loadToolDirs();
5071
+ }
5072
+ /**
5073
+ * Load Claude Code skill configurations from .claude/skills/ directory
5074
+ */
5075
+ async loadClaudecodeSkills() {
5076
+ const paths = ClaudecodeSkill.getSettablePaths({ global: this.global });
5077
+ const skillsDirPath = (0, import_node_path49.join)(this.baseDir, paths.relativeDirPath);
5078
+ const dirPaths = await findFilesByGlobs((0, import_node_path49.join)(skillsDirPath, "*"), { type: "dir" });
5079
+ const dirNames = dirPaths.map((path3) => (0, import_node_path49.basename)(path3));
5080
+ const toolSkills = (await Promise.allSettled(
5081
+ dirNames.map(
5082
+ (dirName) => ClaudecodeSkill.fromDir({
5083
+ baseDir: this.baseDir,
5084
+ dirName,
5085
+ global: this.global
5086
+ })
5087
+ )
5088
+ )).filter((result) => result.status === "fulfilled").map((result) => result.value);
5089
+ logger.info(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
5090
+ return toolSkills;
5091
+ }
5092
+ /**
5093
+ * Load simulated skill configurations from tool-specific directories
3709
5094
  */
3710
- async convertRulesyncFilesToToolFiles(rulesyncFiles) {
3711
- const rulesyncMcp = rulesyncFiles.find(
3712
- (file) => file instanceof RulesyncMcp
3713
- );
3714
- if (!rulesyncMcp) {
3715
- throw new Error(`No ${RULESYNC_MCP_RELATIVE_FILE_PATH} found.`);
3716
- }
3717
- const toolMcps = await Promise.all(
3718
- [rulesyncMcp].map(async (rulesyncMcp2) => {
3719
- switch (this.toolTarget) {
3720
- case "amazonqcli":
3721
- return AmazonqcliMcp.fromRulesyncMcp({
3722
- baseDir: this.baseDir,
3723
- rulesyncMcp: rulesyncMcp2
3724
- });
3725
- case "claudecode":
3726
- return await ClaudecodeMcp.fromRulesyncMcp({
3727
- baseDir: this.baseDir,
3728
- rulesyncMcp: rulesyncMcp2,
3729
- global: this.global,
3730
- modularMcp: this.modularMcp
3731
- });
3732
- case "cline":
3733
- return ClineMcp.fromRulesyncMcp({
3734
- baseDir: this.baseDir,
3735
- rulesyncMcp: rulesyncMcp2
3736
- });
3737
- case "copilot":
3738
- return CopilotMcp.fromRulesyncMcp({
3739
- baseDir: this.baseDir,
3740
- rulesyncMcp: rulesyncMcp2
3741
- });
3742
- case "cursor":
3743
- return CursorMcp.fromRulesyncMcp({
3744
- baseDir: this.baseDir,
3745
- rulesyncMcp: rulesyncMcp2
3746
- });
3747
- case "codexcli":
3748
- return await CodexcliMcp.fromRulesyncMcp({
3749
- baseDir: this.baseDir,
3750
- rulesyncMcp: rulesyncMcp2,
3751
- global: this.global
3752
- });
3753
- case "geminicli":
3754
- return GeminiCliMcp.fromRulesyncMcp({
3755
- baseDir: this.baseDir,
3756
- rulesyncMcp: rulesyncMcp2,
3757
- global: this.global
3758
- });
3759
- case "roo":
3760
- return RooMcp.fromRulesyncMcp({
3761
- baseDir: this.baseDir,
3762
- rulesyncMcp: rulesyncMcp2
3763
- });
3764
- default:
3765
- throw new Error(`Unsupported tool target: ${this.toolTarget}`);
3766
- }
3767
- })
3768
- );
3769
- const toolFiles = toolMcps;
3770
- if (this.modularMcp && mcpProcessorToolTargetsModular.includes(this.toolTarget)) {
3771
- const relativeDirPath = this.toolTarget === "claudecode" ? ClaudecodeMcp.getSettablePaths({ global: this.global }).relativeDirPath : void 0;
3772
- toolFiles.push(
3773
- ModularMcp.fromRulesyncMcp({
5095
+ async loadSimulatedSkills(SkillClass) {
5096
+ const paths = SkillClass.getSettablePaths();
5097
+ const skillsDirPath = (0, import_node_path49.join)(this.baseDir, paths.relativeDirPath);
5098
+ const dirPaths = await findFilesByGlobs((0, import_node_path49.join)(skillsDirPath, "*"), { type: "dir" });
5099
+ const dirNames = dirPaths.map((path3) => (0, import_node_path49.basename)(path3));
5100
+ const toolSkills = (await Promise.allSettled(
5101
+ dirNames.map(
5102
+ (dirName) => SkillClass.fromDir({
3774
5103
  baseDir: this.baseDir,
3775
- rulesyncMcp,
3776
- ...this.global && relativeDirPath ? { global: true, relativeDirPath } : { global: false }
5104
+ dirName
3777
5105
  })
5106
+ )
5107
+ )).filter((result) => result.status === "fulfilled").map((result) => result.value);
5108
+ logger.info(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
5109
+ return toolSkills;
5110
+ }
5111
+ /**
5112
+ * Implementation of abstract method from DirFeatureProcessor
5113
+ * Return the tool targets that this processor supports
5114
+ */
5115
+ static getToolTargets({
5116
+ global = false,
5117
+ includeSimulated = false
5118
+ } = {}) {
5119
+ if (global) {
5120
+ return skillsProcessorToolTargetsGlobal;
5121
+ }
5122
+ if (!includeSimulated) {
5123
+ return skillsProcessorToolTargets.filter(
5124
+ (target) => !skillsProcessorToolTargetsSimulated.includes(target)
3778
5125
  );
3779
5126
  }
3780
- return toolFiles;
5127
+ return skillsProcessorToolTargets;
3781
5128
  }
3782
5129
  /**
3783
- * Implementation of abstract method from FeatureProcessor
3784
- * Convert ToolFile[] to RulesyncFile[]
5130
+ * Return the simulated tool targets
3785
5131
  */
3786
- async convertToolFilesToRulesyncFiles(toolFiles) {
3787
- const toolMcps = toolFiles.filter((file) => file instanceof ToolMcp);
3788
- const rulesyncMcps = toolMcps.map((toolMcp) => {
3789
- return toolMcp.toRulesyncMcp();
3790
- });
3791
- return rulesyncMcps;
5132
+ static getToolTargetsSimulated() {
5133
+ return skillsProcessorToolTargetsSimulated;
3792
5134
  }
3793
5135
  /**
3794
- * Implementation of abstract method from FeatureProcessor
3795
- * Return the tool targets that this processor supports
5136
+ * Return the tool targets that this processor supports in global mode
3796
5137
  */
3797
- static getToolTargets() {
3798
- return mcpProcessorToolTargets;
3799
- }
3800
5138
  static getToolTargetsGlobal() {
3801
- return mcpProcessorToolTargetsGlobal;
5139
+ return skillsProcessorToolTargetsGlobal;
3802
5140
  }
3803
5141
  };
3804
5142
 
3805
- // src/features/rules/rules-processor.ts
3806
- var import_node_path66 = require("path");
3807
- var import_fast_xml_parser = require("fast-xml-parser");
3808
- var import_mini24 = require("zod/mini");
3809
-
3810
5143
  // src/features/subagents/agentsmd-subagent.ts
3811
- var import_node_path38 = require("path");
5144
+ var import_node_path51 = require("path");
3812
5145
 
3813
5146
  // src/features/subagents/simulated-subagent.ts
3814
- var import_node_path37 = require("path");
3815
- var import_mini16 = require("zod/mini");
5147
+ var import_node_path50 = require("path");
5148
+ var import_mini21 = require("zod/mini");
3816
5149
 
3817
5150
  // src/features/subagents/tool-subagent.ts
3818
5151
  var ToolSubagent = class extends ToolFile {
@@ -3847,9 +5180,9 @@ var ToolSubagent = class extends ToolFile {
3847
5180
  };
3848
5181
 
3849
5182
  // src/features/subagents/simulated-subagent.ts
3850
- var SimulatedSubagentFrontmatterSchema = import_mini16.z.object({
3851
- name: import_mini16.z.string(),
3852
- description: import_mini16.z.string()
5183
+ var SimulatedSubagentFrontmatterSchema = import_mini21.z.object({
5184
+ name: import_mini21.z.string(),
5185
+ description: import_mini21.z.string()
3853
5186
  });
3854
5187
  var SimulatedSubagent = class extends ToolSubagent {
3855
5188
  frontmatter;
@@ -3859,7 +5192,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3859
5192
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
3860
5193
  if (!result.success) {
3861
5194
  throw new Error(
3862
- `Invalid frontmatter in ${(0, import_node_path37.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
5195
+ `Invalid frontmatter in ${(0, import_node_path50.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
3863
5196
  );
3864
5197
  }
3865
5198
  }
@@ -3910,7 +5243,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3910
5243
  return {
3911
5244
  success: false,
3912
5245
  error: new Error(
3913
- `Invalid frontmatter in ${(0, import_node_path37.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
5246
+ `Invalid frontmatter in ${(0, import_node_path50.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
3914
5247
  )
3915
5248
  };
3916
5249
  }
@@ -3920,7 +5253,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3920
5253
  relativeFilePath,
3921
5254
  validate = true
3922
5255
  }) {
3923
- const filePath = (0, import_node_path37.join)(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
5256
+ const filePath = (0, import_node_path50.join)(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
3924
5257
  const fileContent = await readFileContent(filePath);
3925
5258
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
3926
5259
  const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -3930,7 +5263,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3930
5263
  return {
3931
5264
  baseDir,
3932
5265
  relativeDirPath: this.getSettablePaths().relativeDirPath,
3933
- relativeFilePath: (0, import_node_path37.basename)(relativeFilePath),
5266
+ relativeFilePath: (0, import_node_path50.basename)(relativeFilePath),
3934
5267
  frontmatter: result.data,
3935
5268
  body: content.trim(),
3936
5269
  validate
@@ -3942,7 +5275,7 @@ var SimulatedSubagent = class extends ToolSubagent {
3942
5275
  var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
3943
5276
  static getSettablePaths() {
3944
5277
  return {
3945
- relativeDirPath: (0, import_node_path38.join)(".agents", "subagents")
5278
+ relativeDirPath: (0, import_node_path51.join)(".agents", "subagents")
3946
5279
  };
3947
5280
  }
3948
5281
  static async fromFile(params) {
@@ -3962,11 +5295,11 @@ var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
3962
5295
  };
3963
5296
 
3964
5297
  // src/features/subagents/codexcli-subagent.ts
3965
- var import_node_path39 = require("path");
5298
+ var import_node_path52 = require("path");
3966
5299
  var CodexCliSubagent = class _CodexCliSubagent extends SimulatedSubagent {
3967
5300
  static getSettablePaths() {
3968
5301
  return {
3969
- relativeDirPath: (0, import_node_path39.join)(".codex", "subagents")
5302
+ relativeDirPath: (0, import_node_path52.join)(".codex", "subagents")
3970
5303
  };
3971
5304
  }
3972
5305
  static async fromFile(params) {
@@ -3986,11 +5319,11 @@ var CodexCliSubagent = class _CodexCliSubagent extends SimulatedSubagent {
3986
5319
  };
3987
5320
 
3988
5321
  // src/features/subagents/copilot-subagent.ts
3989
- var import_node_path40 = require("path");
5322
+ var import_node_path53 = require("path");
3990
5323
  var CopilotSubagent = class _CopilotSubagent extends SimulatedSubagent {
3991
5324
  static getSettablePaths() {
3992
5325
  return {
3993
- relativeDirPath: (0, import_node_path40.join)(".github", "subagents")
5326
+ relativeDirPath: (0, import_node_path53.join)(".github", "subagents")
3994
5327
  };
3995
5328
  }
3996
5329
  static async fromFile(params) {
@@ -4010,11 +5343,11 @@ var CopilotSubagent = class _CopilotSubagent extends SimulatedSubagent {
4010
5343
  };
4011
5344
 
4012
5345
  // src/features/subagents/cursor-subagent.ts
4013
- var import_node_path41 = require("path");
5346
+ var import_node_path54 = require("path");
4014
5347
  var CursorSubagent = class _CursorSubagent extends SimulatedSubagent {
4015
5348
  static getSettablePaths() {
4016
5349
  return {
4017
- relativeDirPath: (0, import_node_path41.join)(".cursor", "subagents")
5350
+ relativeDirPath: (0, import_node_path54.join)(".cursor", "subagents")
4018
5351
  };
4019
5352
  }
4020
5353
  static async fromFile(params) {
@@ -4034,11 +5367,11 @@ var CursorSubagent = class _CursorSubagent extends SimulatedSubagent {
4034
5367
  };
4035
5368
 
4036
5369
  // src/features/subagents/geminicli-subagent.ts
4037
- var import_node_path42 = require("path");
5370
+ var import_node_path55 = require("path");
4038
5371
  var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
4039
5372
  static getSettablePaths() {
4040
5373
  return {
4041
- relativeDirPath: (0, import_node_path42.join)(".gemini", "subagents")
5374
+ relativeDirPath: (0, import_node_path55.join)(".gemini", "subagents")
4042
5375
  };
4043
5376
  }
4044
5377
  static async fromFile(params) {
@@ -4058,11 +5391,11 @@ var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
4058
5391
  };
4059
5392
 
4060
5393
  // src/features/subagents/roo-subagent.ts
4061
- var import_node_path43 = require("path");
5394
+ var import_node_path56 = require("path");
4062
5395
  var RooSubagent = class _RooSubagent extends SimulatedSubagent {
4063
5396
  static getSettablePaths() {
4064
5397
  return {
4065
- relativeDirPath: (0, import_node_path43.join)(".roo", "subagents")
5398
+ relativeDirPath: (0, import_node_path56.join)(".roo", "subagents")
4066
5399
  };
4067
5400
  }
4068
5401
  static async fromFile(params) {
@@ -4082,23 +5415,23 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
4082
5415
  };
4083
5416
 
4084
5417
  // src/features/subagents/subagents-processor.ts
4085
- var import_node_path46 = require("path");
4086
- var import_mini19 = require("zod/mini");
5418
+ var import_node_path59 = require("path");
5419
+ var import_mini24 = require("zod/mini");
4087
5420
 
4088
5421
  // src/features/subagents/claudecode-subagent.ts
4089
- var import_node_path45 = require("path");
4090
- var import_mini18 = require("zod/mini");
5422
+ var import_node_path58 = require("path");
5423
+ var import_mini23 = require("zod/mini");
4091
5424
 
4092
5425
  // src/features/subagents/rulesync-subagent.ts
4093
- var import_node_path44 = require("path");
4094
- var import_mini17 = require("zod/mini");
4095
- var RulesyncSubagentModelSchema = import_mini17.z.enum(["opus", "sonnet", "haiku", "inherit"]);
4096
- var RulesyncSubagentFrontmatterSchema = import_mini17.z.object({
5426
+ var import_node_path57 = require("path");
5427
+ var import_mini22 = require("zod/mini");
5428
+ var RulesyncSubagentModelSchema = import_mini22.z.enum(["opus", "sonnet", "haiku", "inherit"]);
5429
+ var RulesyncSubagentFrontmatterSchema = import_mini22.z.object({
4097
5430
  targets: RulesyncTargetsSchema,
4098
- name: import_mini17.z.string(),
4099
- description: import_mini17.z.string(),
4100
- claudecode: import_mini17.z.optional(
4101
- import_mini17.z.object({
5431
+ name: import_mini22.z.string(),
5432
+ description: import_mini22.z.string(),
5433
+ claudecode: import_mini22.z.optional(
5434
+ import_mini22.z.object({
4102
5435
  model: RulesyncSubagentModelSchema
4103
5436
  })
4104
5437
  )
@@ -4111,7 +5444,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
4111
5444
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
4112
5445
  if (!result.success) {
4113
5446
  throw new Error(
4114
- `Invalid frontmatter in ${(0, import_node_path44.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
5447
+ `Invalid frontmatter in ${(0, import_node_path57.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
4115
5448
  );
4116
5449
  }
4117
5450
  }
@@ -4144,7 +5477,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
4144
5477
  return {
4145
5478
  success: false,
4146
5479
  error: new Error(
4147
- `Invalid frontmatter in ${(0, import_node_path44.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
5480
+ `Invalid frontmatter in ${(0, import_node_path57.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
4148
5481
  )
4149
5482
  };
4150
5483
  }
@@ -4153,14 +5486,14 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
4153
5486
  relativeFilePath
4154
5487
  }) {
4155
5488
  const fileContent = await readFileContent(
4156
- (0, import_node_path44.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath)
5489
+ (0, import_node_path57.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath)
4157
5490
  );
4158
5491
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4159
5492
  const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
4160
5493
  if (!result.success) {
4161
5494
  throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
4162
5495
  }
4163
- const filename = (0, import_node_path44.basename)(relativeFilePath);
5496
+ const filename = (0, import_node_path57.basename)(relativeFilePath);
4164
5497
  return new _RulesyncSubagent({
4165
5498
  baseDir: process.cwd(),
4166
5499
  relativeDirPath: this.getSettablePaths().relativeDirPath,
@@ -4172,10 +5505,10 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
4172
5505
  };
4173
5506
 
4174
5507
  // src/features/subagents/claudecode-subagent.ts
4175
- var ClaudecodeSubagentFrontmatterSchema = import_mini18.z.object({
4176
- name: import_mini18.z.string(),
4177
- description: import_mini18.z.string(),
4178
- model: import_mini18.z.optional(import_mini18.z.enum(["opus", "sonnet", "haiku", "inherit"]))
5508
+ var ClaudecodeSubagentFrontmatterSchema = import_mini23.z.object({
5509
+ name: import_mini23.z.string(),
5510
+ description: import_mini23.z.string(),
5511
+ model: import_mini23.z.optional(import_mini23.z.enum(["opus", "sonnet", "haiku", "inherit"]))
4179
5512
  });
4180
5513
  var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4181
5514
  frontmatter;
@@ -4185,7 +5518,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4185
5518
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
4186
5519
  if (!result.success) {
4187
5520
  throw new Error(
4188
- `Invalid frontmatter in ${(0, import_node_path45.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
5521
+ `Invalid frontmatter in ${(0, import_node_path58.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
4189
5522
  );
4190
5523
  }
4191
5524
  }
@@ -4197,7 +5530,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4197
5530
  }
4198
5531
  static getSettablePaths(_options = {}) {
4199
5532
  return {
4200
- relativeDirPath: (0, import_node_path45.join)(".claude", "agents")
5533
+ relativeDirPath: (0, import_node_path58.join)(".claude", "agents")
4201
5534
  };
4202
5535
  }
4203
5536
  getFrontmatter() {
@@ -4263,7 +5596,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4263
5596
  return {
4264
5597
  success: false,
4265
5598
  error: new Error(
4266
- `Invalid frontmatter in ${(0, import_node_path45.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
5599
+ `Invalid frontmatter in ${(0, import_node_path58.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
4267
5600
  )
4268
5601
  };
4269
5602
  }
@@ -4281,7 +5614,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
4281
5614
  global = false
4282
5615
  }) {
4283
5616
  const paths = this.getSettablePaths({ global });
4284
- const filePath = (0, import_node_path45.join)(baseDir, paths.relativeDirPath, relativeFilePath);
5617
+ const filePath = (0, import_node_path58.join)(baseDir, paths.relativeDirPath, relativeFilePath);
4285
5618
  const fileContent = await readFileContent(filePath);
4286
5619
  const { frontmatter, body: content } = parseFrontmatter(fileContent);
4287
5620
  const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
@@ -4319,7 +5652,7 @@ var subagentsProcessorToolTargetsSimulated = [
4319
5652
  "roo"
4320
5653
  ];
4321
5654
  var subagentsProcessorToolTargetsGlobal = ["claudecode"];
4322
- var SubagentsProcessorToolTargetSchema = import_mini19.z.enum(subagentsProcessorToolTargets);
5655
+ var SubagentsProcessorToolTargetSchema = import_mini24.z.enum(subagentsProcessorToolTargets);
4323
5656
  var SubagentsProcessor = class extends FeatureProcessor {
4324
5657
  toolTarget;
4325
5658
  global;
@@ -4435,7 +5768,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
4435
5768
  * Load and parse rulesync subagent files from .rulesync/subagents/ directory
4436
5769
  */
4437
5770
  async loadRulesyncFiles() {
4438
- const subagentsDir = (0, import_node_path46.join)(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
5771
+ const subagentsDir = (0, import_node_path59.join)(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
4439
5772
  const dirExists = await directoryExists(subagentsDir);
4440
5773
  if (!dirExists) {
4441
5774
  logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
@@ -4450,7 +5783,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
4450
5783
  logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
4451
5784
  const rulesyncSubagents = [];
4452
5785
  for (const mdFile of mdFiles) {
4453
- const filepath = (0, import_node_path46.join)(subagentsDir, mdFile);
5786
+ const filepath = (0, import_node_path59.join)(subagentsDir, mdFile);
4454
5787
  try {
4455
5788
  const rulesyncSubagent = await RulesyncSubagent.fromFile({
4456
5789
  relativeFilePath: mdFile,
@@ -4474,7 +5807,9 @@ var SubagentsProcessor = class extends FeatureProcessor {
4474
5807
  * Implementation of abstract method from Processor
4475
5808
  * Load tool-specific subagent configurations and parse them into ToolSubagent instances
4476
5809
  */
4477
- async loadToolFiles() {
5810
+ async loadToolFiles({
5811
+ forDeletion: _forDeletion = false
5812
+ } = {}) {
4478
5813
  switch (this.toolTarget) {
4479
5814
  case "agentsmd":
4480
5815
  return await this.loadAgentsmdSubagents();
@@ -4494,9 +5829,6 @@ var SubagentsProcessor = class extends FeatureProcessor {
4494
5829
  throw new Error(`Unsupported tool target: ${this.toolTarget}`);
4495
5830
  }
4496
5831
  }
4497
- async loadToolFilesToDelete() {
4498
- return this.loadToolFiles();
4499
- }
4500
5832
  /**
4501
5833
  * Load Agents.md subagent configurations from .agents/subagents/ directory
4502
5834
  */
@@ -4569,8 +5901,8 @@ var SubagentsProcessor = class extends FeatureProcessor {
4569
5901
  relativeDirPath,
4570
5902
  fromFile
4571
5903
  }) {
4572
- 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);
5904
+ const paths = await findFilesByGlobs((0, import_node_path59.join)(this.baseDir, relativeDirPath, "*.md"));
5905
+ const subagents = (await Promise.allSettled(paths.map((path3) => fromFile((0, import_node_path59.basename)(path3))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
4574
5906
  logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
4575
5907
  return subagents;
4576
5908
  }
@@ -4579,8 +5911,12 @@ var SubagentsProcessor = class extends FeatureProcessor {
4579
5911
  * Return the tool targets that this processor supports
4580
5912
  */
4581
5913
  static getToolTargets({
5914
+ global = false,
4582
5915
  includeSimulated = false
4583
5916
  } = {}) {
5917
+ if (global) {
5918
+ return subagentsProcessorToolTargetsGlobal;
5919
+ }
4584
5920
  if (!includeSimulated) {
4585
5921
  return subagentsProcessorToolTargets.filter(
4586
5922
  (target) => !subagentsProcessorToolTargetsSimulated.includes(target)
@@ -4591,36 +5927,33 @@ var SubagentsProcessor = class extends FeatureProcessor {
4591
5927
  static getToolTargetsSimulated() {
4592
5928
  return subagentsProcessorToolTargetsSimulated;
4593
5929
  }
4594
- static getToolTargetsGlobal() {
4595
- return subagentsProcessorToolTargetsGlobal;
4596
- }
4597
5930
  };
4598
5931
 
4599
5932
  // src/features/rules/agentsmd-rule.ts
4600
- var import_node_path49 = require("path");
5933
+ var import_node_path62 = require("path");
4601
5934
 
4602
5935
  // src/features/rules/tool-rule.ts
4603
- var import_node_path48 = require("path");
5936
+ var import_node_path61 = require("path");
4604
5937
 
4605
5938
  // src/features/rules/rulesync-rule.ts
4606
- var import_node_path47 = require("path");
4607
- var import_mini20 = require("zod/mini");
4608
- var RulesyncRuleFrontmatterSchema = import_mini20.z.object({
4609
- root: import_mini20.z.optional(import_mini20.z.optional(import_mini20.z.boolean())),
4610
- targets: import_mini20.z.optional(RulesyncTargetsSchema),
4611
- description: import_mini20.z.optional(import_mini20.z.string()),
4612
- globs: import_mini20.z.optional(import_mini20.z.array(import_mini20.z.string())),
4613
- agentsmd: import_mini20.z.optional(
4614
- import_mini20.z.object({
5939
+ var import_node_path60 = require("path");
5940
+ var import_mini25 = require("zod/mini");
5941
+ var RulesyncRuleFrontmatterSchema = import_mini25.z.object({
5942
+ root: import_mini25.z.optional(import_mini25.z.optional(import_mini25.z.boolean())),
5943
+ targets: import_mini25.z.optional(RulesyncTargetsSchema),
5944
+ description: import_mini25.z.optional(import_mini25.z.string()),
5945
+ globs: import_mini25.z.optional(import_mini25.z.array(import_mini25.z.string())),
5946
+ agentsmd: import_mini25.z.optional(
5947
+ import_mini25.z.object({
4615
5948
  // @example "path/to/subproject"
4616
- subprojectPath: import_mini20.z.optional(import_mini20.z.string())
5949
+ subprojectPath: import_mini25.z.optional(import_mini25.z.string())
4617
5950
  })
4618
5951
  ),
4619
- cursor: import_mini20.z.optional(
4620
- import_mini20.z.object({
4621
- alwaysApply: import_mini20.z.optional(import_mini20.z.boolean()),
4622
- description: import_mini20.z.optional(import_mini20.z.string()),
4623
- globs: import_mini20.z.optional(import_mini20.z.array(import_mini20.z.string()))
5952
+ cursor: import_mini25.z.optional(
5953
+ import_mini25.z.object({
5954
+ alwaysApply: import_mini25.z.optional(import_mini25.z.boolean()),
5955
+ description: import_mini25.z.optional(import_mini25.z.string()),
5956
+ globs: import_mini25.z.optional(import_mini25.z.array(import_mini25.z.string()))
4624
5957
  })
4625
5958
  )
4626
5959
  });
@@ -4632,7 +5965,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4632
5965
  const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
4633
5966
  if (!result.success) {
4634
5967
  throw new Error(
4635
- `Invalid frontmatter in ${(0, import_node_path47.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
5968
+ `Invalid frontmatter in ${(0, import_node_path60.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
4636
5969
  );
4637
5970
  }
4638
5971
  }
@@ -4667,7 +6000,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4667
6000
  return {
4668
6001
  success: false,
4669
6002
  error: new Error(
4670
- `Invalid frontmatter in ${(0, import_node_path47.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
6003
+ `Invalid frontmatter in ${(0, import_node_path60.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
4671
6004
  )
4672
6005
  };
4673
6006
  }
@@ -4676,12 +6009,12 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4676
6009
  relativeFilePath,
4677
6010
  validate = true
4678
6011
  }) {
4679
- const legacyPath = (0, import_node_path47.join)(
6012
+ const legacyPath = (0, import_node_path60.join)(
4680
6013
  process.cwd(),
4681
6014
  this.getSettablePaths().legacy.relativeDirPath,
4682
6015
  relativeFilePath
4683
6016
  );
4684
- const recommendedPath = (0, import_node_path47.join)(
6017
+ const recommendedPath = (0, import_node_path60.join)(
4685
6018
  this.getSettablePaths().recommended.relativeDirPath,
4686
6019
  relativeFilePath
4687
6020
  );
@@ -4700,7 +6033,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4700
6033
  agentsmd: result.data.agentsmd,
4701
6034
  cursor: result.data.cursor
4702
6035
  };
4703
- const filename = (0, import_node_path47.basename)(legacyPath);
6036
+ const filename = (0, import_node_path60.basename)(legacyPath);
4704
6037
  return new _RulesyncRule({
4705
6038
  baseDir: process.cwd(),
4706
6039
  relativeDirPath: this.getSettablePaths().recommended.relativeDirPath,
@@ -4714,7 +6047,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4714
6047
  relativeFilePath,
4715
6048
  validate = true
4716
6049
  }) {
4717
- const filePath = (0, import_node_path47.join)(
6050
+ const filePath = (0, import_node_path60.join)(
4718
6051
  process.cwd(),
4719
6052
  this.getSettablePaths().recommended.relativeDirPath,
4720
6053
  relativeFilePath
@@ -4733,7 +6066,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
4733
6066
  agentsmd: result.data.agentsmd,
4734
6067
  cursor: result.data.cursor
4735
6068
  };
4736
- const filename = (0, import_node_path47.basename)(filePath);
6069
+ const filename = (0, import_node_path60.basename)(filePath);
4737
6070
  return new _RulesyncRule({
4738
6071
  baseDir: process.cwd(),
4739
6072
  relativeDirPath: this.getSettablePaths().recommended.relativeDirPath,
@@ -4808,7 +6141,7 @@ var ToolRule = class extends ToolFile {
4808
6141
  rulesyncRule,
4809
6142
  validate = true,
4810
6143
  rootPath = { relativeDirPath: ".", relativeFilePath: "AGENTS.md" },
4811
- nonRootPath = { relativeDirPath: (0, import_node_path48.join)(".agents", "memories") }
6144
+ nonRootPath = { relativeDirPath: (0, import_node_path61.join)(".agents", "memories") }
4812
6145
  }) {
4813
6146
  const params = this.buildToolRuleParamsDefault({
4814
6147
  baseDir,
@@ -4819,7 +6152,7 @@ var ToolRule = class extends ToolFile {
4819
6152
  });
4820
6153
  const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
4821
6154
  if (!rulesyncFrontmatter.root && rulesyncFrontmatter.agentsmd?.subprojectPath) {
4822
- params.relativeDirPath = (0, import_node_path48.join)(rulesyncFrontmatter.agentsmd.subprojectPath);
6155
+ params.relativeDirPath = (0, import_node_path61.join)(rulesyncFrontmatter.agentsmd.subprojectPath);
4823
6156
  params.relativeFilePath = "AGENTS.md";
4824
6157
  }
4825
6158
  return params;
@@ -4884,7 +6217,7 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
4884
6217
  relativeFilePath: "AGENTS.md"
4885
6218
  },
4886
6219
  nonRoot: {
4887
- relativeDirPath: (0, import_node_path49.join)(".agents", "memories")
6220
+ relativeDirPath: (0, import_node_path62.join)(".agents", "memories")
4888
6221
  }
4889
6222
  };
4890
6223
  }
@@ -4894,8 +6227,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
4894
6227
  validate = true
4895
6228
  }) {
4896
6229
  const isRoot = relativeFilePath === "AGENTS.md";
4897
- const relativePath = isRoot ? "AGENTS.md" : (0, import_node_path49.join)(".agents", "memories", relativeFilePath);
4898
- const fileContent = await readFileContent((0, import_node_path49.join)(baseDir, relativePath));
6230
+ const relativePath = isRoot ? "AGENTS.md" : (0, import_node_path62.join)(".agents", "memories", relativeFilePath);
6231
+ const fileContent = await readFileContent((0, import_node_path62.join)(baseDir, relativePath));
4899
6232
  return new _AgentsMdRule({
4900
6233
  baseDir,
4901
6234
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -4935,12 +6268,12 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
4935
6268
  };
4936
6269
 
4937
6270
  // src/features/rules/amazonqcli-rule.ts
4938
- var import_node_path50 = require("path");
6271
+ var import_node_path63 = require("path");
4939
6272
  var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4940
6273
  static getSettablePaths() {
4941
6274
  return {
4942
6275
  nonRoot: {
4943
- relativeDirPath: (0, import_node_path50.join)(".amazonq", "rules")
6276
+ relativeDirPath: (0, import_node_path63.join)(".amazonq", "rules")
4944
6277
  }
4945
6278
  };
4946
6279
  }
@@ -4950,7 +6283,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4950
6283
  validate = true
4951
6284
  }) {
4952
6285
  const fileContent = await readFileContent(
4953
- (0, import_node_path50.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
6286
+ (0, import_node_path63.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
4954
6287
  );
4955
6288
  return new _AmazonQCliRule({
4956
6289
  baseDir,
@@ -4990,7 +6323,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
4990
6323
  };
4991
6324
 
4992
6325
  // src/features/rules/augmentcode-legacy-rule.ts
4993
- var import_node_path51 = require("path");
6326
+ var import_node_path64 = require("path");
4994
6327
  var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
4995
6328
  toRulesyncRule() {
4996
6329
  const rulesyncFrontmatter = {
@@ -5016,7 +6349,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
5016
6349
  relativeFilePath: ".augment-guidelines"
5017
6350
  },
5018
6351
  nonRoot: {
5019
- relativeDirPath: (0, import_node_path51.join)(".augment", "rules")
6352
+ relativeDirPath: (0, import_node_path64.join)(".augment", "rules")
5020
6353
  }
5021
6354
  };
5022
6355
  }
@@ -5051,8 +6384,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
5051
6384
  }) {
5052
6385
  const settablePaths = this.getSettablePaths();
5053
6386
  const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
5054
- const relativePath = isRoot ? settablePaths.root.relativeFilePath : (0, import_node_path51.join)(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
5055
- const fileContent = await readFileContent((0, import_node_path51.join)(baseDir, relativePath));
6387
+ const relativePath = isRoot ? settablePaths.root.relativeFilePath : (0, import_node_path64.join)(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
6388
+ const fileContent = await readFileContent((0, import_node_path64.join)(baseDir, relativePath));
5056
6389
  return new _AugmentcodeLegacyRule({
5057
6390
  baseDir,
5058
6391
  relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
@@ -5065,7 +6398,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
5065
6398
  };
5066
6399
 
5067
6400
  // src/features/rules/augmentcode-rule.ts
5068
- var import_node_path52 = require("path");
6401
+ var import_node_path65 = require("path");
5069
6402
  var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
5070
6403
  toRulesyncRule() {
5071
6404
  return this.toRulesyncRuleDefault();
@@ -5073,7 +6406,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
5073
6406
  static getSettablePaths() {
5074
6407
  return {
5075
6408
  nonRoot: {
5076
- relativeDirPath: (0, import_node_path52.join)(".augment", "rules")
6409
+ relativeDirPath: (0, import_node_path65.join)(".augment", "rules")
5077
6410
  }
5078
6411
  };
5079
6412
  }
@@ -5097,7 +6430,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
5097
6430
  validate = true
5098
6431
  }) {
5099
6432
  const fileContent = await readFileContent(
5100
- (0, import_node_path52.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
6433
+ (0, import_node_path65.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5101
6434
  );
5102
6435
  const { body: content } = parseFrontmatter(fileContent);
5103
6436
  return new _AugmentcodeRule({
@@ -5120,7 +6453,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
5120
6453
  };
5121
6454
 
5122
6455
  // src/features/rules/claudecode-rule.ts
5123
- var import_node_path53 = require("path");
6456
+ var import_node_path66 = require("path");
5124
6457
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
5125
6458
  static getSettablePaths({
5126
6459
  global
@@ -5139,7 +6472,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
5139
6472
  relativeFilePath: "CLAUDE.md"
5140
6473
  },
5141
6474
  nonRoot: {
5142
- relativeDirPath: (0, import_node_path53.join)(".claude", "memories")
6475
+ relativeDirPath: (0, import_node_path66.join)(".claude", "memories")
5143
6476
  }
5144
6477
  };
5145
6478
  }
@@ -5154,7 +6487,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
5154
6487
  if (isRoot) {
5155
6488
  const relativePath2 = paths.root.relativeFilePath;
5156
6489
  const fileContent2 = await readFileContent(
5157
- (0, import_node_path53.join)(baseDir, paths.root.relativeDirPath, relativePath2)
6490
+ (0, import_node_path66.join)(baseDir, paths.root.relativeDirPath, relativePath2)
5158
6491
  );
5159
6492
  return new _ClaudecodeRule({
5160
6493
  baseDir,
@@ -5168,8 +6501,8 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
5168
6501
  if (!paths.nonRoot) {
5169
6502
  throw new Error("nonRoot path is not set");
5170
6503
  }
5171
- const relativePath = (0, import_node_path53.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
5172
- const fileContent = await readFileContent((0, import_node_path53.join)(baseDir, relativePath));
6504
+ const relativePath = (0, import_node_path66.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
6505
+ const fileContent = await readFileContent((0, import_node_path66.join)(baseDir, relativePath));
5173
6506
  return new _ClaudecodeRule({
5174
6507
  baseDir,
5175
6508
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -5211,10 +6544,10 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
5211
6544
  };
5212
6545
 
5213
6546
  // src/features/rules/cline-rule.ts
5214
- var import_node_path54 = require("path");
5215
- var import_mini21 = require("zod/mini");
5216
- var ClineRuleFrontmatterSchema = import_mini21.z.object({
5217
- description: import_mini21.z.string()
6547
+ var import_node_path67 = require("path");
6548
+ var import_mini26 = require("zod/mini");
6549
+ var ClineRuleFrontmatterSchema = import_mini26.z.object({
6550
+ description: import_mini26.z.string()
5218
6551
  });
5219
6552
  var ClineRule = class _ClineRule extends ToolRule {
5220
6553
  static getSettablePaths() {
@@ -5256,7 +6589,7 @@ var ClineRule = class _ClineRule extends ToolRule {
5256
6589
  validate = true
5257
6590
  }) {
5258
6591
  const fileContent = await readFileContent(
5259
- (0, import_node_path54.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
6592
+ (0, import_node_path67.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5260
6593
  );
5261
6594
  return new _ClineRule({
5262
6595
  baseDir,
@@ -5269,7 +6602,7 @@ var ClineRule = class _ClineRule extends ToolRule {
5269
6602
  };
5270
6603
 
5271
6604
  // src/features/rules/codexcli-rule.ts
5272
- var import_node_path55 = require("path");
6605
+ var import_node_path68 = require("path");
5273
6606
  var CodexcliRule = class _CodexcliRule extends ToolRule {
5274
6607
  static getSettablePaths({
5275
6608
  global
@@ -5288,7 +6621,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
5288
6621
  relativeFilePath: "AGENTS.md"
5289
6622
  },
5290
6623
  nonRoot: {
5291
- relativeDirPath: (0, import_node_path55.join)(".codex", "memories")
6624
+ relativeDirPath: (0, import_node_path68.join)(".codex", "memories")
5292
6625
  }
5293
6626
  };
5294
6627
  }
@@ -5303,7 +6636,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
5303
6636
  if (isRoot) {
5304
6637
  const relativePath2 = paths.root.relativeFilePath;
5305
6638
  const fileContent2 = await readFileContent(
5306
- (0, import_node_path55.join)(baseDir, paths.root.relativeDirPath, relativePath2)
6639
+ (0, import_node_path68.join)(baseDir, paths.root.relativeDirPath, relativePath2)
5307
6640
  );
5308
6641
  return new _CodexcliRule({
5309
6642
  baseDir,
@@ -5317,8 +6650,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
5317
6650
  if (!paths.nonRoot) {
5318
6651
  throw new Error("nonRoot path is not set");
5319
6652
  }
5320
- const relativePath = (0, import_node_path55.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
5321
- const fileContent = await readFileContent((0, import_node_path55.join)(baseDir, relativePath));
6653
+ const relativePath = (0, import_node_path68.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
6654
+ const fileContent = await readFileContent((0, import_node_path68.join)(baseDir, relativePath));
5322
6655
  return new _CodexcliRule({
5323
6656
  baseDir,
5324
6657
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -5360,11 +6693,11 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
5360
6693
  };
5361
6694
 
5362
6695
  // src/features/rules/copilot-rule.ts
5363
- var import_node_path56 = require("path");
5364
- var import_mini22 = require("zod/mini");
5365
- var CopilotRuleFrontmatterSchema = import_mini22.z.object({
5366
- description: import_mini22.z.optional(import_mini22.z.string()),
5367
- applyTo: import_mini22.z.optional(import_mini22.z.string())
6696
+ var import_node_path69 = require("path");
6697
+ var import_mini27 = require("zod/mini");
6698
+ var CopilotRuleFrontmatterSchema = import_mini27.z.object({
6699
+ description: import_mini27.z.optional(import_mini27.z.string()),
6700
+ applyTo: import_mini27.z.optional(import_mini27.z.string())
5368
6701
  });
5369
6702
  var CopilotRule = class _CopilotRule extends ToolRule {
5370
6703
  frontmatter;
@@ -5376,7 +6709,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5376
6709
  relativeFilePath: "copilot-instructions.md"
5377
6710
  },
5378
6711
  nonRoot: {
5379
- relativeDirPath: (0, import_node_path56.join)(".github", "instructions")
6712
+ relativeDirPath: (0, import_node_path69.join)(".github", "instructions")
5380
6713
  }
5381
6714
  };
5382
6715
  }
@@ -5385,7 +6718,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5385
6718
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
5386
6719
  if (!result.success) {
5387
6720
  throw new Error(
5388
- `Invalid frontmatter in ${(0, import_node_path56.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
6721
+ `Invalid frontmatter in ${(0, import_node_path69.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
5389
6722
  );
5390
6723
  }
5391
6724
  }
@@ -5463,11 +6796,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5463
6796
  validate = true
5464
6797
  }) {
5465
6798
  const isRoot = relativeFilePath === "copilot-instructions.md";
5466
- const relativePath = isRoot ? (0, import_node_path56.join)(
6799
+ const relativePath = isRoot ? (0, import_node_path69.join)(
5467
6800
  this.getSettablePaths().root.relativeDirPath,
5468
6801
  this.getSettablePaths().root.relativeFilePath
5469
- ) : (0, import_node_path56.join)(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
5470
- const fileContent = await readFileContent((0, import_node_path56.join)(baseDir, relativePath));
6802
+ ) : (0, import_node_path69.join)(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
6803
+ const fileContent = await readFileContent((0, import_node_path69.join)(baseDir, relativePath));
5471
6804
  if (isRoot) {
5472
6805
  return new _CopilotRule({
5473
6806
  baseDir,
@@ -5486,7 +6819,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5486
6819
  const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
5487
6820
  if (!result.success) {
5488
6821
  throw new Error(
5489
- `Invalid frontmatter in ${(0, import_node_path56.join)(baseDir, relativeFilePath)}: ${formatError(result.error)}`
6822
+ `Invalid frontmatter in ${(0, import_node_path69.join)(baseDir, relativeFilePath)}: ${formatError(result.error)}`
5490
6823
  );
5491
6824
  }
5492
6825
  return new _CopilotRule({
@@ -5510,7 +6843,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5510
6843
  return {
5511
6844
  success: false,
5512
6845
  error: new Error(
5513
- `Invalid frontmatter in ${(0, import_node_path56.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
6846
+ `Invalid frontmatter in ${(0, import_node_path69.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
5514
6847
  )
5515
6848
  };
5516
6849
  }
@@ -5530,12 +6863,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
5530
6863
  };
5531
6864
 
5532
6865
  // src/features/rules/cursor-rule.ts
5533
- var import_node_path57 = require("path");
5534
- var import_mini23 = require("zod/mini");
5535
- var CursorRuleFrontmatterSchema = import_mini23.z.object({
5536
- description: import_mini23.z.optional(import_mini23.z.string()),
5537
- globs: import_mini23.z.optional(import_mini23.z.string()),
5538
- alwaysApply: import_mini23.z.optional(import_mini23.z.boolean())
6866
+ var import_node_path70 = require("path");
6867
+ var import_mini28 = require("zod/mini");
6868
+ var CursorRuleFrontmatterSchema = import_mini28.z.object({
6869
+ description: import_mini28.z.optional(import_mini28.z.string()),
6870
+ globs: import_mini28.z.optional(import_mini28.z.string()),
6871
+ alwaysApply: import_mini28.z.optional(import_mini28.z.boolean())
5539
6872
  });
5540
6873
  var CursorRule = class _CursorRule extends ToolRule {
5541
6874
  frontmatter;
@@ -5543,7 +6876,7 @@ var CursorRule = class _CursorRule extends ToolRule {
5543
6876
  static getSettablePaths() {
5544
6877
  return {
5545
6878
  nonRoot: {
5546
- relativeDirPath: (0, import_node_path57.join)(".cursor", "rules")
6879
+ relativeDirPath: (0, import_node_path70.join)(".cursor", "rules")
5547
6880
  }
5548
6881
  };
5549
6882
  }
@@ -5552,7 +6885,7 @@ var CursorRule = class _CursorRule extends ToolRule {
5552
6885
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
5553
6886
  if (!result.success) {
5554
6887
  throw new Error(
5555
- `Invalid frontmatter in ${(0, import_node_path57.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
6888
+ `Invalid frontmatter in ${(0, import_node_path70.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
5556
6889
  );
5557
6890
  }
5558
6891
  }
@@ -5669,19 +7002,19 @@ var CursorRule = class _CursorRule extends ToolRule {
5669
7002
  validate = true
5670
7003
  }) {
5671
7004
  const fileContent = await readFileContent(
5672
- (0, import_node_path57.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
7005
+ (0, import_node_path70.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5673
7006
  );
5674
7007
  const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
5675
7008
  const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
5676
7009
  if (!result.success) {
5677
7010
  throw new Error(
5678
- `Invalid frontmatter in ${(0, import_node_path57.join)(baseDir, relativeFilePath)}: ${formatError(result.error)}`
7011
+ `Invalid frontmatter in ${(0, import_node_path70.join)(baseDir, relativeFilePath)}: ${formatError(result.error)}`
5679
7012
  );
5680
7013
  }
5681
7014
  return new _CursorRule({
5682
7015
  baseDir,
5683
7016
  relativeDirPath: this.getSettablePaths().nonRoot.relativeDirPath,
5684
- relativeFilePath: (0, import_node_path57.basename)(relativeFilePath),
7017
+ relativeFilePath: (0, import_node_path70.basename)(relativeFilePath),
5685
7018
  frontmatter: result.data,
5686
7019
  body: content.trim(),
5687
7020
  validate
@@ -5698,7 +7031,7 @@ var CursorRule = class _CursorRule extends ToolRule {
5698
7031
  return {
5699
7032
  success: false,
5700
7033
  error: new Error(
5701
- `Invalid frontmatter in ${(0, import_node_path57.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
7034
+ `Invalid frontmatter in ${(0, import_node_path70.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
5702
7035
  )
5703
7036
  };
5704
7037
  }
@@ -5718,7 +7051,7 @@ var CursorRule = class _CursorRule extends ToolRule {
5718
7051
  };
5719
7052
 
5720
7053
  // src/features/rules/geminicli-rule.ts
5721
- var import_node_path58 = require("path");
7054
+ var import_node_path71 = require("path");
5722
7055
  var GeminiCliRule = class _GeminiCliRule extends ToolRule {
5723
7056
  static getSettablePaths({
5724
7057
  global
@@ -5737,7 +7070,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
5737
7070
  relativeFilePath: "GEMINI.md"
5738
7071
  },
5739
7072
  nonRoot: {
5740
- relativeDirPath: (0, import_node_path58.join)(".gemini", "memories")
7073
+ relativeDirPath: (0, import_node_path71.join)(".gemini", "memories")
5741
7074
  }
5742
7075
  };
5743
7076
  }
@@ -5752,7 +7085,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
5752
7085
  if (isRoot) {
5753
7086
  const relativePath2 = paths.root.relativeFilePath;
5754
7087
  const fileContent2 = await readFileContent(
5755
- (0, import_node_path58.join)(baseDir, paths.root.relativeDirPath, relativePath2)
7088
+ (0, import_node_path71.join)(baseDir, paths.root.relativeDirPath, relativePath2)
5756
7089
  );
5757
7090
  return new _GeminiCliRule({
5758
7091
  baseDir,
@@ -5766,8 +7099,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
5766
7099
  if (!paths.nonRoot) {
5767
7100
  throw new Error("nonRoot path is not set");
5768
7101
  }
5769
- const relativePath = (0, import_node_path58.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
5770
- const fileContent = await readFileContent((0, import_node_path58.join)(baseDir, relativePath));
7102
+ const relativePath = (0, import_node_path71.join)(paths.nonRoot.relativeDirPath, relativeFilePath);
7103
+ const fileContent = await readFileContent((0, import_node_path71.join)(baseDir, relativePath));
5771
7104
  return new _GeminiCliRule({
5772
7105
  baseDir,
5773
7106
  relativeDirPath: paths.nonRoot.relativeDirPath,
@@ -5809,7 +7142,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
5809
7142
  };
5810
7143
 
5811
7144
  // src/features/rules/junie-rule.ts
5812
- var import_node_path59 = require("path");
7145
+ var import_node_path72 = require("path");
5813
7146
  var JunieRule = class _JunieRule extends ToolRule {
5814
7147
  static getSettablePaths() {
5815
7148
  return {
@@ -5818,7 +7151,7 @@ var JunieRule = class _JunieRule extends ToolRule {
5818
7151
  relativeFilePath: "guidelines.md"
5819
7152
  },
5820
7153
  nonRoot: {
5821
- relativeDirPath: (0, import_node_path59.join)(".junie", "memories")
7154
+ relativeDirPath: (0, import_node_path72.join)(".junie", "memories")
5822
7155
  }
5823
7156
  };
5824
7157
  }
@@ -5828,8 +7161,8 @@ var JunieRule = class _JunieRule extends ToolRule {
5828
7161
  validate = true
5829
7162
  }) {
5830
7163
  const isRoot = relativeFilePath === "guidelines.md";
5831
- const relativePath = isRoot ? "guidelines.md" : (0, import_node_path59.join)(".junie", "memories", relativeFilePath);
5832
- const fileContent = await readFileContent((0, import_node_path59.join)(baseDir, relativePath));
7164
+ const relativePath = isRoot ? "guidelines.md" : (0, import_node_path72.join)(".junie", "memories", relativeFilePath);
7165
+ const fileContent = await readFileContent((0, import_node_path72.join)(baseDir, relativePath));
5833
7166
  return new _JunieRule({
5834
7167
  baseDir,
5835
7168
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5869,12 +7202,12 @@ var JunieRule = class _JunieRule extends ToolRule {
5869
7202
  };
5870
7203
 
5871
7204
  // src/features/rules/kiro-rule.ts
5872
- var import_node_path60 = require("path");
7205
+ var import_node_path73 = require("path");
5873
7206
  var KiroRule = class _KiroRule extends ToolRule {
5874
7207
  static getSettablePaths() {
5875
7208
  return {
5876
7209
  nonRoot: {
5877
- relativeDirPath: (0, import_node_path60.join)(".kiro", "steering")
7210
+ relativeDirPath: (0, import_node_path73.join)(".kiro", "steering")
5878
7211
  }
5879
7212
  };
5880
7213
  }
@@ -5884,7 +7217,7 @@ var KiroRule = class _KiroRule extends ToolRule {
5884
7217
  validate = true
5885
7218
  }) {
5886
7219
  const fileContent = await readFileContent(
5887
- (0, import_node_path60.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
7220
+ (0, import_node_path73.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
5888
7221
  );
5889
7222
  return new _KiroRule({
5890
7223
  baseDir,
@@ -5924,7 +7257,7 @@ var KiroRule = class _KiroRule extends ToolRule {
5924
7257
  };
5925
7258
 
5926
7259
  // src/features/rules/opencode-rule.ts
5927
- var import_node_path61 = require("path");
7260
+ var import_node_path74 = require("path");
5928
7261
  var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5929
7262
  static getSettablePaths() {
5930
7263
  return {
@@ -5933,7 +7266,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5933
7266
  relativeFilePath: "AGENTS.md"
5934
7267
  },
5935
7268
  nonRoot: {
5936
- relativeDirPath: (0, import_node_path61.join)(".opencode", "memories")
7269
+ relativeDirPath: (0, import_node_path74.join)(".opencode", "memories")
5937
7270
  }
5938
7271
  };
5939
7272
  }
@@ -5943,8 +7276,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5943
7276
  validate = true
5944
7277
  }) {
5945
7278
  const isRoot = relativeFilePath === "AGENTS.md";
5946
- const relativePath = isRoot ? "AGENTS.md" : (0, import_node_path61.join)(".opencode", "memories", relativeFilePath);
5947
- const fileContent = await readFileContent((0, import_node_path61.join)(baseDir, relativePath));
7279
+ const relativePath = isRoot ? "AGENTS.md" : (0, import_node_path74.join)(".opencode", "memories", relativeFilePath);
7280
+ const fileContent = await readFileContent((0, import_node_path74.join)(baseDir, relativePath));
5948
7281
  return new _OpenCodeRule({
5949
7282
  baseDir,
5950
7283
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -5984,7 +7317,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
5984
7317
  };
5985
7318
 
5986
7319
  // src/features/rules/qwencode-rule.ts
5987
- var import_node_path62 = require("path");
7320
+ var import_node_path75 = require("path");
5988
7321
  var QwencodeRule = class _QwencodeRule extends ToolRule {
5989
7322
  static getSettablePaths() {
5990
7323
  return {
@@ -5993,7 +7326,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
5993
7326
  relativeFilePath: "QWEN.md"
5994
7327
  },
5995
7328
  nonRoot: {
5996
- relativeDirPath: (0, import_node_path62.join)(".qwen", "memories")
7329
+ relativeDirPath: (0, import_node_path75.join)(".qwen", "memories")
5997
7330
  }
5998
7331
  };
5999
7332
  }
@@ -6003,8 +7336,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
6003
7336
  validate = true
6004
7337
  }) {
6005
7338
  const isRoot = relativeFilePath === "QWEN.md";
6006
- const relativePath = isRoot ? "QWEN.md" : (0, import_node_path62.join)(".qwen", "memories", relativeFilePath);
6007
- const fileContent = await readFileContent((0, import_node_path62.join)(baseDir, relativePath));
7339
+ const relativePath = isRoot ? "QWEN.md" : (0, import_node_path75.join)(".qwen", "memories", relativeFilePath);
7340
+ const fileContent = await readFileContent((0, import_node_path75.join)(baseDir, relativePath));
6008
7341
  return new _QwencodeRule({
6009
7342
  baseDir,
6010
7343
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
@@ -6041,12 +7374,12 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
6041
7374
  };
6042
7375
 
6043
7376
  // src/features/rules/roo-rule.ts
6044
- var import_node_path63 = require("path");
7377
+ var import_node_path76 = require("path");
6045
7378
  var RooRule = class _RooRule extends ToolRule {
6046
7379
  static getSettablePaths() {
6047
7380
  return {
6048
7381
  nonRoot: {
6049
- relativeDirPath: (0, import_node_path63.join)(".roo", "rules")
7382
+ relativeDirPath: (0, import_node_path76.join)(".roo", "rules")
6050
7383
  }
6051
7384
  };
6052
7385
  }
@@ -6056,7 +7389,7 @@ var RooRule = class _RooRule extends ToolRule {
6056
7389
  validate = true
6057
7390
  }) {
6058
7391
  const fileContent = await readFileContent(
6059
- (0, import_node_path63.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
7392
+ (0, import_node_path76.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
6060
7393
  );
6061
7394
  return new _RooRule({
6062
7395
  baseDir,
@@ -6111,7 +7444,7 @@ var RooRule = class _RooRule extends ToolRule {
6111
7444
  };
6112
7445
 
6113
7446
  // src/features/rules/warp-rule.ts
6114
- var import_node_path64 = require("path");
7447
+ var import_node_path77 = require("path");
6115
7448
  var WarpRule = class _WarpRule extends ToolRule {
6116
7449
  constructor({ fileContent, root, ...rest }) {
6117
7450
  super({
@@ -6127,7 +7460,7 @@ var WarpRule = class _WarpRule extends ToolRule {
6127
7460
  relativeFilePath: "WARP.md"
6128
7461
  },
6129
7462
  nonRoot: {
6130
- relativeDirPath: (0, import_node_path64.join)(".warp", "memories")
7463
+ relativeDirPath: (0, import_node_path77.join)(".warp", "memories")
6131
7464
  }
6132
7465
  };
6133
7466
  }
@@ -6137,8 +7470,8 @@ var WarpRule = class _WarpRule extends ToolRule {
6137
7470
  validate = true
6138
7471
  }) {
6139
7472
  const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
6140
- const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : (0, import_node_path64.join)(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
6141
- const fileContent = await readFileContent((0, import_node_path64.join)(baseDir, relativePath));
7473
+ const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : (0, import_node_path77.join)(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
7474
+ const fileContent = await readFileContent((0, import_node_path77.join)(baseDir, relativePath));
6142
7475
  return new _WarpRule({
6143
7476
  baseDir,
6144
7477
  relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
@@ -6178,12 +7511,12 @@ var WarpRule = class _WarpRule extends ToolRule {
6178
7511
  };
6179
7512
 
6180
7513
  // src/features/rules/windsurf-rule.ts
6181
- var import_node_path65 = require("path");
7514
+ var import_node_path78 = require("path");
6182
7515
  var WindsurfRule = class _WindsurfRule extends ToolRule {
6183
7516
  static getSettablePaths() {
6184
7517
  return {
6185
7518
  nonRoot: {
6186
- relativeDirPath: (0, import_node_path65.join)(".windsurf", "rules")
7519
+ relativeDirPath: (0, import_node_path78.join)(".windsurf", "rules")
6187
7520
  }
6188
7521
  };
6189
7522
  }
@@ -6193,7 +7526,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
6193
7526
  validate = true
6194
7527
  }) {
6195
7528
  const fileContent = await readFileContent(
6196
- (0, import_node_path65.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
7529
+ (0, import_node_path78.join)(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
6197
7530
  );
6198
7531
  return new _WindsurfRule({
6199
7532
  baseDir,
@@ -6251,7 +7584,7 @@ var rulesProcessorToolTargets = [
6251
7584
  "warp",
6252
7585
  "windsurf"
6253
7586
  ];
6254
- var RulesProcessorToolTargetSchema = import_mini24.z.enum(rulesProcessorToolTargets);
7587
+ var RulesProcessorToolTargetSchema = import_mini29.z.enum(rulesProcessorToolTargets);
6255
7588
  var rulesProcessorToolTargetsGlobal = [
6256
7589
  "claudecode",
6257
7590
  "codexcli",
@@ -6261,12 +7594,14 @@ var RulesProcessor = class extends FeatureProcessor {
6261
7594
  toolTarget;
6262
7595
  simulateCommands;
6263
7596
  simulateSubagents;
7597
+ simulateSkills;
6264
7598
  global;
6265
7599
  constructor({
6266
7600
  baseDir = process.cwd(),
6267
7601
  toolTarget,
6268
7602
  simulateCommands = false,
6269
7603
  simulateSubagents = false,
7604
+ simulateSkills = false,
6270
7605
  global = false
6271
7606
  }) {
6272
7607
  super({ baseDir });
@@ -6280,6 +7615,7 @@ var RulesProcessor = class extends FeatureProcessor {
6280
7615
  this.global = global;
6281
7616
  this.simulateCommands = simulateCommands;
6282
7617
  this.simulateSubagents = simulateSubagents;
7618
+ this.simulateSkills = simulateSkills;
6283
7619
  }
6284
7620
  async convertRulesyncFilesToToolFiles(rulesyncFiles) {
6285
7621
  const rulesyncRules = rulesyncFiles.filter(
@@ -6447,7 +7783,7 @@ var RulesProcessor = class extends FeatureProcessor {
6447
7783
  throw new Error(`Unsupported tool target: ${this.toolTarget}`);
6448
7784
  }
6449
7785
  }).filter((rule) => rule !== null);
6450
- const isSimulated = this.simulateCommands || this.simulateSubagents;
7786
+ const isSimulated = this.simulateCommands || this.simulateSubagents || this.simulateSkills;
6451
7787
  if (isSimulated && this.toolTarget === "cursor") {
6452
7788
  toolRules.push(
6453
7789
  new CursorRule({
@@ -6459,6 +7795,9 @@ var RulesProcessor = class extends FeatureProcessor {
6459
7795
  commands: { relativeDirPath: CursorCommand.getSettablePaths().relativeDirPath },
6460
7796
  subagents: {
6461
7797
  relativeDirPath: CursorSubagent.getSettablePaths().relativeDirPath
7798
+ },
7799
+ skills: {
7800
+ relativeDirPath: CursorSkill.getSettablePaths().relativeDirPath
6462
7801
  }
6463
7802
  }),
6464
7803
  relativeDirPath: CursorRule.getSettablePaths().nonRoot.relativeDirPath,
@@ -6520,6 +7859,9 @@ var RulesProcessor = class extends FeatureProcessor {
6520
7859
  this.generateXmlReferencesSection(toolRules) + this.generateAdditionalConventionsSection({
6521
7860
  subagents: {
6522
7861
  relativeDirPath: CodexCliSubagent.getSettablePaths().relativeDirPath
7862
+ },
7863
+ skills: {
7864
+ relativeDirPath: CodexCliSkill.getSettablePaths().relativeDirPath
6523
7865
  }
6524
7866
  }) + rootRule.getFileContent()
6525
7867
  );
@@ -6532,6 +7874,9 @@ var RulesProcessor = class extends FeatureProcessor {
6532
7874
  commands: { relativeDirPath: CopilotCommand.getSettablePaths().relativeDirPath },
6533
7875
  subagents: {
6534
7876
  relativeDirPath: CopilotSubagent.getSettablePaths().relativeDirPath
7877
+ },
7878
+ skills: {
7879
+ relativeDirPath: CopilotSkill.getSettablePaths().relativeDirPath
6535
7880
  }
6536
7881
  }) + rootRule.getFileContent()
6537
7882
  );
@@ -6593,10 +7938,10 @@ var RulesProcessor = class extends FeatureProcessor {
6593
7938
  * Load and parse rulesync rule files from .rulesync/rules/ directory
6594
7939
  */
6595
7940
  async loadRulesyncFiles() {
6596
- const files = await findFilesByGlobs((0, import_node_path66.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md"));
7941
+ const files = await findFilesByGlobs((0, import_node_path79.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md"));
6597
7942
  logger.debug(`Found ${files.length} rulesync files`);
6598
7943
  const rulesyncRules = await Promise.all(
6599
- files.map((file) => RulesyncRule.fromFile({ relativeFilePath: (0, import_node_path66.basename)(file) }))
7944
+ files.map((file) => RulesyncRule.fromFile({ relativeFilePath: (0, import_node_path79.basename)(file) }))
6600
7945
  );
6601
7946
  const rootRules = rulesyncRules.filter((rule) => rule.getFrontmatter().root);
6602
7947
  if (rootRules.length > 1) {
@@ -6614,17 +7959,19 @@ var RulesProcessor = class extends FeatureProcessor {
6614
7959
  return rulesyncRules;
6615
7960
  }
6616
7961
  async loadRulesyncFilesLegacy() {
6617
- const legacyFiles = await findFilesByGlobs((0, import_node_path66.join)(RULESYNC_RELATIVE_DIR_PATH, "*.md"));
7962
+ const legacyFiles = await findFilesByGlobs((0, import_node_path79.join)(RULESYNC_RELATIVE_DIR_PATH, "*.md"));
6618
7963
  logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
6619
7964
  return Promise.all(
6620
- legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: (0, import_node_path66.basename)(file) }))
7965
+ legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: (0, import_node_path79.basename)(file) }))
6621
7966
  );
6622
7967
  }
6623
7968
  /**
6624
7969
  * Implementation of abstract method from FeatureProcessor
6625
7970
  * Load tool-specific rule configurations and parse them into ToolRule instances
6626
7971
  */
6627
- async loadToolFiles() {
7972
+ async loadToolFiles({
7973
+ forDeletion: _forDeletion = false
7974
+ } = {}) {
6628
7975
  try {
6629
7976
  switch (this.toolTarget) {
6630
7977
  case "agentsmd":
@@ -6669,9 +8016,6 @@ var RulesProcessor = class extends FeatureProcessor {
6669
8016
  return [];
6670
8017
  }
6671
8018
  }
6672
- async loadToolFilesToDelete() {
6673
- return this.loadToolFiles();
6674
- }
6675
8019
  async loadToolRulesDefault({
6676
8020
  root,
6677
8021
  nonRoot
@@ -6681,13 +8025,13 @@ var RulesProcessor = class extends FeatureProcessor {
6681
8025
  return [];
6682
8026
  }
6683
8027
  const rootFilePaths = await findFilesByGlobs(
6684
- (0, import_node_path66.join)(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
8028
+ (0, import_node_path79.join)(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
6685
8029
  );
6686
8030
  return await Promise.all(
6687
8031
  rootFilePaths.map(
6688
8032
  (filePath) => root.fromFile({
6689
8033
  baseDir: this.baseDir,
6690
- relativeFilePath: (0, import_node_path66.basename)(filePath),
8034
+ relativeFilePath: (0, import_node_path79.basename)(filePath),
6691
8035
  global: this.global
6692
8036
  })
6693
8037
  )
@@ -6699,13 +8043,13 @@ var RulesProcessor = class extends FeatureProcessor {
6699
8043
  return [];
6700
8044
  }
6701
8045
  const nonRootFilePaths = await findFilesByGlobs(
6702
- (0, import_node_path66.join)(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
8046
+ (0, import_node_path79.join)(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
6703
8047
  );
6704
8048
  return await Promise.all(
6705
8049
  nonRootFilePaths.map(
6706
8050
  (filePath) => nonRoot.fromFile({
6707
8051
  baseDir: this.baseDir,
6708
- relativeFilePath: (0, import_node_path66.basename)(filePath),
8052
+ relativeFilePath: (0, import_node_path79.basename)(filePath),
6709
8053
  global: this.global
6710
8054
  })
6711
8055
  )
@@ -6992,12 +8336,12 @@ var RulesProcessor = class extends FeatureProcessor {
6992
8336
  * Implementation of abstract method from FeatureProcessor
6993
8337
  * Return the tool targets that this processor supports
6994
8338
  */
6995
- static getToolTargets() {
8339
+ static getToolTargets({ global = false } = {}) {
8340
+ if (global) {
8341
+ return rulesProcessorToolTargetsGlobal;
8342
+ }
6996
8343
  return rulesProcessorToolTargets;
6997
8344
  }
6998
- static getToolTargetsGlobal() {
6999
- return rulesProcessorToolTargetsGlobal;
7000
- }
7001
8345
  generateXmlReferencesSection(toolRules) {
7002
8346
  const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
7003
8347
  if (toolRulesWithoutRoot.length === 0) {
@@ -7055,7 +8399,8 @@ var RulesProcessor = class extends FeatureProcessor {
7055
8399
  }
7056
8400
  generateAdditionalConventionsSection({
7057
8401
  commands,
7058
- subagents
8402
+ subagents,
8403
+ skills
7059
8404
  }) {
7060
8405
  const overview = `# Additional Conventions Beyond the Built-in Functions
7061
8406
 
@@ -7072,21 +8417,31 @@ Users can use following syntax to invoke a custom command.
7072
8417
  s/<command> [arguments]
7073
8418
  \`\`\`
7074
8419
 
7075
- This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
8420
+ This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
7076
8421
  The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
7077
8422
 
7078
- When users call a custom slash command, you have to look for the markdown file, \`${(0, import_node_path66.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
8423
+ When users call a custom slash command, you have to look for the markdown file, \`${(0, import_node_path79.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
7079
8424
  const subagentsSection = subagents ? `## Simulated Subagents
7080
8425
 
7081
8426
  Simulated subagents are specialized AI assistants that can be invoked to handle specific types of tasks. In this case, it can be appear something like custom slash commands simply. Simulated subagents can be called by custom slash commands.
7082
8427
 
7083
- When users call a simulated subagent, it will look for the corresponding markdown file, \`${(0, import_node_path66.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
8428
+ When users call a simulated subagent, it will look for the corresponding markdown file, \`${(0, import_node_path79.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
8429
+
8430
+ For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${(0, import_node_path79.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
8431
+ const skillsSection = skills ? `## Simulated Skills
8432
+
8433
+ Simulated skills are specialized capabilities that can be invoked to handle specific types of tasks.
7084
8434
 
7085
- For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${(0, import_node_path66.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
8435
+ When users invoke a simulated skill, look for the corresponding SKILL.md file in \`${(0, import_node_path79.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "{skill}/SKILL.md")}\` and execute its contents as the block of operations.
8436
+
8437
+ For example, if the user instructs \`Use the skill example-skill to achieve something\`, look for \`${(0, import_node_path79.join)(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "example-skill/SKILL.md")}\` and execute its contents.
8438
+
8439
+ Additionally, you should proactively consider using available skills when they would help accomplish a task more effectively, even if the user doesn't explicitly request them.` : "";
7086
8440
  const result = [
7087
8441
  overview,
7088
8442
  ...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
7089
- ...this.simulateSubagents && SubagentsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [subagentsSection] : []
8443
+ ...this.simulateSubagents && SubagentsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [subagentsSection] : [],
8444
+ ...this.simulateSkills && SkillsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [skillsSection] : []
7090
8445
  ].join("\n\n") + "\n\n";
7091
8446
  return result;
7092
8447
  }
@@ -7107,7 +8462,8 @@ async function generateCommand(options) {
7107
8462
  const totalMcpOutputs = await generateMcp(config);
7108
8463
  const totalCommandOutputs = await generateCommands(config);
7109
8464
  const totalSubagentOutputs = await generateSubagents(config);
7110
- const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs;
8465
+ const totalSkillOutputs = await generateSkills(config);
8466
+ const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + totalSkillOutputs;
7111
8467
  if (totalGenerated === 0) {
7112
8468
  const enabledFeatures = config.getFeatures().join(", ");
7113
8469
  logger.warn(`\u26A0\uFE0F No files generated for enabled features: ${enabledFeatures}`);
@@ -7120,6 +8476,7 @@ async function generateCommand(options) {
7120
8476
  if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP files`);
7121
8477
  if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
7122
8478
  if (totalSubagentOutputs > 0) parts.push(`${totalSubagentOutputs} subagents`);
8479
+ if (totalSkillOutputs > 0) parts.push(`${totalSkillOutputs} skills`);
7123
8480
  logger.success(`\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`);
7124
8481
  }
7125
8482
  }
@@ -7130,18 +8487,22 @@ async function generateRules(config) {
7130
8487
  }
7131
8488
  let totalRulesOutputs = 0;
7132
8489
  logger.info("Generating rule files...");
7133
- const toolTargets = config.getGlobal() ? (0, import_es_toolkit2.intersection)(config.getTargets(), RulesProcessor.getToolTargetsGlobal()) : (0, import_es_toolkit2.intersection)(config.getTargets(), RulesProcessor.getToolTargets());
8490
+ const toolTargets = (0, import_es_toolkit2.intersection)(
8491
+ config.getTargets(),
8492
+ RulesProcessor.getToolTargets({ global: config.getGlobal() })
8493
+ );
7134
8494
  for (const baseDir of config.getBaseDirs()) {
7135
8495
  for (const toolTarget of toolTargets) {
7136
8496
  const processor = new RulesProcessor({
7137
8497
  baseDir,
7138
8498
  toolTarget,
7139
8499
  global: config.getGlobal(),
7140
- simulateCommands: config.getSimulatedCommands(),
7141
- simulateSubagents: config.getSimulatedSubagents()
8500
+ simulateCommands: config.getSimulateCommands(),
8501
+ simulateSubagents: config.getSimulateSubagents(),
8502
+ simulateSkills: config.getSimulateSkills()
7142
8503
  });
7143
8504
  if (config.getDelete()) {
7144
- const oldToolFiles = await processor.loadToolFilesToDelete();
8505
+ const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
7145
8506
  await processor.removeAiFiles(oldToolFiles);
7146
8507
  }
7147
8508
  let rulesyncFiles = await processor.loadRulesyncFiles();
@@ -7175,7 +8536,7 @@ async function generateIgnore(config) {
7175
8536
  toolTarget
7176
8537
  });
7177
8538
  if (config.getDelete()) {
7178
- const oldToolFiles = await processor.loadToolFilesToDelete();
8539
+ const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
7179
8540
  await processor.removeAiFiles(oldToolFiles);
7180
8541
  }
7181
8542
  const rulesyncFiles = await processor.loadRulesyncFiles();
@@ -7206,7 +8567,10 @@ async function generateMcp(config) {
7206
8567
  if (config.getModularMcp()) {
7207
8568
  logger.info("\u2139\uFE0F Modular MCP support is experimental.");
7208
8569
  }
7209
- const toolTargets = config.getGlobal() ? (0, import_es_toolkit2.intersection)(config.getTargets(), McpProcessor.getToolTargetsGlobal()) : (0, import_es_toolkit2.intersection)(config.getTargets(), McpProcessor.getToolTargets());
8570
+ const toolTargets = (0, import_es_toolkit2.intersection)(
8571
+ config.getTargets(),
8572
+ McpProcessor.getToolTargets({ global: config.getGlobal() })
8573
+ );
7210
8574
  for (const baseDir of config.getBaseDirs()) {
7211
8575
  for (const toolTarget of toolTargets) {
7212
8576
  const processor = new McpProcessor({
@@ -7216,7 +8580,7 @@ async function generateMcp(config) {
7216
8580
  modularMcp: config.getModularMcp()
7217
8581
  });
7218
8582
  if (config.getDelete()) {
7219
- const oldToolFiles = await processor.loadToolFilesToDelete();
8583
+ const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
7220
8584
  await processor.removeAiFiles(oldToolFiles);
7221
8585
  }
7222
8586
  const rulesyncFiles = await processor.loadRulesyncFiles();
@@ -7235,10 +8599,11 @@ async function generateCommands(config) {
7235
8599
  }
7236
8600
  let totalCommandOutputs = 0;
7237
8601
  logger.info("Generating command files...");
7238
- const toolTargets = config.getGlobal() ? (0, import_es_toolkit2.intersection)(config.getTargets(), CommandsProcessor.getToolTargetsGlobal()) : (0, import_es_toolkit2.intersection)(
8602
+ const toolTargets = (0, import_es_toolkit2.intersection)(
7239
8603
  config.getTargets(),
7240
8604
  CommandsProcessor.getToolTargets({
7241
- includeSimulated: config.getSimulatedCommands()
8605
+ global: config.getGlobal(),
8606
+ includeSimulated: config.getSimulateCommands()
7242
8607
  })
7243
8608
  );
7244
8609
  for (const baseDir of config.getBaseDirs()) {
@@ -7249,7 +8614,7 @@ async function generateCommands(config) {
7249
8614
  global: config.getGlobal()
7250
8615
  });
7251
8616
  if (config.getDelete()) {
7252
- const oldToolFiles = await processor.loadToolFilesToDelete();
8617
+ const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
7253
8618
  await processor.removeAiFiles(oldToolFiles);
7254
8619
  }
7255
8620
  const rulesyncFiles = await processor.loadRulesyncFiles();
@@ -7268,10 +8633,11 @@ async function generateSubagents(config) {
7268
8633
  }
7269
8634
  let totalSubagentOutputs = 0;
7270
8635
  logger.info("Generating subagent files...");
7271
- const toolTargets = config.getGlobal() ? (0, import_es_toolkit2.intersection)(config.getTargets(), SubagentsProcessor.getToolTargetsGlobal()) : (0, import_es_toolkit2.intersection)(
8636
+ const toolTargets = (0, import_es_toolkit2.intersection)(
7272
8637
  config.getTargets(),
7273
8638
  SubagentsProcessor.getToolTargets({
7274
- includeSimulated: config.getSimulatedSubagents()
8639
+ global: config.getGlobal(),
8640
+ includeSimulated: config.getSimulateSubagents()
7275
8641
  })
7276
8642
  );
7277
8643
  for (const baseDir of config.getBaseDirs()) {
@@ -7282,7 +8648,7 @@ async function generateSubagents(config) {
7282
8648
  global: config.getGlobal()
7283
8649
  });
7284
8650
  if (config.getDelete()) {
7285
- const oldToolFiles = await processor.loadToolFilesToDelete();
8651
+ const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
7286
8652
  await processor.removeAiFiles(oldToolFiles);
7287
8653
  }
7288
8654
  const rulesyncFiles = await processor.loadRulesyncFiles();
@@ -7294,16 +8660,51 @@ async function generateSubagents(config) {
7294
8660
  }
7295
8661
  return totalSubagentOutputs;
7296
8662
  }
8663
+ async function generateSkills(config) {
8664
+ if (!config.getFeatures().includes("skills")) {
8665
+ logger.debug("Skipping skill generation (not in --features)");
8666
+ return 0;
8667
+ }
8668
+ let totalSkillOutputs = 0;
8669
+ logger.info("Generating skill files...");
8670
+ const toolTargets = (0, import_es_toolkit2.intersection)(
8671
+ config.getTargets(),
8672
+ SkillsProcessor.getToolTargets({
8673
+ global: config.getGlobal(),
8674
+ includeSimulated: config.getSimulateSkills()
8675
+ })
8676
+ );
8677
+ for (const baseDir of config.getBaseDirs()) {
8678
+ for (const toolTarget of toolTargets) {
8679
+ const processor = new SkillsProcessor({
8680
+ baseDir,
8681
+ toolTarget,
8682
+ global: config.getGlobal()
8683
+ });
8684
+ if (config.getDelete()) {
8685
+ const oldToolDirs = await processor.loadToolDirsToDelete();
8686
+ await processor.removeAiDirs(oldToolDirs);
8687
+ }
8688
+ const rulesyncDirs = await processor.loadRulesyncDirs();
8689
+ const toolDirs = await processor.convertRulesyncDirsToToolDirs(rulesyncDirs);
8690
+ const writtenCount = await processor.writeAiDirs(toolDirs);
8691
+ totalSkillOutputs += writtenCount;
8692
+ logger.success(`Generated ${writtenCount} ${toolTarget} skill(s) in ${baseDir}`);
8693
+ }
8694
+ }
8695
+ return totalSkillOutputs;
8696
+ }
7297
8697
 
7298
8698
  // src/cli/commands/gitignore.ts
7299
- var import_node_path67 = require("path");
8699
+ var import_node_path80 = require("path");
7300
8700
  var gitignoreCommand = async () => {
7301
- const gitignorePath = (0, import_node_path67.join)(process.cwd(), ".gitignore");
8701
+ const gitignorePath = (0, import_node_path80.join)(process.cwd(), ".gitignore");
7302
8702
  const rulesFilesToIgnore = [
7303
8703
  "# Generated by rulesync - AI tool configuration files",
7304
8704
  // AGENTS.md
7305
8705
  "**/AGENTS.md",
7306
8706
  "**/.agents/",
8707
+ "**/.agents/skills/",
7307
8708
  // Amazon Q
7308
8709
  "**/.amazonq/",
7309
8710
  // Augment
@@ -7315,6 +8716,7 @@ var gitignoreCommand = async () => {
7315
8716
  "**/.claude/memories/",
7316
8717
  "**/.claude/commands/",
7317
8718
  "**/.claude/agents/",
8719
+ "**/.claude/skills/",
7318
8720
  "**/.claude/settings.local.json",
7319
8721
  "**/.mcp.json",
7320
8722
  // Cline
@@ -7324,20 +8726,25 @@ var gitignoreCommand = async () => {
7324
8726
  // Codex
7325
8727
  "**/.codexignore",
7326
8728
  "**/.codex/",
8729
+ "**/.codex/skills/",
7327
8730
  // Cursor
7328
8731
  "**/.cursor/",
7329
8732
  "**/.cursorignore",
7330
8733
  "**/.cursor/mcp.json",
8734
+ "**/.cursor/subagents/",
8735
+ "**/.cursor/skills/",
7331
8736
  // Gemini
7332
8737
  "**/GEMINI.md",
7333
8738
  "**/.gemini/memories/",
7334
8739
  "**/.gemini/commands/",
7335
8740
  "**/.gemini/subagents/",
8741
+ "**/.gemini/skills/",
7336
8742
  // GitHub Copilot
7337
8743
  "**/.github/copilot-instructions.md",
7338
8744
  "**/.github/instructions/",
7339
8745
  "**/.github/prompts/",
7340
8746
  "**/.github/subagents/",
8747
+ "**/.github/skills/",
7341
8748
  "**/.vscode/mcp.json",
7342
8749
  // Junie
7343
8750
  "**/.junie/guidelines.md",
@@ -7408,13 +8815,14 @@ async function importCommand(options) {
7408
8815
  await importMcp(config, tool);
7409
8816
  await importCommands(config, tool);
7410
8817
  await importSubagents(config, tool);
8818
+ await importSkills(config, tool);
7411
8819
  }
7412
8820
  async function importRules(config, tool) {
7413
8821
  if (!config.getFeatures().includes("rules")) {
7414
8822
  return 0;
7415
8823
  }
7416
8824
  const global = config.getGlobal();
7417
- const supportedTargets = global ? RulesProcessor.getToolTargetsGlobal() : RulesProcessor.getToolTargets();
8825
+ const supportedTargets = RulesProcessor.getToolTargets({ global });
7418
8826
  if (!supportedTargets.includes(tool)) {
7419
8827
  return 0;
7420
8828
  }
@@ -7468,7 +8876,7 @@ async function importMcp(config, tool) {
7468
8876
  return 0;
7469
8877
  }
7470
8878
  const global = config.getGlobal();
7471
- const supportedTargets = global ? McpProcessor.getToolTargetsGlobal() : McpProcessor.getToolTargets();
8879
+ const supportedTargets = McpProcessor.getToolTargets({ global });
7472
8880
  if (!supportedTargets.includes(tool)) {
7473
8881
  return 0;
7474
8882
  }
@@ -7493,7 +8901,7 @@ async function importCommands(config, tool) {
7493
8901
  return 0;
7494
8902
  }
7495
8903
  const global = config.getGlobal();
7496
- const supportedTargets = global ? CommandsProcessor.getToolTargetsGlobal() : CommandsProcessor.getToolTargets({ includeSimulated: false });
8904
+ const supportedTargets = CommandsProcessor.getToolTargets({ global, includeSimulated: false });
7497
8905
  if (!supportedTargets.includes(tool)) {
7498
8906
  return 0;
7499
8907
  }
@@ -7517,7 +8925,8 @@ async function importSubagents(config, tool) {
7517
8925
  if (!config.getFeatures().includes("subagents")) {
7518
8926
  return 0;
7519
8927
  }
7520
- const supportedTargets = SubagentsProcessor.getToolTargets({ includeSimulated: false });
8928
+ const global = config.getGlobal();
8929
+ const supportedTargets = SubagentsProcessor.getToolTargets({ global, includeSimulated: false });
7521
8930
  if (!supportedTargets.includes(tool)) {
7522
8931
  return 0;
7523
8932
  }
@@ -7537,9 +8946,34 @@ async function importSubagents(config, tool) {
7537
8946
  }
7538
8947
  return writtenCount;
7539
8948
  }
8949
+ async function importSkills(config, tool) {
8950
+ if (!config.getFeatures().includes("skills")) {
8951
+ return 0;
8952
+ }
8953
+ const global = config.getGlobal();
8954
+ const supportedTargets = SkillsProcessor.getToolTargets({ global });
8955
+ if (!supportedTargets.includes(tool)) {
8956
+ return 0;
8957
+ }
8958
+ const skillsProcessor = new SkillsProcessor({
8959
+ baseDir: config.getBaseDirs()[0] ?? ".",
8960
+ toolTarget: tool,
8961
+ global
8962
+ });
8963
+ const toolDirs = await skillsProcessor.loadToolDirs();
8964
+ if (toolDirs.length === 0) {
8965
+ return 0;
8966
+ }
8967
+ const rulesyncDirs = await skillsProcessor.convertToolDirsToRulesyncDirs(toolDirs);
8968
+ const writtenCount = await skillsProcessor.writeAiDirs(rulesyncDirs);
8969
+ if (config.getVerbose() && writtenCount > 0) {
8970
+ logger.success(`Created ${writtenCount} skill directories`);
8971
+ }
8972
+ return writtenCount;
8973
+ }
7540
8974
 
7541
8975
  // src/cli/commands/init.ts
7542
- var import_node_path68 = require("path");
8976
+ var import_node_path81 = require("path");
7543
8977
  async function initCommand() {
7544
8978
  logger.info("Initializing rulesync...");
7545
8979
  await ensureDir(RULESYNC_RELATIVE_DIR_PATH);
@@ -7567,8 +9001,8 @@ async function createConfigFile() {
7567
9001
  delete: true,
7568
9002
  verbose: false,
7569
9003
  global: false,
7570
- simulatedCommands: false,
7571
- simulatedSubagents: false,
9004
+ simulateCommands: false,
9005
+ simulateSubagents: false,
7572
9006
  modularMcp: false
7573
9007
  },
7574
9008
  null,
@@ -7702,14 +9136,14 @@ Attention, again, you are just the planner, so though you can read any files and
7702
9136
  await ensureDir(commandPaths.relativeDirPath);
7703
9137
  await ensureDir(subagentPaths.relativeDirPath);
7704
9138
  await ensureDir(ignorePaths.relativeDirPath);
7705
- const ruleFilepath = (0, import_node_path68.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
9139
+ const ruleFilepath = (0, import_node_path81.join)(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
7706
9140
  if (!await fileExists(ruleFilepath)) {
7707
9141
  await writeFileContent(ruleFilepath, sampleRuleFile.content);
7708
9142
  logger.success(`Created ${ruleFilepath}`);
7709
9143
  } else {
7710
9144
  logger.info(`Skipped ${ruleFilepath} (already exists)`);
7711
9145
  }
7712
- const mcpFilepath = (0, import_node_path68.join)(
9146
+ const mcpFilepath = (0, import_node_path81.join)(
7713
9147
  mcpPaths.recommended.relativeDirPath,
7714
9148
  mcpPaths.recommended.relativeFilePath
7715
9149
  );
@@ -7719,21 +9153,21 @@ Attention, again, you are just the planner, so though you can read any files and
7719
9153
  } else {
7720
9154
  logger.info(`Skipped ${mcpFilepath} (already exists)`);
7721
9155
  }
7722
- const commandFilepath = (0, import_node_path68.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
9156
+ const commandFilepath = (0, import_node_path81.join)(commandPaths.relativeDirPath, sampleCommandFile.filename);
7723
9157
  if (!await fileExists(commandFilepath)) {
7724
9158
  await writeFileContent(commandFilepath, sampleCommandFile.content);
7725
9159
  logger.success(`Created ${commandFilepath}`);
7726
9160
  } else {
7727
9161
  logger.info(`Skipped ${commandFilepath} (already exists)`);
7728
9162
  }
7729
- const subagentFilepath = (0, import_node_path68.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
9163
+ const subagentFilepath = (0, import_node_path81.join)(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
7730
9164
  if (!await fileExists(subagentFilepath)) {
7731
9165
  await writeFileContent(subagentFilepath, sampleSubagentFile.content);
7732
9166
  logger.success(`Created ${subagentFilepath}`);
7733
9167
  } else {
7734
9168
  logger.info(`Skipped ${subagentFilepath} (already exists)`);
7735
9169
  }
7736
- const ignoreFilepath = (0, import_node_path68.join)(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
9170
+ const ignoreFilepath = (0, import_node_path81.join)(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
7737
9171
  if (!await fileExists(ignoreFilepath)) {
7738
9172
  await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
7739
9173
  logger.success(`Created ${ignoreFilepath}`);
@@ -7746,12 +9180,12 @@ Attention, again, you are just the planner, so though you can read any files and
7746
9180
  var import_fastmcp = require("fastmcp");
7747
9181
 
7748
9182
  // src/mcp/commands.ts
7749
- var import_node_path69 = require("path");
7750
- var import_mini25 = require("zod/mini");
9183
+ var import_node_path82 = require("path");
9184
+ var import_mini30 = require("zod/mini");
7751
9185
  var maxCommandSizeBytes = 1024 * 1024;
7752
9186
  var maxCommandsCount = 1e3;
7753
9187
  async function listCommands() {
7754
- const commandsDir = (0, import_node_path69.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
9188
+ const commandsDir = (0, import_node_path82.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
7755
9189
  try {
7756
9190
  const files = await listDirectoryFiles(commandsDir);
7757
9191
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -7763,7 +9197,7 @@ async function listCommands() {
7763
9197
  });
7764
9198
  const frontmatter = command.getFrontmatter();
7765
9199
  return {
7766
- relativePathFromCwd: (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
9200
+ relativePathFromCwd: (0, import_node_path82.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
7767
9201
  frontmatter
7768
9202
  };
7769
9203
  } catch (error) {
@@ -7783,13 +9217,13 @@ async function getCommand({ relativePathFromCwd }) {
7783
9217
  relativePath: relativePathFromCwd,
7784
9218
  intendedRootDir: process.cwd()
7785
9219
  });
7786
- const filename = (0, import_node_path69.basename)(relativePathFromCwd);
9220
+ const filename = (0, import_node_path82.basename)(relativePathFromCwd);
7787
9221
  try {
7788
9222
  const command = await RulesyncCommand.fromFile({
7789
9223
  relativeFilePath: filename
7790
9224
  });
7791
9225
  return {
7792
- relativePathFromCwd: (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
9226
+ relativePathFromCwd: (0, import_node_path82.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
7793
9227
  frontmatter: command.getFrontmatter(),
7794
9228
  body: command.getBody()
7795
9229
  };
@@ -7808,7 +9242,7 @@ async function putCommand({
7808
9242
  relativePath: relativePathFromCwd,
7809
9243
  intendedRootDir: process.cwd()
7810
9244
  });
7811
- const filename = (0, import_node_path69.basename)(relativePathFromCwd);
9245
+ const filename = (0, import_node_path82.basename)(relativePathFromCwd);
7812
9246
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
7813
9247
  if (estimatedSize > maxCommandSizeBytes) {
7814
9248
  throw new Error(
@@ -7818,7 +9252,7 @@ async function putCommand({
7818
9252
  try {
7819
9253
  const existingCommands = await listCommands();
7820
9254
  const isUpdate = existingCommands.some(
7821
- (command2) => command2.relativePathFromCwd === (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
9255
+ (command2) => command2.relativePathFromCwd === (0, import_node_path82.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
7822
9256
  );
7823
9257
  if (!isUpdate && existingCommands.length >= maxCommandsCount) {
7824
9258
  throw new Error(`Maximum number of commands (${maxCommandsCount}) reached`);
@@ -7833,11 +9267,11 @@ async function putCommand({
7833
9267
  fileContent,
7834
9268
  validate: true
7835
9269
  });
7836
- const commandsDir = (0, import_node_path69.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
9270
+ const commandsDir = (0, import_node_path82.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
7837
9271
  await ensureDir(commandsDir);
7838
9272
  await writeFileContent(command.getFilePath(), command.getFileContent());
7839
9273
  return {
7840
- relativePathFromCwd: (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
9274
+ relativePathFromCwd: (0, import_node_path82.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
7841
9275
  frontmatter: command.getFrontmatter(),
7842
9276
  body: command.getBody()
7843
9277
  };
@@ -7852,12 +9286,12 @@ async function deleteCommand({ relativePathFromCwd }) {
7852
9286
  relativePath: relativePathFromCwd,
7853
9287
  intendedRootDir: process.cwd()
7854
9288
  });
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);
9289
+ const filename = (0, import_node_path82.basename)(relativePathFromCwd);
9290
+ const fullPath = (0, import_node_path82.join)(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
7857
9291
  try {
7858
9292
  await removeFile(fullPath);
7859
9293
  return {
7860
- relativePathFromCwd: (0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
9294
+ relativePathFromCwd: (0, import_node_path82.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
7861
9295
  };
7862
9296
  } catch (error) {
7863
9297
  throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -7866,23 +9300,23 @@ async function deleteCommand({ relativePathFromCwd }) {
7866
9300
  }
7867
9301
  }
7868
9302
  var commandToolSchemas = {
7869
- listCommands: import_mini25.z.object({}),
7870
- getCommand: import_mini25.z.object({
7871
- relativePathFromCwd: import_mini25.z.string()
9303
+ listCommands: import_mini30.z.object({}),
9304
+ getCommand: import_mini30.z.object({
9305
+ relativePathFromCwd: import_mini30.z.string()
7872
9306
  }),
7873
- putCommand: import_mini25.z.object({
7874
- relativePathFromCwd: import_mini25.z.string(),
9307
+ putCommand: import_mini30.z.object({
9308
+ relativePathFromCwd: import_mini30.z.string(),
7875
9309
  frontmatter: RulesyncCommandFrontmatterSchema,
7876
- body: import_mini25.z.string()
9310
+ body: import_mini30.z.string()
7877
9311
  }),
7878
- deleteCommand: import_mini25.z.object({
7879
- relativePathFromCwd: import_mini25.z.string()
9312
+ deleteCommand: import_mini30.z.object({
9313
+ relativePathFromCwd: import_mini30.z.string()
7880
9314
  })
7881
9315
  };
7882
9316
  var commandTools = {
7883
9317
  listCommands: {
7884
9318
  name: "listCommands",
7885
- description: `List all commands from ${(0, import_node_path69.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
9319
+ description: `List all commands from ${(0, import_node_path82.join)(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
7886
9320
  parameters: commandToolSchemas.listCommands,
7887
9321
  execute: async () => {
7888
9322
  const commands = await listCommands();
@@ -7924,11 +9358,11 @@ var commandTools = {
7924
9358
  };
7925
9359
 
7926
9360
  // src/mcp/ignore.ts
7927
- var import_node_path70 = require("path");
7928
- var import_mini26 = require("zod/mini");
9361
+ var import_node_path83 = require("path");
9362
+ var import_mini31 = require("zod/mini");
7929
9363
  var maxIgnoreFileSizeBytes = 100 * 1024;
7930
9364
  async function getIgnoreFile() {
7931
- const ignoreFilePath = (0, import_node_path70.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9365
+ const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
7932
9366
  try {
7933
9367
  const content = await readFileContent(ignoreFilePath);
7934
9368
  return {
@@ -7942,7 +9376,7 @@ async function getIgnoreFile() {
7942
9376
  }
7943
9377
  }
7944
9378
  async function putIgnoreFile({ content }) {
7945
- const ignoreFilePath = (0, import_node_path70.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9379
+ const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
7946
9380
  const contentSizeBytes = Buffer.byteLength(content, "utf8");
7947
9381
  if (contentSizeBytes > maxIgnoreFileSizeBytes) {
7948
9382
  throw new Error(
@@ -7963,7 +9397,7 @@ async function putIgnoreFile({ content }) {
7963
9397
  }
7964
9398
  }
7965
9399
  async function deleteIgnoreFile() {
7966
- const ignoreFilePath = (0, import_node_path70.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
9400
+ const ignoreFilePath = (0, import_node_path83.join)(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
7967
9401
  try {
7968
9402
  await removeFile(ignoreFilePath);
7969
9403
  return {
@@ -7976,11 +9410,11 @@ async function deleteIgnoreFile() {
7976
9410
  }
7977
9411
  }
7978
9412
  var ignoreToolSchemas = {
7979
- getIgnoreFile: import_mini26.z.object({}),
7980
- putIgnoreFile: import_mini26.z.object({
7981
- content: import_mini26.z.string()
9413
+ getIgnoreFile: import_mini31.z.object({}),
9414
+ putIgnoreFile: import_mini31.z.object({
9415
+ content: import_mini31.z.string()
7982
9416
  }),
7983
- deleteIgnoreFile: import_mini26.z.object({})
9417
+ deleteIgnoreFile: import_mini31.z.object({})
7984
9418
  };
7985
9419
  var ignoreTools = {
7986
9420
  getIgnoreFile: {
@@ -8013,8 +9447,8 @@ var ignoreTools = {
8013
9447
  };
8014
9448
 
8015
9449
  // src/mcp/mcp.ts
8016
- var import_node_path71 = require("path");
8017
- var import_mini27 = require("zod/mini");
9450
+ var import_node_path84 = require("path");
9451
+ var import_mini32 = require("zod/mini");
8018
9452
  var maxMcpSizeBytes = 1024 * 1024;
8019
9453
  async function getMcpFile() {
8020
9454
  const config = await ConfigResolver.resolve({});
@@ -8023,7 +9457,7 @@ async function getMcpFile() {
8023
9457
  validate: true,
8024
9458
  modularMcp: config.getModularMcp()
8025
9459
  });
8026
- const relativePathFromCwd = (0, import_node_path71.join)(
9460
+ const relativePathFromCwd = (0, import_node_path84.join)(
8027
9461
  rulesyncMcp.getRelativeDirPath(),
8028
9462
  rulesyncMcp.getRelativeFilePath()
8029
9463
  );
@@ -8056,7 +9490,7 @@ async function putMcpFile({ content }) {
8056
9490
  const paths = RulesyncMcp.getSettablePaths();
8057
9491
  const relativeDirPath = paths.recommended.relativeDirPath;
8058
9492
  const relativeFilePath = paths.recommended.relativeFilePath;
8059
- const fullPath = (0, import_node_path71.join)(baseDir, relativeDirPath, relativeFilePath);
9493
+ const fullPath = (0, import_node_path84.join)(baseDir, relativeDirPath, relativeFilePath);
8060
9494
  const rulesyncMcp = new RulesyncMcp({
8061
9495
  baseDir,
8062
9496
  relativeDirPath,
@@ -8065,9 +9499,9 @@ async function putMcpFile({ content }) {
8065
9499
  validate: true,
8066
9500
  modularMcp: config.getModularMcp()
8067
9501
  });
8068
- await ensureDir((0, import_node_path71.join)(baseDir, relativeDirPath));
9502
+ await ensureDir((0, import_node_path84.join)(baseDir, relativeDirPath));
8069
9503
  await writeFileContent(fullPath, content);
8070
- const relativePathFromCwd = (0, import_node_path71.join)(relativeDirPath, relativeFilePath);
9504
+ const relativePathFromCwd = (0, import_node_path84.join)(relativeDirPath, relativeFilePath);
8071
9505
  return {
8072
9506
  relativePathFromCwd,
8073
9507
  content: rulesyncMcp.getFileContent()
@@ -8082,15 +9516,15 @@ async function deleteMcpFile() {
8082
9516
  try {
8083
9517
  const baseDir = process.cwd();
8084
9518
  const paths = RulesyncMcp.getSettablePaths();
8085
- const recommendedPath = (0, import_node_path71.join)(
9519
+ const recommendedPath = (0, import_node_path84.join)(
8086
9520
  baseDir,
8087
9521
  paths.recommended.relativeDirPath,
8088
9522
  paths.recommended.relativeFilePath
8089
9523
  );
8090
- const legacyPath = (0, import_node_path71.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
9524
+ const legacyPath = (0, import_node_path84.join)(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
8091
9525
  await removeFile(recommendedPath);
8092
9526
  await removeFile(legacyPath);
8093
- const relativePathFromCwd = (0, import_node_path71.join)(
9527
+ const relativePathFromCwd = (0, import_node_path84.join)(
8094
9528
  paths.recommended.relativeDirPath,
8095
9529
  paths.recommended.relativeFilePath
8096
9530
  );
@@ -8104,11 +9538,11 @@ async function deleteMcpFile() {
8104
9538
  }
8105
9539
  }
8106
9540
  var mcpToolSchemas = {
8107
- getMcpFile: import_mini27.z.object({}),
8108
- putMcpFile: import_mini27.z.object({
8109
- content: import_mini27.z.string()
9541
+ getMcpFile: import_mini32.z.object({}),
9542
+ putMcpFile: import_mini32.z.object({
9543
+ content: import_mini32.z.string()
8110
9544
  }),
8111
- deleteMcpFile: import_mini27.z.object({})
9545
+ deleteMcpFile: import_mini32.z.object({})
8112
9546
  };
8113
9547
  var mcpTools = {
8114
9548
  getMcpFile: {
@@ -8141,12 +9575,12 @@ var mcpTools = {
8141
9575
  };
8142
9576
 
8143
9577
  // src/mcp/rules.ts
8144
- var import_node_path72 = require("path");
8145
- var import_mini28 = require("zod/mini");
9578
+ var import_node_path85 = require("path");
9579
+ var import_mini33 = require("zod/mini");
8146
9580
  var maxRuleSizeBytes = 1024 * 1024;
8147
9581
  var maxRulesCount = 1e3;
8148
9582
  async function listRules() {
8149
- const rulesDir = (0, import_node_path72.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
9583
+ const rulesDir = (0, import_node_path85.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
8150
9584
  try {
8151
9585
  const files = await listDirectoryFiles(rulesDir);
8152
9586
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -8159,7 +9593,7 @@ async function listRules() {
8159
9593
  });
8160
9594
  const frontmatter = rule.getFrontmatter();
8161
9595
  return {
8162
- relativePathFromCwd: (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
9596
+ relativePathFromCwd: (0, import_node_path85.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
8163
9597
  frontmatter
8164
9598
  };
8165
9599
  } catch (error) {
@@ -8179,14 +9613,14 @@ async function getRule({ relativePathFromCwd }) {
8179
9613
  relativePath: relativePathFromCwd,
8180
9614
  intendedRootDir: process.cwd()
8181
9615
  });
8182
- const filename = (0, import_node_path72.basename)(relativePathFromCwd);
9616
+ const filename = (0, import_node_path85.basename)(relativePathFromCwd);
8183
9617
  try {
8184
9618
  const rule = await RulesyncRule.fromFile({
8185
9619
  relativeFilePath: filename,
8186
9620
  validate: true
8187
9621
  });
8188
9622
  return {
8189
- relativePathFromCwd: (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
9623
+ relativePathFromCwd: (0, import_node_path85.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
8190
9624
  frontmatter: rule.getFrontmatter(),
8191
9625
  body: rule.getBody()
8192
9626
  };
@@ -8205,7 +9639,7 @@ async function putRule({
8205
9639
  relativePath: relativePathFromCwd,
8206
9640
  intendedRootDir: process.cwd()
8207
9641
  });
8208
- const filename = (0, import_node_path72.basename)(relativePathFromCwd);
9642
+ const filename = (0, import_node_path85.basename)(relativePathFromCwd);
8209
9643
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
8210
9644
  if (estimatedSize > maxRuleSizeBytes) {
8211
9645
  throw new Error(
@@ -8215,7 +9649,7 @@ async function putRule({
8215
9649
  try {
8216
9650
  const existingRules = await listRules();
8217
9651
  const isUpdate = existingRules.some(
8218
- (rule2) => rule2.relativePathFromCwd === (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
9652
+ (rule2) => rule2.relativePathFromCwd === (0, import_node_path85.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
8219
9653
  );
8220
9654
  if (!isUpdate && existingRules.length >= maxRulesCount) {
8221
9655
  throw new Error(`Maximum number of rules (${maxRulesCount}) reached`);
@@ -8228,11 +9662,11 @@ async function putRule({
8228
9662
  body,
8229
9663
  validate: true
8230
9664
  });
8231
- const rulesDir = (0, import_node_path72.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
9665
+ const rulesDir = (0, import_node_path85.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
8232
9666
  await ensureDir(rulesDir);
8233
9667
  await writeFileContent(rule.getFilePath(), rule.getFileContent());
8234
9668
  return {
8235
- relativePathFromCwd: (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
9669
+ relativePathFromCwd: (0, import_node_path85.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
8236
9670
  frontmatter: rule.getFrontmatter(),
8237
9671
  body: rule.getBody()
8238
9672
  };
@@ -8247,12 +9681,12 @@ async function deleteRule({ relativePathFromCwd }) {
8247
9681
  relativePath: relativePathFromCwd,
8248
9682
  intendedRootDir: process.cwd()
8249
9683
  });
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);
9684
+ const filename = (0, import_node_path85.basename)(relativePathFromCwd);
9685
+ const fullPath = (0, import_node_path85.join)(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
8252
9686
  try {
8253
9687
  await removeFile(fullPath);
8254
9688
  return {
8255
- relativePathFromCwd: (0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
9689
+ relativePathFromCwd: (0, import_node_path85.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
8256
9690
  };
8257
9691
  } catch (error) {
8258
9692
  throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
@@ -8261,23 +9695,23 @@ async function deleteRule({ relativePathFromCwd }) {
8261
9695
  }
8262
9696
  }
8263
9697
  var ruleToolSchemas = {
8264
- listRules: import_mini28.z.object({}),
8265
- getRule: import_mini28.z.object({
8266
- relativePathFromCwd: import_mini28.z.string()
9698
+ listRules: import_mini33.z.object({}),
9699
+ getRule: import_mini33.z.object({
9700
+ relativePathFromCwd: import_mini33.z.string()
8267
9701
  }),
8268
- putRule: import_mini28.z.object({
8269
- relativePathFromCwd: import_mini28.z.string(),
9702
+ putRule: import_mini33.z.object({
9703
+ relativePathFromCwd: import_mini33.z.string(),
8270
9704
  frontmatter: RulesyncRuleFrontmatterSchema,
8271
- body: import_mini28.z.string()
9705
+ body: import_mini33.z.string()
8272
9706
  }),
8273
- deleteRule: import_mini28.z.object({
8274
- relativePathFromCwd: import_mini28.z.string()
9707
+ deleteRule: import_mini33.z.object({
9708
+ relativePathFromCwd: import_mini33.z.string()
8275
9709
  })
8276
9710
  };
8277
9711
  var ruleTools = {
8278
9712
  listRules: {
8279
9713
  name: "listRules",
8280
- description: `List all rules from ${(0, import_node_path72.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
9714
+ description: `List all rules from ${(0, import_node_path85.join)(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
8281
9715
  parameters: ruleToolSchemas.listRules,
8282
9716
  execute: async () => {
8283
9717
  const rules = await listRules();
@@ -8319,12 +9753,12 @@ var ruleTools = {
8319
9753
  };
8320
9754
 
8321
9755
  // src/mcp/subagents.ts
8322
- var import_node_path73 = require("path");
8323
- var import_mini29 = require("zod/mini");
9756
+ var import_node_path86 = require("path");
9757
+ var import_mini34 = require("zod/mini");
8324
9758
  var maxSubagentSizeBytes = 1024 * 1024;
8325
9759
  var maxSubagentsCount = 1e3;
8326
9760
  async function listSubagents() {
8327
- const subagentsDir = (0, import_node_path73.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
9761
+ const subagentsDir = (0, import_node_path86.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
8328
9762
  try {
8329
9763
  const files = await listDirectoryFiles(subagentsDir);
8330
9764
  const mdFiles = files.filter((file) => file.endsWith(".md"));
@@ -8337,7 +9771,7 @@ async function listSubagents() {
8337
9771
  });
8338
9772
  const frontmatter = subagent.getFrontmatter();
8339
9773
  return {
8340
- relativePathFromCwd: (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
9774
+ relativePathFromCwd: (0, import_node_path86.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
8341
9775
  frontmatter
8342
9776
  };
8343
9777
  } catch (error) {
@@ -8359,14 +9793,14 @@ async function getSubagent({ relativePathFromCwd }) {
8359
9793
  relativePath: relativePathFromCwd,
8360
9794
  intendedRootDir: process.cwd()
8361
9795
  });
8362
- const filename = (0, import_node_path73.basename)(relativePathFromCwd);
9796
+ const filename = (0, import_node_path86.basename)(relativePathFromCwd);
8363
9797
  try {
8364
9798
  const subagent = await RulesyncSubagent.fromFile({
8365
9799
  relativeFilePath: filename,
8366
9800
  validate: true
8367
9801
  });
8368
9802
  return {
8369
- relativePathFromCwd: (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
9803
+ relativePathFromCwd: (0, import_node_path86.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
8370
9804
  frontmatter: subagent.getFrontmatter(),
8371
9805
  body: subagent.getBody()
8372
9806
  };
@@ -8385,7 +9819,7 @@ async function putSubagent({
8385
9819
  relativePath: relativePathFromCwd,
8386
9820
  intendedRootDir: process.cwd()
8387
9821
  });
8388
- const filename = (0, import_node_path73.basename)(relativePathFromCwd);
9822
+ const filename = (0, import_node_path86.basename)(relativePathFromCwd);
8389
9823
  const estimatedSize = JSON.stringify(frontmatter).length + body.length;
8390
9824
  if (estimatedSize > maxSubagentSizeBytes) {
8391
9825
  throw new Error(
@@ -8395,7 +9829,7 @@ async function putSubagent({
8395
9829
  try {
8396
9830
  const existingSubagents = await listSubagents();
8397
9831
  const isUpdate = existingSubagents.some(
8398
- (subagent2) => subagent2.relativePathFromCwd === (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
9832
+ (subagent2) => subagent2.relativePathFromCwd === (0, import_node_path86.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
8399
9833
  );
8400
9834
  if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
8401
9835
  throw new Error(`Maximum number of subagents (${maxSubagentsCount}) reached`);
@@ -8408,11 +9842,11 @@ async function putSubagent({
8408
9842
  body,
8409
9843
  validate: true
8410
9844
  });
8411
- const subagentsDir = (0, import_node_path73.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
9845
+ const subagentsDir = (0, import_node_path86.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
8412
9846
  await ensureDir(subagentsDir);
8413
9847
  await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
8414
9848
  return {
8415
- relativePathFromCwd: (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
9849
+ relativePathFromCwd: (0, import_node_path86.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
8416
9850
  frontmatter: subagent.getFrontmatter(),
8417
9851
  body: subagent.getBody()
8418
9852
  };
@@ -8427,12 +9861,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
8427
9861
  relativePath: relativePathFromCwd,
8428
9862
  intendedRootDir: process.cwd()
8429
9863
  });
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);
9864
+ const filename = (0, import_node_path86.basename)(relativePathFromCwd);
9865
+ const fullPath = (0, import_node_path86.join)(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
8432
9866
  try {
8433
9867
  await removeFile(fullPath);
8434
9868
  return {
8435
- relativePathFromCwd: (0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
9869
+ relativePathFromCwd: (0, import_node_path86.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
8436
9870
  };
8437
9871
  } catch (error) {
8438
9872
  throw new Error(
@@ -8444,23 +9878,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
8444
9878
  }
8445
9879
  }
8446
9880
  var subagentToolSchemas = {
8447
- listSubagents: import_mini29.z.object({}),
8448
- getSubagent: import_mini29.z.object({
8449
- relativePathFromCwd: import_mini29.z.string()
9881
+ listSubagents: import_mini34.z.object({}),
9882
+ getSubagent: import_mini34.z.object({
9883
+ relativePathFromCwd: import_mini34.z.string()
8450
9884
  }),
8451
- putSubagent: import_mini29.z.object({
8452
- relativePathFromCwd: import_mini29.z.string(),
9885
+ putSubagent: import_mini34.z.object({
9886
+ relativePathFromCwd: import_mini34.z.string(),
8453
9887
  frontmatter: RulesyncSubagentFrontmatterSchema,
8454
- body: import_mini29.z.string()
9888
+ body: import_mini34.z.string()
8455
9889
  }),
8456
- deleteSubagent: import_mini29.z.object({
8457
- relativePathFromCwd: import_mini29.z.string()
9890
+ deleteSubagent: import_mini34.z.object({
9891
+ relativePathFromCwd: import_mini34.z.string()
8458
9892
  })
8459
9893
  };
8460
9894
  var subagentTools = {
8461
9895
  listSubagents: {
8462
9896
  name: "listSubagents",
8463
- description: `List all subagents from ${(0, import_node_path73.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
9897
+ description: `List all subagents from ${(0, import_node_path86.join)(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
8464
9898
  parameters: subagentToolSchemas.listSubagents,
8465
9899
  execute: async () => {
8466
9900
  const subagents = await listSubagents();
@@ -8534,7 +9968,7 @@ async function mcpCommand({ version }) {
8534
9968
  }
8535
9969
 
8536
9970
  // src/cli/index.ts
8537
- var getVersion = () => "3.23.6";
9971
+ var getVersion = () => "3.25.0";
8538
9972
  var main = async () => {
8539
9973
  const program = new import_commander.Command();
8540
9974
  const version = getVersion();
@@ -8600,20 +10034,23 @@ var main = async () => {
8600
10034
  "-b, --base-dir <paths>",
8601
10035
  "Base directories to generate files (comma-separated for multiple paths)"
8602
10036
  ).option("-V, --verbose", "Verbose output").option("-c, --config <path>", "Path to configuration file").option("-g, --global", "Generate for global(user scope) configuration files").option(
8603
- "--simulated-commands",
10037
+ "--simulate-commands",
8604
10038
  "Generate simulated commands. This feature is only available for copilot, cursor and codexcli."
8605
10039
  ).option(
8606
- "--simulated-subagents",
10040
+ "--simulate-subagents",
8607
10041
  "Generate simulated subagents. This feature is only available for copilot, cursor and codexcli."
10042
+ ).option(
10043
+ "--simulate-skills",
10044
+ "Generate simulated skills. This feature is only available for copilot, cursor and codexcli."
8608
10045
  ).option(
8609
10046
  "--experimental-global",
8610
10047
  "Generate for global(user scope) configuration files (deprecated: use --global instead)"
8611
10048
  ).option(
8612
10049
  "--experimental-simulate-commands",
8613
- "Generate simulated commands (deprecated: use --simulated-commands instead)"
10050
+ "Generate simulated commands (deprecated: use --simulate-commands instead)"
8614
10051
  ).option(
8615
10052
  "--experimental-simulate-subagents",
8616
- "Generate simulated subagents (deprecated: use --simulated-subagents instead)"
10053
+ "Generate simulated subagents (deprecated: use --simulate-subagents instead)"
8617
10054
  ).option(
8618
10055
  "--modular-mcp",
8619
10056
  "Generate modular-mcp configuration for context compression (experimental)"
@@ -8627,8 +10064,9 @@ var main = async () => {
8627
10064
  baseDirs: options.baseDirs,
8628
10065
  configPath: options.config,
8629
10066
  global: options.global,
8630
- simulatedCommands: options.simulatedCommands,
8631
- simulatedSubagents: options.simulatedSubagents,
10067
+ simulateCommands: options.simulateCommands,
10068
+ simulateSubagents: options.simulateSubagents,
10069
+ simulateSkills: options.simulateSkills,
8632
10070
  modularMcp: options.modularMcp,
8633
10071
  experimentalGlobal: options.experimentalGlobal,
8634
10072
  experimentalSimulateCommands: options.experimentalSimulateCommands,